/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_SoundDataManager.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include #include #include #include #include #include #include #include namespace nw { namespace snd { SoundDataManager::SoundDataManager() : m_pFileTable ( NULL ), m_pFileManager( NULL ) { } SoundDataManager::~SoundDataManager() { } size_t SoundDataManager::GetRequiredMemSize( const SoundArchive* arc ) const { NW_NULL_ASSERT( arc ); size_t size = 0; size += ut::RoundUp( sizeof( u32 ) + sizeof( FileAddress ) * arc->detail_GetFileCount(), 4 ); return size; } bool SoundDataManager::Initialize( const SoundArchive* arc, void* buffer, u32 size ) { NW_NULL_ASSERT( arc ); NW_NULL_ASSERT( buffer ); NW_ALIGN4_ASSERT( buffer ); NW_ASSERT( size >= GetRequiredMemSize( arc ) ); void* endp = static_cast(buffer) + size; void* buf = buffer; if ( ! CreateFileAddressTable( arc, &buf, endp ) ) { return false; } NW_ASSERT( static_cast(buf) - static_cast(buffer) == GetRequiredMemSize( arc ) ); SetSoundArchive( arc ); internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance(); internal::DriverCommandDisposeCallback* command = cmdmgr.AllocCommand(); command->id = internal::DRIVER_COMMAND_REGIST_DISPOSE_CALLBACK; command->callback = this; cmdmgr.PushCommand(command); return true; } void SoundDataManager::Finalize() { internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance(); internal::DriverCommandDisposeCallback* command = cmdmgr.AllocCommand(); command->id = internal::DRIVER_COMMAND_UNREGIST_DISPOSE_CALLBACK; command->callback = this; cmdmgr.PushCommand(command); u32 tag = cmdmgr.FlushCommand( true ); cmdmgr.WaitCommandReply( tag ); m_pFileManager = NULL; m_pFileTable = NULL; } bool SoundDataManager::CreateFileAddressTable( const SoundArchive* arc, void** buffer, void* endp ) { size_t requiredSize = sizeof( u32 ) + sizeof( FileAddress ) * arc->detail_GetFileCount(); void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requiredSize ), 4 ); if ( ut::ComparePtr( ep, endp ) > 0 ) { return false; } m_pFileTable = reinterpret_cast< FileTable* >(*buffer); *buffer = ep; m_pFileTable->count = arc->detail_GetFileCount(); for( u32 i = 0 ; i < m_pFileTable->count ; i++ ) { m_pFileTable->item[ i ].address = NULL; } return true; } /*---------------------------------------------------------------------------* Name: InvalidateData Description: ロードされたデータが破棄されたときにテーブルから削除する Arguments: start - 開始アドレス end - 終了アドレス Returns: None. *---------------------------------------------------------------------------*/ void SoundDataManager::InvalidateData( const void* start, const void* end ) { // ファイルアドレステーブルから破棄 if ( m_pFileTable != NULL ) { for( u32 i = 0 ; i < m_pFileTable->count ; i++ ) { const void* addr = m_pFileTable->item[ i ].address; if ( start <= addr && addr <= end ) { m_pFileTable->item[ i ].address = NULL; } } } if ( ut::GetOffsetFromPtr( start, end ) >= sizeof(IndividualWaveInfo) ) { if ( start != NULL ) { const IndividualWaveInfo* info = reinterpret_cast( start ); if ( info->signature == SoundDataManager::SIGNATURE_INDIVIDUAL_WAVE ) { const void* pWarcTable = GetFileAddressFromTable( info->fileId ); if ( pWarcTable != NULL ) { internal::WaveArchiveFileReader reader( pWarcTable, true ); reader.SetWaveFile( info->waveIndex, NULL ); } } } } } /*---------------------------------------------------------------------------* Name: detail_GetFileAddress Description: 記憶させたファイルアドレスを取得 Arguments: fileId - ファイルID Returns: ファイルアドレス *---------------------------------------------------------------------------*/ const void* SoundDataManager::detail_GetFileAddress( SoundArchive::FileId fileId ) const { return GetFileAddressImpl( fileId ); } const void* SoundDataManager::GetFileAddressImpl( SoundArchive::FileId fileId ) const { // 外部のファイルマネージャに問い合わせ if ( m_pFileManager != NULL ) { const void* addr = m_pFileManager->GetFileAddress( fileId ); if ( addr != NULL ) return addr; } // サウンドアーカイブに問い合わせ { const void* addr = GetFileAddressFromSoundArchive( fileId ); if ( addr != NULL ) return addr; } // ファイルアドレステーブルを参照 { const void* fileData = GetFileAddressFromTable( fileId ); if ( fileData != NULL ) return fileData; } return NULL; } const void* SoundDataManager::SetFileAddressToTable( SoundArchive::FileId fileId, const void* address ) { if ( m_pFileTable == NULL ) { NW_WARNING( m_pFileTable != NULL, "Failed to SoundDataManager::SetFileAddress because file table is not allocated.\n" ); return NULL; } NW_MINMAXLT_ASSERT( fileId, 0, m_pFileTable->count ); const void* preAddress = m_pFileTable->item[ fileId ].address; m_pFileTable->item[ fileId ].address = address; return preAddress; } /*---------------------------------------------------------------------------* Name: GetFileAddressFromTable Description: 記憶させたファイルアドレスを取得 Arguments: fileId - ファイルID Returns: ファイルアドレス *---------------------------------------------------------------------------*/ const void* SoundDataManager::GetFileAddressFromTable( SoundArchive::FileId fileId ) const { if ( m_pFileTable == NULL ) { NW_WARNING( m_pFileTable != NULL, "Failed to SoundDataManager::GetFileAddress because file table is not allocated.\n" ); return NULL; } if ( fileId >= m_pFileTable->count ) return NULL; return m_pFileTable->item[ fileId ].address; } /*---------------------------------------------------------------------------* Name: SetFileAddress Description: ファイルアドレスを記憶 Arguments: fileId - ファイル番号 address - ファイルアドレス Returns: セットする前に書かれていたファイルアドレス *---------------------------------------------------------------------------*/ const void* SoundDataManager::SetFileAddress( SoundArchive::FileId fileId, const void* address ) { return SetFileAddressToTable( fileId, address ); } // ロード済みファイルテーブルの中から、 // 引数と一致するアドレスを持つファイルのファイル ID を取得する u32 SoundDataManager::detail_GetFileIdFromTable( const void* address ) const { for ( u32 i = 0; i < m_pFileTable->count; i++ ) { if ( address == m_pFileTable->item[i].address ) { return i; } } return SoundArchive::INVALID_ID; } #if 0 void SoundDataManager::InvalidateSoundData( void* mem, size_t size ) { internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance(); internal::DriverCommandInvalidateData* command = cmdmgr.AllocCommand(); command->id = internal::DRIVER_COMMAND_INVALIDATE_DATA; command->mem = mem; command->size = size; cmdmgr.PushCommand(command); u32 tag = cmdmgr.FlushCommand( true ); cmdmgr.WaitCommandReply( tag ); } #endif } // namespace nw::snd } // namespace nw