/[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 3034 - (hide annotations) (download)
Mon Oct 31 00:05:00 2016 UTC (7 years, 4 months ago) by schoenebeck
File size: 14568 byte(s)
* Fixed a bunch of minor issues (mostly compiler warnings).
* Bumped version (2.0.0.svn31).

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

  ViewVC Help
Powered by ViewVC