/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_StreamSoundFileLoader.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. 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. $Revision: 13145 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include namespace nw { namespace snd { namespace internal { /* ======================================================================== StreamSoundFileLoader ======================================================================== */ /*---------------------------------------------------------------------------* Name: LoadFileHeader Description: ストリームデータのファイルヘッダとHEADブロックをロードし、 StreamSoundFileReaderに渡す Arguments: buffer - ロードに使用するバッファ size - バッファサイズ Returns: AdpcmInfo構造体 *---------------------------------------------------------------------------*/ bool StreamSoundFileLoader::LoadFileHeader( void* buffer, unsigned long size ) { const size_t headerSize = NW_SND_ROUND_UP_32B( sizeof( StreamSoundFile::FileHeader ) ); u8 buffer2[ headerSize+32 ]; // RVL_SDK の DVDRead( DVDFileInfo*, void* addr, s32 len, s32 ofs ); の制限は、 // 「addr = 32 バイト境界, len = 32 バイトの倍数, ofs = 4 バイトの倍数」 // ファイルヘッダロード m_Stream.Seek( 0, io::FILE_STREAM_SEEK_BEGIN ); s32 readSize = m_Stream.Read( ut::RoundUp( buffer2, 32 ), headerSize ); if ( readSize != headerSize ) { return false; } StreamSoundFile::FileHeader* header = reinterpret_cast( ut::RoundUp( buffer2, 32 ) ); StreamSoundFileReader reader; if ( ! reader.IsValidFileHeader( header ) ) { return false; } // バッファサイズがファイルヘッダーと INFO ブロックをロードできるサイズかチェック // (必ず、ヘッダーと INFO ブロックが並んで格納されているものとする) u32 loadSize = header->GetInfoBlockOffset() + header->GetInfoBlockSize(); if ( loadSize > size ) { return false; } // ファイルヘッダーと INFO ブロックをロード m_Stream.Seek( 0, io::FILE_STREAM_SEEK_BEGIN ); readSize = m_Stream.Read( buffer, loadSize ); if ( readSize != loadSize ) { return false; } m_Reader.Initialize( buffer ); return true; } /*---------------------------------------------------------------------------* Name: GetTrackCount Description: トラック数取得 Arguments: なし Returns: トラック数 *---------------------------------------------------------------------------*/ u32 StreamSoundFileLoader::GetTrackCount() const { if ( ! m_Reader.IsAvailable() ) return 0; return m_Reader.GetTrackCount(); } /*---------------------------------------------------------------------------* Name: GetChannelCount Description: チャンネル数取得 Arguments: なし Returns: チャンネル数 *---------------------------------------------------------------------------*/ u32 StreamSoundFileLoader::GetChannelCount() const { if ( ! m_Reader.IsAvailable() ) return 0; return m_Reader.GetChannelCount(); } /*---------------------------------------------------------------------------* Name: ReadStrmInfo Description: Arguments: strmInfo - Returns: *---------------------------------------------------------------------------*/ bool StreamSoundFileLoader::ReadStreamInfo( StreamSoundFile::StreamSoundInfo* strmInfo ) const { if ( ! m_Reader.IsAvailable() ) return false; m_Reader.ReadStreamSoundInfo( strmInfo ); return true; } /*---------------------------------------------------------------------------* Name: ReadStrmTrackInfo Description: Arguments: trackInfo - trackIndex - Returns: *---------------------------------------------------------------------------*/ bool StreamSoundFileLoader::ReadStreamTrackInfo( StreamSoundFileReader::TrackInfo* trackInfo, int trackIndex ) const { if ( ! m_Reader.IsAvailable() ) return false; m_Reader.ReadStreamTrackInfo( trackInfo, trackIndex ); return true; } /*---------------------------------------------------------------------------* Name: ReadDspAdpcmChannelInfo Description: Arguments: adpcmInfo - channelIndex - Returns: *---------------------------------------------------------------------------*/ bool StreamSoundFileLoader::ReadDspAdpcmChannelInfo( DspAdpcmParam* adpcmParam, DspAdpcmLoopParam* adpcmLoopParam, int channelIndex ) const { if ( ! m_Reader.IsAvailable() ) return false; m_Reader.ReadDspAdpcmChannelInfo( adpcmParam, adpcmLoopParam, channelIndex ); return true; } /*---------------------------------------------------------------------------* Name: ReadAdpcBlockData Description: ADPCブロックの指定されたデータを読み取る Arguments: yn1, yn2 - 読み取ったデータを格納する配列 blockIndex - 読み取るデータのブロック番号 channelCount - チャンネル数(yn1,yn2の配列サイズ) Returns: 読み取れたら true, 読み取れなかったら false *---------------------------------------------------------------------------*/ bool StreamSoundFileLoader::ReadAdpcBlockData( u16* yn1, u16* yn2, int blockIndex, int channelCount ) { if ( ! m_Reader.IsAvailable() ) return false; s32 readOffset = static_cast( m_Reader.GetSeekBlockOffset() + sizeof(ut::BinaryBlockHeader) + sizeof(s16) * 2 * channelCount * blockIndex ); m_Stream.Seek( readOffset, io::FILE_STREAM_SEEK_BEGIN ); // TODO: 以下は8チャンネル以上で動作できないコードなのでASSERT u32 readDataSize = sizeof(s16) * 2 * channelCount; NW_ASSERT( readDataSize <= 32 ); // DVDは32Byte単位でしかReadできないので32Byte読んでしまう NN_ATTRIBUTE_ALIGN(32) static u16 buffer[16]; int readSize = m_Stream.Read( buffer, sizeof( buffer ) ); if ( readSize != sizeof(buffer) ) return false; for ( int i=0; i< channelCount; i++ ) { yn1[i] = buffer[i*2]; yn2[i] = buffer[i*2+1]; } return true; } } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw