1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_SoundThread.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: 31311 $ 16 *---------------------------------------------------------------------------*/ 17 18 #ifndef NW_SND_SOUND_THREAD_H_ 19 #define NW_SND_SOUND_THREAD_H_ 20 21 #include <nn/os.h> 22 #include <nw/os.h> 23 #include <nw/ut/ut_LinkList.h> 24 #include <nw/ut/ut_PreProcessor.h> 25 #include <nw/snd/snd_Config.h> 26 #include <nw/snd/snd_HardwareManager.h> 27 #include <nw/snd/snd_ThreadStack.h> 28 #include <nw/snd/snd_Global.h> 29 30 namespace nw { 31 namespace snd { 32 namespace internal { 33 namespace driver { 34 35 class SoundThread 36 { 37 /* ------------------------------------------------------------------------ 38 typename definition 39 ------------------------------------------------------------------------ */ 40 public: 41 class SoundFrameCallback 42 { 43 public: 44 ut::LinkListNode m_Link; 45 ~SoundFrameCallback()46 virtual ~SoundFrameCallback() {} OnBeginSoundFrame()47 virtual void OnBeginSoundFrame() {} OnEndSoundFrame()48 virtual void OnEndSoundFrame() {} 49 }; 50 51 class PlayerCallback 52 { 53 public: 54 ut::LinkListNode m_Link; 55 ~PlayerCallback()56 virtual ~PlayerCallback() {} OnUpdateFrameSoundThread()57 virtual void OnUpdateFrameSoundThread() {} OnUpdateVoiceSoundThread()58 virtual void OnUpdateVoiceSoundThread() {} OnShutdownSoundThread()59 virtual void OnShutdownSoundThread() {} 60 }; 61 62 /* ------------------------------------------------------------------------ 63 constant definition 64 ------------------------------------------------------------------------ */ 65 private: 66 #ifdef NW_PLATFORM_CTRWIN 67 static const int THREAD_MESSAGE_BUFSIZE = 8; 68 static const int MESSAGE_HW_CALLBACK = 1; 69 static const int MESSAGE_SHUTDOWN = 2; 70 #endif 71 72 /* ------------------------------------------------------------------------ 73 class member 74 ------------------------------------------------------------------------ */ 75 public: 76 static SoundThread& GetInstance(); 77 78 #if defined( NW_SND_AVAILABLE_NN_SND_STARTSOUNDTHREAD ) 79 80 #if defined ( NW_SND_AVAILABLE_NN_SND_STARTSOUNDTHREAD2 ) 81 bool CreateSoundThread( 82 uptr stackBufferAddress, 83 size_t stackBufferSize, 84 s32 priority, 85 uptr userThreadStackBufferAddress, 86 size_t userThreadStackBufferSize, 87 s32 userThreadPriority, 88 s32 coreNo, 89 bool isEnableGetTick 90 ); 91 #else 92 bool CreateSoundThread( 93 uptr stackBufferAddress, 94 size_t stackBufferSize, 95 s32 priority, 96 s32 coreNo, 97 bool isEnableGetTick ); 98 bool CreateUserSoundThread( // サウンドスレッドコア1動作時用、AUX 等処理スレッド 99 uptr stackBufferAddress, 100 size_t stackBufferSize, 101 s32 priority ); 102 #endif 103 104 #else 105 bool Create( 106 s32 priority, 107 ThreadStack& stack, 108 s32 coreNo, 109 bool enableGetTick ); 110 #endif 111 void Destroy(); IsCreated()112 bool IsCreated() const { return m_CreateFlag != 0; } 113 114 void Initialize(); 115 void Finalize(); 116 Pause(bool pauseFlag)117 void Pause( bool pauseFlag ) { m_PauseFlag = pauseFlag; } 118 void FrameProcess(); 119 120 // ユーザーが自前で SDK の Wait/Send を呼ぶ場合に利用する FrameProcessForExternalThread()121 void FrameProcessForExternalThread() 122 { 123 FrameProcess(); 124 } 125 RegisterSoundFrameUserCallback(SoundFrameUserCallback callback,uptr arg)126 void RegisterSoundFrameUserCallback( SoundFrameUserCallback callback, uptr arg ) 127 { 128 m_UserCallback = callback; 129 m_UserCallbackArg = arg; 130 } ClearSoundFrameUserCallback()131 void ClearSoundFrameUserCallback() 132 { 133 m_UserCallback = NULL; 134 m_UserCallbackArg = NULL; 135 } GetRegisteredSoundFrameUserCallback(SoundFrameUserCallback * pCallback,uptr * pArg)136 void GetRegisteredSoundFrameUserCallback( SoundFrameUserCallback* pCallback, uptr* pArg ) 137 { 138 *pCallback = m_UserCallback; 139 *pArg = m_UserCallbackArg; 140 } 141 142 void RegisterSoundFrameCallback( SoundFrameCallback* callback ); 143 void UnregisterSoundFrameCallback( SoundFrameCallback* callback ); 144 145 void RegisterPlayerCallback( PlayerCallback* callback ); 146 void UnregisterPlayerCallback( PlayerCallback* callback ); 147 148 #ifdef NW_PLATFORM_CTR 149 void CalcProcessCost( const nn::os::Tick& tick ); 150 void GetTickCount( nn::os::Tick& tick, int& count ) const; 151 void ClearTickCount(); GetDspCycles()152 int GetDspCycles() const 153 { 154 return m_DspCycles; 155 } ClearDspCycles()156 void ClearDspCycles() 157 { 158 m_DspCycles = 0; 159 } GetPerfHistogram()160 Util::PerfHistogram& GetPerfHistogram() { return m_PerfHistogram; } BeginCalcPerf()161 void BeginCalcPerf() { m_IsBeginCalcPerf = true; m_PerfDataCount = 0; } EndCalcPerf()162 void EndCalcPerf() { m_IsBeginCalcPerf = false; } ResetCalcPerf()163 void ResetCalcPerf() { m_PerfDataCount = 0; } 164 #endif 165 Lock()166 void Lock() { m_CriticalSection.Enter(); } Unlock()167 void Unlock() { m_CriticalSection.Leave(); } 168 169 private: 170 typedef 171 ut::LinkList< SoundFrameCallback, offsetof(SoundFrameCallback,m_Link)> 172 SoundFrameCallbackList; 173 typedef 174 ut::LinkList< PlayerCallback, offsetof(PlayerCallback,m_Link)> 175 PlayerCallbackList; 176 177 SoundThread(); 178 179 bool PrepareForCreate( bool enableGetTick ); 180 181 void SoundThreadProc(); 182 void VoiceUpdate(); 183 #ifdef NW_PLATFORM_CTRWIN 184 void HwCallbackProc(); 185 static void HwCallbackFunc(); 186 #endif 187 static void SoundThreadFunc( uptr arg ); 188 static void UserThreadCallback( uptr arg ); 189 190 #ifdef NW_SND_AVAILABLE_NN_SND_STARTSOUNDTHREAD 191 // nn::snd::StartSoundThread では、SDK 内部に nn::os::Thread を保持する 192 #else 193 nn::os::Thread m_Thread; 194 #endif 195 196 #ifdef NW_PLATFORM_CTRWIN 197 HardwareManager::CallbackListNode m_HwCallbackNode; 198 uptr m_MsgBuffer[ THREAD_MESSAGE_BUFSIZE ]; 199 nn::os::BlockingQueue m_BlockingQueue; 200 #else 201 nn::os::Tick m_SoundThreadSumTick; // サウンドスレッド累積処理時間 202 int m_SoundThreadCount; // サウンドスレッド累積処理回数 203 int m_DspCycles; // 累積 DSP サイクル 204 Util::PerfHistogram m_PerfHistogram; 205 bool m_IsBeginCalcPerf; 206 #endif 207 208 #ifdef NW_SND_CONFIG_USE_INTERCORE_CRITICALSECTION 209 typedef nn::os::InterCoreCriticalSection CriticalSection; 210 #else 211 typedef nn::os::CriticalSection CriticalSection; 212 #endif 213 mutable CriticalSection m_CriticalSection; 214 215 SoundFrameCallbackList m_SoundFrameCallbackList; 216 PlayerCallbackList m_PlayerCallbackList; 217 SoundFrameUserCallback m_UserCallback; 218 uptr m_UserCallbackArg; 219 s32 m_SoundThreadCoreNo; 220 bool m_CreateFlag; 221 bool m_PauseFlag; 222 bool m_IsEnableGetTick; 223 volatile bool m_IsFinalizing; 224 225 // デバッグ 226 public: 227 struct PerfData 228 { 229 f32 load; // 処理負荷 (整数%) 230 u8 voice; // 使用ボイス数 231 u8 noteOn; // ノート音の数 232 u8 padding[2]; 233 }; SetPerfDataBuffer(PerfData * data,int num)234 void SetPerfDataBuffer( PerfData* data, int num ) 235 { 236 m_pPerfData = data; 237 m_PerfDataNum = num; 238 } IncrNoteOnCount()239 void IncrNoteOnCount() { m_NoteOnCount += 1; } GetPerfDataCount()240 int GetPerfDataCount() const { return m_PerfDataCount; } 241 private: 242 PerfData* m_pPerfData; 243 int m_NoteOnCount; 244 int m_PerfDataNum; 245 int m_PerfDataCount; 246 }; 247 248 class SoundThreadLock 249 { 250 public: SoundThreadLock()251 SoundThreadLock() 252 { 253 SoundThread::GetInstance().Lock(); 254 } 255 ~SoundThreadLock()256 ~SoundThreadLock() 257 { 258 SoundThread::GetInstance().Unlock(); 259 } 260 261 private: 262 NW_DISALLOW_COPY_AND_ASSIGN( SoundThreadLock ); 263 }; 264 265 } // namespace nw::snd::internal::driver 266 } // namespace nw::snd::internal 267 } // namespace nw::snd 268 } // namespace nw 269 270 271 #endif /* NW_SND_SOUND_THREAD_H_ */ 272 273