1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_HardwareManager.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: 32385 $ 16 *---------------------------------------------------------------------------*/ 17 18 #ifndef NW_SND_HARDWARE_MANAGER_H_ 19 #define NW_SND_HARDWARE_MANAGER_H_ 20 21 #include <nw/ut/ut_LinkList.h> 22 #include <nw/snd/snd_Global.h> 23 #include <nw/snd/snd_MoveValue.h> 24 #include <nw/snd/snd_Util.h> 25 #include <nw/snd/snd_Macro.h> 26 #include <nw/snd/snd_FxBase.h> 27 #include <nw/snd/snd_BiquadFilterCallback.h> 28 #include <nw/snd/snd_BiquadFilterPresets.h> 29 30 namespace nw { 31 namespace snd { 32 namespace internal { 33 namespace driver { 34 35 class HardwareManager : public Util::Singleton<HardwareManager> 36 { 37 public: 38 typedef void (*HardwareCallback)(); 39 40 public: 41 42 // 1 オーディオフレームあたり何ミリ秒か? 43 static const u32 SOUND_FRAME_INTERVAL_MSEC = 5; // 大体の数値 44 45 // 何ボイスあるか? 46 static const u32 SOUND_VOICE_COUNT = NN_SND_VOICE_NUM; 47 48 // ------------------------------------------------------------------------ 49 // 初期化 50 void Initialize(); IsInitialized()51 bool IsInitialized() { return m_IsInitialized != 0; } 52 void Finalize(); 53 54 void Update(); 55 56 // ------------------------------------------------------------------------ 57 // 出力モード 58 void SetOutputMode( OutputMode mode ); GetOutputMode()59 OutputMode GetOutputMode() const { return m_OutputMode; } 60 61 // ------------------------------------------------------------------------ 62 // エフェクト 63 64 // エフェクト管理 65 typedef ut::LinkList< FxBase, offsetof(FxBase, m_Link) > FxList; 66 static const SampleFormat FX_SAMPLE_FORMAT = SAMPLE_FORMAT_PCM_S32; 67 static const int FX_SAMPLE_RATE = 32728; 68 69 // エフェクト登録、削除、削除確認 70 bool AppendEffect( AuxBus bus, FxBase* pFx ); 71 #ifdef NW_PLATFORM_CTR 72 bool AppendEffect( AuxBus bus, nn::snd::FxDelay* pFx ); 73 bool AppendEffect( AuxBus bus, nn::snd::FxReverb* pFx ); 74 #endif 75 void ClearEffect( AuxBus bus, int fadeTimes ); IsFinishedClearEffect(AuxBus bus)76 bool IsFinishedClearEffect( AuxBus bus ) const 77 { 78 NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM ); 79 return m_AuxFadeVolume[ bus ].IsFinished(); 80 } 81 82 // リターンボリューム SetAuxReturnVolume(AuxBus bus,f32 volume,int fadeTimes)83 void SetAuxReturnVolume( AuxBus bus, f32 volume, int fadeTimes ) 84 { 85 NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM ); 86 m_AuxUserVolume[ bus ].SetTarget( volume, fadeTimes ); 87 } GetAuxReturnVolume(AuxBus bus)88 f32 GetAuxReturnVolume( AuxBus bus ) const 89 { 90 NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM ); 91 return m_AuxUserVolume[ bus ].GetValue(); 92 } 93 94 #ifdef NW_PLATFORM_CTR 95 // エフェクト負荷計測 GetEffectProcessTick(AuxBus bus)96 nn::os::Tick GetEffectProcessTick( AuxBus bus ) const 97 { 98 return m_EffectProcessTick[ bus ]; 99 } 100 #endif 101 102 103 // ------------------------------------------------------------------------ 104 f32 GetOutputVolume() const; 105 106 // ------------------------------------------------------------------------ 107 // マスターボリューム 108 void SetMasterVolume( float volume, int fadeTimes ); GetMasterVolume()109 f32 GetMasterVolume() const { return m_MasterVolume.GetValue(); } 110 111 // ------------------------------------------------------------------------ 112 // SRC タイプ 113 void SetSrcType( SrcType type ); GetSrcType()114 SrcType GetSrcType() const { return m_SrcType; } 115 116 // ------------------------------------------------------------------------ 117 // Biquad フィルタ 118 void SetBiquadFilterCallback( int type, const BiquadFilterCallback* cb ); GetBiquadFilterCallback(int type)119 const BiquadFilterCallback* GetBiquadFilterCallback( int type ) 120 { 121 NW_MINMAX_ASSERT( type, BIQUAD_FILTER_TYPE_NONE, BIQUAD_FILTER_TYPE_USER_MAX ); 122 return m_BiquadFilterCallbackTable[ type ]; 123 } 124 125 // ------------------------------------------------------------------------ 126 // リセット前準備 127 void PrepareReset(); 128 bool IsResetReady() const; 129 130 u32 GetChannelCount() const; 131 132 HardwareManager(); 133 134 private: 135 static const u8 AUX_CALLBACK_WAIT_FRAME = 2; 136 #ifdef NW_PLATFORM_CTRWIN 137 static const u16 AUX_RETURN_VOLUME_MAX = 0x8000; 138 static void AuxCallbackFunc( void* data, void* context ); 139 typedef void (*AuxCallback)(void *data, void *context); 140 #else 141 static const f32 AUX_RETURN_VOLUME_MAX = 1.0f; 142 static void AuxCallbackFunc( nn::snd::AuxBusData* data, s32 sampleLength, uptr userData ); 143 typedef void (*AuxCallback)( nn::snd::AuxBusData* data, s32 sampleLength, uptr userData ); 144 #endif 145 static const BiquadFilterLpf BIQUAD_FILTER_LPF; 146 static const BiquadFilterHpf BIQUAD_FILTER_HPF; 147 static const BiquadFilterBpf512 BIQUAD_FILTER_BPF_512; 148 static const BiquadFilterBpf1024 BIQUAD_FILTER_BPF_1024; 149 static const BiquadFilterBpf2048 BIQUAD_FILTER_BPF_2048; 150 151 void FinalizeEffect( AuxBus bus ); GetEffectList(AuxBus bus)152 FxList& GetEffectList( AuxBus bus ) 153 { 154 NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM ); 155 return m_FxList[ bus ]; 156 } 157 158 bool m_IsInitialized; 159 160 OutputMode m_OutputMode; 161 SrcType m_SrcType; 162 163 MoveValue<f32,int> m_MasterVolume; 164 MoveValue<f32,int> m_VolumeForReset; 165 MoveValue<f32,int> m_AuxFadeVolume[ AUX_BUS_NUM ]; 166 MoveValue<f32,int> m_AuxUserVolume[ AUX_BUS_NUM ]; 167 FxList m_FxList[ AUX_BUS_NUM ]; 168 AuxCallback m_AuxCallback[ AUX_BUS_NUM ]; // Initialize 前の登録 CB 169 170 const BiquadFilterCallback* m_BiquadFilterCallbackTable[BIQUAD_FILTER_TYPE_USER_MAX+1]; 171 172 #ifdef NW_PLATFORM_CTRWIN 173 void* m_AuxCallbackContext[ AUX_BUS_NUM ]; 174 OSTick m_EffectProcessTick[ AUX_BUS_NUM ]; 175 #else 176 uptr m_AuxCallbackContext[ AUX_BUS_NUM ]; 177 nn::os::Tick m_EffectProcessTick[ AUX_BUS_NUM ]; 178 #endif 179 180 // コールバック登録後、バッファがクリアになるまで待つ 181 // (AUX_CALLBACK_WAIT_FRAME [=2] フレーム) 182 u8 m_AuxCallbackWaitCounter[ AUX_BUS_NUM ]; 183 184 #ifdef NW_PLATFORM_CTRWIN 185 public: 186 struct CallbackListNode 187 { 188 ut::LinkListNode link; 189 HardwareCallback callback; 190 }; 191 192 typedef ut::LinkList< CallbackListNode, offsetof(CallbackListNode,link)> CallbackList; 193 194 // 195 // プラットフォーム固有のもの 196 // 197 public: 198 static void AxCallbackFunc(); 199 static const int ZERO_BUFFER_SIZE = 256; 200 201 // ------------------------------------------------------------------------ 202 // 定期的なコールバック設定 (3msec[等] ごとに呼ばれる) 203 void RegisterCallback( CallbackListNode* node, HardwareCallback callback ); 204 void UnregisterCallback( CallbackListNode* node ); 205 206 void* GetZeroBufferAddress(); 207 208 private: 209 static void HardwareCallbackFunc(); 210 static void AiDmaCallbackFunc(); // for PrepareReset 211 void PrepareResetProc(); // for PrepareReset 212 213 CallbackList m_CallbackList; 214 215 AXUserCallback m_PreRegisteredCallback; 216 void* m_pZeroBufferAddress; 217 AIDCallback m_OldAidCallback; 218 vs32 m_ResetReadyCounter; 219 #endif // NW_PLATFORM_CTRWIN 220 221 }; 222 223 } // namespace nw::snd::internal::driver 224 } // namespace nw::snd::internal 225 } // namespace nw::snd 226 } // namespace nw 227 228 229 #endif /* NW_SND_HARDWARE_MANAGER_H_ */ 230 231