1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_StreamSoundFileReader.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_StreamSoundFileReader.h>
21 #include <nw/snd/snd_WaveFile.h> // EncodeMethod
22
23 namespace nw {
24 namespace snd {
25 namespace internal {
26
27 namespace {
28
29 const u32 SIGNATURE_FILE = NW_UT_MAKE_SIGWORD( 'C', 'S', 'T', 'M' );
30 const u32 SIGNATURE_INFO_BLOCK = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'O' );
31 const u32 SIGNATURE_SEEK_BLOCK = NW_UT_MAKE_SIGWORD( 'S', 'E', 'E', 'K' );
32 const u32 SIGNATURE_DATA_BLOCK = NW_UT_MAKE_SIGWORD( 'D', 'A', 'T', 'A' );
33
34 const int SUPPORTED_FILE_VERSION = 0x02000000;
35 const int CURRENT_FILE_VERSION = 0x02000000;
36
37 } // anonymous namespace
38
StreamSoundFileReader()39 StreamSoundFileReader::StreamSoundFileReader()
40 : m_pHeader( NULL ),
41 m_pInfoBlockBody( NULL )
42 {
43 }
44
Initialize(const void * streamSoundFile)45 void StreamSoundFileReader::Initialize( const void* streamSoundFile )
46 {
47 NW_NULL_ASSERT( streamSoundFile );
48
49 if ( ! IsValidFileHeader( streamSoundFile ) ) return;
50
51 m_pHeader =
52 reinterpret_cast<const StreamSoundFile::FileHeader*>( streamSoundFile );
53 const StreamSoundFile::InfoBlock* infoBlock = m_pHeader->GetInfoBlock();
54 NW_ASSERT( infoBlock->header.kind == SIGNATURE_INFO_BLOCK );
55
56 m_pInfoBlockBody = &infoBlock->body;
57 NW_ASSERT( m_pInfoBlockBody->GetStreamSoundInfo()->oneBlockBytes % 32 == 0 );
58 }
59
Finalize()60 void StreamSoundFileReader::Finalize()
61 {
62 m_pHeader = NULL;
63 m_pInfoBlockBody = NULL;
64 }
65
ReadStreamSoundInfo(StreamSoundFile::StreamSoundInfo * strmInfo) const66 bool StreamSoundFileReader::ReadStreamSoundInfo(
67 StreamSoundFile::StreamSoundInfo* strmInfo ) const
68 {
69 NW_NULL_ASSERT( m_pInfoBlockBody );
70 const StreamSoundFile::StreamSoundInfo* info =
71 m_pInfoBlockBody->GetStreamSoundInfo();
72
73 NW_ALIGN32_ASSERT( info->oneBlockBytes );
74 NW_ALIGN32_ASSERT( info->lastBlockPaddedBytes );
75
76 // struct copy
77 *strmInfo = *info;
78
79 return true;
80 }
81
ReadStreamTrackInfo(TrackInfo * pTrackInfo,int trackIndex) const82 bool StreamSoundFileReader::ReadStreamTrackInfo(
83 TrackInfo* pTrackInfo, int trackIndex ) const
84 {
85 NW_NULL_ASSERT( m_pInfoBlockBody );
86 NW_NULL_ASSERT( pTrackInfo );
87 const StreamSoundFile::TrackInfoTable* table =
88 m_pInfoBlockBody->GetTrackInfoTable();
89
90 if ( trackIndex >= static_cast<int>( table->GetTrackCount() ) )
91 {
92 return false;
93 }
94
95 const StreamSoundFile::TrackInfo* src = table->GetTrackInfo( trackIndex );
96 pTrackInfo->volume = src->volume;
97 pTrackInfo->pan = src->pan;
98 pTrackInfo->channelCount = static_cast<u8>( src->GetTrackChannelCount() ); // TODO: バイナリデータも 1 バイトでいいかも (NW4C-0.1.0)
99
100 u32 count = ut::Min( static_cast<int>( pTrackInfo->channelCount ), WAVE_CHANNEL_MAX );
101 for ( u32 i = 0; i < count; i++ )
102 {
103 pTrackInfo->globalChannelIndex[ i ] = src->GetGlobalChannelIndex( i );
104 }
105
106 return true;
107 }
108
ReadDspAdpcmChannelInfo(DspAdpcmParam * pParam,DspAdpcmLoopParam * pLoopParam,int channelIndex) const109 bool StreamSoundFileReader::ReadDspAdpcmChannelInfo(
110 DspAdpcmParam* pParam,
111 DspAdpcmLoopParam* pLoopParam,
112 int channelIndex ) const
113 {
114 NW_NULL_ASSERT( m_pInfoBlockBody );
115 NW_NULL_ASSERT( pParam );
116 NW_NULL_ASSERT( pLoopParam );
117
118 const StreamSoundFile::DspAdpcmChannelInfo* src =
119 m_pInfoBlockBody->
120 GetChannelInfoTable()->
121 GetChannelInfo( channelIndex )->
122 GetDspAdpcmChannelInfo();
123 if ( src == NULL ) return false;
124
125 *pParam = src->param;
126 *pLoopParam = src->loopParam;
127 return true;
128 }
129
IsValidFileHeader(const void * streamSoundFile) const130 bool StreamSoundFileReader::IsValidFileHeader( const void* streamSoundFile ) const
131 {
132 NW_NULL_ASSERT( streamSoundFile );
133
134 const ut::BinaryFileHeader& header =
135 *reinterpret_cast<const ut::BinaryFileHeader*>( streamSoundFile );
136
137 // シグニチャ確認
138 NW_ASSERTMSG(
139 header.signature == SIGNATURE_FILE,
140 "invalid file signature. stream data is not available." );
141 if ( header.signature != SIGNATURE_FILE ) return false;
142
143 // バージョン確認
144 NW_ASSERTMSG(
145 header.version >= SUPPORTED_FILE_VERSION,
146 "stream file is not supported version.\n"
147 "please reconvert file using new version tools.\n"
148 "(SUPPORTED_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
149 SUPPORTED_FILE_VERSION, header.version
150 );
151 if ( header.version < SUPPORTED_FILE_VERSION ) return false;
152 NW_ASSERTMSG(
153 header.version <= CURRENT_FILE_VERSION,
154 "stream file is not supported version.\n"
155 "please reconvert file using new version tools.\n"
156 "(CURRENT_FILE_VERSION:0x%08x <= your version:0x%08x)\n",
157 CURRENT_FILE_VERSION, header.version
158 );
159 if ( header.version > CURRENT_FILE_VERSION ) return false;
160
161 return true;
162 }
163
164 } // namespace nw::snd::internal
165 } // namespace nw::snd
166 } // namespace nw
167
168