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