1/*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_HardwareManagerDSP.cppi 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision:$ 14 *---------------------------------------------------------------------------*/ 15 16#define DSP_32BIT_TO_ARM(value) (u32)(((u32)(value) >> 16) | ((u32)(value) << 16)) 17 18namespace nw { 19namespace snd { 20namespace internal { 21namespace driver { 22 23namespace 24{ 25class Perf 26{ 27private: 28 static const int LOG_BUF_SIZE = 7; 29#ifdef NW_PLATFORM_CTR 30 nn::os::Tick m_Ticks[ LOG_BUF_SIZE ]; 31 nn::os::Tick m_TmpTick; 32#endif 33 int m_Counter; 34public: 35 Perf() : m_Counter( 0 ) {} 36 37 void Begin() 38 { 39 m_TmpTick = nn::os::Tick::GetSystemCurrent(); 40 } 41 void End() 42 { 43 m_Ticks[m_Counter] = nn::os::Tick::GetSystemCurrent() - m_TmpTick; 44 m_Counter += 1; 45 46 if ( m_Counter == LOG_BUF_SIZE ) 47 { 48 char str[300]; str[0] = '\0'; 49 for ( int i = 0; i < LOG_BUF_SIZE; i++ ) 50 { 51 std::snprintf( str, 300, "%s %5lld,", 52 str, m_Ticks[i].ToTimeSpan().GetMicroSeconds() ); 53 } 54 NN_LOG("%s\n", str ); 55 m_Counter = 0; 56 } 57 } 58}; 59Perf s_Perf; 60 61} 62 63// 64// 関数 65// 66/*---------------------------------------------------------------------------* 67 Name: HardwareManager 68 69 Description: コンストラクタ 70 71 Arguments: なし 72 73 Returns: なし 74 *---------------------------------------------------------------------------*/ 75HardwareManager::HardwareManager() 76: m_IsInitialized( false ), 77 m_OutputMode( OUTPUT_MODE_STEREO ), 78 m_SrcType( SRC_TYPE_4TAP ) 79{ 80 m_MasterVolume.InitValue( 1.0f ); 81 m_VolumeForReset.InitValue( 1.0f ); 82 83 for ( int i=0; i<AUX_BUS_NUM; i++ ) 84 { 85 m_AuxFadeVolume[ i ].InitValue( 1.0f ); 86 m_AuxUserVolume[ i ].InitValue( 1.0f ); 87 m_AuxCallback[ i ] = NULL; 88 m_AuxCallbackContext[ i ] = NULL; 89 m_EffectProcessTick[ i ] = nn::os::Tick( 0 ); 90 } 91} 92 93void HardwareManager::Initialize() 94{ 95 if ( m_IsInitialized ) return; 96 97 // AUX コールバック設定、既に登録されている AUX コールバックを保存する 98 for ( int busId = nn::snd::AUX_BUS_A; busId < nn::snd::AUX_BUS_NUM; busId++ ) 99 { 100#ifndef NW_SND_DEBUG_NOUSE_CTRSDK 101 nn::snd::GetAuxCallback( 102 static_cast<nn::snd::AuxBusId>( busId ), 103 &m_AuxCallback[ busId ], 104 &m_AuxCallbackContext[ busId ] ); 105 nn::snd::RegisterAuxCallback( static_cast<nn::snd::AuxBusId>(busId), NULL, NULL ); 106#endif 107 } 108 109 // biquadフィルタテーブル初期化 110 for ( int i = 0; i < BIQUAD_FILTER_TYPE_USER_MAX + 1; i++ ) 111 { 112 m_BiquadFilterCallbackTable[i] = NULL; 113 } 114 SetBiquadFilterCallback( BIQUAD_FILTER_TYPE_LPF, &BIQUAD_FILTER_LPF ); 115 SetBiquadFilterCallback( BIQUAD_FILTER_TYPE_HPF, &BIQUAD_FILTER_HPF ); 116 SetBiquadFilterCallback( BIQUAD_FILTER_TYPE_BPF512, &BIQUAD_FILTER_BPF_512 ); 117 SetBiquadFilterCallback( BIQUAD_FILTER_TYPE_BPF1024, &BIQUAD_FILTER_BPF_1024 ); 118 SetBiquadFilterCallback( BIQUAD_FILTER_TYPE_BPF2048, &BIQUAD_FILTER_BPF_2048 ); 119 120 // マスターボリューム設定 121 nn::snd::SetMasterVolume( 1.0f ); 122 123 // サウンド出力モード設定 124 nn::snd::OutputMode mode = nn::snd::GetSoundOutputMode(); 125 switch ( mode ) 126 { 127 case nn::snd::OUTPUT_MODE_MONO: 128 m_OutputMode = OUTPUT_MODE_MONO; 129 break; 130 case nn::snd::OUTPUT_MODE_STEREO: 131 m_OutputMode = OUTPUT_MODE_STEREO; 132 break; 133 case nn::snd::OUTPUT_MODE_3DSURROUND: 134 m_OutputMode = OUTPUT_MODE_SURROUND; 135 break; 136 default: 137 NW_ASSERT( false ); 138 break; 139 } 140 141 m_IsInitialized = true; 142} 143 144void HardwareManager::Finalize() 145{ 146 if ( !m_IsInitialized ) return; 147 148 // エフェクトクリア 149 for ( int id = AUX_BUS_A; id < AUX_BUS_NUM; id++ ) 150 { 151 FinalizeEffect( static_cast<AuxBus>( id ) ); 152#ifndef NW_SND_DEBUG_NOUSE_CTRSDK 153 nn::snd::RegisterAuxCallback( 154 static_cast<nn::snd::AuxBusId>( id ), 155 m_AuxCallback[ id ], 156 static_cast<uptr>( m_AuxCallbackContext[ id ] ) ); 157#endif 158 m_AuxCallback[ id ] = NULL; 159 m_AuxCallbackContext[ id ] = NULL; 160 } 161 162 m_IsInitialized = false; 163} 164 165void HardwareManager::Update() 166{ 167 // ClearEffect のフェード処理。フェードが完了したらエフェクトをクリア 168 for ( int i=0; i<AUX_BUS_NUM; i++ ) 169 { 170 bool updateFlag = false; 171 if ( ! m_AuxUserVolume[ i ].IsFinished() ) 172 { 173 m_AuxUserVolume[ i ].Update(); 174 updateFlag = true; 175 } 176 if ( ! m_AuxFadeVolume[ i ].IsFinished() ) 177 { 178 m_AuxFadeVolume[ i ].Update(); 179 if ( m_AuxFadeVolume[ i ].IsFinished() ) 180 { 181 FinalizeEffect( static_cast<AuxBus>( i ) ); 182 } 183 updateFlag = true; 184 } 185 186 if ( updateFlag ) 187 { 188 f32 returnVolume = 1.0f; 189 returnVolume *= ut::Clamp( m_AuxUserVolume[ i ].GetValue(), 0.0f, 1.0f ); 190 returnVolume *= ut::Clamp( m_AuxFadeVolume[ i ].GetValue(), 0.0f, 1.0f ); 191#ifndef NW_SND_DEBUG_NOUSE_CTRSDK 192 nn::snd::SetAuxReturnVolume( static_cast<nn::snd::AuxBusId>(i), returnVolume ); 193#endif 194 } 195 } 196 197 // 音量のアップデート 198 if ( ! m_MasterVolume.IsFinished() ) { 199 m_MasterVolume.Update(); 200 VoiceManager::GetInstance().UpdateAllVoicesSync( Voice::UPDATE_VE ); 201 } 202 203 if ( ! m_VolumeForReset.IsFinished() ) { 204 m_VolumeForReset.Update(); 205 VoiceManager::GetInstance().UpdateAllVoicesSync( Voice::UPDATE_VE ); 206 } 207 208 // ( SDK 層の ) マスターボリュームの調整 209 { 210 f32 volume = 1.0f; 211 volume *= m_VolumeForReset.GetValue(); 212 volume = ut::Clamp( volume, 0.0f, 1.0f ); 213#ifndef NW_SND_DEBUG_NOUSE_CTRSDK 214 nn::snd::SetMasterVolume( volume ); 215#endif 216 } 217} 218 // RVL は計96ch中、マージン16だった 219 220u32 HardwareManager::GetChannelCount() const 221{ 222 return SOUND_VOICE_COUNT; 223} 224 225/* ======================================================================== 226 リセット前準備 227 ======================================================================== */ 228 229void HardwareManager::PrepareReset() 230{ 231 // if ( m_OldAidCallback != NULL ) return; 232 233 m_VolumeForReset.SetTarget( 0.0f, 3 ); // 3オーディオフレームかけてフェードアウト 234 // m_ResetReadyCounter = -1; 235 // m_OldAidCallback = ::AI_RegisterDMACallback( AiDmaCallbackFunc ); 236} 237 238bool HardwareManager::IsResetReady() const 239{ 240 return true; // m_ResetReadyCounter == 0 ? true : false; 241} 242 243} /* namespace nw::snd::internal::driver */ 244} /* namespace nw::snd::internal */ 245} /* namespace nw::snd */ 246} /* namespace nw */ 247