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