/[svn]/linuxsampler/trunk/src/engines/sf2/Voice.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/sf2/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2559 - (hide annotations) (download)
Sun May 18 17:38:25 2014 UTC (9 years, 11 months ago) by schoenebeck
File size: 14535 byte(s)
* Aftertouch: extended API to explicitly handle channel pressure and
  polyphonic key pressure events (so far polyphonic pressure was not
  supported at all, and channel pressure was rerouted as CC128 but not
  used so far).
* Gig Engine: Fixed support for 'aftertouch' attenuation controller.
* Bumped version (1.0.0.svn39).

1 iliev 2012 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 persson 2055 * Copyright (C) 2005 - 2008 Christian Schoenebeck *
7 persson 2327 * Copyright (C) 2009 - 2012 Christian Schoenebeck and Grigor Iliev *
8 iliev 2012 * *
9     * This program is free software; you can redistribute it and/or modify *
10     * it under the terms of the GNU General Public License as published by *
11     * the Free Software Foundation; either version 2 of the License, or *
12     * (at your option) any later version. *
13     * *
14     * This program is distributed in the hope that it will be useful, *
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17     * GNU General Public License for more details. *
18     * *
19     * You should have received a copy of the GNU General Public License *
20     * along with this program; if not, write to the Free Software *
21     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22     * MA 02111-1307 USA *
23     ***************************************************************************/
24    
25 iliev 2015 #include "Voice.h"
26    
27 iliev 2012 #include "Engine.h"
28     #include "EngineChannel.h"
29    
30     namespace LinuxSampler { namespace sf2 {
31    
32 iliev 2217 typedef LinuxSampler::VoiceBase<EngineChannel, ::sf2::Region, ::sf2::Sample, DiskThread> SF2Voice;
33     Voice::Voice(): SignalRack(this), SF2Voice(&SignalRack) {
34 persson 2055 pEngine = NULL;
35 iliev 2217 pEG1 = NULL;
36     pEG2 = NULL;
37 iliev 2012 }
38    
39     Voice::~Voice() {
40 iliev 2015
41 iliev 2012 }
42    
43 iliev 2205 void Voice::AboutToTrigger() {
44    
45     }
46    
47 iliev 2015 EngineChannel* Voice::GetSf2EngineChannel() {
48     return static_cast<EngineChannel*>(pEngineChannel);
49     }
50    
51 iliev 2012 void Voice::SetEngine(LinuxSampler::Engine* pEngine) {
52     Engine* engine = static_cast<Engine*>(pEngine);
53     this->pEngine = engine;
54     this->pDiskThread = engine->pDiskThread;
55     dmsg(6,("Voice::SetEngine()\n"));
56     }
57    
58 iliev 2015 Voice::SampleInfo Voice::GetSampleInfo() {
59     SampleInfo si;
60     si.SampleRate = pSample->SampleRate;
61     si.ChannelCount = pSample->GetChannelCount();
62     si.FrameSize = pSample->GetFrameSize();
63     si.BitDepth = (pSample->GetFrameSize() / pSample->GetChannelCount()) * 8;
64     si.TotalFrameCount = pSample->GetTotalFrameCount();
65 iliev 2012
66 iliev 2021 si.HasLoops = pRegion->HasLoop;
67     si.LoopStart = (si.HasLoops) ? pRegion->LoopStart : 0;
68     si.LoopLength = (si.HasLoops) ? ((pRegion->LoopEnd) - pRegion->LoopStart): 0;
69 iliev 2015 si.LoopPlayCount = 0; // TODO:
70     si.Unpitched = pSample->IsUnpitched();
71 iliev 2012
72 iliev 2015 return si;
73     }
74 iliev 2012
75 iliev 2015 Voice::RegionInfo Voice::GetRegionInfo() {
76 iliev 2027 ::sf2::Region* reg = NULL;
77     ::sf2::Preset* preset = GetSf2EngineChannel()->pInstrument;
78     for (int i = 0; i < preset->GetRegionCount(); i++) { // TODO: some optimization?
79     if (preset->GetRegion(i)->pInstrument == pRegion->GetParentInstrument()) {
80 persson 2203 reg = preset->GetRegion(i); // TODO: Can the instrument belong to more than one preset region?
81 iliev 2027 break;
82     }
83     }
84 persson 2203 pPresetRegion = reg;
85    
86 iliev 2015 RegionInfo ri;
87 iliev 2021 ri.UnityNote = pRegion->GetUnityNote();
88 iliev 2027 ri.FineTune = pRegion->GetFineTune(reg) + (pRegion->GetCoarseTune(reg) * 100);
89     ri.Pan = pRegion->GetPan(reg);
90 iliev 2015 ri.SampleStartOffset = pRegion->startAddrsOffset + pRegion->startAddrsCoarseOffset;
91 iliev 2012
92 iliev 2027 // sample pitch
93 iliev 2207 ri.VCFEnabled = true; // TODO:
94 persson 2175 ri.VCFType = Filter::vcf_type_2p_lowpass; // TODO:
95 iliev 2015 ri.VCFResonance = 0; // TODO:
96 iliev 2012
97 iliev 2015 ri.ReleaseTriggerDecay = 0; // TODO:
98 iliev 2012
99 iliev 2015 return ri;
100     }
101    
102     Voice::InstrumentInfo Voice::GetInstrumentInfo() {
103     InstrumentInfo ii;
104     ii.FineTune = 0; // TODO:
105     ii.PitchbendRange = 2; // TODO:
106    
107     return ii;
108     }
109    
110     double Voice::GetSampleAttenuation() {
111     return 1.0; // TODO:
112     }
113    
114     double Voice::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
115     return double(MIDIKeyVelocity) / 127.0f; // TODO:
116     }
117    
118     double Voice::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
119     return 0.9; // TODO:
120     }
121    
122     void Voice::ProcessCCEvent(RTList<Event>::Iterator& itEvent) {
123     /*if (itEvent->Type == Event::type_control_change && itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
124     if (pRegion->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
125     itEvent->Param.CC.Controller == pRegion->AttenuationController.controller_number) {
126     CrossfadeSmoother.update(AbstractEngine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]);
127     }
128     }*/ // TODO: ^^^
129     }
130 schoenebeck 2559
131     void Voice::ProcessChannelPressureEvent(RTList<Event>::Iterator& itEvent) {
132     //TODO: ...
133     }
134    
135     void Voice::ProcessPolyphonicKeyPressureEvent(RTList<Event>::Iterator& itEvent) {
136     //TODO: ...
137     }
138 iliev 2015
139     void Voice::ProcessCutoffEvent(RTList<Event>::Iterator& itEvent) {
140     /*int ccvalue = itEvent->Param.CC.Value;
141     if (VCFCutoffCtrl.value == ccvalue) return;
142     VCFCutoffCtrl.value == ccvalue;
143     if (pRegion->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
144     if (ccvalue < pRegion->VCFVelocityScale) ccvalue = pRegion->VCFVelocityScale;
145     float cutoff = CutoffBase * float(ccvalue);
146     if (cutoff > 127.0f) cutoff = 127.0f;
147    
148     VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
149     fFinalCutoff = cutoff;*/ // TODO: ^^^
150     }
151    
152     double Voice::CalculateCrossfadeVolume(uint8_t MIDIKeyVelocity) {
153 iliev 2012 /*float crossfadeVolume;
154     switch (pRegion->AttenuationController.type) {
155     case ::gig::attenuation_ctrl_t::type_channelaftertouch:
156 iliev 2015 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetSf2EngineChannel()->ControllerTable[128])];
157 iliev 2012 break;
158     case ::gig::attenuation_ctrl_t::type_velocity:
159 iliev 2015 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(MIDIKeyVelocity)];
160 iliev 2012 break;
161     case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
162 iliev 2015 crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(GetSf2EngineChannel()->ControllerTable[pRegion->AttenuationController.controller_number])];
163 iliev 2012 break;
164     case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
165     default:
166     crossfadeVolume = 1.0f;
167     }
168    
169 iliev 2015 return crossfadeVolume;*/ // TODO: ^^^
170     return 1.0f;
171     }
172 iliev 2012
173 iliev 2015 double Voice::GetEG1ControllerValue(uint8_t MIDIKeyVelocity) {
174     /*double eg1controllervalue = 0;
175     switch (pRegion->EG1Controller.type) {
176     case ::gig::eg1_ctrl_t::type_none: // no controller defined
177     eg1controllervalue = 0;
178     break;
179     case ::gig::eg1_ctrl_t::type_channelaftertouch:
180     eg1controllervalue = GetSf2EngineChannel()->ControllerTable[128];
181     break;
182     case ::gig::eg1_ctrl_t::type_velocity:
183     eg1controllervalue = MIDIKeyVelocity;
184     break;
185     case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
186     eg1controllervalue = GetSf2EngineChannel()->ControllerTable[pRegion->EG1Controller.controller_number];
187     break;
188 iliev 2012 }
189 iliev 2015 if (pRegion->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
190 iliev 2012
191 iliev 2015 return eg1controllervalue;*/ // TODO: ^^^
192     return 0;
193     }
194 iliev 2012
195 iliev 2015 Voice::EGInfo Voice::CalculateEG1ControllerInfluence(double eg1ControllerValue) {
196     /*EGInfo eg;
197     // (eg1attack is different from the others)
198     eg.Attack = (pRegion->EG1ControllerAttackInfluence) ?
199     1 + 0.031 * (double) (pRegion->EG1ControllerAttackInfluence == 1 ?
200     1 : 1 << pRegion->EG1ControllerAttackInfluence) * eg1ControllerValue : 1.0;
201     eg.Decay = (pRegion->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerDecayInfluence) * eg1ControllerValue : 1.0;
202     eg.Release = (pRegion->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG1ControllerReleaseInfluence) * eg1ControllerValue : 1.0;
203 iliev 2012
204 iliev 2015 return eg;*/ // TODO: ^^^
205     EGInfo eg;
206     eg.Attack = 1.0;
207     eg.Decay = 1.0;
208     eg.Release = 1.0;
209     return eg;
210     }
211 iliev 2012
212 iliev 2015 double Voice::GetEG2ControllerValue(uint8_t MIDIKeyVelocity) {
213     /*double eg2controllervalue = 0;
214     switch (pRegion->EG2Controller.type) {
215     case ::gig::eg2_ctrl_t::type_none: // no controller defined
216     eg2controllervalue = 0;
217     break;
218     case ::gig::eg2_ctrl_t::type_channelaftertouch:
219     eg2controllervalue = GetSf2EngineChannel()->ControllerTable[128];
220     break;
221     case ::gig::eg2_ctrl_t::type_velocity:
222     eg2controllervalue = MIDIKeyVelocity;
223     break;
224     case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
225     eg2controllervalue = GetSf2EngineChannel()->ControllerTable[pRegion->EG2Controller.controller_number];
226     break;
227 iliev 2012 }
228 iliev 2015 if (pRegion->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
229 iliev 2012
230 iliev 2015 return eg2controllervalue;*/ // TODO: ^^^
231     return 0;
232     }
233 iliev 2012
234 iliev 2015 Voice::EGInfo Voice::CalculateEG2ControllerInfluence(double eg2ControllerValue) {
235     /*EGInfo eg;
236     eg.Attack = (pRegion->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerAttackInfluence) * eg2ControllerValue : 1.0;
237     eg.Decay = (pRegion->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerDecayInfluence) * eg2ControllerValue : 1.0;
238     eg.Release = (pRegion->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pRegion->EG2ControllerReleaseInfluence) * eg2ControllerValue : 1.0;
239 iliev 2012
240 iliev 2015 return eg;*/ // TODO: ^^^
241     EGInfo eg;
242     eg.Attack = 1.0;
243     eg.Decay = 1.0;
244     eg.Release = 1.0;
245     return eg;
246     }
247 iliev 2012
248 iliev 2015 float Voice::CalculateCutoffBase(uint8_t MIDIKeyVelocity) {
249 iliev 2207 float cutoff = pRegion->GetInitialFilterFc(pPresetRegion);
250     if (MIDIKeyVelocity == 0) return cutoff;
251    
252     cutoff *= RTMath::CentsToFreqRatioUnlimited (
253     ((127 - MIDIKeyVelocity) / 127.0) * -2400 // 8.4.2 MIDI Note-On Velocity to Filter Cutoff
254     );
255    
256     return cutoff;
257 iliev 2012 }
258    
259 iliev 2015 float Voice::CalculateFinalCutoff(float cutoffBase) {
260     /*int cvalue;
261     if (VCFCutoffCtrl.controller) {
262     cvalue = GetSf2EngineChannel()->ControllerTable[VCFCutoffCtrl.controller];
263     if (pRegion->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
264     // VCFVelocityScale in this case means Minimum cutoff
265     if (cvalue < pRegion->VCFVelocityScale) cvalue = pRegion->VCFVelocityScale;
266 iliev 2012 }
267 iliev 2015 else {
268     cvalue = pRegion->VCFCutoff;
269     }
270     float fco = cutoffBase * float(cvalue);
271     if (fco > 127.0f) fco = 127.0f;
272 iliev 2012
273 iliev 2015 return fco;*/ // TODO: ^^^
274 iliev 2207 return cutoffBase;
275 iliev 2012 }
276    
277 iliev 2015 uint8_t Voice::GetVCFCutoffCtrl() {
278     /*uint8_t ctrl;
279     switch (pRegion->VCFCutoffController) {
280     case ::gig::vcf_cutoff_ctrl_modwheel:
281     ctrl = 1;
282     break;
283     case ::gig::vcf_cutoff_ctrl_effect1:
284     ctrl = 12;
285     break;
286     case ::gig::vcf_cutoff_ctrl_effect2:
287     ctrl = 13;
288     break;
289     case ::gig::vcf_cutoff_ctrl_breath:
290     ctrl = 2;
291     break;
292     case ::gig::vcf_cutoff_ctrl_foot:
293     ctrl = 4;
294     break;
295     case ::gig::vcf_cutoff_ctrl_sustainpedal:
296     ctrl = 64;
297     break;
298     case ::gig::vcf_cutoff_ctrl_softpedal:
299     ctrl = 67;
300     break;
301     case ::gig::vcf_cutoff_ctrl_genpurpose7:
302     ctrl = 82;
303     break;
304     case ::gig::vcf_cutoff_ctrl_genpurpose8:
305     ctrl = 83;
306     break;
307     case ::gig::vcf_cutoff_ctrl_aftertouch:
308     ctrl = 128;
309     break;
310     case ::gig::vcf_cutoff_ctrl_none:
311     default:
312     ctrl = 0;
313     break;
314 iliev 2012 }
315    
316 iliev 2015 return ctrl;*/ // TODO: ^^^
317     return 0;
318 iliev 2012 }
319    
320 iliev 2015 uint8_t Voice::GetVCFResonanceCtrl() {
321     /*uint8_t ctrl;
322     switch (pRegion->VCFResonanceController) {
323     case ::gig::vcf_res_ctrl_genpurpose3:
324     ctrl = 18;
325     break;
326     case ::gig::vcf_res_ctrl_genpurpose4:
327     ctrl = 19;
328     break;
329     case ::gig::vcf_res_ctrl_genpurpose5:
330     ctrl = 80;
331     break;
332     case ::gig::vcf_res_ctrl_genpurpose6:
333     ctrl = 81;
334     break;
335     case ::gig::vcf_res_ctrl_none:
336     default:
337     ctrl = 0;
338 iliev 2012 }
339    
340 iliev 2015 return ctrl;*/ // TODO: ^^^
341     return 0;
342 iliev 2012 }
343    
344 persson 2114 void Voice::ProcessGroupEvent(RTList<Event>::Iterator& itEvent) {
345     if (itEvent->Param.Note.Key != MIDIKey) {
346     // kill the voice fast
347 iliev 2218 SignalRack.EnterFadeOutStage();
348 persson 2114 }
349     }
350    
351 persson 2327 void Voice::CalculateFadeOutCoeff(float FadeOutTime, float SampleRate) {
352     SignalRack.CalculateFadeOutCoeff(FadeOutTime, SampleRate);
353     }
354    
355 persson 2382 int Voice::CalculatePan(uint8_t pan) {
356     int p = pan + RgnInfo.Pan;
357    
358     if (p < 0) return 0;
359     if (p > 127) return 127;
360     return p;
361     }
362    
363 iliev 2012 }} // namespace LinuxSampler::sf2

  ViewVC Help
Powered by ViewVC