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: 25221 $
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) const59 Channel* Bank::NoteOn(
60     const void* bankFile,
61     const NoteOnInfo& noteOnInfo,
62     const SoundArchive& archive,
63     const SoundArchivePlayer& player
64 ) const
65 {
66     if ( bankFile == NULL )
67     {
68         return NULL;
69     }
70 
71     // VelocityRegionInfo の取得
72     VelocityRegionInfo regionInfo;
73     {
74         BankFileReader reader( bankFile );
75         if ( ! reader.ReadVelocityRegionInfo(
76                 &regionInfo,
77                 noteOnInfo.prgNo,
78                 noteOnInfo.key,
79                 noteOnInfo.velocity ) )
80         {
81             return NULL;
82         }
83     }
84 
85     // regnioInfo に応じた波形を取得する
86     const void* waveFile = Util::GetWaveFile(
87             regionInfo.waveArchiveId, regionInfo.waveIndex, archive, player );
88     if ( waveFile == NULL )
89     {
90         return NULL;
91     }
92 
93     // 波形の詳細を取得、Channel 確保
94     WaveInfo waveInfo;
95     {
96         WaveFileReader reader( waveFile );
97         if ( ! reader.ReadWaveInfo( &waveInfo ) )
98         {
99             return NULL;
100         }
101     }
102 
103     Channel* pChannel = Channel::AllocChannel(
104         ut::Min( static_cast<int>( waveInfo.channelCount ), 2 ),
105         noteOnInfo.priority,
106         noteOnInfo.channelCallback,
107         noteOnInfo.channelCallbackData
108     );
109     if ( pChannel == NULL )
110     {
111         return NULL;
112     }
113 
114     // 初期パラメータ設定
115     pChannel->SetKey( noteOnInfo.key, regionInfo.originalKey );
116 
117     register int velocity = noteOnInfo.velocity;
118     velocity *= velocity;
119     velocity *= regionInfo.volume;
120     float initVolume = static_cast<float>( velocity );
121     initVolume /= (127.0f * 127.0f * 127.0f);
122     pChannel->SetInitVolume( initVolume );
123     pChannel->SetTune( regionInfo.pitch );
124 
125     pChannel->SetAttack( regionInfo.adshrCurve.attack );
126     pChannel->SetHold( regionInfo.adshrCurve.hold );
127     pChannel->SetDecay( regionInfo.adshrCurve.decay );
128     pChannel->SetSustain( regionInfo.adshrCurve.sustain );
129     pChannel->SetRelease( regionInfo.adshrCurve.release );
130 
131     float initPan = static_cast<f32>( noteOnInfo.initPan + regionInfo.pan - 64 ) / 63.0f;
132     pChannel->SetInitPan( initPan );
133 //    pChannel->SetInitSurroundPan( 0.0f );
134 
135     pChannel->SetKeyGroupId( regionInfo.keyGroup );
136     pChannel->SetIsIgnoreNoteOff( regionInfo.isIgnoreNoteOff );
137     pChannel->SetInterpolationType( regionInfo.interpolationType );
138 
139     pChannel->Start( waveInfo, noteOnInfo.length, 0 );
140 
141     return pChannel;
142 }
143 
144 } // namespace nw::snd::internal::driver
145 } // namespace nw::snd::internal
146 } // namespace nw::snd
147 } // namespace nw
148 
149