/*---------------------------------------------------------------------------* Project: Horizon File: snd_Voice.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 25765 $ *---------------------------------------------------------------------------*/ #ifndef NN_SND_VOICE_H_ #define NN_SND_VOICE_H_ #include #include #include #ifdef __cplusplus /*! @file @brief Voice に関する関数、およびクラス定義 */ namespace nn { namespace snd { namespace CTR { /*! @brief ライブラリがボイスを解放する際に呼び出すコールバック関数の型定義です。 @param[in] pVoice 解放したボイスオブジェクトへの参照 @param[in] userArg ユーザーパラメータ */ typedef void (*VoiceDropCallbackFunc)(class Voice *, uptr userArg); class VoiceManager; /*! @brief Voice を操作するクラスです。 */ class Voice { friend class VoiceManager; public: /*! @brief ボイスの状態を表す列挙型です。 */ enum State { STATE_PLAY, //!< 再生指令状態を表します。 STATE_STOP, //!< 停止状態を表します。 STATE_PAUSE //!< 一時停止状態を表します。再生を再開する際は、SetState により再生状態を設定して下さい。 }; private: const s32 m_Id; // ボイス番号(管理用) s16 m_SyncCount; // DSP との同期カウンタ(管理用) u16 m_bufferId; s32 m_PlayPosition; // 再生位置 bool m_Playing; // 実際に再生されてるかどうか State m_State; // 状態 InterpolationType m_InterpolationType; // 補間方法 FilterType m_iirType; // フィルタタイプ MonoFilterCoefficients m_monoFilterCoeffs; // 単極フィルタ係数 BiquadFilterCoefficients m_biquadFilterCoeffs; // 双極フィルタ係数 u16 m_SampleInfo; // ChannelCount と SampleFormat をまとめた情報 s32 m_SampleRate; // 標本化周波数 f32 m_Pitch; // ピッチ(SampleRate に対する比) u32 m_DspCycles; // DSP で消費されるサイクル数 s32 m_Priority; // 優先度 Voice * m_PriorVoice; // 優先度が高い Voice へのポインタ Voice * m_InferiorVoice; // 優先度が低い Voice へのポインタ VoiceDropCallbackFunc m_Callback; // Voice がシステムにより解放された場合に呼び出されるコールバック関数 uptr m_UserArg; // 上記コールバック呼び出し時のユーザ引数 WaveBuffer * m_pWaveBuffer; // 音源データ情報の先頭 WaveBuffer * m_pNextBuffer[NN_SND_NEXT_BUFFER_NUM]; s32 m_SentBufferCount; // 登録されているバッファの数 s32 m_NextBufferIndex; // NextBuffer のインデクス MixParam m_MixParam; // 各チャンネルへのゲイン f32 m_Volume; // ボリューム bit16 m_ModifiedParamFlag; // 変更があったパラメータを表すフラグ bool m_IsFirstWaveBufferForAdpcm; // ADPCM 係数がセットされたかどうか NN_PADDING1; /*! :private @brief Voice の初期化を行います。 */ void Initialize(void); /*! :private @brief バッファの状態を更新します。 @param[in] bufferId 再生中のバッファ ID */ void UpdateWaveBufferStatus( const u16 bufferId ); /*! :private @brief バッファの登録を行います。 */ void SendWaveBuffer( void ); /*! :private @brief バッファの解放を行います。 */ void ReleaseWaveBuffer( void ) ; /*! :private @brief 再生します。 */ void Start ( void ); /*! :private @brief 停止し、バッファの解放を行います。 */ void Stop ( void ) ; /*! :private @brief 停止します。 */ void Pause ( void ) const ; /*! :private @brief サイクルを取得します。 @return サイクル数を返します。 */ s32 GetCycle( void ) const ; /*! :private @brief DSP でのサイクル数を計算します。 @return なし。 */ void CalculateDspCycle( void ) ; /*! :private @brief タイマー値を設定します。アプリからは直接呼び出すことはできません。 */ void SetTimer( void ); /*! :private @brief ボリューム値を設定します。アプリからは直接呼び出すことはできません。 */ void SetMixVolume( void ); /*! :private @brief 同期カウントを設定します。 */ void SetSyncCount ( void ) ; /*! :private @brief ハードウェアのサンプリング周波数に対する比を計算する。 @return ハードウェアの周波数に対する比。 */ f32 CalcFsRatio ( void ) const; /*! :private @brief タイマー値を計算。 @return タイマー値。 */ u32 CalcTimer( void ) const; /*! :private @brief ポリフェイズフィルタの係数を選択する。 @return 係数値を返します。 */ u16 SelectCoefficient( void ); void UpdateInterpolationType(void); public: /*! @brief コンストラクタです。 @param[in] id ボイスの ID */ Voice(s32 id); /*! @brief デストラクタです。 */ ~Voice(); /*! @brief ボイスのチャンネル数を設定します。 @param[in] channelCount チャンネル数 */ void SetChannelCount( s32 channelCount ); /*! @brief ボイスにリンクされるサンプルの形式を設定します。 @param[in] format サンプルの形式 */ void SetSampleFormat( SampleFormat format ); /*! @brief 3D サラウンドが有効な場合に、フロントチャンネルをバイパスするかを設定します。 @param[in] flag true ならフロントバイパス、false ならフロントにも 3D サラウンドを適用 */ void SetFrontBypassFlag(bool flag); /*! @brief 再生開始時にボリューム 0 からの短いフェードインを用いるかどうかを指定します。 @param[in] flag On/Off フラグ */ void SetStartFrameFadeInFlag(bool flag); /*! @brief ボイスのサンプリングレートを設定します。 @param[in] sampleRate サンプリングレート */ void SetSampleRate ( s32 sampleRate ); /*! @brief ボイスのピッチを設定します。 @param[in] pitch サンプリングレートに対する再生速度比 */ void SetPitch ( f32 pitch ); /*! @brief ボイスのピッチを取得します。 @return ピッチを返します。 */ f32 GetPitch ( void ) const ; /*! @brief Adpcm の係数を設定します。 @param[in] param Adpcm 係数構造体への参照 */ void SetAdpcmParam ( const AdpcmParam& param ); /*! @brief ボイスの優先度を設定します。 @param[in] priority 優先度 */ void SetPriority ( s32 priority ); /*! @brief ボイスの優先度を取得します。 @return 優先度を返します。 */ s32 GetPriority( void ) const ; /*! @brief ボイスに対してサンプルデータ情報を追加します。 @param[in] buffer バッファ情報構造体のポインタ */ void AppendWaveBuffer ( WaveBuffer * buffer); /*! :private @brief DSP からの戻り値に基づき、Voice の状態を更新します。 @param[in] pVars ステータス構造体のポインタ */ void UpdateStatus( const void * pVars ); /*! :private @brief バッファリストを更新します。 */ void UpdateWaveBufferList ( void ); /*! @brief ボイスの状態を設定します。 @param[in] state 状態 */ void SetState( State state ); /*! @brief ボイスの状態を取得します。 @return 状態を返します。 */ Voice::State GetState( void ) const ; /*! @brief ボイスの各チャンネルのゲインを設定します。 @param[in] mixParam ゲイン構造体への参照 */ void SetMixParam( const MixParam& mixParam ); /*! @brief ボイスの各チャンネルのゲインを取得します。 @return ゲイン構造体への参照を返します。 */ const MixParam & GetMixParam( void ) const ; /*! @brief ボイスのボリュームを設定します。 @param[in] volume ボリューム値 */ void SetVolume( f32 volume ); /*! @brief ボイスのボリュームを取得します。 @return ボリューム値を返します。 */ f32 GetVolume( void ) const ; /*! @brief 使用中のバッファ内での再生位置を取得します。 @return 再生位置をサンプル数で返します。 */ s32 GetPlayPosition( void ) const ; /*! :private @brief ボイスの ID を取得します。 @return ボイスの ID を返します。 */ s32 GetId ( void ) const ; /*! @brief ボイスの再生状態を取得します。 @return ボイスの再生状態を返します。 */ bool IsPlaying ( void ) const ; /*! @brief ボイスの補間方法を設定します。 @param[in] type 補間方法 */ void SetInterpolationType( InterpolationType type ); /*! @brief ボイスの補間方法を取得します。 @return 現在の補間方法を返します。 */ InterpolationType GetInterpolationType() const; /*! @brief フィルタタイプを設定します。 @param[in] type フィルタタイプ */ void SetFilterType(FilterType type); /*! @brief フィルタの使用状況を取得します。 @return フィルタタイプ。 */ FilterType GetFilterType(void) const; /*! :overload coef @brief 単極フィルタの係数を設定します。 @param[in] pCoeff 係数バッファ */ void SetMonoFilterCoefficients(MonoFilterCoefficients* pCoeff); /*! :overload freq @brief 指定したカットオフ周波数を持つ、単極ローパスフィルタを設定します。 @param[in] cutoff カットオフ周波数 (0 <= cutoff <= 16000) */ void SetMonoFilterCoefficients(u16 cutoff); /*! @brief 単極フィルタの係数を取得します。 @param[out] pCoeff 係数バッファ */ void GetMonoFilterCoefficients(MonoFilterCoefficients* pCoeff); /*! @brief 双極フィルタの係数を設定します。 @param[in] pCoeff 係数バッファ */ void SetBiquadFilterCoefficients(BiquadFilterCoefficients* pCoeff); /*! @brief 双極フィルタの係数を取得します。 @param[out] pCoeff 係数バッファ */ void GetBiquadFilterCoefficients(BiquadFilterCoefficients* pCoeff); /*! :private @brief パラメータを DSP に反映します。 */ void UpdateParams(void); /*! :private @brief パラメータを強制的に DSP に反映します。 */ void ForceUpdateParams(void); /*! @brief Bcwav ファイルを解釈し、再生準備を行います。 @param[in] addrBcwav Bcwav ファイルの先頭アドレス @param[in] pWaveBuffer0 初回再生時に使用する nn::snd::WaveBuffer へのポインタ @param[in] pWaveBuffer1 ループ再生時に使用する nn::snd::WaveBuffer へのポインタ @param[in] channelIndex 使用するチャンネル @return 成功なら true, 失敗なら false を返します。 */ bool SetupBcwav(uptr addrBcwav, WaveBuffer* pWaveBuffer0, WaveBuffer* pWaveBuffer1, Bcwav::ChannelIndex channelIndex = Bcwav::CHANNEL_INDEX_L); }; // class Voice //-------------------------------- // inline 関数 //-------------------------------- // 優先度を取得。 inline s32 Voice::GetPriority( void ) const { return m_Priority; } // 状態を取得。 inline Voice::State Voice::GetState( void ) const { return m_State; } // ピッチを取得。 inline f32 Voice::GetPitch( void ) const { return m_Pitch; } // ゲインへの参照を取得。 inline const MixParam& Voice::GetMixParam( void ) const { return m_MixParam; } // ボリュームを取得。 inline f32 Voice::GetVolume (void ) const { return m_Volume; } // 優先度を取得。 inline s32 Voice::GetId ( void ) const { return m_Id; } // 再生状態を取得。 inline bool Voice::IsPlaying ( void ) const { return m_Playing; } // 補間方法を取得。 inline InterpolationType Voice::GetInterpolationType ( void ) const { return m_InterpolationType; } // ベース周波数に対する再生周波数の比を計算する。 inline f32 Voice::CalcFsRatio( void ) const { return (m_SampleRate * m_Pitch) / NN_SND_HW_I2S_CLOCK_32KHZ_F32; } // タイマー値を計算。 inline u32 Voice::CalcTimer( void ) const { return static_cast(CalcFsRatio() * NN_SND_TIMER_EQUIV); } /*! @brief ボイスを取得します。 @param[in] priority 優先順位 @param[in] callback コールバック関数のアドレス @param[in] userArg ユーザ引数 @return 成功した場合、Voice オブジェクトのアドレスを返します。失敗した場合、NULL を返します。 */ Voice* AllocVoice( s32 priority, VoiceDropCallbackFunc callback, uptr userArg ); /*! @brief ボイスを解放します。 @param[in] pVoice ボイスオブジェクトのアドレス。 */ void FreeVoice ( Voice * pVoice ); }}} // namespace nn::snd::CTR #endif // __cplusplus #endif //NN_SND_VOICE_H_