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