ctr_Repair/trunk/ConsoleDataMigration/sources/common/SimplePlayer.cpp
N2614 eeca247d7e FSのTry系APIのハンドリング見直し
吸出しスレッドのResultをチェックするように
HeapManagerの挙動変更。コンストラクタでAllocateしてデストラクタでFreeするように。
PlayHistoryManagerの削除

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@358 385bec56-5757-e545-9c3a-d8741f4650f1
2011-07-06 07:20:39 +00:00

241 lines
7.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: Horizon
File: SimplePlayer.cpp
Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Rev$
*---------------------------------------------------------------------------*/
#include <nn.h>
#include <nn/os.h>
#include <nn/fnd.h>
#include <nn/fs.h>
#include <nn/hid.h>
#include <nn/snd.h>
#include <string.h>
#include "SimplePlayer.h"
#include "wave.h"
#include "HeapManager.h"
namespace common
{
namespace
{
const int nFiles = 4; // 使用できる voice の最大値は 24
const char* apFileNames[nFiles] =
{
"rom:/ok.wav",
"rom:/ng.wav",
"rom:/cursor.wav",
"rom:/annotation.wav"
};
nn::snd::CTR::Voice* apVoice[nFiles];
nn::snd::CTR::WaveBuffer aBuffer[nFiles];
WaveFmt fmt[nFiles];
WaveData data[nFiles];
u8* apMemory[nFiles];
nn::os::CriticalSection s_CriticalSection;
bool s_SoundThreadInitialized = false;
// サウンドスレッド関連
const int SOUND_THREAD_STACK_SIZE = 4096;
nn::os::StackBuffer<SOUND_THREAD_STACK_SIZE> s_SoundThreadStack;
nn::os::Thread threadSound;
bool threadSoundFlag;
void SoundThreadFunc()
{
// サウンド出力をステレオに
nn::snd::SetSoundOutputMode(nn::snd::OUTPUT_MODE_STEREO);
// マスターボリュームを設定
nn::snd::SetMasterVolume( 1.0 );
NN_LOG("Loading wav files...\n");
// ファイルを開く
for (int i = 0; i < nFiles; i++)
{
if (apFileNames[i] == NULL) continue;
nn::snd::Voice* pVoice = NULL;
nn::fs::FileReader fileReader;
nn::Result result = fileReader.TryInitialize(apFileNames[i]);
NN_UTIL_PANIC_IF_FAILED(result);
if (::std::strcmp(::std::strrchr(apFileNames[i], '.'), ".wav") == false)
{
// 連続メモリ領域の取得、確認
apMemory[i] = reinterpret_cast<u8*>(ForceAllocate(GetWaveLength(fileReader), 32));
if (apMemory[i] == NULL)
{
NN_LOG("Failed to allocate continuous memory\n");
continue;
}
// Wave データを読み込み、キャッシュを無効に
data[i].buf = apMemory[i];
LoadWave(fileReader, &fmt[i], &data[i]);
nn::snd::FlushDataCache(reinterpret_cast<uptr>(apMemory[i]), data[i].size);
NN_LOG("%s (%1dch, %5dHz, %2d-bit wav file)\n",
apFileNames[i], fmt[i].channel, fmt[i].sample_rate, fmt[i].quantum_bits);
pVoice = apVoice[i] = nn::snd::AllocVoice(128, NULL, NULL);
NN_TASSERT_(pVoice);
nn::snd::SampleFormat format = (fmt[i].quantum_bits == 8) ?
nn::snd::SAMPLE_FORMAT_PCM8 :
nn::snd::SAMPLE_FORMAT_PCM16;
pVoice->SetChannelCount( fmt[i].channel );
pVoice->SetSampleFormat( format );
nn::snd::InitializeWaveBuffer(&aBuffer[i]);
aBuffer[i].bufferAddress = apMemory[i];
aBuffer[i].sampleLength = nn::snd::GetSampleLength(data[i].size, format, fmt[i].channel);
aBuffer[i].loopFlag = false;
fileReader.Finalize();
// 音量の設定
nn::snd::MixParam mix;
mix.mainBus[nn::snd::CHANNEL_INDEX_FRONT_LEFT ] = 0.707f; // メインボリューム (L)
mix.mainBus[nn::snd::CHANNEL_INDEX_FRONT_RIGHT] = 0.707f; // メインボリューム (R)
pVoice->SetMixParam(mix);
pVoice->SetVolume(1.0f);
// pitch の設定
pVoice->SetSampleRate(fmt[i].sample_rate);
pVoice->SetPitch(1.0f);
}
}
// 再生開始
for (int i = 0; i < nFiles; i++)
{
if (apFileNames[i] != NULL)
{
apVoice[i]->SetState( nn::snd::Voice::STATE_PLAY );
}
}
s_SoundThreadInitialized = true;
threadSoundFlag = true;
while (threadSoundFlag)
{
nn::snd::WaitForDspSync(); // DSP からのデータ受信を待つ。
s_CriticalSection.Enter(); // メインスレッドとの排他制御
nn::snd::SendParameterToDsp(); // パラメータを DSP に送信。
s_CriticalSection.Leave(); // メインスレッドとの排他制御
}
// 再生終了
for (int i = 0; i < nFiles; i++)
{
if (apVoice[i])
{
nn::snd::FreeVoice(apVoice[i]);
}
}
}
}
void InitializeSimplePlayer()
{
NN_LOG("Initialize SimplePlayer\n");
nn::Result result;
const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
static char buffer[ROMFS_BUFFER_SIZE];
NN_UTIL_PANIC_IF_FAILED(
nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
// dsp, snd の初期化
result = nn::dsp::Initialize();
NN_UTIL_PANIC_IF_FAILED(result);
result = nn::dsp::LoadDefaultComponent();
NN_UTIL_PANIC_IF_FAILED(result);
result = nn::snd::Initialize();
NN_UTIL_PANIC_IF_FAILED(result);
s_CriticalSection.Initialize();
// サウンドスレッドを起動DSP 割り込みイベント待ち)
threadSound.Start(SoundThreadFunc, s_SoundThreadStack);
}
void PlaySound(SoundEffect index)
{
NN_ASSERT(index < SOUND_MAX);
while(!s_SoundThreadInitialized)
{
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
}
nn::snd::CTR::Voice* pVoice = apVoice[index];
if (!pVoice->IsPlaying())
{
nn::snd::InitializeWaveBuffer(&aBuffer[index]);
aBuffer[index].bufferAddress = apMemory[index];
nn::snd::SampleFormat format = (fmt[index].quantum_bits == 8) ? nn::snd::SAMPLE_FORMAT_PCM8
: nn::snd::SAMPLE_FORMAT_PCM16;
aBuffer[index].sampleLength = nn::snd::GetSampleLength(data[index].size, format, fmt[index].channel);
aBuffer[index].loopFlag = false;
pVoice->AppendWaveBuffer(&aBuffer[index]);
NN_LOG("[voice%d] %s (pitch = %f)\n",
index,
(pVoice->GetState() == nn::snd::Voice::STATE_PAUSE ? "pause" : "play "),
pVoice->GetPitch());
}
}
void FinalizeSimplePlayer()
{
nn::Result result;
// サウンドスレッドの破棄
threadSoundFlag = false;
threadSound.Join();
// SND の終了処理
result = nn::snd::Finalize();
NN_UTIL_PANIC_IF_FAILED(result);
s_CriticalSection.Finalize();
// DSP の終了処理
result = nn::dsp::UnloadComponent();
NN_UTIL_PANIC_IF_FAILED(result);
nn::dsp::Finalize();
NN_LOG("Finalize SimplePlayer\n");
}
} // namespace ConsoleBackup
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/