1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     snd_Api.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: 26219 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_SND_API_H_
17 #define NN_SND_API_H_
18 
19 #include <nn/Result.h>
20 #include <nn/snd/CTR/Common/snd_Types.h>
21 #include <nn/snd/CTR/MPCore/snd_Voice.h>
22 
23 #ifdef __cplusplus
24 
25 /*! @file
26     @brief      サウンド(SND)に関する API の宣言
27 */
28 
29 namespace nn  { namespace snd { namespace CTR {
30 
31 /*!
32     @brief      1 サウンドフレームあたりの DSP のサイクル数の最大値です。
33 */
34 static const s32 NN_SND_DSP_MAXIMUM_CYCLES = 622535;
35 
36 
37 /*!
38   @name     Initialize/Finalize
39 
40   @{
41 */
42 /*!
43     @brief      サウンドライブラリの初期化処理を行います。
44 
45                 @ref nn::dsp::Initialize() によりDSP プロセスとのセッション確立後に使用できます。
46 
47     @return     処理の結果が返ってきます。<BR>
48                   LEVEL_SUCCESS:SUMMARY_SUCCESS:MODULE_COMMON:DESCRIPTION_SUCCESS・・・成功しました。
49 */
50 nn::Result Initialize();
51 
52 /*!
53     @brief      サウンドライブラリの終了処理を行います。
54 
55     @return     処理の結果が返ってきます。<BR>
56                   LEVEL_SUCCESS:SUMMARY_SUCCESS:MODULE_COMMON:DESCRIPTION_SUCCESS・・・成功しました。
57 */
58 nn::Result Finalize();
59 
60 /*!
61     @brief      バッファ情報構造体の初期化を行います。
62 
63                 @ref nn::snd::Voice::AppendWaveBuffer を呼び出す前に、本関数で構造体を初期化して下さい。
64 
65     @param[in]  pWaveBuffer   バッファ情報構造体へのポインタ
66     @return     なし。
67 */
68 void InitializeWaveBuffer(WaveBuffer * pWaveBuffer);
69 
70 /*! :private
71     @brief      サウンドスレッドを作成します。
72  */
73 nn::Result StartSoundThread(
74     void (*callback)(uptr),
75     uptr arg,
76     uptr stackBuffer,
77     size_t stackSize,
78     s32 prio,
79     s32 coreNo = NN_OS_CORE_NO_USE_PROCESS_VALUE
80 );
81 
82 /*! :private
83     @brief      ユーザーサウンドスレッドを作成します。
84  */
85 nn::Result StartUserSoundThread(uptr stackBuffer, size_t stackSize, s32 prio);
86 
87 /*! :private
88     @brief      StartSoundThread で作成したサウンドスレッドを終了します。
89  */
90 void FinalizeSoundThread();
91 
92 /*! :private
93     @brief      StartUserSoundThread で作成したユーザーサウンドスレッドを終了します。
94  */
95 void FinalizeUserSoundThread();
96 
97 /*! :private
98     @brief      サウンドフレームの処理負荷を有効 / 無効にします。
99 
100                 デフォルトは無効です。
101 
102     @param[in]  enable      true なら有効、false なら無効
103  */
104 void EnableSoundThreadTickCounter(bool enable);
105 
106 /*! :private
107     @brief      StartSoundThread で作成したサウンドスレッドの、1 サウンドフレームあたりの処理負荷を取得します。
108 
109                 コールバック内で呼び出した場合は、ひとつ前のサウンドフレームの処理負荷が得られます。
110  */
111 nn::os::Tick GetSoundThreadTick();
112 
113 /*! :private
114     @brief      コア 1 での Aux バス処理を有効 / 無効にします。
115 
116                 コア 1 でサウンドフレームを走らせる場合、Aux バス処理はコア 0 のユーザー
117                 サウンドスレッドで行われますが、この API を用いることで、コア 1 の
118                 サウンドスレッドで Aux バスを処理するよう設定することができます。
119 
120                 この API はデバグ目的で用意されたものであり、動作の保証はされていません。
121                 本 API は将来的に削除され、コア 1 での Aux バス処理は制限される予定です。
122 
123                 デフォルトは無効です。
124  */
125 void EnableAuxBusProcessingOnCore1(bool enable);
126 
127 /*!
128   @}
129 */
130 
131 /*!
132   @name     キャッシュ操作
133 
134   @{
135 */
136 /*!
137     @brief      指定された範囲のデータをキャッシュからメモリに書き戻し、キャッシュを無効にします。
138 
139                 動作は @ref nn::dsp::CTR::FlushDataCache と同じです。
140 
141     @param[in]  addr          メモリアドレス
142     @param[in]  size          メモリサイズ
143     @return     処理の結果が返ります。<BR>
144                 LEVEL_SUCCESS:SUMMARY_SUCCESS:MODULE_COMMON:DESCRIPTION_SUCCESS・・・成功しました。<BR>
145                 LEVEL_STATUS:SUMMARY_INVALID_STATE:MODULE_NN_DSP:DESCRIPTION_NOT_INITIALIZED・・・DSP ライブラリが初期化されていません。<BR>
146 */
147 nn::Result FlushDataCache( uptr addr, size_t size );
148 
149 /*!
150     @brief      指定された範囲のキャッシュを無効にします。
151 
152                 動作は @ref nn::dsp::CTR::InvalidateDataCache と同じです。
153 
154     @param[in]  addr          メモリアドレス
155     @param[in]  size          メモリサイズ
156       @return   処理の結果が返ります。<BR>
157                 LEVEL_SUCCESS:SUMMARY_SUCCESS:MODULE_COMMON:DESCRIPTION_SUCCESS・・・成功しました。<BR>
158                 LEVEL_STATUS:SUMMARY_INVALID_STATE:MODULE_NN_DSP:DESCRIPTION_NOT_INITIALIZED・・・DSP ライブラリが初期化されていません。<BR>
159 */
160 nn::Result InvalidateDataCache( uptr addr, size_t size );
161 
162 /*!
163   @}
164 */
165 
166 /*!
167   @name     同期処理
168 
169   @{
170 */
171 
172 /*!
173     @brief      DSP で処理を行った結果を受信します。
174 
175                 サウンドフレームイベントが発生するまで待機します。
176                 シグナルが通知された後、DSP からのデータを受信します。
177 
178     @return     なし。
179 */
180 void WaitForDspSync(void);
181 
182 /*!
183     @brief      DSP で処理を行った結果を受信します。
184 
185                 タイムアウト時間までにサウンドフレームイベントを待ちます。
186                 シグナルが通知された場合、DSP からのデータを受信します。
187 
188     @param[in]  timeout タイムアウト時間を指定します。0 を指定すると即座に処理を返します。
189     @return     タイムアウト時間までにサウンドフレームイベントが発生したかを返します。
190 */
191 bool WaitForDspSync(nn::fnd::TimeSpan timeout);
192 
193 /*!
194     :private
195 
196     @brief      DSP で処理を行った結果を受信し、受信に要した処理時間を取得します。
197 
198                 サウンドフレームイベントが発生するまで待機します。
199                 シグナルが通知された後、DSP からのデータを受信します。
200 
201     @param[out] pTick         内部の Wait 以外の処理に要したサイクル数
202     @return     なし。
203 */
204 void WaitForDspSync(nn::os::Tick* pTick);
205 
206 /*!
207     @brief      設定されたパラメータをDSP に反映します。
208 
209     @return     なし。
210 */
211 void SendParameterToDsp( void );
212 
213 /*!
214   @}
215 */
216 
217 /*!
218   @brief        サンプルの長さを取得します。
219 
220   @param[in]    size          サイズ(バイト単位)
221   @param[in]    format        形式
222   @param[in]    channelCount  チャンネル数
223   @return       サンプルの長さを返します。
224 */
225 s32 GetSampleLength( s32 size, SampleFormat format, s32 channelCount ) ;
226 
227 /*!
228     @brief      マスターボリュームを設定します。
229 
230     @param[in]  volume        マスターボリューム(1.0 が等倍)
231     @return     なし。
232 */
233 void SetMasterVolume ( f32 volume );
234 
235 /*!
236     @brief      Aux バスボリュームを設定します。
237 
238                 等倍は 1.0 です。
239 
240                 デフォルト値は 1.0 です。
241 
242     @param[in]  busId         バスの ID
243     @param[in]  volume        エフェクト 0 バスボリューム(1.0 が等倍)
244     @return     なし。
245 */
246 void SetAuxReturnVolume ( AuxBusId busId, f32 volume );
247 
248 /*!
249     @brief      Aux バスボリュームを取得します。
250 
251                 等倍は 1.0 です。
252 
253                 デフォルト値は 1.0 です。
254 
255     @param[in]  busId         バスの ID
256     @return     バスボリューム。
257 */
258 f32 GetAuxReturnVolume ( AuxBusId busId ) ;
259 
260 /*!
261     @brief      Aux バスのコールバック関数を設定します。
262 
263     @param[in]  busId         バスの ID
264     @param[in]  callback      コールバック関数
265     @param[in]  userData      ユーザ定義データ
266     @return     なし。
267 */
268 void RegisterAuxCallback( AuxBusId busId, AuxCallback callback, uptr userData );
269 
270 /*!
271     @brief      Aux バスのコールバック関数を取得します。
272 
273     @param[in]  busId         バスの ID
274     @param[out] pCallback     コールバック関数の格納先
275     @param[out] pUserData     ユーザ定義データの格納先
276     @return     なし。
277 */
278 void GetAuxCallback( AuxBusId busId, AuxCallback* pCallback, uptr* pUserData );
279 
280 /*!
281     @brief      Aux バスのコールバック関数を解除します。
282 
283     @param[in]  busId         バスの ID
284     @return     なし。
285 */
286 void ClearAuxCallback( AuxBusId busId );
287 
288 /*!
289     @brief      Aux バスのフロントバイパスを設定します。
290     @param[in]  busId         バスの ID
291     @param[in]  flag          フロントバイパスの有効 / 無効フラグ
292     @return     設定に成功すれば true を、失敗すれば false を返します。
293  */
294 bool SetAuxFrontBypass(AuxBusId busId, bool flag);
295 
296 /*!
297     @brief      Mix バスデータを指定のバッファにコピーします。
298 
299                 データはインターリーブされて pData から始まるアドレスにコピーされます。
300                 Mix バスデータは 16bit ステレオ PCM 波形を含んでいるので、
301                 コピーされるデータ長は sizeof(s16) * nSamplesPerFrame * 2 となります。
302 
303     @param[out] pData               Mix バスデータの内容をコピーするバッファアドレス
304     @param[in]  nSamplesPerFrame    チャンネルあたりのサンプル数(通常は NN_SND_SAMPLES_PER_FRAME を指定します)
305     @return     データ取得に成功すれば true を、失敗すれば false を返します。
306  */
307 bool GetMixedBusData(s16* pData, s32 nSamplesPerFrame = NN_SND_SAMPLES_PER_FRAME);
308 
309 /*!
310   @name     3D サラウンド
311   @{
312  */
313 /*!
314     @brief      サウンド出力モードを設定します。
315 
316     @param[in]  mode          サウンド出力モード
317     @return     設定に成功すれば true を、失敗すれば false を返します。
318  */
319 bool SetSoundOutputMode(OutputMode mode);
320 
321 /*!
322     @brief      サウンド出力モードを取得します。
323 
324     @return     サウンド出力モード
325  */
326 OutputMode GetSoundOutputMode(void);
327 
328 /*!
329   @brief        クリッピングモードを設定します。
330   @param[in]    mode          モード
331   @return       設定に成功すれば true を、失敗すれば false を返します。
332 */
333 bool SetClippingMode(ClippingMode mode);
334 
335 /*!
336   @brief        クリッピングモードを取得します。
337   @return       モード
338 */
339 ClippingMode GetClippingMode(void);
340 
341 /*!
342     :private
343     @brief      ミックス時のリア成分への重みを設定します。サラウンドモードでは無視されます。
344 
345     @param[in]  depth         重み (0 以上 1 以下の値でなければなりません)
346     @return     設定に成功すれば true を、失敗すれば false を返します。
347  */
348 bool SetRearRatio(f32 depth);
349 
350 /*!
351     @brief      サラウンドデプスを設定します。
352 
353                 サラウンドデプスは、スピーカー出力時の 3D サラウンドの効果の大小を
354                 表すパラメータです。値が大きい程、効果が大きくなります。
355                 サラウンドデプスはヘッドフォン出力時の効果には影響しません。
356 
357                 デフォルト値は 1.0f です。
358 
359     @param[in]  depth         サラウンドデプス(0 &lt;= depth &lt;= 1.0f)
360     @return     設定に成功すれば true を、失敗すれば false を返します。
361  */
362 bool SetSurroundDepth(f32 depth);
363 
364 /*!
365     @brief      3D サラウンドの仮想スピーカー位置を設定します。
366 
367     @param[in]  pos           仮想スピーカー位置
368     @return     設定に成功すれば true を、失敗すれば false を返します。
369  */
370 bool SetSurroundSpeakerPosition(SurroundSpeakerPosition pos);
371 
372 /*!
373     :private
374     @brief      3D サラウンド用空間フィルタを設定します。
375 
376     @param[in]  pSrc          フィルタ係数バッファアドレス
377     @param[in]  nCoeffs       フィルタのタップ数
378     @return     設定に成功すれば true を、失敗すれば false を返します。
379  */
380 bool SetSurroundSpacialFilter(s16* pSrc, s32 nCoeffs);
381 
382 /*!
383     :private
384     @brief      3D サラウンド用方向フィルタを設定します。
385 
386     @param[in]  pSrc          フィルタ係数バッファアドレス
387     @param[in]  nCoeffs       フィルタのタップ数
388     @param[in]  mode          モード(NN_SND_DEBUG_3DS_SPEAKER / NN_SND_DEBUG_3DS_HEADPHONE のいずれか)
389     @return     設定に成功すれば true を、失敗すれば false を返します。
390  */
391 bool SetSurroundDirectionFilter(s16* pSrc, s32 nCoeffs, s32 mode);
392 
393 /*!
394     :private
395     @brief      3D サラウンド用 IIR フィルタを設定します。
396 
397     @param[in]  pSrc          フィルタ係数バッファアドレス
398     @param[in]  nCoeffs       フィルタのタップ数
399     @param[in]  mode          モード(NN_SND_DEBUG_3DS_SPEAKER / NN_SND_DEBUG_3DS_HEADPHONE のいずれか)
400     @return     設定に成功すれば true を、失敗すれば false を返します。
401  */
402 bool SetSurroundIirFilterCoeffs(s32* pSrc, s32 nCoeffs, s32 mode);
403 
404 /*!
405     :private
406     @brief      3D サラウンド用 IIR フィルタの On/Off を設定します。
407 
408     @param[in]  flag          true なら On, false なら Off
409     @return     設定に成功すれば true を、失敗すれば false を返します。
410  */
411 bool SetSurroundIirFilterFlag(bool flag);
412 
413 /*!
414   @}
415  */
416 
417 /*!
418     @brief      サウンドが使用できるDSP サイクル数を設定します。
419 
420                 初期状態ではNN_SND_DSP_MAXIMUM_CYCLES が設定されています。
421                 NN_SND_DSP_MAXIMUM_CYCLES 以上の値が入力された場合は
422                 NN_SND_DSP_MAXIMUM_CYCLES が設定されます。
423 
424     @param[in]  cycles サイクル数
425     @return     なし。
426 */
427 void SetMaximumDspCycles( s32 cycles );
428 
429 /*!
430     @brief      サウンドに割り当てているDSP サイクル数を取得します。
431 
432     @return     サイクル数を返します。
433 */
434 s32 GetMaximumDspCycles( void );
435 
436 /*!
437     @brief      最後のオーディオフレーム作成でDSP が費やしたサイクル数を取得します。
438 
439     @return     DSP で消費したサイクル数を返します。
440 */
441 s32 GetDspCycles( void );
442 
443 /*! :private
444     @brief      snd 処理を一時中断し、終了処理を行います。
445  */
446 void Sleep();
447 
448 /*! :private
449     @brief      一時中断した snd の処理を復元します。
450  */
451 void WakeUp();
452 
453 /*! :private
454     @brief      終了処理のための準備を行います。
455  */
456 void OrderToWaitForFinalize();
457 
458 /*!
459     @brief      ヘッドホンの挿入状態を取得します。
460     @return     挿入されている場合は true を返します。
461  */
462 bool GetHeadphoneStatus( void );
463 
464 /*!
465     @brief      ヘッドホンの挿入状態を更新し、取得します。
466     @return     挿入されている場合は true を返します。
467  */
468 bool UpdateHeadphoneStatus( void );
469 
470 /*!
471     @name       処理落ち検出
472     @{
473  */
474 /*!
475     @brief      処理落ちしたサウンドフレームの数を取得します。
476     @return     処理落ちしたサウンドフレームの数を返します。
477  */
478 s32 GetDroppedSoundFrameCount();
479 
480 /*!
481     @brief      処理落ちしたサウンドフレームの数を初期化します。
482  */
483 void ClearDroppedSoundFrameCount();
484 /*!
485     @}
486  */
487 
488 /*!
489   @name     DSP-ADPCM 関連
490   @{
491  */
492 /*!
493   @brief        16bit PCM データを DSP-ADPCM フォーマットにエンコードします。
494 
495   @param[in]    pInput        入力バッファアドレス
496   @param[out]   pOutput       出力バッファアドレス(4 バイトアラインされている必要があります)
497   @param[in]    nSamples      入力サンプル数
498   @param[in]    sampleRate    サンプル周波数
499   @param[in]    loopStart     ループ開始サンプル位置(0 オリジン)
500   @param[in]    loopEnd       ループ終了サンプル位置(0 オリジン)
501   @param[out]   pInfo         ヘッダ構造体アドレス
502   @return       なし
503  */
504 s32 EncodeAdpcmData(s16* pInput, u8* pOutput, s32 nSamples, s32 sampleRate, s32 loopStart, s32 loopEnd, DspsndAdpcmHeader* pInfo);
505 
506 /*!
507   @brief        DSP-ADPCM データをデコードします。
508 
509   @param[in]    pInput        入力バッファアドレス
510   @param[out]   pOutput       出力バッファアドレス
511   @param[in]    param         ADPCM パラメータ
512   @param[in]    context       ADPCM コンテキスト
513   @param[in]    nSamples      入力サンプル数
514  */
515 void DecodeAdpcmData(u8* pInput, s16* pOutput, AdpcmParam& param, AdpcmContext& context, s32 nSamples);
516 
517 /*!
518   @brief        エンコード時に必要な出力バッファのサイズを返します。
519 
520   @param[in]    nSamples      入力サンプル数
521   @return       出力バッファのサイズ
522  */
523 s32 GetAdpcmOutputBufferSize(s32 nSamples);
524 
525 /*!
526   @brief        サンプル位置をニブル数に変換します。
527 
528   @param[in]    nPos          サンプル位置
529   @return                     ニブル数
530  */
531 u32 ConvertAdpcmPos2Nib(u32 nPos);
532 /*!
533   @brief        ニブル数をサンプル位置に変換します。
534 
535   @param[in]    nNib          ニブル数
536   @return                     サンプル位置
537  */
538 u32 ConvertAdpcmNib2Pos(u32 nNib);
539 
540 /*!
541   @}
542  */
543 
544 }}} // namespace nn::snd::CTR
545 
546 #endif // __cplusplus
547 
548 // 以下、C 用宣言
549 /*!
550     @addtogroup   nn_snd   snd
551 
552     @{
553 */
554 
555 /*!
556 @brief      対応する C++ 関数 @ref nn::snd::CTR::Initialize を参照してください。
557 */
558 NN_EXTERN_C nnResult nnsndInitialize();
559 
560 /*!
561     @}
562 */
563 
564 #endif //NN_SND_API_H_
565