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