1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_Bank.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_Bank.h>
21 #include <nw/snd/snd_NoteOnCallback.h>      // NoteOnInfo
22 #include <nw/snd/snd_BankFileReader.h>
23 #include <nw/snd/snd_WaveFileReader.h>
24 #include <nw/snd/snd_Util.h>                // GetWaveFile
25 
26 namespace nw {
27 namespace snd {
28 namespace internal {
29 namespace driver {
30 
31 /* ========================================================================
32         public functions
33    ======================================================================== */
34 
35 /*---------------------------------------------------------------------------*
36   Name:         Bank
37 
38   Description:  コンストラクタ
39 
40   Arguments:    bankData - バンクデータへの参照
41 
42   Returns:      None.
43  *---------------------------------------------------------------------------*/
Bank()44 Bank::Bank()
45 {
46 }
47 
48 /*---------------------------------------------------------------------------*
49   Name:         ~Bank
50 
51   Description:  デストラクタ
52 
53   Arguments:    None.
54 
55   Returns:      None.
56  *---------------------------------------------------------------------------*/
~Bank()57 Bank::~Bank()
58 {
59 }
60 
NoteOn(const void * bankFile,const NoteOnInfo & noteOnInfo,const SoundArchive & archive,const SoundArchivePlayer & player,const PlayerHeapDataManager * dataMgr) const61 Channel* Bank::NoteOn(
62     const void* bankFile,
63     const NoteOnInfo& noteOnInfo,
64     const SoundArchive& archive,
65     const SoundArchivePlayer& player,
66     const PlayerHeapDataManager* dataMgr
67 ) const
68 {
69     if ( bankFile == NULL )
70     {
71         return NULL;
72     }
73 
74     // VelocityRegionInfo の取得
75     VelocityRegionInfo regionInfo;
76     {
77         BankFileReader reader( bankFile );
78         if ( ! reader.ReadVelocityRegionInfo(
79                 &regionInfo,
80                 noteOnInfo.prgNo,
81                 noteOnInfo.key,
82                 noteOnInfo.velocity ) )
83         {
84             return NULL;
85         }
86     }
87 
88     // regnioInfo に応じた波形を取得する
89     const void* waveFile = Util::GetWaveFile(
90             regionInfo.waveArchiveId, regionInfo.waveIndex, archive, player );
91     if ( waveFile == NULL )
92     {
93         if ( dataMgr != NULL )
94         {
95             waveFile = Util::GetWaveFile(
96                     regionInfo.waveArchiveId, regionInfo.waveIndex, archive, dataMgr );
97             if ( waveFile == NULL )
98             {
99                 return NULL;
100             }
101         }
102         else
103         {
104             return NULL;
105         }
106     }
107 
108     // 波形の詳細を取得、Channel 確保
109     WaveInfo waveInfo;
110     {
111         WaveFileReader reader( waveFile );
112         if ( ! reader.ReadWaveInfo( &waveInfo ) )
113         {
114             return NULL;
115         }
116     }
117 
118     Channel* pChannel = Channel::AllocChannel(
119         ut::Min( static_cast<int>( waveInfo.channelCount ), 2 ),
120         noteOnInfo.priority,
121         noteOnInfo.channelCallback,
122         noteOnInfo.channelCallbackData
123     );
124     if ( pChannel == NULL )
125     {
126         return NULL;
127     }
128 
129     // 初期パラメータ設定
130     pChannel->SetKey( noteOnInfo.key, regionInfo.originalKey );
131 
132     register int velocity = noteOnInfo.velocity;
133     velocity *= velocity;
134     velocity *= regionInfo.volume;
135     float initVolume = static_cast<float>( velocity );
136     initVolume /= (127.0f * 127.0f * 127.0f);
137     pChannel->SetInitVolume( initVolume );
138     pChannel->SetTune( regionInfo.pitch );
139 
140     pChannel->SetAttack( regionInfo.adshrCurve.attack );
141     pChannel->SetHold( regionInfo.adshrCurve.hold );
142     pChannel->SetDecay( regionInfo.adshrCurve.decay );
143     pChannel->SetSustain( regionInfo.adshrCurve.sustain );
144     pChannel->SetRelease( regionInfo.adshrCurve.release );
145 
146     float initPan = static_cast<f32>( noteOnInfo.initPan + regionInfo.pan - 64 ) / 63.0f;
147     pChannel->SetInitPan( initPan );
148 //    pChannel->SetInitSurroundPan( 0.0f );
149 
150     pChannel->SetKeyGroupId( regionInfo.keyGroup );
151     pChannel->SetIsIgnoreNoteOff( regionInfo.isIgnoreNoteOff );
152     pChannel->SetInterpolationType( regionInfo.interpolationType );
153 
154     pChannel->Start( waveInfo, noteOnInfo.length, 0 );
155 
156     return pChannel;
157 }
158 
159 } // namespace nw::snd::internal::driver
160 } // namespace nw::snd::internal
161 } // namespace nw::snd
162 } // namespace nw
163 
164