1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundDataManager.cpp
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: 27749 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_SoundDataManager.h>
19
20 #include <nw/snd/snd_DisposeCallbackManager.h>
21 #include <nw/snd/snd_DriverCommand.h>
22 #include <nw/snd/snd_SoundArchiveLoader.h>
23 #include <nw/snd/snd_GroupFileReader.h>
24 #include <nw/snd/snd_WaveArchiveFile.h>
25 #include <nw/snd/snd_Util.h>
26 #include <nn/os.h>
27
28 namespace nw {
29 namespace snd {
30
31
SoundDataManager()32 SoundDataManager::SoundDataManager()
33 : m_pFileTable ( NULL ),
34 m_pFileManager( NULL )
35 {
36 }
37
~SoundDataManager()38 SoundDataManager::~SoundDataManager()
39 {
40 }
41
GetRequiredMemSize(const SoundArchive * arc) const42 size_t SoundDataManager::GetRequiredMemSize( const SoundArchive* arc ) const
43 {
44 NW_NULL_ASSERT( arc );
45 size_t size = 0;
46
47 size += ut::RoundUp(
48 sizeof( u32 ) +
49 sizeof( FileAddress ) * arc->detail_GetFileCount(), 4 );
50 return size;
51 }
52
Initialize(const SoundArchive * arc,void * buffer,u32 size)53 bool SoundDataManager::Initialize( const SoundArchive* arc, void* buffer, u32 size )
54 {
55 NW_NULL_ASSERT( arc );
56 NW_NULL_ASSERT( buffer );
57 NW_ALIGN4_ASSERT( buffer );
58 NW_ASSERT( size >= GetRequiredMemSize( arc ) );
59
60 void* endp = static_cast<char*>(buffer) + size;
61 void* buf = buffer;
62
63 if ( ! CreateFileAddressTable( arc, &buf, endp ) )
64 {
65 return false;
66 }
67
68 NW_ASSERT( static_cast<char*>(buf) - static_cast<char*>(buffer) == GetRequiredMemSize( arc ) );
69 SetSoundArchive( arc );
70
71 internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance();
72
73 internal::DriverCommandDisposeCallback* command =
74 cmdmgr.AllocCommand<internal::DriverCommandDisposeCallback>();
75 command->id = internal::DRIVER_COMMAND_REGIST_DISPOSE_CALLBACK;
76 command->callback = this;
77 cmdmgr.PushCommand(command);
78
79 return true;
80 }
81
Finalize()82 void SoundDataManager::Finalize()
83 {
84 internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance();
85
86 internal::DriverCommandDisposeCallback* command =
87 cmdmgr.AllocCommand<internal::DriverCommandDisposeCallback>();
88 command->id = internal::DRIVER_COMMAND_UNREGIST_DISPOSE_CALLBACK;
89 command->callback = this;
90 cmdmgr.PushCommand(command);
91 u32 tag = cmdmgr.FlushCommand( true );
92 cmdmgr.WaitCommandReply( tag );
93
94 m_pFileManager = NULL;
95 m_pFileTable = NULL;
96 }
97
CreateFileAddressTable(const SoundArchive * arc,void ** buffer,void * endp)98 bool SoundDataManager::CreateFileAddressTable(
99 const SoundArchive* arc,
100 void** buffer,
101 void* endp
102 )
103 {
104 size_t requiredSize =
105 sizeof( u32 ) +
106 sizeof( FileAddress ) * arc->detail_GetFileCount();
107
108 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requiredSize ), 4 );
109 if ( ut::ComparePtr( ep, endp ) > 0 )
110 {
111 return false;
112 }
113 m_pFileTable = reinterpret_cast< FileTable* >(*buffer);
114 *buffer = ep;
115
116
117 m_pFileTable->count = arc->detail_GetFileCount();
118 for( u32 i = 0 ; i < m_pFileTable->count ; i++ )
119 {
120 m_pFileTable->item[ i ].address = NULL;
121 }
122
123 return true;
124 }
125
126
127 /*---------------------------------------------------------------------------*
128 Name: InvalidateData
129
130 Description: ロードされたデータが破棄されたときにテーブルから削除する
131
132 Arguments: start - 開始アドレス
133 end - 終了アドレス
134
135 Returns: None.
136 *---------------------------------------------------------------------------*/
InvalidateData(const void * start,const void * end)137 void SoundDataManager::InvalidateData( const void* start, const void* end )
138 {
139 // ファイルアドレステーブルから破棄
140 if ( m_pFileTable != NULL )
141 {
142 for( u32 i = 0 ; i < m_pFileTable->count ; i++ )
143 {
144 const void* addr = m_pFileTable->item[ i ].address;
145 if ( start <= addr && addr <= end )
146 {
147 m_pFileTable->item[ i ].address = NULL;
148 }
149 }
150 }
151
152 if ( ut::GetOffsetFromPtr( start, end ) >= sizeof(IndividualWaveInfo) )
153 {
154 if ( start != NULL )
155 {
156 const IndividualWaveInfo* info =
157 reinterpret_cast<const IndividualWaveInfo*>( start );
158 if ( info->signature == SoundDataManager::SIGNATURE_INDIVIDUAL_WAVE )
159 {
160 const void* pWarcTable = GetFileAddressFromTable( info->fileId );
161 if ( pWarcTable != NULL )
162 {
163 internal::WaveArchiveFileReader reader( pWarcTable, true );
164 reader.SetWaveFile( info->waveIndex, NULL );
165 }
166 }
167 }
168 }
169 }
170
171 /*---------------------------------------------------------------------------*
172 Name: detail_GetFileAddress
173
174 Description: 記憶させたファイルアドレスを取得
175
176 Arguments: fileId - ファイルID
177
178 Returns: ファイルアドレス
179 *---------------------------------------------------------------------------*/
detail_GetFileAddress(SoundArchive::FileId fileId) const180 const void* SoundDataManager::detail_GetFileAddress( SoundArchive::FileId fileId ) const
181 {
182 return GetFileAddressImpl( fileId );
183 }
184
GetFileAddressImpl(SoundArchive::FileId fileId) const185 const void* SoundDataManager::GetFileAddressImpl( SoundArchive::FileId fileId ) const
186 {
187 // 外部のファイルマネージャに問い合わせ
188 if ( m_pFileManager != NULL )
189 {
190 const void* addr = m_pFileManager->GetFileAddress( fileId );
191 if ( addr != NULL ) return addr;
192 }
193
194 // サウンドアーカイブに問い合わせ
195 {
196 const void* addr = GetFileAddressFromSoundArchive( fileId );
197 if ( addr != NULL ) return addr;
198 }
199
200 // ファイルアドレステーブルを参照
201 {
202 const void* fileData = GetFileAddressFromTable( fileId );
203 if ( fileData != NULL ) return fileData;
204 }
205 return NULL;
206 }
207
SetFileAddressToTable(SoundArchive::FileId fileId,const void * address)208 const void* SoundDataManager::SetFileAddressToTable(
209 SoundArchive::FileId fileId,
210 const void* address )
211 {
212 if ( m_pFileTable == NULL )
213 {
214 NW_WARNING(
215 m_pFileTable != NULL,
216 "Failed to SoundDataManager::SetFileAddress because file table is not allocated.\n"
217 );
218 return NULL;
219 }
220
221 NW_MINMAXLT_ASSERT( fileId, 0, m_pFileTable->count );
222
223 const void* preAddress = m_pFileTable->item[ fileId ].address;
224 m_pFileTable->item[ fileId ].address = address;
225 return preAddress;
226 }
227
228
229 /*---------------------------------------------------------------------------*
230 Name: GetFileAddressFromTable
231
232 Description: 記憶させたファイルアドレスを取得
233
234 Arguments: fileId - ファイルID
235
236 Returns: ファイルアドレス
237 *---------------------------------------------------------------------------*/
GetFileAddressFromTable(SoundArchive::FileId fileId) const238 const void* SoundDataManager::GetFileAddressFromTable( SoundArchive::FileId fileId ) const
239 {
240 if ( m_pFileTable == NULL )
241 {
242 NW_WARNING(
243 m_pFileTable != NULL,
244 "Failed to SoundDataManager::GetFileAddress because file table is not allocated.\n"
245 );
246 return NULL;
247 }
248
249 if ( fileId >= m_pFileTable->count ) return NULL;
250
251 return m_pFileTable->item[ fileId ].address;
252 }
253
254 /*---------------------------------------------------------------------------*
255 Name: SetFileAddress
256
257 Description: ファイルアドレスを記憶
258
259 Arguments: fileId - ファイル番号
260 address - ファイルアドレス
261
262 Returns: セットする前に書かれていたファイルアドレス
263 *---------------------------------------------------------------------------*/
264 const void*
SetFileAddress(SoundArchive::FileId fileId,const void * address)265 SoundDataManager::SetFileAddress( SoundArchive::FileId fileId, const void* address )
266 {
267 return SetFileAddressToTable( fileId, address );
268 }
269
270 // ロード済みファイルテーブルの中から、
271 // 引数と一致するアドレスを持つファイルのファイル ID を取得する
detail_GetFileIdFromTable(const void * address) const272 u32 SoundDataManager::detail_GetFileIdFromTable( const void* address ) const
273 {
274 for ( u32 i = 0; i < m_pFileTable->count; i++ )
275 {
276 if ( address == m_pFileTable->item[i].address )
277 {
278 return i;
279 }
280 }
281 return SoundArchive::INVALID_ID;
282 }
283
284 #if 0
285 void SoundDataManager::InvalidateSoundData( void* mem, size_t size )
286 {
287 internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance();
288
289 internal::DriverCommandInvalidateData* command =
290 cmdmgr.AllocCommand<internal::DriverCommandInvalidateData>();
291 command->id = internal::DRIVER_COMMAND_INVALIDATE_DATA;
292 command->mem = mem;
293 command->size = size;
294 cmdmgr.PushCommand(command);
295 u32 tag = cmdmgr.FlushCommand( true );
296 cmdmgr.WaitCommandReply( tag );
297 }
298 #endif
299
300
301 } // namespace nw::snd
302 } // namespace nw
303
304