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