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