1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SoundDataManager.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: 22506 $
14  *---------------------------------------------------------------------------*/
15 
16 /**
17  * :include nw/snd/snd_SoundDataManager.h
18  *
19  * @file snd_SoundDataManager.h
20  */
21 
22 #ifndef NW_SND_SOUND_DATA_MANAGER_H_
23 #define NW_SND_SOUND_DATA_MANAGER_H_
24 
25 #include <nw/snd/snd_DisposeCallback.h>
26 #include <nw/snd/snd_SoundArchive.h>
27 #include <nw/snd/snd_Util.h>
28 
29 namespace nw {
30 namespace snd {
31 
32 class SoundMemoryAllocatable;
33 
34 namespace internal
35 {
36 
37 //! @details :private
38 class SoundFileManager
39 {
40   public:
41     virtual const void* GetFileAddress( SoundArchive::FileId fileId ) const = 0;
42     virtual const void* GetFileWaveDataAddress( SoundArchive::FileId fileId ) const = 0;
43 };
44 
45 } // namespace nw::snd::internal
46 
47 //---------------------------------------------------------------------------
48 //! @brief    サウンドアーカイブのデータをロードするためのクラスです。
49 //!
50 //! @see SoundArchivePlayer クラス
51 //!
52 //! @date 2010/04/09 IsDataLoaded 関数を追加
53 //! @date 2010/02/01 「参照」に SoundArchivePlayer クラス追加
54 //! @date 2010/01/15 初版
55 //---------------------------------------------------------------------------
56 class SoundDataManager : public internal::driver::DisposeCallback
57 {
58 public:
59     //! @details :private
60     static const u32 SIGNATURE_INDIVIDUAL_WAVE = NW_UT_MAKE_SIGWORD( 'C', 'I', 'W', 'V' );
61 
62     //---------------------------------------------------------------------------
63     //! @brief    ロードフラグです。
64     //!
65     //!           @ref LoadData の loadFlag に論理和を渡すと、関連するデータのうち、
66     //!           ロードしたいデータのみロードすることができます。
67     //!
68     //! @see LoadData
69     //!
70     //! @date 2010/01/15 初版
71     //---------------------------------------------------------------------------
72     enum LoadFlag
73     {
74         // サウンド
75         LOAD_SEQ    = ( 1 << 0 ),   //!< シーケンスサウンドをロードします
76         LOAD_WSD    = ( 1 << 1 ),   //!< ウェーブサウンドをロードします
77 
78         // バンク
79         LOAD_BANK   = ( 1 << 2 ),   //!< バンクをロードします
80 
81         // 波形アーカイブ
82         LOAD_WARC   = ( 1 << 3 ),   //!< 波形アーカイブをロードします
83 
84         LOAD_ALL    = 0xffffffff    //!< 関連するファイルをすべてロードします
85     };
86 
87     //----------------------------------------
88     //! @name コンストラクタ / デストラクタ
89     //@{
90     //---------------------------------------------------------------------------
91     //! @brief    コンストラクタです。
92     //!
93     //! @date 2010/01/15 初版
94     //---------------------------------------------------------------------------
95     SoundDataManager();
96 
97     //---------------------------------------------------------------------------
98     //! @brief    デストラクタです。
99     //!
100     //! @date 2010/01/15 初版
101     //---------------------------------------------------------------------------
102     virtual ~SoundDataManager();
103     //@}
104 
105     //----------------------------------------
106     //! @name 初期化
107     //@{
108     //---------------------------------------------------------------------------
109     //! @brief    初期化に必要なメモリのサイズを取得します。
110     //!
111     //! @param[in]    arc     このサウンドデータマネージャを登録するプレイヤーで
112     //!                       使用するサウンドアーカイブです。
113     //!
114     //! @return   初期化に必要なメモリのサイズを返します。
115     //!
116     //! @see Initialize
117     //! @see SoundArchivePlayer::Initialize
118     //!
119     //! @date 2010/02/01 関数名変更 (Setup → Initialize) にともなう文言の調整
120     //! @date 2010/01/15 初版
121     //---------------------------------------------------------------------------
122     size_t GetRequiredMemSize( const SoundArchive* arc ) const;
123 
124     //---------------------------------------------------------------------------
125     //! @brief    サウンドデータマネージャの初期化を行います。
126     //!
127     //!           サウンドデータマネージャを使用する前に初期化を行う必要があります。
128     //!           初期化を行うことにより、
129     //!           サウンドデータマネージャがサウンドアーカイブと関連付けられ、
130     //!           サウンドアーカイブプレイヤーに登録することができます。
131     //!
132     //!           サウンドデータマネージャが必要とするメモリのサイズは
133     //!           @ref GetRequiredMemSize で取得することができます。
134     //!
135     //! @param[in]    arc     このサウンドデータマネージャを登録するプレイヤーで
136     //!                       使用するサウンドアーカイブです。
137     //! @param[out]   buffer  バッファへのポインタです。
138     //!                       4 バイトアライメントされている必要があります。
139     //! @param[in]    size    バッファサイズです。
140     //!
141     //! @return   初期化に成功したら true を、失敗したら false を返します。
142     //!
143     //! @see GetRequiredMemSize
144     //! @see Finalize
145     //! @see IsAvailable
146     //!
147     //! @date 2010/02/01 関数名変更 (Setup → Initialize)
148     //! @date 2010/01/15 初版
149     //---------------------------------------------------------------------------
150     bool Initialize( const SoundArchive* arc, void* buffer, u32 size );
151 
152     //---------------------------------------------------------------------------
153     //! @brief    サウンドデータマネージャが利用可能な状態かどうかを調べます。
154     //!
155     //!           サウンドデータマネージャを利用するためには @ref Initialize
156     //!           を呼び出して初期化を完了させる必要があります。
157     //!           また、@ref Finalize を呼び出すと、
158     //!           サウンドデータマネージャの終了処理が行われ、利用できない状態になります。
159     //!
160     //! @return   サウンドデータマネージャが利用可能な状態なら true を、
161     //!           そうでなければ false を返します。
162     //!
163     //! @see Initialize
164     //! @see Finalize
165     //!
166     //! @date 2010/01/15 初版
167     //---------------------------------------------------------------------------
168     bool IsAvailable() const;
169 
170     //---------------------------------------------------------------------------
171     //! @brief    サウンドデータマネージャを破棄します。
172     //!
173     //! @see Initialize
174     //! @see IsAvailable
175     //!
176     //! @date 2010/02/01 関数名変更 (Shutdown → Finalize)
177     //! @date 2010/01/15 初版
178     //---------------------------------------------------------------------------
179     void Finalize();
180     //@}
181 
182     //----------------------------------------
183     //! @name ロード
184     //@{
185 
186     //---------------------------------------------------------------------------
187     //! @brief    サウンドアーカイブ中のデータをロードします。
188     //!
189     //!           ロードに必要なメモリはアロケータ pAllocator から確保されます。
190     //!           十分なメモリが確保できない場合は false を返します。
191     //!
192     //!           この関数はサウンドデータの同期ロードを行います。
193     //!           非同期でサウンドデータをロードする場合は、
194     //!           ロード用のスレッドでこの関数を呼び出してください。
195     //!           関連付けられているサウンドアーカイブや、
196     //!           引数で渡すサウンドヒープに対する操作をロード中に行わない限り、
197     //!           この関数はスレッドセーフです。
198     //!
199     //! @param[in]    id              ロードするデータのアイテム ID です。
200     //! @param[in]    pAllocator      ロードするメモリを確保するためのアロケータです。
201     //! @param[in]    loadFlag        関連するデータをロードするためのフラグです。
202     //! @param[in]    loadBlockSize   データを分割ロードする際の分割サイズを、
203     //!                               バイト単位で指定します。
204     //!
205     //! @return   ロードに成功したら true を、失敗したら false を返します。
206     //!
207     //! @see Initialize
208     //! @see IsAvailable
209     //!
210     //! @date 2010/09/06 loadBlockSize 指定の対応にともない、引数の文言を調整
211     //! @date 2010/04/09 文言の修正 (グループ→サウンドデータ)、「参照」に IsDataLoaded 追加
212     //! @date 2010/01/15 初版
213     //---------------------------------------------------------------------------
214     bool LoadData(
215         SoundArchive::ItemId id,
216         SoundMemoryAllocatable* pAllocator,
217         u32 loadFlag = LOAD_ALL, // LoadFlag の論理和を渡す
218         size_t loadBlockSize = 0
219     );
220 
221     //---------------------------------------------------------------------------
222     //! @brief    サウンドアーカイブ中のデータをロードします。
223     //!
224     //!           ロードに必要なメモリはアロケータ pAllocator から確保されます。
225     //!           十分なメモリが確保できない場合は false を返します。
226     //!
227     //!           この関数はサウンドデータの同期ロードを行います。
228     //!           非同期でサウンドデータをロードする場合は、
229     //!           ロード用のスレッドでこの関数を呼び出してください。
230     //!           関連付けられているサウンドアーカイブや、
231     //!           引数で渡すサウンドヒープに対する操作をロード中に行わない限り、
232     //!           この関数はスレッドセーフです。
233     //!
234     //! @param[in]    pItemName       ロードするデータのラベル文字列です。
235     //! @param[in]    pAllocator      ロードするメモリを確保するためのアロケータです。
236     //! @param[in]    loadFlag        関連するデータをロードするためのフラグです。
237     //! @param[in]    loadBlockSize   データを分割ロードする際の分割サイズを、
238     //!                               バイト単位で指定します。
239     //!
240     //! @return   ロードに成功したら true を、失敗したら false を返します。
241     //!
242     //! @see Initialize
243     //! @see IsAvailable
244     //! @see IsDataLoaded
245     //!
246     //! @date 2010/09/06 loadBlockSize 指定の対応にともない、引数の文言を調整
247     //! @date 2010/04/09 文言の修正 (グループ→サウンドデータ)、「参照」に IsDataLoaded 追加
248     //! @date 2010/01/15 初版
249     //---------------------------------------------------------------------------
250     bool LoadData(
251         const char* pItemName,
252         SoundMemoryAllocatable* pAllocator,
253         u32 loadFlag = LOAD_ALL, // LoadFlag の論理和を渡す
254         size_t loadBlockSize = 0
255     );
256 
257     //---------------------------------------------------------------------------
258     //! @brief    指定したデータがロードされているか調べます。
259     //!
260     //!           loadFlag を利用することで、確認するデータを制限することができます。
261     //!           デフォルトはすべての関連アイテムがロードされているかを確認します。
262     //!
263     //! @param[in] itemId     ロードされているか確認するサウンドデータのアイテム ID です。
264     //! @param[in] loadFlag   関連するデータを確認するかを示すフラグです。
265     //!
266     //! @return   ロードされていれば true を、されていなければ false を返します。
267     //!
268     //! @see LoadData
269     //!
270     //! @date 2010/04/09 初版
271     //---------------------------------------------------------------------------
272     bool IsDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag = LOAD_ALL ) const;
273 
274     //---------------------------------------------------------------------------
275     //! @brief    指定したデータがロードされているか調べます。
276     //!
277     //!           loadFlag を利用することで、確認するデータを制限することができます。
278     //!           デフォルトはすべての関連アイテムがロードされているかを確認します。
279     //!
280     //! @param[in] pItemName  ロードされているか確認するデータのラベル文字列です。
281     //! @param[in] loadFlag   関連するデータを確認するかを示すフラグです。
282     //!
283     //! @return   ロードされていれば true を、されていなければ false を返します。
284     //!
285     //! @see LoadData
286     //!
287     //! @date 2010/04/09 初版
288     //---------------------------------------------------------------------------
289     bool IsDataLoaded( const char* pItemName, u32 loadFlag = LOAD_ALL ) const;
290 
291     // TODO: u32 GetDataSize( SoundArchive::ItemId ) const;
292     // TODO: u32 GetDataSize( const char* pItemName ) const;
293     // TODO: itemId の型が int/unsinged int/long 版も必要?
294     //@}
295 
296     //! @details :private
detail_SetFileManager(internal::SoundFileManager * fileManager)297     void detail_SetFileManager( internal::SoundFileManager* fileManager )
298     {
299         m_pFileManager = fileManager;
300     }
301 
302     //! @details :private
303     const void* SetFileAddress( SoundArchive::FileId fileId, const void* address );
304 
305     //! @details :private
306     const void* detail_GetFileAddress( SoundArchive::FileId fileId ) const;
307 
308     //! @details :private
309     u32 detail_GetFileId( const void* address ) const;
310 
311     //! @details :private
312     bool SetGroupItem(
313             const void* pGroupFile,
314             SoundMemoryAllocatable* pAllocator = NULL,
315             size_t loadBlockSize = 0 );
316 
317     // 外部ロードしたサウンドデータを破棄する直前に呼び、データ・インスタンスを無効化する
318     //! @details :private
319     void InvalidateSoundData( void* mem, size_t size );
320 
321 protected:
322     //! @details :private
323     virtual void InvalidateData( const void* start, const void* end );
324 
325 private:
326     struct FileAddress
327     {
328         const void* address;
329     };
330 
331     typedef internal::Util::Table<FileAddress> FileTable;
332 
333     //! @details :private
334     bool LoadSequenceSound(
335             SoundArchive::ItemId soundId,
336             SoundMemoryAllocatable* pAllocator,
337             u32 loadFlag,
338             size_t loadBlockSize );
339     //! @details :private
340     bool LoadWaveSound(
341             SoundArchive::ItemId soundId,
342             SoundMemoryAllocatable* pAllocator,
343             u32 loadFlag,
344             size_t loadBlockSize,
345             SoundArchive::ItemId waveSoundSetId = SoundArchive::INVALID_ID );
346     //! @details :private
347     bool LoadBank(
348             SoundArchive::ItemId bankId,
349             SoundMemoryAllocatable* pAllocator,
350             u32 loadFlag,
351             size_t loadBlockSize );
352     //! @details :private
353     bool LoadWaveArchive(
354             SoundArchive::ItemId warcId,
355             SoundMemoryAllocatable* pAllocator,
356             u32 loadFlag,
357             size_t loadBlockSize );
358     //! @details :private
359     const void* LoadWaveArchiveTable(
360             SoundArchive::ItemId warcId,
361             SoundMemoryAllocatable* pAllocator,
362             size_t loadBlockSize );
363     //! @details :private
364     bool LoadIndividualWave(
365             SoundArchive::ItemId warcId,
366             u32 waveIndex,
367             SoundMemoryAllocatable* pAllocator,
368             size_t loadBlockSize );
369     //! @details :private
370     bool LoadGroup(
371             SoundArchive::ItemId groupId,
372             SoundMemoryAllocatable* pAllocator,
373             size_t loadBlockSize );
374     //! @details :private
375     bool LoadSoundGroup(
376             SoundArchive::ItemId soundGroupId,
377             SoundMemoryAllocatable* pAllocator,
378             u32 loadFlag,
379             size_t loadBlockSize );
380 
381     //! @details :private
382     const void* LoadImpl(
383             SoundArchive::FileId fileId,
384             SoundMemoryAllocatable* pAllocator,
385             size_t loadBlockSize,
386             bool needDeviceMemory = false );
387 
388     //! @details :private
389     bool LoadWaveArchiveImpl(
390             SoundArchive::ItemId warcId,
391             u32 waveIndex,
392             SoundMemoryAllocatable* pAllocator,
393             u32 loadFlag,
394             size_t loadBlockSize );
395 
396     //! @details :private
397     bool IsSequenceSoundDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
398     //! @details :private
399     bool IsWaveSoundDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
400     //! @details :private
401     bool IsBankDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
402     //! @details :private
403     bool IsWaveArchiveDataLoaded( SoundArchive::ItemId itemId, u32 waveIndex ) const;
404     //! @details :private
405     bool IsGroupDataLoaded( SoundArchive::ItemId itemId ) const;
406     //! @details :private
407     bool IsSoundGroupDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
408 
409     //! @details :private
410     const void* GetFileAddress( SoundArchive::FileId fileId ) const;
411     //! @details :private
412     bool CreateFileAddressTable( const SoundArchive* arc, void** buffer, void* endp );
413 
414 private:
415     FileTable* m_pFileTable;
416     const SoundArchive* m_pSoundArchive;
417     internal::SoundFileManager* m_pFileManager;
418 };
419 
420 } // namespace nw::snd
421 } // namespace nw
422 
423 
424 #endif /* NW_SND_SOUND_DATA_MANAGER_H_ */
425 
426