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