1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SoundArchiveLoader.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_SND_SOUND_ARCHIVE_LOADER_H_
19 #define NW_SND_SOUND_ARCHIVE_LOADER_H_
20 
21 #include <nw/io/io_FileStream.h>
22 #include <nw/snd/snd_SoundArchive.h>
23 #include <nw/snd/snd_Util.h>
24 
25 namespace nw {
26 namespace snd {
27 
28 class SoundMemoryAllocatable;
29 
30 namespace internal {
31 
32 struct LoadItemInfo
33 {
34     nw::snd::SoundArchive::ItemId itemId;
35     const void* address;
36 
LoadItemInfoLoadItemInfo37     LoadItemInfo()
38     : itemId( nw::snd::SoundArchive::INVALID_ID ),
39       address( NULL )
40     {}
41 };
42 
43 /* ========================================================================
44         class difinition
45    ======================================================================== */
46 
47 class SoundArchiveLoader
48 {
49 public:
50     //! @details :private
51     static const u32 SIGNATURE_INDIVIDUAL_WAVE = NW_UT_MAKE_SIGWORD( 'C', 'I', 'W', 'V' );
52 
53     // 個別ロード波形のメモリブロック先頭に置かれる情報
54     struct IndividualWaveInfo
55     {
56         // データ
57         u32 signature;
58         u32 fileId;         //< 所属する波形アーカイブファイル ID
59         u32 waveIndex;      //< 波形アーカイブ内インデックス
60         u32 padding[5];
61 
62         // メソッド
IndividualWaveInfoIndividualWaveInfo63         IndividualWaveInfo( u32 id, u32 index )
64         : signature( SoundArchiveLoader::SIGNATURE_INDIVIDUAL_WAVE ),
65           fileId( id ),
66           waveIndex( index )
67         {}
68     };
69 
70 
71     //---------------------------------------------------------------------------
72     //! @brief  ロードフラグです。
73     //---------------------------------------------------------------------------
74     enum LoadFlag
75     {
76         // サウンド
77         LOAD_SEQ    = ( 1 << 0 ),   //!< シーケンスサウンドをロードします
78         LOAD_WSD    = ( 1 << 1 ),   //!< ウェーブサウンドをロードします
79 
80         // バンク
81         LOAD_BANK   = ( 1 << 2 ),   //!< バンクをロードします
82 
83         // 波形アーカイブ
84         LOAD_WARC   = ( 1 << 3 ),   //!< 波形アーカイブをロードします
85 
86         LOAD_ALL    = 0xffffffff    //!< 関連するファイルをすべてロードします
87     };
88 
89     SoundArchiveLoader();
90     virtual ~SoundArchiveLoader();
91 
92     //----------------------------------------
93     //! @name 初期化
94     //@{
95     //---------------------------------------------------------------------------
96     //! @brief  サウンドデータマネージャが利用可能な状態かどうかを調べます。
97     //!
98     //! @return   サウンドデータマネージャが利用可能な状態なら true を、
99     //!           そうでなければ false を返します。
100     //---------------------------------------------------------------------------
101     bool IsAvailable() const;
102     //@}
103 
104 
105     //----------------------------------------
106     //! @name ロード
107     //@{
108     //---------------------------------------------------------------------------
109     //! @brief    サウンドアーカイブ中のデータをロードします。
110     //!
111     //!           ロードに必要なメモリはアロケータ pAllocator から確保されます。
112     //!           十分なメモリが確保できない場合は false を返します。
113     //!
114     //!           この関数はサウンドデータの同期ロードを行います。
115     //!           非同期でサウンドデータをロードする場合は、
116     //!           ロード用のスレッドでこの関数を呼び出してください。
117     //!           関連付けられているサウンドアーカイブや、
118     //!           引数で渡すサウンドヒープに対する操作をロード中に行わない限り、
119     //!           この関数はスレッドセーフです。
120     //!
121     //! @param[in]    id              ロードするデータのアイテム ID です。
122     //! @param[in]    pAllocator      ロードするメモリを確保するためのアロケータです。
123     //! @param[in]    loadFlag        関連するデータをロードするためのフラグです。
124     //! @param[in]    loadBlockSize   データを分割ロードする際の分割サイズを、
125     //!                               バイト単位で指定します。
126     //!
127     //! @return   ロードに成功したら true を、失敗したら false を返します。
128     //!
129     //! @date 2010/12/17 参照から「Initialize」「IsAvailable」を削除、「IsDataLoaded」追加
130     //! @date 2010/09/06 loadBlockSize 指定の対応にともない、引数の文言を調整
131     //! @date 2010/04/09 文言の修正 (グループ→サウンドデータ)、「参照」に IsDataLoaded 追加
132     //! @date 2010/01/15 初版
133     //---------------------------------------------------------------------------
134     bool LoadData(
135         SoundArchive::ItemId id,
136         SoundMemoryAllocatable* pAllocator,
137         u32 loadFlag = LOAD_ALL, // LoadFlag の論理和を渡す
138         size_t loadBlockSize = 0
139     );
140 
141     //---------------------------------------------------------------------------
142     //! @brief    サウンドアーカイブ中のデータをロードします。
143     //!
144     //!           ロードに必要なメモリはアロケータ pAllocator から確保されます。
145     //!           十分なメモリが確保できない場合は false を返します。
146     //!
147     //!           この関数はサウンドデータの同期ロードを行います。
148     //!           非同期でサウンドデータをロードする場合は、
149     //!           ロード用のスレッドでこの関数を呼び出してください。
150     //!           関連付けられているサウンドアーカイブや、
151     //!           引数で渡すサウンドヒープに対する操作をロード中に行わない限り、
152     //!           この関数はスレッドセーフです。
153     //!
154     //! @param[in]    pItemName       ロードするデータのラベル文字列です。
155     //! @param[in]    pAllocator      ロードするメモリを確保するためのアロケータです。
156     //! @param[in]    loadFlag        関連するデータをロードするためのフラグです。
157     //! @param[in]    loadBlockSize   データを分割ロードする際の分割サイズを、
158     //!                               バイト単位で指定します。
159     //!
160     //! @return   ロードに成功したら true を、失敗したら false を返します。
161     //!
162     //! @date 2010/12/17 参照から「Initialize」「IsAvailable」を削除
163     //! @date 2010/09/06 loadBlockSize 指定の対応にともない、引数の文言を調整
164     //! @date 2010/04/09 文言の修正 (グループ→サウンドデータ)、「参照」に IsDataLoaded 追加
165     //! @date 2010/01/15 初版
166     //---------------------------------------------------------------------------
167     bool LoadData(
168         const char* pItemName,
169         SoundMemoryAllocatable* pAllocator,
170         u32 loadFlag = LOAD_ALL, // LoadFlag の論理和を渡す
171         size_t loadBlockSize = 0
172     );
173 
174     //---------------------------------------------------------------------------
175     //! @brief    指定したデータがロードされているか調べます。
176     //!
177     //!           loadFlag を利用することで、確認するデータを制限することができます。
178     //!           デフォルトはすべての関連アイテムがロードされているかを確認します。
179     //!
180     //! @param[in] itemId     ロードされているか確認するサウンドデータのアイテム ID です。
181     //! @param[in] loadFlag   関連するデータを確認するかを示すフラグです。
182     //!
183     //! @return   ロードされていれば true を、されていなければ false を返します。
184     //!
185     //! @date 2010/04/09 初版
186     //---------------------------------------------------------------------------
187     bool IsDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag = LOAD_ALL ) const;
188 
189     //---------------------------------------------------------------------------
190     //! @brief    指定したデータがロードされているか調べます。
191     //!
192     //!           loadFlag を利用することで、確認するデータを制限することができます。
193     //!           デフォルトはすべての関連アイテムがロードされているかを確認します。
194     //!
195     //! @param[in] pItemName  ロードされているか確認するデータのラベル文字列です。
196     //! @param[in] loadFlag   関連するデータを確認するかを示すフラグです。
197     //!
198     //! @return   ロードされていれば true を、されていなければ false を返します。
199     //!
200     //! @date 2010/04/09 初版
201     //---------------------------------------------------------------------------
202     bool IsDataLoaded( const char* pItemName, u32 loadFlag = LOAD_ALL ) const;
203 
204     //---------------------------------------------------------------------------
205     //! @brief  実行中の @ref LoadData をキャンセルします。
206     //!
207     //!         @ref LoadData では、loadBlockSize に非ゼロの値を指定すると、
208     //!         そのサイズごとに分割ロードされますが、
209     //!         この分割のタイミングでキャンセルされ、LoadData 関数から返ってきます。
210     //!
211     //!         ロードがキャンセルされても、本来ロードに必要であったメモリは占有されたままです。
212     //!         そのため、ヒープを有効に使うには、適切に解放処理
213     //!         (@ref SoundHeap::LoadState など) を呼び出す必要があります。
214     //!
215     //! @return   現在ロード中のデータがあれば true を、ロード中でなければ false を返します。
216     //!
217     //! @date 2011/02/17 初版
218     //---------------------------------------------------------------------------
219     bool CancelLoading();
220     //@}
221 
222     //! @details :private
223     const void* detail_GetFileAddressByItemId( SoundArchive::ItemId itemId ) const;
224 
225     //! @details :private
226     bool detail_LoadWaveArchiveByBankFile(
227             const void* bankFile,
228             SoundMemoryAllocatable* pAllocator );
229 
230     //! @details :private
231     bool detail_LoadWaveArchiveByWaveSoundFile(
232             const void* wsdFile,
233             s32 waveSoundIndex,
234             SoundMemoryAllocatable* pAllocator );
235 
236 protected:
237     //! @details :private
238     void SetSoundArchive( const SoundArchive* arc );
239     //! @details :private
240     const void* GetFileAddressFromSoundArchive( SoundArchive::FileId fileId ) const;
241 
242     //! @details :private
243     virtual const void* SetFileAddressToTable(
244             SoundArchive::FileId fileId, const void* address ) = 0;
245     //! @details :private
246     virtual const void* GetFileAddressFromTable( SoundArchive::FileId fileId ) const = 0;
247 
248     //! @detail :private
249     virtual const void* GetFileAddressImpl( SoundArchive::FileId fileId ) const = 0;
250         // テーブルを含め、アクセス可能な箇所にデータが読み込まれているかを確認する
251 
252 private:
253     bool LoadSequenceSound(
254             SoundArchive::ItemId soundId,
255             SoundMemoryAllocatable* pAllocator,
256             u32 loadFlag,
257             size_t loadBlockSize );
258     bool LoadWaveSound(
259             SoundArchive::ItemId soundId,
260             SoundMemoryAllocatable* pAllocator,
261             u32 loadFlag,
262             size_t loadBlockSize,
263             SoundArchive::ItemId waveSoundSetId = SoundArchive::INVALID_ID );
264     bool LoadBank(
265             SoundArchive::ItemId bankId,
266             SoundMemoryAllocatable* pAllocator,
267             u32 loadFlag,
268             size_t loadBlockSize );
269     bool LoadWaveArchive(
270             SoundArchive::ItemId warcId,
271             SoundMemoryAllocatable* pAllocator,
272             u32 loadFlag,
273             size_t loadBlockSize );
274     const void* LoadWaveArchiveTable(
275             SoundArchive::ItemId warcId,
276             SoundMemoryAllocatable* pAllocator,
277             size_t loadBlockSize );
278     bool LoadIndividualWave(
279             SoundArchive::ItemId warcId,
280             u32 waveIndex,
281             SoundMemoryAllocatable* pAllocator,
282             size_t loadBlockSize );
283     bool LoadGroup(
284             SoundArchive::ItemId groupId,
285             SoundMemoryAllocatable* pAllocator,
286             size_t loadBlockSize );
287     bool LoadSoundGroup(
288             SoundArchive::ItemId soundGroupId,
289             SoundMemoryAllocatable* pAllocator,
290             u32 loadFlag,
291             size_t loadBlockSize );
292     const void* LoadImpl(
293             SoundArchive::FileId fileId,
294             SoundMemoryAllocatable* pAllocator,
295             size_t loadBlockSize,
296             bool needDeviceMemory = false );
297     bool LoadWaveArchiveImpl(
298             SoundArchive::ItemId warcId,
299             u32 waveIndex,
300             SoundMemoryAllocatable* pAllocator,
301             u32 loadFlag,
302             size_t loadBlockSize = 0 );
303 
304     bool PostProcessForLoadedGroupFile(
305             const void* pGroupFile,
306             SoundMemoryAllocatable* pAllocator = NULL,
307             size_t loadBlockSize = 0 );
308 
309     bool IsSequenceSoundDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
310     bool IsWaveSoundDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
311     bool IsBankDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
312     bool IsWaveArchiveDataLoaded( SoundArchive::ItemId itemId, u32 waveIndex ) const;
313     bool IsGroupDataLoaded( SoundArchive::ItemId itemId ) const;
314     bool IsSoundGroupDataLoaded( SoundArchive::ItemId itemId, u32 loadFlag ) const;
315 
316     void* LoadFile(
317         SoundArchive::FileId fileId,
318         SoundMemoryAllocatable* allocator,
319         size_t loadBlockSize,
320         bool needDeviceMemory
321     );
322     s32 ReadFile(
323             SoundArchive::FileId fileId,
324             void* buffer,
325             size_t size,
326             s32 offset,
327             size_t loadBlockSize );
328 
329     void SetWaveArchiveTableWithSeqInEmbeddedGroup(
330             SoundArchive::ItemId seqId, SoundMemoryAllocatable* pAllocator );
331     void SetWaveArchiveTableWithBankInEmbeddedGroup(
332             SoundArchive::ItemId bankId, SoundMemoryAllocatable* pAllocator );
333     void SetWaveArchiveTableWithWsdInEmbeddedGroup(
334             SoundArchive::ItemId wsdId, SoundMemoryAllocatable* pAllocator );
335     void SetWaveArchiveTableInEmbeddedGroupImpl(
336             SoundArchive::ItemId warcId, SoundMemoryAllocatable* pAllocator );
337 
338     const SoundArchive* m_pSoundArchive;
339     u32 m_StreamArea[ 128 ];
340 
341     u16 m_LoadDataCallCount;
342     bool m_IsCancelLoading;
343 };
344 
345 } // namespace nw::snd::internal
346 } // namespace nw::snd
347 } // namespace nw
348 
349 
350 #endif /* NW_SND_SOUND_ARCHIVE_LOADER_H_ */
351 
352