1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_Voice.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_VOICE_H_ 19 #define NW_SND_VOICE_H_ 20 21 #include <nn/snd.h> 22 #include <nw/snd/snd_Global.h> 23 #include <nw/ut/ut_LinkList.h> // for ut::LinkListNode 24 25 #ifdef NW_PLATFORM_CTRWIN 26 #include <nw/snd/snd_HardwareChannel.h> 27 #endif // NW_PLATFORM_CTRWIN 28 29 namespace nw { 30 namespace snd { 31 namespace internal { 32 namespace driver { 33 34 #ifdef NW_PLATFORM_CTR 35 typedef nn::snd::Voice HardwareChannel; 36 #endif 37 38 class Voice 39 { 40 friend class VoiceManager; 41 42 public: 43 // ------------------------------------------------------------------------ 44 // 更新フラグ 45 static const int UPDATE_START = 0x0001 << 0; 46 static const int UPDATE_PAUSE = 0x0001 << 1; 47 static const int UPDATE_SRC = 0x0001 << 2; 48 static const int UPDATE_MIX = 0x0001 << 3; 49 static const int UPDATE_LPF = 0x0001 << 4; 50 static const int UPDATE_BIQUAD = 0x0001 << 5; 51 static const int UPDATE_VE = 0x0001 << 6; 52 53 // ------------------------------------------------------------------------ 54 // コールバック関数 55 enum VoiceCallbackStatus 56 { 57 CALLBACK_STATUS_FINISH_WAVE, 58 CALLBACK_STATUS_CANCEL, 59 CALLBACK_STATUS_DROP_VOICE, 60 CALLBACK_STATUS_DROP_DSP 61 }; 62 63 typedef void (*VoiceCallback)( 64 Voice* voice, 65 VoiceCallbackStatus status, 66 void* callbackData 67 ); 68 69 static const int CHANNEL_MAX = nw::snd::internal::WAVE_CHANNEL_MAX; 70 71 // ------------------------------------------------------------------------ 72 // パラメータ境界 73 static const f32 VOLUME_MIN; 74 static const f32 VOLUME_DEFAULT; 75 static const f32 VOLUME_MAX; 76 static const f32 PAN_LEFT; 77 static const f32 PAN_CENTER; 78 static const f32 PAN_RIGHT; 79 static const f32 SPAN_FRONT; 80 static const f32 SPAN_CENTER; 81 static const f32 SPAN_REAR; 82 static const f32 CUTOFF_FREQ_MIN; 83 static const f32 CUTOFF_FREQ_MAX; 84 static const f32 BIQUAD_VALUE_MIN; 85 static const f32 BIQUAD_VALUE_MAX; 86 static const f32 SEND_MIN; 87 static const f32 SEND_MAX; 88 89 private: 90 // Voiceの仮想プライオリティ 91 #ifdef NW_PLATFORM_CTRWIN 92 static const int PRIORITY_MAX = 255; 93 #else 94 static const int PRIORITY_MAX = nn::snd::VOICE_PRIORITY_NODROP; 95 #endif 96 static const int PRIORITY_MIN = 0; 97 98 // TODO: SDK での優先度との摺合せをする必要アリ 99 // AXのボイスで使用される実際のプライオリティ 100 #ifdef NW_PLATFORM_CTRWIN 101 static const u32 VOICE_PRIORITY_MAX = AX_PRIORITY_STACKS - 1; 102 static const int VOICE_PRIORITY_FREE = 0; 103 static const u32 VOICE_PRIORITY_USE = 16; // Voiceクラスが使用するプライオリティ 104 static const u32 VOICE_PRIORITY_ALLOC = VOICE_PRIORITY_USE + 1; 105 static const u32 VOICE_PRIORITY_NODROP = VOICE_PRIORITY_MAX; 106 static const u32 VOICE_PRIORITY_RELEASE = VOICE_PRIORITY_USE - 1; 107 #else 108 // static const u32 VOICE_PRIORITY_MAX = PRIORITY_MAX; 109 static const u32 VOICE_PRIORITY_RELEASE = 1; 110 #endif 111 112 public: 113 static const int PRIORITY_NODROP = PRIORITY_MAX; 114 static const int PRIORITY_RELEASE = 1; 115 116 public: 117 Voice(); 118 ~Voice(); 119 120 // ------------------------------------------------------------------------ 121 // 確保と開放 122 bool Alloc( // NW4R では Voice::Acquire 123 int channelCount, 124 int priority, 125 Voice::VoiceCallback callback, 126 void* callbackData 127 ); 128 void Free(); 129 void Initialize( const WaveInfo& waveInfo, u32 startOffset ); 130 131 // ------------------------------------------------------------------------ 132 // 動作 133 void Start(); 134 void Stop(); 135 void StopFinished(); 136 void Pause( bool flag ); 137 138 void Calc(); 139 void Update(); 140 141 // ------------------------------------------------------------------------ 142 // 動作状態 IsActive()143 bool IsActive() const { return m_pHardwareChannel[0] != NULL; } 144 bool IsRun() const; IsPause()145 bool IsPause() const { return m_IsPause == true; } 146 bool IsPlayFinished() const; 147 148 // ------------------------------------------------------------------------ 149 // パラメータ GetVolume()150 f32 GetVolume() const { return m_Volume; } 151 void SetVolume( f32 volume ); 152 GetPitch()153 f32 GetPitch() const { return m_Pitch; } 154 void SetPitch( f32 pitch ); 155 156 void SetPanMode( PanMode panMode ); 157 void SetPanCurve( PanCurve panCurve ); 158 GetPan()159 f32 GetPan() const { return m_Pan; } 160 void SetPan( f32 pan ); 161 GetSurroundPan()162 f32 GetSurroundPan() const { return m_SurroundPan; } 163 void SetSurroundPan( f32 span ); 164 GetLpfFreq()165 f32 GetLpfFreq() const { return m_LpfFreq; } 166 void SetLpfFreq( f32 lpfFreq ); 167 GetBiquadType()168 int GetBiquadType() const { return m_BiquadType; } GetBiquadValue()169 f32 GetBiquadValue() const { return m_BiquadValue; } 170 void SetBiquadFilter( int type, f32 value ); 171 GetPriority()172 int GetPriority() const { return m_Priority; } 173 void SetPriority( int priority ); 174 175 void SetFrontBypass( bool isFrontBypass ); 176 void SetInterpolationType( u8 interpolationType ); 177 178 // ------------------------------------------------------------------------ 179 // ボイスパラメータ GetPhysicalVoiceCount()180 int GetPhysicalVoiceCount() const { return m_ChannelCount; } GetChannelCount()181 int GetChannelCount() const { return m_ChannelCount; } 182 const HardwareChannel* GetHardwareChannel( int channelIndex ) const; 183 184 void UpdateVoicesPriority(); 185 186 // ------------------------------------------------------------------------ 187 // 出力パラメータ GetMainSend()188 f32 GetMainSend() const { return m_MainSend; } 189 void SetMainSend( f32 send ); 190 GetFxSend(AuxBus bus)191 f32 GetFxSend( AuxBus bus ) const { return m_FxSend[ bus ]; } 192 void SetFxSend( AuxBus bus, f32 send ); 193 194 // ------------------------------------------------------------------------ 195 // サンプルの調整 196 u32 GetCurrentPlayingSample() const; 197 198 #ifdef NW_PLATFORM_CTRWIN 199 void StopAtPoint( int channelIndex, const void* baseAddress, u32 samples ); 200 void SetLoopFlag( bool flag ); 201 void SetLoopStart( s32 channelIndex, const void* baseAddress, u32 samples = 0 ); 202 void SetLoopEnd( s32 channelIndex, const void* baseAddress, u32 samples ); 203 void SetDspAdpcmLoop( s32 channelIndex, const DspAdpcmLoopParam* param ); 204 #endif // NW_PLATFORM_CTRWIN 205 206 nw::snd::SampleFormat GetFormat() const; 207 208 209 210 private: 211 #ifdef NW_PLATFORM_CTRWIN 212 // Voice のアロケート時に渡すコールバック関数。ボイスドロップ時に呼ばれる。 213 static void HardwareChannelCallbackFunc( 214 HardwareChannel* hardwareChannel, 215 HardwareChannel::HardwareChannelCallbackStatus status, 216 void* callbackData 217 ); 218 #else 219 static void SdkVoiceDropCallbackFunc( 220 nn::snd::Voice* pDropVoice, 221 uptr userArg 222 ); 223 static void SdkVoiceDropCallbackFuncMulti( 224 nn::snd::Voice* pDropVoice, 225 uptr userArg 226 ); 227 #endif 228 229 void InitParam( 230 int channelCount, 231 Voice::VoiceCallback callback, 232 void* callbackData 233 ); 234 235 // Update関数 236 #ifdef NW_PLATFORM_CTRWIN 237 void SyncHardwareChannel(); 238 #endif 239 void CalcSrc( bool initialUpdate ); 240 void CalcVe(); 241 void CalcMix(); 242 void CalcLpf(); 243 void CalcBiquadFilter(); 244 245 void CalcMixParam( 246 int channelIndex, 247 nw::snd::internal::MixParam* mix 248 ); 249 250 void RunAllHardwareChannel(); 251 void StopAllHardwareChannel(); 252 void PauseAllHardwareChannel(); 253 254 private: 255 HardwareChannel* m_pHardwareChannel[ CHANNEL_MAX ]; 256 257 int m_ChannelCount; 258 259 VoiceCallback m_Callback; 260 void* m_pCallbackData; 261 262 bool m_IsActive; 263 bool m_IsStart; 264 bool m_IsStarted; 265 bool m_IsPause; 266 bool m_IsPausing; 267 bool m_IsInitialized; 268 bool m_IsAllocating; 269 bool m_AllocateErrorFlag; 270 271 nn::snd::WaveBuffer* m_pLastWaveBuffer; 272 273 u16 m_SyncFlag; 274 275 u8 m_BiquadType; 276 277 f32 m_Volume; 278 f32 m_Pitch; 279 PanMode m_PanMode; 280 PanCurve m_PanCurve; 281 f32 m_Pan; 282 f32 m_SurroundPan; 283 f32 m_LpfFreq; 284 f32 m_BiquadValue; 285 int m_Priority; 286 287 f32 m_MainSend; 288 f32 m_FxSend[ AUX_BUS_NUM ]; 289 290 nw::snd::SampleFormat m_Format; 291 292 #ifdef NW_PLATFORM_CTR 293 public: 294 static u32 FrameToByte( u32 sample, nw::snd::SampleFormat format ); 295 296 void AppendWaveBuffer( 297 int channelIndex, 298 nn::snd::WaveBuffer* pBuffer, 299 bool lastFlag 300 ); 301 302 void SetAdpcmParam( 303 int channelIndex, 304 const nn::snd::AdpcmParam& param ); 305 306 private: 307 uptr m_VoiceUser; // Channel or StreamTrack 308 #endif // NW_PLATFORM_CTR 309 310 public: 311 ut::LinkListNode m_LinkNode; 312 313 #ifdef NW_DEBUG 314 // デバッグ用 315 public: 316 // 直近にサラウンドパン計算したボイスのサラウンドパン値を取得する 317 // (事実上、1 ボイス再生時にしか用途がない) 318 static void GetDebugMixParam( f32& pan, f32& span, nw::snd::internal::MixParam& mix ); 319 #endif 320 }; 321 322 } // namespace nw::snd::internal::driver 323 } // namespace nw::snd::internal 324 } // namespace nw::snd 325 } // namespace nw 326 327 #endif /* NW_SND_VOICE_H_ */ 328 329