1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_WaveSoundFile.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: 23497 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 #include <nw/snd/snd_WaveSoundFile.h>
18 
19 #include <nw/snd/snd_ElementType.h>
20 #include <nw/ut/ut_Inlines.h>               // ut::AddOffsetToPtr
21 
22 namespace nw {
23 namespace snd {
24 namespace internal {
25 
26 namespace {
27 
28 const u8 DEFAULT_PAN            = 64;   // 中央
29 const s8 DEFAULT_SURROUND_PAN   = 0;    // 中央
30 const f32 DEFAULT_PITCH         = 1.0f;
31 const u8 DEFAULT_MAIN_SEND      = 127;  // 最大
32 const u8 DEFAULT_FX_SEND        = 0;    // 最小
33 const AdshrCurve DEFAULT_ADSHR_CURVE(
34     127,    // u8 attack
35     127,    // u8 decay
36     127,    // u8 sustain
37     127,    // u8 hold
38     127     // u8 release
39 );
40 const u8 DEFAULT_KEY            = 64;   // TODO: おそらく中央
41 const u8 DEFAULT_VOLUME         = 96;
42 
43 enum WaveSoundInfoBitFlag
44 {
45     WAVE_SOUND_INFO_PAN = 0x00,
46     WAVE_SOUND_INFO_PITCH,
47     WAVE_SOUND_INFO_SEND = 0x08,
48     WAVE_SOUND_INFO_ENVELOPE,
49     WAVE_SOUND_INFO_RANDOMIZER  // 未実装
50 };
51 
52 enum NoteInfoBitFlag
53 {
54     NOTE_INFO_KEY = 0x00,
55     NOTE_INFO_VOLUME,
56     NOTE_INFO_PAN,
57     NOTE_INFO_PITCH,
58     NOTE_INFO_SEND = 0x08,
59     NOTE_INFO_ENVELOPE,
60     NOTE_INFO_RANDOMIZER,   // 未実装
61     NOTE_INFO_LFO           // 未実装
62 };
63 
64 struct SendValue
65 {
66     u8 mainSend;
67     Util::Table<u8,u8> fxSend;
68 };
69 
70 } // anonymous namespace
71 
72 
73 //
74 // WaveSoundFile::FileHeader
75 //
GetInfoBlock() const76 const WaveSoundFile::InfoBlock* WaveSoundFile::FileHeader::GetInfoBlock() const
77 {
78     return reinterpret_cast<const InfoBlock*>( GetBlock( ElementType_WaveSoundFile_InfoBlock ) );
79 }
80 
81 
82 //
83 // WaveSoundFile::InfoBlockBody
84 //
85 
86 const WaveSoundFile::WaveSoundData&
GetWaveSoundData(u32 index) const87 WaveSoundFile::InfoBlockBody::GetWaveSoundData( u32 index ) const
88 {
89     NW_ASSERT( index < GetWaveSoundCount() );
90     const void* pWaveSoundData =
91         GetWaveSoundDataReferenceTable().GetReferedItem(
92                 index,
93                 ElementType_WaveSoundFile_WaveSoundMetaData );
94     NW_NULL_ASSERT( pWaveSoundData );
95     return *reinterpret_cast<const WaveSoundData*>( pWaveSoundData );
96 }
97 const Util::ReferenceTable&
GetWaveSoundDataReferenceTable() const98 WaveSoundFile::InfoBlockBody::GetWaveSoundDataReferenceTable() const
99 {
100     return *reinterpret_cast<const Util::ReferenceTable*>(
101             ut::AddOffsetToPtr( this, toWaveSoundDataReferenceTable.offset ) );
102 }
103 const Util::WaveIdTable&
GetWaveIdTable() const104 WaveSoundFile::InfoBlockBody::GetWaveIdTable() const
105 {
106     return *reinterpret_cast<const Util::WaveIdTable*>(
107             ut::AddOffsetToPtr( this, toWaveIdTable.offset ) );
108 }
109 
110 
111 //
112 // WaveSoundFile::WaveSoundData
113 //
114 const WaveSoundFile::WaveSoundInfo&
GetWaveSoundInfo() const115 WaveSoundFile::WaveSoundData::GetWaveSoundInfo() const
116 {
117     NW_ASSERT( toWaveSoundInfo.IsValidTypeId(
118                 ElementType_WaveSoundFile_WaveSoundInfo ) );
119 
120     return *reinterpret_cast<const WaveSoundInfo*>(
121             ut::AddOffsetToPtr( this, toWaveSoundInfo.offset ) );
122 }
123 
124 const Util::ReferenceTable&
GetTrackInfoReferenceTable() const125 WaveSoundFile::WaveSoundData::GetTrackInfoReferenceTable() const
126 {
127     return *reinterpret_cast<const Util::ReferenceTable*>(
128             ut::AddOffsetToPtr( this, toTrackInfoReferenceTable.offset ) );
129 }
130 
131 const Util::ReferenceTable&
GetNoteInfoReferenceTable() const132 WaveSoundFile::WaveSoundData::GetNoteInfoReferenceTable() const
133 {
134     return *reinterpret_cast<const Util::ReferenceTable*>(
135             ut::AddOffsetToPtr( this, toNoteInfoReferenceTable.offset ) );
136 }
137 
138 const WaveSoundFile::TrackInfo&
GetTrackInfo(u32 index) const139 WaveSoundFile::WaveSoundData::GetTrackInfo( u32 index ) const
140 {
141     NW_ASSERT( index < GetTrackCount() );
142 
143     const void* pTrackInfo =
144         GetTrackInfoReferenceTable().GetReferedItem(
145                 index,
146                 ElementType_WaveSoundFile_TrackInfo );
147     NW_NULL_ASSERT( pTrackInfo );
148 
149     return *reinterpret_cast<const TrackInfo*>( pTrackInfo );
150 }
151 
152 const WaveSoundFile::NoteInfo&
GetNoteInfo(u32 index) const153 WaveSoundFile::WaveSoundData::GetNoteInfo( u32 index ) const
154 {
155     NW_ASSERT( index < GetNoteCount() );
156 
157     const void* pNoteInfo =
158         GetNoteInfoReferenceTable().GetReferedItem(
159                 index,
160                 ElementType_WaveSoundFile_NoteInfo );
161     NW_NULL_ASSERT( pNoteInfo );
162 
163     return *reinterpret_cast<const NoteInfo*>( pNoteInfo );
164 }
165 
166 
167 //
168 // WaveSoundFile::WaveSoundInfo
169 //
GetPan() const170 u8 WaveSoundFile::WaveSoundInfo::GetPan() const
171 {
172     u32 value;
173     bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PAN );
174     if ( result == false ) return DEFAULT_PAN;
175     return Util::DevideBy8bit( value, 0 );
176 }
GetSurroundPan() const177 s8 WaveSoundFile::WaveSoundInfo::GetSurroundPan() const
178 {
179     u32 value;
180     bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PAN );
181     if ( result == false ) return DEFAULT_SURROUND_PAN;
182     return static_cast<s8>( Util::DevideBy8bit( value, 1 ) );
183 }
GetPitch() const184 f32 WaveSoundFile::WaveSoundInfo::GetPitch() const
185 {
186     f32 value;
187     bool result = optionParameter.GetValueF32( &value, WAVE_SOUND_INFO_PITCH );
188     if ( result == false ) return DEFAULT_PITCH;
189     return value;
190 }
191 
GetSendValue(u8 * mainSend,u8 * fxSend,u8 fxSendCount) const192 void WaveSoundFile::WaveSoundInfo::GetSendValue(
193         u8* mainSend, u8* fxSend, u8 fxSendCount ) const
194 {
195     u32 value;
196     bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_SEND );
197     if ( result == false )
198     {
199         *mainSend = DEFAULT_MAIN_SEND;
200         for ( int i = 0; i < fxSendCount; i++ )
201         {
202             fxSend[ i ] = DEFAULT_FX_SEND;
203         }
204         return;
205     }
206 
207     const SendValue& sendValue = *reinterpret_cast<const SendValue*>(
208             ut::AddOffsetToPtr( this, value ) );
209 
210     NW_ASSERT( fxSendCount <= sendValue.fxSend.count );
211     *mainSend = sendValue.mainSend;
212     int countSize = sendValue.fxSend.count > AUX_BUS_NUM ?
213         AUX_BUS_NUM : sendValue.fxSend.count;
214     for ( int i = 0; i < countSize; i++ )
215     {
216         fxSend[ i ] = sendValue.fxSend.item[ i ];
217     }
218 }
219 
GetAdshrCurve() const220 const AdshrCurve& WaveSoundFile::WaveSoundInfo::GetAdshrCurve() const
221 {
222     u32 offsetToReference;
223     bool result = optionParameter.GetValue( &offsetToReference, WAVE_SOUND_INFO_ENVELOPE );
224     if ( result == false ) return DEFAULT_ADSHR_CURVE;
225 
226     const Util::Reference& ref = *reinterpret_cast<const Util::Reference*>(
227             ut::AddOffsetToPtr( this, offsetToReference ) );
228     return *reinterpret_cast<const AdshrCurve*>(
229             ut::AddOffsetToPtr( &ref, ref.offset ) );
230 }
231 
232 
233 //
234 // WaveSoundFile::TrackInfo
235 //
236 const Util::ReferenceTable&
GetNoteEventReferenceTable() const237 WaveSoundFile::TrackInfo::GetNoteEventReferenceTable() const
238 {
239     return *reinterpret_cast<const Util::ReferenceTable*>(
240             ut::AddOffsetToPtr( this, toNoteEventReferenceTable.offset ) );
241 }
242 
243 const WaveSoundFile::NoteEvent&
GetNoteEvent(u32 index) const244 WaveSoundFile::TrackInfo::GetNoteEvent( u32 index ) const
245 {
246     NW_ASSERT( index < GetNoteEventCount() );
247 
248     const void* pNoteEvent =
249         GetNoteEventReferenceTable().GetReferedItem(
250                 index,
251                 ElementType_WaveSoundFile_NoteEvent );
252     NW_NULL_ASSERT( pNoteEvent );
253 
254     return *reinterpret_cast<const NoteEvent*>( pNoteEvent );
255 }
256 
257 
258 //
259 // WaveSoundFile::NoteInfo
260 //
GetOriginalKey() const261 u8 WaveSoundFile::NoteInfo::GetOriginalKey() const
262 {
263     u32 value;
264     bool result = optionParameter.GetValue( &value, NOTE_INFO_KEY );
265     if ( result == false ) return DEFAULT_KEY;
266     return Util::DevideBy8bit( value, 0 );
267 }
268 
GetVolume() const269 u8 WaveSoundFile::NoteInfo::GetVolume() const
270 {
271     u32 value;
272     bool result = optionParameter.GetValue( &value, NOTE_INFO_VOLUME );
273     if ( result == false ) return DEFAULT_VOLUME;
274     return Util::DevideBy8bit( value, 0 );
275 }
276 
GetPan() const277 u8 WaveSoundFile::NoteInfo::GetPan() const
278 {
279     u32 value;
280     bool result = optionParameter.GetValue( &value, NOTE_INFO_PAN );
281     if ( result == false ) return DEFAULT_PAN;
282     return Util::DevideBy8bit( value, 0 );
283 }
GetSurroundPan() const284 u8 WaveSoundFile::NoteInfo::GetSurroundPan() const
285 {
286     u32 value;
287     bool result = optionParameter.GetValue( &value, NOTE_INFO_PAN );
288     if ( result == false ) return DEFAULT_SURROUND_PAN;
289     return static_cast<s8>( Util::DevideBy8bit( value, 1 ) );
290 }
GetPitch() const291 f32 WaveSoundFile::NoteInfo::GetPitch() const
292 {
293     f32 value;
294     bool result = optionParameter.GetValueF32( &value, NOTE_INFO_PITCH );
295     if ( result == false ) return DEFAULT_PITCH;
296     return value;
297 }
298 
GetSendValue(u8 * mainSend,u8 * fxSend[],u8 fxSendCount) const299 void WaveSoundFile::NoteInfo::GetSendValue( u8* mainSend, u8* fxSend[], u8 fxSendCount ) const
300 {
301     u32 value;
302     bool result = optionParameter.GetValue( &value, NOTE_INFO_SEND );
303     if ( result == false )
304     {
305         *mainSend = DEFAULT_MAIN_SEND;
306         for ( int i = 0; i < fxSendCount; i++ )
307         {
308             *fxSend[i] = DEFAULT_FX_SEND;
309         }
310         return;
311     }
312 
313     const SendValue& sendValue = *reinterpret_cast<const SendValue*>(
314             ut::AddOffsetToPtr( this, value ) );
315 
316     NW_ASSERT( fxSendCount <= sendValue.fxSend.count );
317     *mainSend = sendValue.mainSend;
318     int countSize = sendValue.fxSend.count > AUX_BUS_NUM ?
319         AUX_BUS_NUM : sendValue.fxSend.count;
320     for ( int i = 0; i < countSize; i++ )
321     {
322         *fxSend[ i ] = sendValue.fxSend.item[ i ];
323     }
324 }
325 
GetAdshrCurve() const326 const AdshrCurve& WaveSoundFile::NoteInfo::GetAdshrCurve() const
327 {
328     u32 offsetToReference;
329     bool result = optionParameter.GetValue( &offsetToReference, NOTE_INFO_ENVELOPE );
330     if ( result == false ) return DEFAULT_ADSHR_CURVE;
331 
332     const Util::Reference& ref = *reinterpret_cast<const Util::Reference*>(
333             ut::AddOffsetToPtr( this, offsetToReference ) );
334     return *reinterpret_cast<const AdshrCurve*>(
335             ut::AddOffsetToPtr( &ref, ref.offset ) );
336 }
337 
338 
339 } // namespace nw::snd::internal
340 } // namespace nw::snd
341 } // namespace nw
342