1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_BankFileReader.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 27041 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/snd/snd_BankFileReader.h>
19 
20 namespace nw {
21 namespace snd {
22 namespace internal {
23 
24 namespace
25 {
26 
27 const u32 SIGNATURE_INFO_BLOCK  = NW_UT_MAKE_SIGWORD( 'I', 'N', 'F', 'O' );
28 
29 const u32 SUPPORTED_FILE_VERSION = 0x01000000;
30 const u32 CURRENT_FILE_VERSION   = 0x01000100;
31 
IsValidFileHeader(const void * bankFile)32 bool IsValidFileHeader( const void* bankFile )
33 {
34     const ut::BinaryFileHeader* header =
35         reinterpret_cast<const ut::BinaryFileHeader*>( bankFile );
36 
37     // シグニチャ確認
38     NW_ASSERTMSG( header->signature == BankFileReader::SIGNATURE_FILE,
39             "invalid file signature. bank file is not available." );
40     if ( header->signature != BankFileReader::SIGNATURE_FILE ) return false;
41 
42     // バージョン確認
43     NW_ASSERTMSG( header->version >= SUPPORTED_FILE_VERSION,
44             "bank file is not supported version.\n"
45             "please reconvert file using new version tools.\n"
46             "(SUPPORTED_FILE_VERSION:0x%08x >= your version:0x%08x)\n",
47             SUPPORTED_FILE_VERSION, header->version
48     );
49     if ( header->version < SUPPORTED_FILE_VERSION ) return false;
50 
51     NW_ASSERTMSG( header->version <= CURRENT_FILE_VERSION,
52             "bank file is not supported version.\n"
53             "please reconvert file using new version tools.\n"
54             "(CURRENT_FILE_VERSION:0x%08x <= your version:0x%08x)\n",
55             CURRENT_FILE_VERSION, header->version
56     );
57     if ( header->version > CURRENT_FILE_VERSION ) return false;
58 
59     return true;
60 }
61 
62 } // anonymous namespace
63 
64 
BankFileReader(const void * bankFile)65 BankFileReader::BankFileReader( const void* bankFile )
66 : m_pHeader( NULL ),
67   m_pInfoBlockBody( NULL )
68 {
69     NW_NULL_ASSERT( bankFile );
70 
71     if ( ! IsValidFileHeader( bankFile ) ) return;
72 
73     m_pHeader = reinterpret_cast<const BankFile::FileHeader*>( bankFile );
74 
75     const BankFile::InfoBlock* infoBlock = m_pHeader->GetInfoBlock();
76     NW_NULL_ASSERT( infoBlock );
77     NW_ASSERT( infoBlock->header.kind == SIGNATURE_INFO_BLOCK );
78     m_pInfoBlockBody = &infoBlock->body;
79 }
80 
ReadVelocityRegionInfo(VelocityRegionInfo * info,int programNo,int key,int velocity) const81 bool BankFileReader::ReadVelocityRegionInfo(
82         VelocityRegionInfo* info,
83         int programNo,
84         int key,
85         int velocity ) const
86 {
87     // イレギュラーな programNo を指定された場合
88     if ( programNo < 0 || programNo >= m_pInfoBlockBody->GetInstrumentCount() )
89     {
90         return false;
91     }
92 
93     // ベロシティリージョンを取得
94     const BankFile::Instrument* instrument =
95         m_pInfoBlockBody->GetInstrument( programNo );
96     if ( instrument == NULL )
97     {
98         return false;
99     }
100 
101     const BankFile::KeyRegion* keyRegion = instrument->GetKeyRegion( key );
102     if ( keyRegion == NULL )
103     {
104         return false;
105     }
106 
107     const BankFile::VelocityRegion* velocityRegion =
108         keyRegion->GetVelocityRegion( velocity );
109     if ( velocityRegion == NULL )
110     {
111         return false;
112     }
113 
114     // 波形アーカイブ ID / 波形アーカイブ内インデックスを取得
115     NW_ASSERT( velocityRegion->waveIdTableIndex < m_pInfoBlockBody->GetWaveIdCount() );
116     const Util::WaveId& waveId =
117         m_pInfoBlockBody->GetWaveId( velocityRegion->waveIdTableIndex );
118 
119     if ( waveId.waveIndex == 0xffffffff )   // 当該リージョンに波形ファイルが割り当たっていない
120     {
121         NW_WARNING( false,
122                 "This region [programNo(%d) key(%d) velocity(%d)] is not assigned wave file.",
123                 programNo, key, velocity );
124         return false;
125     }
126 
127     // info への書き込み
128     info->waveArchiveId     = waveId.waveArchiveId;
129     info->waveIndex         = waveId.waveIndex;
130     const BankFile::RegionParameter* regionParameter = velocityRegion->GetRegionParameter();
131     if ( regionParameter == NULL )
132     {
133         info->originalKey       = velocityRegion->GetOriginalKey();
134         info->volume            = velocityRegion->GetVolume();
135         info->pan               = velocityRegion->GetPan();
136     #ifdef NW_PLATFORM_RVL
137         info->surroundPan       = velocityRegion->GetSurroundPan();
138     #endif /* NW_PLATFORM_RVL */
139         info->pitch             = velocityRegion->GetPitch();
140         info->isIgnoreNoteOff   = velocityRegion->IsIgnoreNoteOff();
141         info->keyGroup          = velocityRegion->GetKeyGroup();
142         info->interpolationType = velocityRegion->GetInterpolationType();
143         info->adshrCurve        = velocityRegion->GetAdshrCurve();
144     }
145     else
146     {
147         info->originalKey       = regionParameter->originalKey;
148         info->volume            = regionParameter->volume;
149         info->pan               = regionParameter->pan;
150     #ifdef NW_PLATFORM_RVL
151         info->surroundPan       = regionParameter->surroundPan;
152     #endif /* NW_PLATFORM_RVL */
153         info->pitch             = regionParameter->pitch;
154         info->isIgnoreNoteOff   = regionParameter->isIgnoreNoteOff;
155         info->keyGroup          = regionParameter->keyGroup;
156         info->interpolationType = regionParameter->interpolationType;
157         info->adshrCurve        = regionParameter->adshrCurve;
158     }
159 
160     return true;
161 }
162 
163 const Util::WaveIdTable&
GetWaveIdTable() const164 BankFileReader::GetWaveIdTable() const
165 {
166     return m_pInfoBlockBody->GetWaveIdTable();
167 }
168 
169 } // namespace nw::snd::internal
170 } // namespace nw::snd
171 } // namespace nw
172 
173