1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     snd_FxDelay.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: $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_SND_FX_DELAY_H_
17 #define NN_SND_FX_DELAY_H_
18 
19 #ifdef __cplusplus
20 
21 namespace nn  { namespace snd { namespace CTR {
22 
23 //---------------------------------------------------------------------------
24 //! @brief  ディレイエフェクトクラスです。
25 //!
26 //!         エフェクトを実行するには、@ref SetEffect 関数を呼び出してください。
27 //!
28 //!         エフェクトは CPU で処理されます (DSP では処理されません)。
29 //!
30 //!         @ref Param 構造体の m_IsEnableSurround フラグを利用することで、
31 //!         前方 2ch のみのエフェクトか、
32 //!         後方 2ch を含めた計 4ch のエフェクト処理かを選ぶことができます。
33 //!
34 //! @see FxReverb クラス
35 //!
36 //! @date 2010/10/20 初版
37 //---------------------------------------------------------------------------
38 class FxDelay
39 {
40 public:
41     //---------------------------------------------------------------------------
42     //! @brief  ディレイパラメータの構造体です。
43     //!
44     //!         m_DelayTime はディレイ時間を表します。
45     //!         単位は msec です。
46     //!         この値を大きくすればするほど、反響が遅れてやって来ます。
47     //!         また、この値を大きくすると @ref GetRequiredMemSize
48     //!         で得られる必要メモリサイズが大きくなります。
49     //!         初期値は 250 です。
50     //!
51     //!         m_FeedbackGain をディレイ音のフィードバックゲインを表します。
52     //!         0.0f ~ 1.0f で設定する必要があります。
53     //!         この値を大きくすればするほど、ディレイ音がなかなか消えなくなります。
54     //!         0.0f を指定すると、ワンショットディレイ (フィードバックなし) になります。
55     //!         初期値は 0.4f です。
56     //!
57     //!         m_Damping は LPF (ローパスフィルタ) のかかり具合を表します。
58     //!         0.0f ~ 1.0f で設定する必要があります。
59     //!         この値を大きくすればするほど、カットオフ周波数が下がっていきます。
60     //!         0.0f にすると、ローパスフィルタはかかりません。
61     //!         初期値は 0.5f です。
62     //!
63     //!         m_IsEnableSurround が true の場合、サラウンド (リアの L と R)
64     //!         成分もディレイ処理されます。
65     //!         false の場合は、サラウンド成分のディレイ処理はスキップされ、
66     //!         その分処理負荷が減ります。
67     //!         一方、true にすると、処理負荷は増え、
68     //!         @ref GetRequiredMemSize で得られる必要メモリサイズも大きくなります。
69     //!
70     //!         エフェクト実行中に m_DelayTime を変更すると、ノイズがのる可能性があります。
71     //!
72     //!         また、m_FeedbackGain および m_Damping は、
73     //!         エフェクト実行中であっても「連続的に」変化させる場合は、
74     //!         ノイズはのりません。
75     //!
76     //!         エフェクト実行中にパラメータ変更をするには、@ref SetParam を呼び出してください。
77     //!
78     //! @date 2010/10/21 初期値を変更
79     //! @date 2010/10/20 初版
80     //---------------------------------------------------------------------------
81     struct Param
82     {
83         //! ディレイ時間 (msec) です。初期値は 250 です。
84         u32 m_DelayTime;
85 
86         //! フィードバックゲインです。0.0f ~ 1.0f で指定します。初期値は 0.4f です。
87         f32 m_FeedbackGain;
88 
89         //! LPF のかかり具合です。0.0f ~ 1.0f で指定します。初期値は 0.5f です。
90         f32 m_Damping;
91 
92         //! ディレイ処理をサラウンドチャンネルも有効にするかどうかのフラグです。初期値は false です。
93         bool m_IsEnableSurround;
94 
95         NN_PADDING3;
96 
97         //---------------------------------------------------------------------------
98         //! @brief    コンストラクタです。
99         //!
100         //! @date 2010/10/21 初期値を変更
101         //! @date 2010/10/20 初版
102         //---------------------------------------------------------------------------
ParamParam103         Param()
104         : m_DelayTime( 250 ),
105           m_FeedbackGain( 0.4f ),
106           m_Damping( 0.5f ),
107           m_IsEnableSurround( false )
108           {}
109     };
110 
111     //----------------------------------------------------------------
112     /// @name   コンストラクタ/デストラクタ
113     //----------------------------------------------------------------
114     //@{
115     //---------------------------------------------------------------------------
116     //! @brief    コンストラクタです。
117     //!
118     //! @date 2010/10/20 初版
119     //---------------------------------------------------------------------------
120     FxDelay();
121 
122     //---------------------------------------------------------------------------
123     //! @brief    デストラクタです。
124     //!
125     //! @date 2010/10/20 初版
126     //---------------------------------------------------------------------------
127     virtual ~FxDelay();
128     //@}
129 
130     //----------------------------------------------------------------
131     /// @name   パラメータ設定/取得
132     //----------------------------------------------------------------
133     //@{
134     //---------------------------------------------------------------------------
135     //! @brief  ディレイパラメータを設定します。
136     //!
137     //!         @ref GetRequiredMemSize 関数は、
138     //!         ここで設定されたディレイパラメータを元に必要なメモリサイズを計算します。
139     //!
140     //!         設定された @ref Param 構造体は、FxDelay インスタンス内部でコピーされます。
141     //!
142     //!         FxDelay インスタンスを @ref SetEffect 関数に渡す前と後で挙動が変わります。
143     //!
144     //!         @ref SetEffect を呼び出す前は、
145     //!         @ref Param 構造体のうち、m_FeedbackGain および m_Damping
146     //!         の範囲チェックが行われます。
147     //!         範囲外の場合は、Debug / Development 版ではアサートで停止し、
148     //!         Release 版では false を返します。
149     //!
150     //!         @ref SetEffect 呼び出し後は、
151     //!         呼び出し前に行われる範囲チェックに加え、
152     //!         必要メモリサイズが増えるかどうかのチェックが行われます。
153     //!         すなわち、@n
154     //!         ・m_DelayTime に @ref SetEffect が呼び出された時より大きな値を設定する @n
155     //!         ・m_IsEnableSurround が @ref SetEffect 呼び出し時には false を設定していたのに
156     //!         true を設定する @n
157     //!         のような操作をした場合、本関数は失敗し false を返します。
158     //!         上記の条件を満たさない場合は、
159     //!         @ref SetEffect 以降でもパラメータの変更が可能です。
160     //!
161     //! @param[in] param  ディレイパラメータです。
162     //!
163     //! @return     設定に成功すると true を、失敗 (範囲外の値を設定するなど) した場合は
164     //!             false を返します
165     //!
166     //! @see GetRequiredMemSize
167     //! @see GetParam
168     //! @see SetEffect
169     //!
170     //! @date 2010/11/04 関数名誤記修正 (Initialize → SetEffect)
171     //! @date 2010/10/20 初版
172     //---------------------------------------------------------------------------
173     bool SetParam( const FxDelay::Param& param );
174 
175     //---------------------------------------------------------------------------
176     //! @brief  ディレイパラメータを取得します。
177     //!
178     //! @return   現在のディレイパラメータを返します。
179     //!
180     //! @see SetParam
181     //!
182     //! @date 2010/10/20 初版
183     //---------------------------------------------------------------------------
GetParam()184     const Param& GetParam() const
185     {
186         return m_Param;
187     }
188     //@}
189 
190     //----------------------------------------
191     //! @name メモリ割り当て
192     //@{
193     //---------------------------------------------------------------------------
194     //! @brief    エフェクトに必要なメモリサイズを取得します。
195     //!
196     //!           あらかじめ @ref SetParam 関数で、
197     //!           ディレイパラメータを設定しておく必要があります。
198     //!
199     //! @return   ディレイエフェクトに必要なメモリサイズを返します。
200     //!
201     //! @see AssignWorkBuffer
202     //!
203     //! @date 2010/10/20 初版
204     //---------------------------------------------------------------------------
205     size_t GetRequiredMemSize();
206 
207     //---------------------------------------------------------------------------
208     //! @brief    エフェクトで使用するメモリ領域を割り当てます。
209     //!
210     //!           メモリ領域の割り当ては、エフェクトを
211     //!           @ref SetEffect 関数に渡す前に行う必要があります。
212     //!
213     //!           エフェクトが必要とするバッファサイズは、パラメータの値によって変化しますので、
214     //!           @ref GetRequiredMemSize を呼び出して、必要なメモリサイズを取得してください。
215     //!
216     //! @param[in] buffer 割り当てるメモリの先頭アドレスです。
217     //! @param[in] size   割り当てるメモリのサイズです。
218     //!
219     //! @return   メモリ領域の割り当てに成功すると true を、
220     //!           失敗すると false を返します。
221     //!
222     //! @see GetRequiredMemSize
223     //! @see ReleaseWorkBuffer
224     //! @see SetEffect
225     //!
226     //! @date 2010/10/20 初版
227     //---------------------------------------------------------------------------
228     bool AssignWorkBuffer( uptr buffer, size_t size );
229 
230     //---------------------------------------------------------------------------
231     //! @brief    エフェクトで使用していたメモリ領域を解放します。
232     //!
233     //!           この関数で解放を行う前に、@ref ClearEffect
234     //!           関数でエフェクトを削除しておく必要があります。
235     //!
236     //! @see AssignWorkBuffer
237     //! @see ClearEffect
238     //!
239     //! @date 2010/11/04 誤植修正 (開放→解放)
240     //! @date 2010/10/20 初版
241     //---------------------------------------------------------------------------
242     void ReleaseWorkBuffer();
243     //@}
244 
245     /*! :private */
246     bool Initialize();
247 
248     /*! :private */
249     void Finalize();
250 
251     /*! :private */
252     void UpdateBuffer( uptr data );
253 
254 
255 private:
256     struct WorkBuffer
257     {
258         s32* m_Delay[4];      ///< ディレイ
259         s32  m_Lpf[4];        ///< one-pole LPF の履歴
260     };
261 
262     void AllocBuffer();
263     void FreeBuffer();
264     void InitializeParam();
265 
266     Param   m_Param;
267     uptr    m_Buffer;            ///< バッファ
268     size_t  m_BufferSize;        ///< バッファサイズ
269 
270     WorkBuffer  m_WorkBuffer;    ///< ワークバッファ
271 
272     u32     m_DelayFrames;       ///< ディレイフレーム数(オーディオフレームが幾つ分か)
273     u32     m_CurFrame;          ///< 現在のフレーム
274 
275     s32     m_FeedbackGain;      ///< フィードバックゲイン
276     s32     m_LpfCoef1;          ///< LPF係数1
277     s32     m_LpfCoef2;          ///< LPF係数2
278 
279     u32     m_DelayTimeAtInitialize;
280     bool    m_IsEnableSurroundAtInitialize;
281 
282     u8      m_ProcessChannelCount;
283     bool    m_IsActive;          ///< アクティブか?
284 
285     NN_PADDING1;
286 };
287 
288 }}} // namespace nn::snd::CTR
289 
290 #endif // __cplusplus
291 
292 #endif /* NN_SND_FX_DELAY_H_ */
293 
294