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