1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SoundHeap.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  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   $Revision: 26164 $
14  *---------------------------------------------------------------------------*/
15 
16 /**
17  * :include nw/snd/snd_SoundHeap.h
18  *
19  * @file snd_SoundHeap.h
20  */
21 
22 #ifndef NW_SND_SOUND_HEAP_H_
23 #define NW_SND_SOUND_HEAP_H_
24 
25 #include <nw/snd/snd_SoundMemoryAllocatable.h>
26 #include <nw/snd/snd_FrameHeap.h>
27 #include <nw/snd/snd_Util.h>
28 
29 namespace nw {
30 namespace snd {
31 
32 //---------------------------------------------------------------------------
33 //! @brief    サウンドデータ用のヒープクラスです。
34 //!
35 //!           サウンドヒープでは、
36 //!           メモリブロックが解放された時に呼び出されるコールバックを
37 //!           設定することができます。
38 //!           サウンドライブラリではこの機能を用いて、
39 //!           サウンドデータを含むメモリブロックが解放された時に、
40 //!           安全にデータを解放するための処理を行うように設計されています。
41 //!
42 //! @date 2009/12/28 初版
43 //---------------------------------------------------------------------------
44 class SoundHeap : public SoundMemoryAllocatable
45 {
46   public:
47     //---------------------------------------------------------------------------
48     //! @brief    メモリブロックが破棄された時に呼び出されるコールバックです。
49     //!
50     //!           コールバック関数は @ref SoundHeap::Alloc
51     //!           の引数としてメモリブロックに渡し、
52     //!           @ref SoundHeap::Clear または @ref SoundHeap::LoadState によって、
53     //!           メモリブロックが解放されたときに呼びだされます。
54     //!
55     //! @param[in]    mem         解放されたメモリブロックの先頭アドレスです。
56     //! @param[in]    size        解放されたメモリブロックのサイズです。
57     //! @param[in]    userArg     ユーザ引数です。
58     //!
59     //! @see Alloc
60     //! @see Clear
61     //! @see LoadState
62     //!
63     //! @date 2010/01/15 Alloc, Clear, LoadState 関数への参照を追加
64     //! @date 2010/01/14 初版
65     //---------------------------------------------------------------------------
66     typedef void (*DisposeCallback)( void* mem, unsigned long size, void* userArg );
67 
68 
69   public:
70     //----------------------------------------
71     //! @name コンストラクタ/デストラクタ
72     //@{
73     //---------------------------------------------------------------------------
74     //! @brief        コンストラクタです。
75     //!
76     //! @date 2009/12/28 初版
77     //---------------------------------------------------------------------------
78     SoundHeap();
79 
80     //---------------------------------------------------------------------------
81     //! @brief        デストラクタです。
82     //!
83     //! @date 2009/12/28 初版
84     //---------------------------------------------------------------------------
85     virtual ~SoundHeap();
86     //@}
87 
88     //----------------------------------------
89     //! @name ヒープ操作
90     //@{
91     //---------------------------------------------------------------------------
92     //! @brief        サウンドヒープを作成します。
93     //!
94     //!               メモリ領域のサイズ size が十分に無いと、関数は失敗します。
95     //!               ヒープの管理領域が必要なため、
96     //!               作成されたメモリのヒープサイズは size よりも小さくなります。
97     //!
98     //!               この関数に渡したメモリ領域を再利用するには、
99     //!               @ref nw::snd::SoundHeap::Destroy
100     //!               でヒープを破棄する必要があります。
101     //!
102     //!               波形データをロードする場合は、
103     //!               startAddress にはデバイスメモリのアドレスを指定する必要があります。
104     //!
105     //! @param[in]    startAddress    ヒープとして使用するメモリの先頭アドレス。
106     //! @param[in]    size            ヒープとして使用するメモリのサイズ。
107     //!
108     //! @return       ヒープの作成に成功したら true を、
109     //!               失敗したら false を返します。
110     //!
111     //! @date 2009/12/28 初版
112     //---------------------------------------------------------------------------
113     bool Create(
114         void* startAddress,
115         size_t size
116     );
117 
118     //---------------------------------------------------------------------------
119     //! @brief        サウンドヒープを破棄します。
120     //!
121     //!               確保済みのメモリブロックそれぞれに対して、
122     //!               @ref Alloc で設定したコールバック関数が呼び出されます。
123     //!
124     //! @date 2009/12/28 初版
125     //---------------------------------------------------------------------------
126     void Destroy();
127 
128     //---------------------------------------------------------------------------
129     //! @brief        サウンドヒープからメモリを確保します。
130     //!
131     //!               各メモリブロックには管理領域が必要になります。
132     //!               そのため、実際には確保するメモリサイズ size
133     //!               よりも少し大きな空き容量が必要になります。
134     //!               空き容量が足りない場合は、関数は失敗します。
135     //!
136     //! @param[in]    size            確保するメモリサイズ。
137     //!
138     //! @return       確保したメモリブロックの先頭アドレスを返します。
139     //!
140     //! @date 2009/12/28 初版
141     //---------------------------------------------------------------------------
142     virtual void* Alloc( size_t size );
143 
144     //---------------------------------------------------------------------------
145     //! @brief        サウンドヒープからメモリを確保します。
146     //!
147     //!               各メモリブロックには管理領域が必要になります。
148     //!               そのため、実際には確保するメモリサイズ size
149     //!               よりも少し大きな空き容量が必要になります。
150     //!               空き容量が足りない場合は、関数は失敗します。
151     //!
152     //!               コールバック関数 callback は、
153     //!               @ref Clear または @ref LoadState によって、
154     //!               メモリブロックが解放されたときに呼び出されます。
155     //!               コールバック関数が不要の時は、callback に NULL を入れます。
156     //!
157     //! @param[in]    size            確保するメモリサイズ。
158     //! @param[in]    callback        メモリブロックが解放されるときに呼び出される
159     //!                               コールバック関数。
160     //! @param[in]    callbackArg     コールバック関数の引数用のユーザーデータ。
161     //!
162     //! @return       確保したメモリブロックの先頭アドレスを返します。
163     //!
164     //! @date 2009/12/28 初版
165     //---------------------------------------------------------------------------
166     void* Alloc(
167         size_t size,
168         SoundHeap::DisposeCallback callback,
169         void* callbackArg
170     );
171 
172     //---------------------------------------------------------------------------
173     //! @brief        確保したメモリブロックを全て解放します。
174     //!
175     //!               解放したメモリブロックそれぞれに対して、@ref Alloc で設定した
176     //!               コールバック関数が呼び出されます。
177     //!
178     //! @date 2009/12/28 初版
179     //---------------------------------------------------------------------------
180     void Clear();
181 
182     //---------------------------------------------------------------------------
183     //! @brief        サウンドヒープが有効かどうかを調べます。
184     //!
185     //!               @ref Create を呼び出してサウンドヒープが作成され、
186     //!               メモリブロックの確保が可能な状態であれば、true を返します。
187     //!
188     //! @return       サウンドヒープが有効なら true を返します。
189     //!
190     //! @date 2009/12/28 初版
191     //---------------------------------------------------------------------------
IsValid()192     bool IsValid() const { return m_FrameHeap.IsValid(); }
193     //@}
194 
195     //----------------------------------------
196     //! @name 階層管理
197     //---------------------------------------------------------------------------
198     //! @brief        サウンドヒープの現在の状態を保存します。
199     //!
200     //!               ヒープ作成直後の階層レベルは 0 で、
201     //!               この関数を呼ぶ毎に階層レベルがひとつ増えます。
202     //!               @ref LoadState を呼びだすことで、
203     //!               指定した階層レベルの保存直後の状態に復元させることができます。
204     //!
205     //!               状態の保存にはヒープを少し消費します。
206     //!               ヒープの空き容量が足りない場合は、関数の呼びだしは失敗します。
207     //!
208     //! @return       状態保存後の階層レベルを返します。
209     //!               状態の保存に失敗すると -1 を返します。
210     //!
211     //! @date 2009/12/28 初版
212     //---------------------------------------------------------------------------
213     int SaveState();
214 
215     //---------------------------------------------------------------------------
216     //! @brief        保存したサウンドヒープの状態を復元します。
217     //!
218     //!               サウンドヒープを @ref SaveState で保存した直後の状態に戻します。
219     //!               状態を保存してから現在までに確保されたメモリブロックは、
220     //!               全て解放されます。 解放したメモリブロックそれぞれに対して、
221     //!               @ref Alloc で設定したコールバック関数が呼びだされます。
222     //!
223     //!               階層レベル level は現在の階層レベルの値と同じか、
224     //!               より小さい値を指定します。
225     //!               0 を指定すると、@ref Clear と同じ意味になります。
226     //!               ヒープは、状態が保存された直後の状態に戻り、
227     //!               現在の階層レベルも指定した値になります。
228     //!
229     //! @param[in]    level   復元する階層レベル。
230     //!
231     //! @date 2009/12/28 初版
232     //---------------------------------------------------------------------------
233     void LoadState( int level );
234 
235     //---------------------------------------------------------------------------
236     //! @brief        現在のサウンドヒープの階層レベルを取得します。
237     //!
238     //!               ヒープ作成直後の階層レベルは 0 です。
239     //!               @ref SaveState を呼びだす毎に、階層レベルがひとつ増えます。
240     //!               @ref LoadState で状態を復元すると、
241     //!               現在の階層レベルも指定した階層レベルに戻ります。
242     //!
243     //! @return       現在の階層レベルを返します。
244     //!
245     //! @date 2009/12/28 初版
246     //---------------------------------------------------------------------------
GetCurrentLevel()247     int GetCurrentLevel() const
248     {
249 		nn::os::CriticalSection::ScopedLock lock( m_CriticalSection );
250         return m_FrameHeap.GetCurrentLevel();
251     }
252     //@}
253 
254     //----------------------------------------
255     //! @name 情報取得
256     //---------------------------------------------------------------------------
257     //! @brief        メモリ上のヒープのサイズを取得します。
258     //!
259     //! @return       メモリ上のヒープのサイズ。
260     //!
261     //! @date 2009/12/28 初版
262     //---------------------------------------------------------------------------
GetSize()263     size_t GetSize() const
264     {
265 		nn::os::CriticalSection::ScopedLock lock( m_CriticalSection );
266         return m_FrameHeap.GetSize();
267     }
268 
269     //---------------------------------------------------------------------------
270     //! @brief        メモリ上のヒープの空き容量を取得します。
271     //!
272     //! @return       メモリ上のヒープの空き容量のサイズ。
273     //!
274     //! @date 2009/12/28 初版
275     //---------------------------------------------------------------------------
GetFreeSize()276     size_t GetFreeSize() const
277     {
278         nn::os::CriticalSection::ScopedLock lock( m_CriticalSection );
279         return m_FrameHeap.GetFreeSize();
280     }
281 
282     //---------------------------------------------------------------------------
283     //! @brief      ヒープの内容をダンプします。
284     //!
285     //!             arc には、@ref SoundDataManager::Initialize 関数に渡した
286     //!             サウンドアーカイブを指定する必要があります。
287     //!
288     //!             サウンドヒープに複数のサウンドアーカイブのデータをロードしていると、
289     //!             本関数は正常に動作しません。
290     //!
291     //! @param[in]   mgr  サウンドデータマネージャです。
292     //! @param[in]   arc  サウンドアーカイブです。
293     //!
294     //! @date 2010/10/27 複数のサウンドアーカイブのデータをロードした場合の注意点を追記
295     //! @date 2009/12/28 初版
296     //---------------------------------------------------------------------------
Dump(nw::snd::SoundDataManager & mgr,nw::snd::SoundArchive & arc)297     void Dump( nw::snd::SoundDataManager& mgr, nw::snd::SoundArchive& arc )
298     {
299         nn::os::CriticalSection::ScopedLock lock( m_CriticalSection );
300         m_FrameHeap.Dump( mgr, arc );
301     }
302     //@}
303 
304   private:
305     static void DisposeCallbackFunc( void* mem, unsigned long size, void* arg );
306 
307 	mutable nn::os::CriticalSection m_CriticalSection;
308     internal::FrameHeap m_FrameHeap;       // メインメモリ管理ヒープ
309 };
310 
311 } // namespace nw::snd
312 } // namespace nw
313 
314 
315 #endif /* NW_SND_SOUND_HEAP_H_ */
316 
317