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