1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: snd_Voice.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. 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 $Rev: 25765 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NN_SND_VOICE_H_
17 #define NN_SND_VOICE_H_
18
19 #include <nn/os.h>
20 #include <nn/Result.h>
21
22 #include <nn/snd/CTR/Common/snd_Types.h>
23
24 #ifdef __cplusplus
25
26 /*! @file
27 @brief Voice に関する関数、およびクラス定義
28 */
29
30 namespace nn { namespace snd { namespace CTR {
31
32 /*!
33 @brief ライブラリがボイスを解放する際に呼び出すコールバック関数の型定義です。
34 @param[in] pVoice 解放したボイスオブジェクトへの参照
35 @param[in] userArg ユーザーパラメータ
36 */
37 typedef void (*VoiceDropCallbackFunc)(class Voice *, uptr userArg);
38
39 class VoiceManager;
40
41 /*!
42 @brief Voice を操作するクラスです。
43 */
44 class Voice
45 {
46 friend class VoiceManager;
47
48 public:
49
50 /*!
51 @brief ボイスの状態を表す列挙型です。
52 */
53 enum State
54 {
55 STATE_PLAY, //!< 再生指令状態を表します。
56 STATE_STOP, //!< 停止状態を表します。
57 STATE_PAUSE //!< 一時停止状態を表します。再生を再開する際は、SetState により再生状態を設定して下さい。
58 };
59
60 private:
61 const s32 m_Id; // ボイス番号(管理用)
62 s16 m_SyncCount; // DSP との同期カウンタ(管理用)
63 u16 m_bufferId;
64 s32 m_PlayPosition; // 再生位置
65
66 bool m_Playing; // 実際に再生されてるかどうか
67 State m_State; // 状態
68 InterpolationType m_InterpolationType; // 補間方法
69
70 FilterType m_iirType; // フィルタタイプ
71 MonoFilterCoefficients m_monoFilterCoeffs; // 単極フィルタ係数
72 BiquadFilterCoefficients m_biquadFilterCoeffs; // 双極フィルタ係数
73
74 u16 m_SampleInfo; // ChannelCount と SampleFormat をまとめた情報
75
76 s32 m_SampleRate; // 標本化周波数
77 f32 m_Pitch; // ピッチ(SampleRate に対する比)
78
79 u32 m_DspCycles; // DSP で消費されるサイクル数
80 s32 m_Priority; // 優先度
81 Voice * m_PriorVoice; // 優先度が高い Voice へのポインタ
82 Voice * m_InferiorVoice; // 優先度が低い Voice へのポインタ
83
84 VoiceDropCallbackFunc m_Callback; // Voice がシステムにより解放された場合に呼び出されるコールバック関数
85 uptr m_UserArg; // 上記コールバック呼び出し時のユーザ引数
86
87 WaveBuffer * m_pWaveBuffer; // 音源データ情報の先頭
88
89 WaveBuffer * m_pNextBuffer[NN_SND_NEXT_BUFFER_NUM];
90
91 s32 m_SentBufferCount; // 登録されているバッファの数
92 s32 m_NextBufferIndex; // NextBuffer のインデクス
93
94 MixParam m_MixParam; // 各チャンネルへのゲイン
95 f32 m_Volume; // ボリューム
96
97 bit16 m_ModifiedParamFlag; // 変更があったパラメータを表すフラグ
98
99 bool m_IsFirstWaveBufferForAdpcm; // ADPCM 係数がセットされたかどうか
100 NN_PADDING1;
101
102 /*! :private
103 @brief Voice の初期化を行います。
104 */
105 void Initialize(void);
106
107 /*! :private
108 @brief バッファの状態を更新します。
109 @param[in] bufferId 再生中のバッファ ID
110 */
111 void UpdateWaveBufferStatus( const u16 bufferId );
112
113 /*! :private
114 @brief バッファの登録を行います。
115 */
116 void SendWaveBuffer( void );
117
118 /*! :private
119 @brief バッファの解放を行います。
120 */
121 void ReleaseWaveBuffer( void ) ;
122
123 /*! :private
124 @brief 再生します。
125 */
126 void Start ( void );
127
128 /*! :private
129 @brief 停止し、バッファの解放を行います。
130 */
131 void Stop ( void ) ;
132
133 /*! :private
134 @brief 停止します。
135 */
136 void Pause ( void ) const ;
137
138 /*! :private
139 @brief サイクルを取得します。
140 @return サイクル数を返します。
141 */
142 s32 GetCycle( void ) const ;
143
144 /*! :private
145 @brief DSP でのサイクル数を計算します。
146 @return なし。
147 */
148 void CalculateDspCycle( void ) ;
149
150 /*! :private
151 @brief タイマー値を設定します。アプリからは直接呼び出すことはできません。
152 */
153 void SetTimer( void );
154
155 /*! :private
156 @brief ボリューム値を設定します。アプリからは直接呼び出すことはできません。
157 */
158 void SetMixVolume( void );
159
160 /*! :private
161 @brief 同期カウントを設定します。
162 */
163 void SetSyncCount ( void ) ;
164
165 /*! :private
166 @brief ハードウェアのサンプリング周波数に対する比を計算する。
167 @return ハードウェアの周波数に対する比。
168 */
169 f32 CalcFsRatio ( void ) const;
170
171 /*! :private
172 @brief タイマー値を計算。
173 @return タイマー値。
174 */
175 u32 CalcTimer( void ) const;
176
177 /*! :private
178 @brief ポリフェイズフィルタの係数を選択する。
179 @return 係数値を返します。
180 */
181 u16 SelectCoefficient( void );
182
183 void UpdateInterpolationType(void);
184
185 public:
186 /*!
187 @brief コンストラクタです。
188 @param[in] id ボイスの ID
189 */
190 Voice(s32 id);
191
192 /*!
193 @brief デストラクタです。
194 */
195 ~Voice();
196
197 /*!
198 @brief ボイスのチャンネル数を設定します。
199 @param[in] channelCount チャンネル数
200 */
201 void SetChannelCount( s32 channelCount );
202
203 /*!
204 @brief ボイスにリンクされるサンプルの形式を設定します。
205 @param[in] format サンプルの形式
206 */
207 void SetSampleFormat( SampleFormat format );
208
209 /*!
210 @brief 3D サラウンドが有効な場合に、フロントチャンネルをバイパスするかを設定します。
211 @param[in] flag true ならフロントバイパス、false ならフロントにも 3D サラウンドを適用
212 */
213 void SetFrontBypassFlag(bool flag);
214
215 /*!
216 @brief 再生開始時にボリューム 0 からの短いフェードインを用いるかどうかを指定します。
217 @param[in] flag On/Off フラグ
218 */
219 void SetStartFrameFadeInFlag(bool flag);
220
221 /*!
222 @brief ボイスのサンプリングレートを設定します。
223 @param[in] sampleRate サンプリングレート
224 */
225 void SetSampleRate ( s32 sampleRate );
226
227 /*!
228 @brief ボイスのピッチを設定します。
229 @param[in] pitch サンプリングレートに対する再生速度比
230 */
231 void SetPitch ( f32 pitch );
232
233 /*!
234 @brief ボイスのピッチを取得します。
235 @return ピッチを返します。
236 */
237 f32 GetPitch ( void ) const ;
238
239 /*!
240 @brief Adpcm の係数を設定します。
241 @param[in] param Adpcm 係数構造体への参照
242 */
243 void SetAdpcmParam ( const AdpcmParam& param );
244
245 /*!
246 @brief ボイスの優先度を設定します。
247 @param[in] priority 優先度
248 */
249 void SetPriority ( s32 priority );
250
251 /*!
252 @brief ボイスの優先度を取得します。
253 @return 優先度を返します。
254 */
255 s32 GetPriority( void ) const ;
256
257 /*!
258 @brief ボイスに対してサンプルデータ情報を追加します。
259 @param[in] buffer バッファ情報構造体のポインタ
260 */
261 void AppendWaveBuffer ( WaveBuffer * buffer);
262
263 /*! :private
264 @brief DSP からの戻り値に基づき、Voice の状態を更新します。
265 @param[in] pVars ステータス構造体のポインタ
266 */
267 void UpdateStatus( const void * pVars );
268
269 /*! :private
270 @brief バッファリストを更新します。
271 */
272 void UpdateWaveBufferList ( void );
273
274 /*!
275 @brief ボイスの状態を設定します。
276 @param[in] state 状態
277 */
278 void SetState( State state );
279
280 /*!
281 @brief ボイスの状態を取得します。
282 @return 状態を返します。
283 */
284 Voice::State GetState( void ) const ;
285
286 /*!
287 @brief ボイスの各チャンネルのゲインを設定します。
288 @param[in] mixParam ゲイン構造体への参照
289 */
290 void SetMixParam( const MixParam& mixParam );
291
292 /*!
293 @brief ボイスの各チャンネルのゲインを取得します。
294 @return ゲイン構造体への参照を返します。
295 */
296 const MixParam & GetMixParam( void ) const ;
297
298 /*!
299 @brief ボイスのボリュームを設定します。
300 @param[in] volume ボリューム値
301 */
302 void SetVolume( f32 volume );
303
304 /*!
305 @brief ボイスのボリュームを取得します。
306 @return ボリューム値を返します。
307 */
308 f32 GetVolume( void ) const ;
309
310 /*!
311 @brief 使用中のバッファ内での再生位置を取得します。
312 @return 再生位置をサンプル数で返します。
313 */
314 s32 GetPlayPosition( void ) const ;
315
316 /*! :private
317 @brief ボイスの ID を取得します。
318 @return ボイスの ID を返します。
319 */
320 s32 GetId ( void ) const ;
321
322 /*!
323 @brief ボイスの再生状態を取得します。
324 @return ボイスの再生状態を返します。
325 */
326 bool IsPlaying ( void ) const ;
327
328 /*!
329 @brief ボイスの補間方法を設定します。
330 @param[in] type 補間方法
331 */
332 void SetInterpolationType( InterpolationType type );
333
334 /*!
335 @brief ボイスの補間方法を取得します。
336 @return 現在の補間方法を返します。
337 */
338 InterpolationType GetInterpolationType() const;
339
340 /*!
341 @brief フィルタタイプを設定します。
342 @param[in] type フィルタタイプ
343 */
344 void SetFilterType(FilterType type);
345
346 /*!
347 @brief フィルタの使用状況を取得します。
348 @return フィルタタイプ。
349 */
350 FilterType GetFilterType(void) const;
351
352 /*! :overload coef
353 @brief 単極フィルタの係数を設定します。
354 @param[in] pCoeff 係数バッファ
355 */
356 void SetMonoFilterCoefficients(MonoFilterCoefficients* pCoeff);
357
358 /*! :overload freq
359 @brief 指定したカットオフ周波数を持つ、単極ローパスフィルタを設定します。
360 @param[in] cutoff カットオフ周波数 (0 <= cutoff <= 16000)
361 */
362 void SetMonoFilterCoefficients(u16 cutoff);
363
364 /*!
365 @brief 単極フィルタの係数を取得します。
366 @param[out] pCoeff 係数バッファ
367 */
368 void GetMonoFilterCoefficients(MonoFilterCoefficients* pCoeff);
369
370 /*!
371 @brief 双極フィルタの係数を設定します。
372 @param[in] pCoeff 係数バッファ
373 */
374 void SetBiquadFilterCoefficients(BiquadFilterCoefficients* pCoeff);
375
376 /*!
377 @brief 双極フィルタの係数を取得します。
378 @param[out] pCoeff 係数バッファ
379 */
380 void GetBiquadFilterCoefficients(BiquadFilterCoefficients* pCoeff);
381
382 /*! :private
383 @brief パラメータを DSP に反映します。
384 */
385 void UpdateParams(void);
386
387 /*! :private
388 @brief パラメータを強制的に DSP に反映します。
389 */
390 void ForceUpdateParams(void);
391
392 /*!
393 @brief Bcwav ファイルを解釈し、再生準備を行います。
394 @param[in] addrBcwav Bcwav ファイルの先頭アドレス
395 @param[in] pWaveBuffer0 初回再生時に使用する nn::snd::WaveBuffer へのポインタ
396 @param[in] pWaveBuffer1 ループ再生時に使用する nn::snd::WaveBuffer へのポインタ
397 @param[in] channelIndex 使用するチャンネル
398 @return 成功なら true, 失敗なら false を返します。
399 */
400 bool SetupBcwav(uptr addrBcwav, WaveBuffer* pWaveBuffer0, WaveBuffer* pWaveBuffer1, Bcwav::ChannelIndex channelIndex = Bcwav::CHANNEL_INDEX_L);
401
402 }; // class Voice
403
404 //--------------------------------
405 // inline 関数
406 //--------------------------------
407 // 優先度を取得。
GetPriority(void)408 inline s32 Voice::GetPriority( void ) const
409 {
410 return m_Priority;
411 }
412 // 状態を取得。
GetState(void)413 inline Voice::State Voice::GetState( void ) const
414 {
415 return m_State;
416 }
417 // ピッチを取得。
GetPitch(void)418 inline f32 Voice::GetPitch( void ) const
419 {
420 return m_Pitch;
421 }
422 // ゲインへの参照を取得。
GetMixParam(void)423 inline const MixParam& Voice::GetMixParam( void ) const
424 {
425 return m_MixParam;
426 }
427 // ボリュームを取得。
GetVolume(void)428 inline f32 Voice::GetVolume (void ) const
429 {
430 return m_Volume;
431 }
432 // 優先度を取得。
GetId(void)433 inline s32 Voice::GetId ( void ) const
434 {
435 return m_Id;
436 }
437 // 再生状態を取得。
IsPlaying(void)438 inline bool Voice::IsPlaying ( void ) const
439 {
440 return m_Playing;
441 }
442 // 補間方法を取得。
GetInterpolationType(void)443 inline InterpolationType Voice::GetInterpolationType ( void ) const
444 {
445 return m_InterpolationType;
446 }
447 // ベース周波数に対する再生周波数の比を計算する。
CalcFsRatio(void)448 inline f32 Voice::CalcFsRatio( void ) const
449 {
450 return (m_SampleRate * m_Pitch) / NN_SND_HW_I2S_CLOCK_32KHZ_F32;
451 }
452 // タイマー値を計算。
CalcTimer(void)453 inline u32 Voice::CalcTimer( void ) const
454 {
455 return static_cast<u32>(CalcFsRatio() * NN_SND_TIMER_EQUIV);
456 }
457
458 /*!
459 @brief ボイスを取得します。
460 @param[in] priority 優先順位
461 @param[in] callback コールバック関数のアドレス
462 @param[in] userArg ユーザ引数
463 @return 成功した場合、Voice オブジェクトのアドレスを返します。失敗した場合、NULL を返します。
464 */
465 Voice* AllocVoice( s32 priority, VoiceDropCallbackFunc callback, uptr userArg );
466
467 /*!
468 @brief ボイスを解放します。
469 @param[in] pVoice ボイスオブジェクトのアドレス。
470 */
471 void FreeVoice ( Voice * pVoice );
472
473 }}} // namespace nn::snd::CTR
474
475 #endif // __cplusplus
476
477 #endif //NN_SND_VOICE_H_
478