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