/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_StreamSoundFile.h 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: 14125 $ *---------------------------------------------------------------------------*/ #ifndef NW_SND_STREAM_SOUND_FILE_H_ #define NW_SND_STREAM_SOUND_FILE_H_ #include #include #include #include #include namespace nw { namespace snd { namespace internal { /* ストリームファイル (*.bcstm) の構造 bcstm | +-- FileHeader +-- InfoBlock | | | +-- BinaryBlockHeader | +-- InfoBlockBody | | | +-- reference to StreamSoundInfo --+ | | | | | +------------------------------+ | | | | | +-> StreamSoundInfo | | | | | +-- u8 encodeMethod | | +-- bool isLoop | | +-- u8 channelCount | | +-- u8 padding | | +-- u32 sampleRate | | +-- u32 loopStart | | +-- u32 frameCount | | +-- u32 blockCount | | +-- u32 oneBlockBytes | | +-- u32 oneBlockSamples | | +-- u32 lastBlockBytes | | +-- u32 lastBlockSamples | | +-- u32 lastBlockPaddedBytes | | +-- u32 sizeofSeekInfoAtom | | +-- u32 seekInfoIntervalSamples | | +-- reference to sampleDataOffset | | | +-- reference to TrackInfoTable --+ | | | | | +-----------------------------+ | | | | | +-> TrackInfoTable | | | | | +-- s32 count | | +-- reference to TrackInfo[0] --+ | | : | | | +------------------------------------+ | | | | | +-> TrackInfo | | | | | +-- u8 volume | | +-- u8 pan | | +-- u16 padding | | +-- reference to GlobalChannelIndexTable --+ | | | | | +-----------------------------------------------+ | | | | | +-> GlobalChannelIndexTable | | | | | +-- u32 count | | +-- u8 globalChannelIndex[0] | | : | | | +-- reference to ChannelInfoTable --+ | | | +-------------------------------+ | | | +-> ChannelInfoTable | | | +-- u32 count | +-- reference to ChannelInfo[0] --+ | : | | +--------------------------------------+ | | | +-> ChannelInfo | | | +-- reference to detailChannelInfo --+ | | | +-----------------------------------------+ | | | +-> DspAdpcmChannelInfo | . | | . +-- DspAdpcm | . | | | . | +-- u16 coef[16] | . | +-- u16 predScale | . | +-- u16 yn1 | . | +-- u16 yn2 | . | | . +-- DspAdpcmLoopParam | . | | . +-- u16 loopPredScale | . +-- u16 loopYn1 | . +-- u16 loopYn2 | . | +-> (他のエンコード情報もあるかも) | +-- SeekBlock | | | +-- BinaryBlockHeader | +-- (ブロック全体はメモリに展開されない。 | 必要な部分のみ StreamSoundFileLoader でロードされる) | +-- DataBlock | +-- BinaryBlockHeader +-- (ブロック全体はメモリに展開されない。 必要な部分のみ StreamSoundFileLoader でロードされる) */ struct StreamSoundFile { // 前方宣言 struct InfoBlock; struct InfoBlockBody; struct SeekBlock; struct DataBlock; // 定数 // ファイルヘッダー // メモ : ストリームファイルは、ヘッダーおよび INFO ブロックのみ先にロードするので、 // Util::SoundFileHeader を継承できない。 struct FileHeader : public ut::BinaryFileHeader { private: // 定数 static const int BLOCK_SIZE = 3; public: // データ Util::ReferenceWithSize toBlocks[ BLOCK_SIZE ]; // 各ブロックのサイズ u32 GetInfoBlockSize() const; u32 GetSeekBlockSize() const; u32 GetDataBlockSize() const; // ファイル先頭から各ブロックへのオフセット u32 GetInfoBlockOffset() const; u32 GetSeekBlockOffset() const; u32 GetDataBlockOffset() const; const InfoBlock* GetInfoBlock() const { return static_cast( ut::AddOffsetToPtr( this, GetInfoBlockOffset() ) ); } private: const Util::ReferenceWithSize* GetReferenceBy( u16 typeId ) const; }; // -------------------------- // INFO ブロック struct StreamSoundInfo; struct TrackInfoTable; struct ChannelInfoTable; struct InfoBlockBody { // データ Util::Reference toStreamSoundInfo; Util::Reference toTrackInfoTable; Util::Reference toChannelInfoTable; // アクセサ const StreamSoundInfo* GetStreamSoundInfo() const; const TrackInfoTable* GetTrackInfoTable() const; const ChannelInfoTable* GetChannelInfoTable() const; }; struct InfoBlock { ut::BinaryBlockHeader header; InfoBlockBody body; }; struct StreamSoundInfo { u8 encodeMethod; // WaveFile::EncodeMethod が入る bool isLoop; u8 channelCount; u8 padding; ut::ResU32 sampleRate; ut::ResU32 loopStart; ut::ResU32 frameCount; ut::ResU32 blockCount; ut::ResU32 oneBlockBytes; ut::ResU32 oneBlockSamples; ut::ResU32 lastBlockBytes; ut::ResU32 lastBlockSamples; ut::ResU32 lastBlockPaddedBytes; ut::ResU32 sizeofSeekInfoAtom; // シーク情報のサイズ (1ch 分) ut::ResU32 seekInfoIntervalSamples; Util::Reference sampleDataOffset; // DATA ブロックボディ先頭から、 // サンプルデータへのオフセット }; struct TrackInfo; struct TrackInfoTable { // データ Util::ReferenceTable table; // アクセサ const TrackInfo* GetTrackInfo( u32 index ) const; u32 GetTrackCount() const { return table.count; } }; struct GlobalChannelIndexTable; struct TrackInfo { // データ u8 volume; u8 pan; u16 padding; Util::Reference toGlobalChannelIndexTable; // アクセサ NW_INLINE u32 GetTrackChannelCount() const { return GetGlobalChannelIndexTable().GetCount(); } NW_INLINE u8 GetGlobalChannelIndex( u32 index ) const { return GetGlobalChannelIndexTable().GetGlobalIndex( index ); } private: const GlobalChannelIndexTable& GetGlobalChannelIndexTable() const { return *reinterpret_cast( ut::AddOffsetToPtr( this, toGlobalChannelIndexTable.offset ) ); } }; struct GlobalChannelIndexTable { // データ Util::Table table; // トラック内のローカルチャンネルインデックスと、 // ストリームサウンド全体のグローバルチャンネルインデックスを紐付けます // アクセサ NW_INLINE u32 GetCount() const { return table.count; } NW_INLINE u8 GetGlobalIndex( u32 index ) const { NW_ASSERT( index < table.count ); return table.item[ index ]; } }; struct ChannelInfo; struct ChannelInfoTable { // データ Util::ReferenceTable table; // アクセサ NW_INLINE u32 GetChannelCount() const { return table.count; } const ChannelInfo* GetChannelInfo( u32 index ) const; }; struct DspAdpcmChannelInfo; // エンコードによっては、ほかにもあるかも struct ChannelInfo { Util::Reference toDetailChannelInfo; const DspAdpcmChannelInfo* GetDspAdpcmChannelInfo() const; }; struct DspAdpcmChannelInfo { // データ DspAdpcmParam param; DspAdpcmLoopParam loopParam; }; // -------------------------- // SEEK ブロック (途中再生用の情報) struct SeekBlock { ut::BinaryBlockHeader header; // ブロック全体はメモリに展開されない。 // ファイルストリーム経由で、Seek, Read するため、 // アクセサは StreamSoundFileLoader に任せる。 }; // -------------------------- // DATA ブロック (サンプルデータ) struct DataBlock { ut::BinaryBlockHeader header; // ブロック全体はメモリに展開されない。 // ファイルストリーム経由で、Seek, Read するため、 // アクセサは StreamSoundFileLoader に任せる。 }; }; } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw #endif /* NW_SND_STREAM_SOUND_FILE_H_ */