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

Contents of /linuxsampler/trunk/src/engines/gig/Voice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 770 - (show annotations) (download)
Sun Sep 11 15:56:29 2005 UTC (18 years, 6 months ago) by schoenebeck
File size: 44822 byte(s)
* synthesis core optimizations

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 Christian Schoenebeck *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "../../common/Features.h"
25 #include "Synthesizer.h"
26 #include "Profiler.h"
27
28 #include "Voice.h"
29
30 namespace LinuxSampler { namespace gig {
31
32 const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff());
33
34 float Voice::CalculateFilterCutoffCoeff() {
35 return log(CONFIG_FILTER_CUTOFF_MAX / CONFIG_FILTER_CUTOFF_MIN);
36 }
37
38 Voice::Voice() {
39 pEngine = NULL;
40 pDiskThread = NULL;
41 PlaybackState = playback_state_end;
42 pLFO1 = new LFOUnsigned(1.0f); // amplitude EG (0..1 range)
43 pLFO2 = new LFOUnsigned(1.0f); // filter EG (0..1 range)
44 pLFO3 = new LFOSigned(1200.0f); // pitch EG (-1200..+1200 range)
45 KeyGroup = 0;
46 SynthesisMode = 0; // set all mode bits to 0 first
47 // select synthesis implementation (currently either pure C++ or MMX+SSE(1))
48 #if CONFIG_ASM && ARCH_X86
49 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE());
50 #else
51 SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false);
52 #endif
53 SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, Profiler::isEnabled());
54
55 finalSynthesisParameters.filterLeft.Reset();
56 finalSynthesisParameters.filterRight.Reset();
57 }
58
59 Voice::~Voice() {
60 if (pLFO1) delete pLFO1;
61 if (pLFO2) delete pLFO2;
62 if (pLFO3) delete pLFO3;
63 }
64
65 void Voice::SetEngine(Engine* pEngine) {
66 this->pEngine = pEngine;
67 this->pDiskThread = pEngine->pDiskThread;
68 dmsg(6,("Voice::SetEngine()\n"));
69 }
70
71 /**
72 * Initializes and triggers the voice, a disk stream will be launched if
73 * needed.
74 *
75 * @param pEngineChannel - engine channel on which this voice was ordered
76 * @param itNoteOnEvent - event that caused triggering of this voice
77 * @param PitchBend - MIDI detune factor (-8192 ... +8191)
78 * @param pDimRgn - points to the dimension region which provides sample wave(s) and articulation data
79 * @param VoiceType - type of this voice
80 * @param iKeyGroup - a value > 0 defines a key group in which this voice is member of
81 * @returns 0 on success, a value < 0 if the voice wasn't triggered
82 * (either due to an error or e.g. because no region is
83 * defined for the given key)
84 */
85 int Voice::Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup) {
86 this->pEngineChannel = pEngineChannel;
87 this->pDimRgn = pDimRgn;
88
89 #if CONFIG_DEVMODE
90 if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging
91 dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n"));
92 }
93 #endif // CONFIG_DEVMODE
94
95 Type = VoiceType;
96 MIDIKey = itNoteOnEvent->Param.Note.Key;
97 PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet
98 Delay = itNoteOnEvent->FragmentPos();
99 itTriggerEvent = itNoteOnEvent;
100 itKillEvent = Pool<Event>::Iterator();
101 KeyGroup = iKeyGroup;
102 pSample = pDimRgn->pSample; // sample won't change until the voice is finished
103
104 // calculate volume
105 const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity);
106
107 Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0)
108
109 Volume *= pDimRgn->SampleAttenuation;
110
111 // the volume of release triggered samples depends on note length
112 if (Type == type_release_trigger) {
113 float noteLength = float(pEngine->FrameTime + Delay -
114 pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate;
115 float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength;
116 if (attenuation <= 0) return -1;
117 Volume *= attenuation;
118 }
119
120 // select channel mode (mono or stereo)
121 SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2);
122
123 // get starting crossfade volume level
124 switch (pDimRgn->AttenuationController.type) {
125 case ::gig::attenuation_ctrl_t::type_channelaftertouch:
126 CrossfadeVolume = 1.0f; //TODO: aftertouch not supported yet
127 break;
128 case ::gig::attenuation_ctrl_t::type_velocity:
129 CrossfadeVolume = CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity);
130 break;
131 case ::gig::attenuation_ctrl_t::type_controlchange: //FIXME: currently not sample accurate
132 CrossfadeVolume = CrossfadeAttenuation(pEngineChannel->ControllerTable[pDimRgn->AttenuationController.controller_number]);
133 break;
134 case ::gig::attenuation_ctrl_t::type_none: // no crossfade defined
135 default:
136 CrossfadeVolume = 1.0f;
137 }
138
139 PanLeft = 1.0f - float(RTMath::Max(pDimRgn->Pan, 0)) / 63.0f;
140 PanRight = 1.0f - float(RTMath::Min(pDimRgn->Pan, 0)) / -64.0f;
141
142 finalSynthesisParameters.dPos = pDimRgn->SampleStartOffset; // offset where we should start playback of sample (0 - 2000 sample points)
143
144 // Check if the sample needs disk streaming or is too short for that
145 long cachedsamples = pSample->GetCache().Size / pSample->FrameSize;
146 DiskVoice = cachedsamples < pSample->SamplesTotal;
147
148 if (DiskVoice) { // voice to be streamed from disk
149 MaxRAMPos = cachedsamples - (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) / pSample->Channels; //TODO: this calculation is too pessimistic and may better be moved to Render() method, so it calculates MaxRAMPos dependent to the current demand of sample points to be rendered (e.g. in case of JACK)
150
151 // check if there's a loop defined which completely fits into the cached (RAM) part of the sample
152 if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) {
153 RAMLoop = true;
154 loop.uiTotalCycles = pSample->LoopPlayCount;
155 loop.uiCyclesLeft = pSample->LoopPlayCount;
156 loop.uiStart = pSample->LoopStart;
157 loop.uiEnd = pSample->LoopEnd;
158 loop.uiSize = pSample->LoopSize;
159 }
160 else RAMLoop = false;
161
162 if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos, !RAMLoop) < 0) {
163 dmsg(1,("Disk stream order failed!\n"));
164 KillImmediately();
165 return -1;
166 }
167 dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no"));
168 }
169 else { // RAM only voice
170 MaxRAMPos = cachedsamples;
171 if (pSample->Loops) {
172 RAMLoop = true;
173 loop.uiCyclesLeft = pSample->LoopPlayCount;
174 }
175 else RAMLoop = false;
176 dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no"));
177 }
178
179
180 // calculate initial pitch value
181 {
182 double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12];
183 if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100;
184 this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->SampleRate));
185 this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents
186 }
187
188 // the length of the decay and release curves are dependent on the velocity
189 const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity);
190
191 // setup EG 1 (VCA EG)
192 {
193 // get current value of EG1 controller
194 double eg1controllervalue;
195 switch (pDimRgn->EG1Controller.type) {
196 case ::gig::eg1_ctrl_t::type_none: // no controller defined
197 eg1controllervalue = 0;
198 break;
199 case ::gig::eg1_ctrl_t::type_channelaftertouch:
200 eg1controllervalue = 0; // TODO: aftertouch not yet supported
201 break;
202 case ::gig::eg1_ctrl_t::type_velocity:
203 eg1controllervalue = itNoteOnEvent->Param.Note.Velocity;
204 break;
205 case ::gig::eg1_ctrl_t::type_controlchange: // MIDI control change controller
206 eg1controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG1Controller.controller_number];
207 break;
208 }
209 if (pDimRgn->EG1ControllerInvert) eg1controllervalue = 127 - eg1controllervalue;
210
211 // calculate influence of EG1 controller on EG1's parameters
212 // (eg1attack is different from the others)
213 double eg1attack = (pDimRgn->EG1ControllerAttackInfluence) ?
214 1 + 0.031 * (double) (pDimRgn->EG1ControllerAttackInfluence == 1 ?
215 1 : 1 << pDimRgn->EG1ControllerAttackInfluence) * eg1controllervalue : 1.0;
216 double eg1decay = (pDimRgn->EG1ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerDecayInfluence) * eg1controllervalue : 1.0;
217 double eg1release = (pDimRgn->EG1ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG1ControllerReleaseInfluence) * eg1controllervalue : 1.0;
218
219 EG1.trigger(pDimRgn->EG1PreAttack,
220 pDimRgn->EG1Attack * eg1attack,
221 pDimRgn->EG1Hold,
222 pSample->LoopStart,
223 pDimRgn->EG1Decay1 * eg1decay * velrelease,
224 pDimRgn->EG1Decay2 * eg1decay * velrelease,
225 pDimRgn->EG1InfiniteSustain,
226 pDimRgn->EG1Sustain,
227 pDimRgn->EG1Release * eg1release * velrelease,
228 velocityAttenuation,
229 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
230 }
231
232
233 // setup EG 2 (VCF Cutoff EG)
234 {
235 // get current value of EG2 controller
236 double eg2controllervalue;
237 switch (pDimRgn->EG2Controller.type) {
238 case ::gig::eg2_ctrl_t::type_none: // no controller defined
239 eg2controllervalue = 0;
240 break;
241 case ::gig::eg2_ctrl_t::type_channelaftertouch:
242 eg2controllervalue = 0; // TODO: aftertouch not yet supported
243 break;
244 case ::gig::eg2_ctrl_t::type_velocity:
245 eg2controllervalue = itNoteOnEvent->Param.Note.Velocity;
246 break;
247 case ::gig::eg2_ctrl_t::type_controlchange: // MIDI control change controller
248 eg2controllervalue = pEngineChannel->ControllerTable[pDimRgn->EG2Controller.controller_number];
249 break;
250 }
251 if (pDimRgn->EG2ControllerInvert) eg2controllervalue = 127 - eg2controllervalue;
252
253 // calculate influence of EG2 controller on EG2's parameters
254 double eg2attack = (pDimRgn->EG2ControllerAttackInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerAttackInfluence) * eg2controllervalue : 1.0;
255 double eg2decay = (pDimRgn->EG2ControllerDecayInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerDecayInfluence) * eg2controllervalue : 1.0;
256 double eg2release = (pDimRgn->EG2ControllerReleaseInfluence) ? 1 + 0.00775 * (double) (1 << pDimRgn->EG2ControllerReleaseInfluence) * eg2controllervalue : 1.0;
257
258 EG2.trigger(pDimRgn->EG2PreAttack,
259 pDimRgn->EG2Attack * eg2attack,
260 false,
261 pSample->LoopStart,
262 pDimRgn->EG2Decay1 * eg2decay * velrelease,
263 pDimRgn->EG2Decay2 * eg2decay * velrelease,
264 pDimRgn->EG2InfiniteSustain,
265 pDimRgn->EG2Sustain,
266 pDimRgn->EG2Release * eg2release * velrelease,
267 velocityAttenuation,
268 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
269 }
270
271
272 // setup EG 3 (VCO EG)
273 {
274 double eg3depth = RTMath::CentsToFreqRatio(pDimRgn->EG3Depth);
275 EG3.trigger(eg3depth, pDimRgn->EG3Attack, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
276 }
277
278
279 // setup LFO 1 (VCA LFO)
280 {
281 uint16_t lfo1_internal_depth;
282 switch (pDimRgn->LFO1Controller) {
283 case ::gig::lfo1_ctrl_internal:
284 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
285 pLFO1->ExtController = 0; // no external controller
286 bLFO1Enabled = (lfo1_internal_depth > 0);
287 break;
288 case ::gig::lfo1_ctrl_modwheel:
289 lfo1_internal_depth = 0;
290 pLFO1->ExtController = 1; // MIDI controller 1
291 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
292 break;
293 case ::gig::lfo1_ctrl_breath:
294 lfo1_internal_depth = 0;
295 pLFO1->ExtController = 2; // MIDI controller 2
296 bLFO1Enabled = (pDimRgn->LFO1ControlDepth > 0);
297 break;
298 case ::gig::lfo1_ctrl_internal_modwheel:
299 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
300 pLFO1->ExtController = 1; // MIDI controller 1
301 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
302 break;
303 case ::gig::lfo1_ctrl_internal_breath:
304 lfo1_internal_depth = pDimRgn->LFO1InternalDepth;
305 pLFO1->ExtController = 2; // MIDI controller 2
306 bLFO1Enabled = (lfo1_internal_depth > 0 || pDimRgn->LFO1ControlDepth > 0);
307 break;
308 default:
309 lfo1_internal_depth = 0;
310 pLFO1->ExtController = 0; // no external controller
311 bLFO1Enabled = false;
312 }
313 if (bLFO1Enabled) pLFO1->trigger(pDimRgn->LFO1Frequency,
314 start_level_max,
315 lfo1_internal_depth,
316 pDimRgn->LFO1ControlDepth,
317 pDimRgn->LFO1FlipPhase,
318 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
319 }
320
321
322 // setup LFO 2 (VCF Cutoff LFO)
323 {
324 uint16_t lfo2_internal_depth;
325 switch (pDimRgn->LFO2Controller) {
326 case ::gig::lfo2_ctrl_internal:
327 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
328 pLFO2->ExtController = 0; // no external controller
329 bLFO2Enabled = (lfo2_internal_depth > 0);
330 break;
331 case ::gig::lfo2_ctrl_modwheel:
332 lfo2_internal_depth = 0;
333 pLFO2->ExtController = 1; // MIDI controller 1
334 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
335 break;
336 case ::gig::lfo2_ctrl_foot:
337 lfo2_internal_depth = 0;
338 pLFO2->ExtController = 4; // MIDI controller 4
339 bLFO2Enabled = (pDimRgn->LFO2ControlDepth > 0);
340 break;
341 case ::gig::lfo2_ctrl_internal_modwheel:
342 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
343 pLFO2->ExtController = 1; // MIDI controller 1
344 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
345 break;
346 case ::gig::lfo2_ctrl_internal_foot:
347 lfo2_internal_depth = pDimRgn->LFO2InternalDepth;
348 pLFO2->ExtController = 4; // MIDI controller 4
349 bLFO2Enabled = (lfo2_internal_depth > 0 || pDimRgn->LFO2ControlDepth > 0);
350 break;
351 default:
352 lfo2_internal_depth = 0;
353 pLFO2->ExtController = 0; // no external controller
354 bLFO2Enabled = false;
355 }
356 if (bLFO2Enabled) pLFO2->trigger(pDimRgn->LFO2Frequency,
357 start_level_max,
358 lfo2_internal_depth,
359 pDimRgn->LFO2ControlDepth,
360 pDimRgn->LFO2FlipPhase,
361 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
362 }
363
364
365 // setup LFO 3 (VCO LFO)
366 {
367 uint16_t lfo3_internal_depth;
368 switch (pDimRgn->LFO3Controller) {
369 case ::gig::lfo3_ctrl_internal:
370 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
371 pLFO3->ExtController = 0; // no external controller
372 bLFO3Enabled = (lfo3_internal_depth > 0);
373 break;
374 case ::gig::lfo3_ctrl_modwheel:
375 lfo3_internal_depth = 0;
376 pLFO3->ExtController = 1; // MIDI controller 1
377 bLFO3Enabled = (pDimRgn->LFO3ControlDepth > 0);
378 break;
379 case ::gig::lfo3_ctrl_aftertouch:
380 lfo3_internal_depth = 0;
381 pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet
382 bLFO3Enabled = false; // see TODO comment in line above
383 break;
384 case ::gig::lfo3_ctrl_internal_modwheel:
385 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
386 pLFO3->ExtController = 1; // MIDI controller 1
387 bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0);
388 break;
389 case ::gig::lfo3_ctrl_internal_aftertouch:
390 lfo3_internal_depth = pDimRgn->LFO3InternalDepth;
391 pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet
392 bLFO3Enabled = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above
393 break;
394 default:
395 lfo3_internal_depth = 0;
396 pLFO3->ExtController = 0; // no external controller
397 bLFO3Enabled = false;
398 }
399 if (bLFO3Enabled) pLFO3->trigger(pDimRgn->LFO3Frequency,
400 start_level_mid,
401 lfo3_internal_depth,
402 pDimRgn->LFO3ControlDepth,
403 false,
404 pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
405 }
406
407
408 #if CONFIG_FORCE_FILTER
409 const bool bUseFilter = true;
410 #else // use filter only if instrument file told so
411 const bool bUseFilter = pDimRgn->VCFEnabled;
412 #endif // CONFIG_FORCE_FILTER
413 SYNTHESIS_MODE_SET_FILTER(SynthesisMode, bUseFilter);
414 if (bUseFilter) {
415 #ifdef CONFIG_OVERRIDE_CUTOFF_CTRL
416 VCFCutoffCtrl.controller = CONFIG_OVERRIDE_CUTOFF_CTRL;
417 #else // use the one defined in the instrument file
418 switch (pDimRgn->VCFCutoffController) {
419 case ::gig::vcf_cutoff_ctrl_modwheel:
420 VCFCutoffCtrl.controller = 1;
421 break;
422 case ::gig::vcf_cutoff_ctrl_effect1:
423 VCFCutoffCtrl.controller = 12;
424 break;
425 case ::gig::vcf_cutoff_ctrl_effect2:
426 VCFCutoffCtrl.controller = 13;
427 break;
428 case ::gig::vcf_cutoff_ctrl_breath:
429 VCFCutoffCtrl.controller = 2;
430 break;
431 case ::gig::vcf_cutoff_ctrl_foot:
432 VCFCutoffCtrl.controller = 4;
433 break;
434 case ::gig::vcf_cutoff_ctrl_sustainpedal:
435 VCFCutoffCtrl.controller = 64;
436 break;
437 case ::gig::vcf_cutoff_ctrl_softpedal:
438 VCFCutoffCtrl.controller = 67;
439 break;
440 case ::gig::vcf_cutoff_ctrl_genpurpose7:
441 VCFCutoffCtrl.controller = 82;
442 break;
443 case ::gig::vcf_cutoff_ctrl_genpurpose8:
444 VCFCutoffCtrl.controller = 83;
445 break;
446 case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet
447 case ::gig::vcf_cutoff_ctrl_none:
448 default:
449 VCFCutoffCtrl.controller = 0;
450 break;
451 }
452 #endif // CONFIG_OVERRIDE_CUTOFF_CTRL
453
454 #ifdef CONFIG_OVERRIDE_RESONANCE_CTRL
455 VCFResonanceCtrl.controller = CONFIG_OVERRIDE_RESONANCE_CTRL;
456 #else // use the one defined in the instrument file
457 switch (pDimRgn->VCFResonanceController) {
458 case ::gig::vcf_res_ctrl_genpurpose3:
459 VCFResonanceCtrl.controller = 18;
460 break;
461 case ::gig::vcf_res_ctrl_genpurpose4:
462 VCFResonanceCtrl.controller = 19;
463 break;
464 case ::gig::vcf_res_ctrl_genpurpose5:
465 VCFResonanceCtrl.controller = 80;
466 break;
467 case ::gig::vcf_res_ctrl_genpurpose6:
468 VCFResonanceCtrl.controller = 81;
469 break;
470 case ::gig::vcf_res_ctrl_none:
471 default:
472 VCFResonanceCtrl.controller = 0;
473 }
474 #endif // CONFIG_OVERRIDE_RESONANCE_CTRL
475
476 #ifndef CONFIG_OVERRIDE_FILTER_TYPE
477 finalSynthesisParameters.filterLeft.SetType(pDimRgn->VCFType);
478 finalSynthesisParameters.filterRight.SetType(pDimRgn->VCFType);
479 #else // override filter type
480 FilterLeft.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
481 FilterRight.SetType(CONFIG_OVERRIDE_FILTER_TYPE);
482 #endif // CONFIG_OVERRIDE_FILTER_TYPE
483
484 VCFCutoffCtrl.value = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
485 VCFResonanceCtrl.value = pEngineChannel->ControllerTable[VCFResonanceCtrl.controller];
486
487 // calculate cutoff frequency
488 float cutoff = pDimRgn->GetVelocityCutoff(itNoteOnEvent->Param.Note.Velocity);
489 if (pDimRgn->VCFKeyboardTracking) {
490 cutoff *= exp((itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.057762265f); // (ln(2) / 12)
491 }
492 CutoffBase = cutoff;
493
494 int cvalue;
495 if (VCFCutoffCtrl.controller) {
496 cvalue = pEngineChannel->ControllerTable[VCFCutoffCtrl.controller];
497 if (pDimRgn->VCFCutoffControllerInvert) cvalue = 127 - cvalue;
498 if (cvalue < pDimRgn->VCFVelocityScale) cvalue = pDimRgn->VCFVelocityScale;
499 }
500 else {
501 cvalue = pDimRgn->VCFCutoff;
502 }
503 cutoff *= float(cvalue) * 0.00787402f; // (1 / 127)
504 if (cutoff > 1.0) cutoff = 1.0;
505 cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN;
506
507 // calculate resonance
508 float resonance = (float) VCFResonanceCtrl.value * 0.00787f; // 0.0..1.0
509 if (pDimRgn->VCFKeyboardTracking) {
510 resonance += (float) (itNoteOnEvent->Param.Note.Key - pDimRgn->VCFKeyboardTrackingBreakpoint) * 0.00787f;
511 }
512 Constrain(resonance, 0.0, 1.0); // correct resonance if outside allowed value range (0.0..1.0)
513
514 VCFCutoffCtrl.fvalue = cutoff - CONFIG_FILTER_CUTOFF_MIN;
515 VCFResonanceCtrl.fvalue = resonance;
516 }
517 else {
518 VCFCutoffCtrl.controller = 0;
519 VCFResonanceCtrl.controller = 0;
520 }
521
522 return 0; // success
523 }
524
525 /**
526 * Renders the audio data for this voice for the current audio fragment.
527 * The sample input data can either come from RAM (cached sample or sample
528 * part) or directly from disk. The output signal will be rendered by
529 * resampling / interpolation. If this voice is a disk streaming voice and
530 * the voice completely played back the cached RAM part of the sample, it
531 * will automatically switch to disk playback for the next RenderAudio()
532 * call.
533 *
534 * @param Samples - number of samples to be rendered in this audio fragment cycle
535 */
536 void Voice::Render(uint Samples) {
537
538 // select default values for synthesis mode bits
539 SYNTHESIS_MODE_SET_LOOP(SynthesisMode, false);
540
541 switch (this->PlaybackState) {
542
543 case playback_state_init:
544 this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed
545 // no break - continue with playback_state_ram
546
547 case playback_state_ram: {
548 if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping
549
550 // render current fragment
551 Synthesize(Samples, (sample_t*) pSample->GetCache().pStart, Delay);
552
553 if (DiskVoice) {
554 // check if we reached the allowed limit of the sample RAM cache
555 if (finalSynthesisParameters.dPos > MaxRAMPos) {
556 dmsg(5,("Voice: switching to disk playback (Pos=%f)\n", finalSynthesisParameters.dPos));
557 this->PlaybackState = playback_state_disk;
558 }
559 } else if (finalSynthesisParameters.dPos >= pSample->GetCache().Size / pSample->FrameSize) {
560 this->PlaybackState = playback_state_end;
561 }
562 }
563 break;
564
565 case playback_state_disk: {
566 if (!DiskStreamRef.pStream) {
567 // check if the disk thread created our ordered disk stream in the meantime
568 DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID);
569 if (!DiskStreamRef.pStream) {
570 std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush;
571 KillImmediately();
572 return;
573 }
574 DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(finalSynthesisParameters.dPos) - MaxRAMPos));
575 finalSynthesisParameters.dPos -= int(finalSynthesisParameters.dPos);
576 RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet
577 }
578
579 const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace();
580
581 // add silence sample at the end if we reached the end of the stream (for the interpolator)
582 if (DiskStreamRef.State == Stream::state_end) {
583 const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << CONFIG_MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm
584 if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) {
585 // remember how many sample words there are before any silence has been added
586 if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead;
587 DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead);
588 }
589 }
590
591 sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from
592
593 // render current audio fragment
594 Synthesize(Samples, ptr, Delay);
595
596 const int iPos = (int) finalSynthesisParameters.dPos;
597 const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read
598 DiskStreamRef.pStream->IncrementReadPos(readSampleWords);
599 finalSynthesisParameters.dPos -= iPos; // just keep fractional part of playback position
600
601 // change state of voice to 'end' if we really reached the end of the sample data
602 if (RealSampleWordsLeftToRead >= 0) {
603 RealSampleWordsLeftToRead -= readSampleWords;
604 if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end;
605 }
606 }
607 break;
608
609 case playback_state_end:
610 std::cerr << "gig::Voice::Render(): entered with playback_state_end, this is a bug!\n" << std::flush;
611 break;
612 }
613
614 // Reset synthesis event lists
615 pEngineChannel->pEvents->clear();
616
617 // Reset delay
618 Delay = 0;
619
620 itTriggerEvent = Pool<Event>::Iterator();
621
622 // If sample stream or release stage finished, kill the voice
623 if (PlaybackState == playback_state_end || EG1.getSegmentType() == EGADSR::segment_end) KillImmediately();
624 }
625
626 /**
627 * Resets voice variables. Should only be called if rendering process is
628 * suspended / not running.
629 */
630 void Voice::Reset() {
631 finalSynthesisParameters.filterLeft.Reset();
632 finalSynthesisParameters.filterRight.Reset();
633 DiskStreamRef.pStream = NULL;
634 DiskStreamRef.hStream = 0;
635 DiskStreamRef.State = Stream::state_unused;
636 DiskStreamRef.OrderID = 0;
637 PlaybackState = playback_state_end;
638 itTriggerEvent = Pool<Event>::Iterator();
639 itKillEvent = Pool<Event>::Iterator();
640 }
641
642 /**
643 * Process given list of MIDI note on, note off and sustain pedal events
644 * for the given time.
645 *
646 * @param itEvent - iterator pointing to the next event to be processed
647 * @param End - youngest time stamp where processing should be stopped
648 */
649 void Voice::processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End) {
650 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
651 if (itEvent->Type == Event::type_release) {
652 EG1.update(EGADSR::event_release, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
653 EG2.update(EGADSR::event_release, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
654 } else if (itEvent->Type == Event::type_cancel_release) {
655 EG1.update(EGADSR::event_cancel_release, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
656 EG2.update(EGADSR::event_cancel_release, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
657 }
658 }
659 }
660
661 /**
662 * Process given list of MIDI control change and pitch bend events for
663 * the given time.
664 *
665 * @param itEvent - iterator pointing to the next event to be processed
666 * @param End - youngest time stamp where processing should be stopped
667 */
668 void Voice::processCCEvents(RTList<Event>::Iterator& itEvent, uint End) {
669 for (; itEvent && itEvent->FragmentPos() <= End; ++itEvent) {
670 if (itEvent->Type == Event::type_control_change &&
671 itEvent->Param.CC.Controller) { // if (valid) MIDI control change event
672 if (itEvent->Param.CC.Controller == VCFCutoffCtrl.controller) {
673 processCutoffEvent(itEvent);
674 }
675 if (itEvent->Param.CC.Controller == VCFResonanceCtrl.controller) {
676 processResonanceEvent(itEvent);
677 }
678 if (itEvent->Param.CC.Controller == pLFO1->ExtController) {
679 pLFO1->update(itEvent->Param.CC.Value);
680 }
681 if (itEvent->Param.CC.Controller == pLFO2->ExtController) {
682 pLFO2->update(itEvent->Param.CC.Value);
683 }
684 if (itEvent->Param.CC.Controller == pLFO3->ExtController) {
685 pLFO3->update(itEvent->Param.CC.Value);
686 }
687 if (pDimRgn->AttenuationController.type == ::gig::attenuation_ctrl_t::type_controlchange &&
688 itEvent->Param.CC.Controller == pDimRgn->AttenuationController.controller_number) {
689 processCrossFadeEvent(itEvent);
690 }
691 } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event
692 processPitchEvent(itEvent);
693 }
694 }
695 }
696
697 void Voice::processPitchEvent(RTList<Event>::Iterator& itEvent) {
698 const float pitch = RTMath::CentsToFreqRatio(((double) itEvent->Param.Pitch.Pitch / 8192.0) * 200.0); // +-two semitones = +-200 cents
699 finalSynthesisParameters.fFinalPitch *= pitch;
700 PitchBend = pitch;
701 }
702
703 void Voice::processCrossFadeEvent(RTList<Event>::Iterator& itEvent) {
704 CrossfadeVolume = CrossfadeAttenuation(itEvent->Param.CC.Value);
705 #if CONFIG_PROCESS_MUTED_CHANNELS
706 const float effectiveVolume = CrossfadeVolume * Volume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);
707 #else
708 const float effectiveVolume = CrossfadeVolume * Volume * pEngineChannel->GlobalVolume;
709 #endif
710 fFinalVolume = effectiveVolume;
711 }
712
713 void Voice::processCutoffEvent(RTList<Event>::Iterator& itEvent) {
714 int ccvalue = itEvent->Param.CC.Value;
715 if (VCFCutoffCtrl.value == ccvalue) return;
716 VCFCutoffCtrl.value == ccvalue;
717 if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue;
718 if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale;
719 float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127)
720 if (cutoff > 1.0) cutoff = 1.0;
721 cutoff = exp(cutoff * FILTER_CUTOFF_COEFF) * CONFIG_FILTER_CUTOFF_MIN - CONFIG_FILTER_CUTOFF_MIN;
722 VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time
723 fFinalCutoff = cutoff;
724 }
725
726 void Voice::processResonanceEvent(RTList<Event>::Iterator& itEvent) {
727 // convert absolute controller value to differential
728 const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value;
729 VCFResonanceCtrl.value = itEvent->Param.CC.Value;
730 const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0
731 fFinalResonance += resonancedelta;
732 // needed for initialization of parameter
733 VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f;
734 }
735
736 /**
737 * Synthesizes the current audio fragment for this voice.
738 *
739 * @param Samples - number of sample points to be rendered in this audio
740 * fragment cycle
741 * @param pSrc - pointer to input sample data
742 * @param Skip - number of sample points to skip in output buffer
743 */
744 void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) {
745 finalSynthesisParameters.pOutLeft = &pEngineChannel->pOutputLeft[Skip];
746 finalSynthesisParameters.pOutRight = &pEngineChannel->pOutputRight[Skip];
747 finalSynthesisParameters.pSrc = pSrc;
748
749 RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first();
750 RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first();
751
752 if (Skip) { // skip events that happened before this voice was triggered
753 while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent;
754 while (itNoteEvent && itNoteEvent->FragmentPos() <= Skip) ++itNoteEvent;
755 }
756
757 uint i = Skip;
758 while (i < Samples) {
759 int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples);
760
761 // initialize all final synthesis parameters
762 finalSynthesisParameters.fFinalPitch = PitchBase * PitchBend;
763 #if CONFIG_PROCESS_MUTED_CHANNELS
764 fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume);
765 #else
766 fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume;
767 #endif
768 fFinalCutoff = VCFCutoffCtrl.fvalue;
769 fFinalResonance = VCFResonanceCtrl.fvalue;
770
771 // process MIDI control change and pitchbend events for this subfragment
772 processCCEvents(itCCEvent, iSubFragmentEnd);
773
774 // process transition events (note on, note off & sustain pedal)
775 processTransitionEvents(itNoteEvent, iSubFragmentEnd);
776
777 // process envelope generators
778 switch (EG1.getSegmentType()) {
779 case EGADSR::segment_lin:
780 fFinalVolume *= EG1.processLin();
781 break;
782 case EGADSR::segment_exp:
783 fFinalVolume *= EG1.processExp();
784 break;
785 case EGADSR::segment_end:
786 fFinalVolume *= EG1.getLevel();
787 break; // noop
788 }
789 switch (EG2.getSegmentType()) {
790 case EGADSR::segment_lin:
791 fFinalCutoff *= EG2.processLin();
792 break;
793 case EGADSR::segment_exp:
794 fFinalCutoff *= EG2.processExp();
795 break;
796 case EGADSR::segment_end:
797 fFinalCutoff *= EG2.getLevel();
798 break; // noop
799 }
800 if (EG3.active()) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render());
801
802 // process low frequency oscillators
803 if (bLFO1Enabled) fFinalVolume *= pLFO1->render();
804 if (bLFO2Enabled) fFinalCutoff *= pLFO2->render();
805 if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render());
806
807 // if filter enabled then update filter coefficients
808 if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) {
809 finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
810 finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate);
811 }
812
813 // do we need resampling?
814 const float __PLUS_ONE_CENT = 1.000577789506554859250142541782224725466f;
815 const float __MINUS_ONE_CENT = 0.9994225441413807496009516495583113737666f;
816 const bool bResamplingRequired = !(finalSynthesisParameters.fFinalPitch <= __PLUS_ONE_CENT &&
817 finalSynthesisParameters.fFinalPitch >= __MINUS_ONE_CENT);
818 SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, bResamplingRequired);
819
820 // prepare final synthesis parameters structure
821 finalSynthesisParameters.fFinalVolumeLeft = fFinalVolume * PanLeft;
822 finalSynthesisParameters.fFinalVolumeRight = fFinalVolume * PanRight;
823 finalSynthesisParameters.uiToGo = iSubFragmentEnd - i;
824
825 // render audio for one subfragment
826 RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop);
827
828 // increment envelopes' positions
829 if (EG1.active()) {
830 EG1.increment(1);
831 if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
832 }
833 if (EG2.active()) {
834 EG2.increment(1);
835 if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, finalSynthesisParameters.dPos, finalSynthesisParameters.fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
836 }
837 EG3.increment(1);
838 if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached
839
840 i = iSubFragmentEnd;
841 }
842 }
843
844 /**
845 * Immediately kill the voice. This method should not be used to kill
846 * a normal, active voice, because it doesn't take care of things like
847 * fading down the volume level to avoid clicks and regular processing
848 * until the kill event actually occured!
849 *
850 * @see Kill()
851 */
852 void Voice::KillImmediately() {
853 if (DiskVoice && DiskStreamRef.State != Stream::state_unused) {
854 pDiskThread->OrderDeletionOfStream(&DiskStreamRef);
855 }
856 Reset();
857 }
858
859 /**
860 * Kill the voice in regular sense. Let the voice render audio until
861 * the kill event actually occured and then fade down the volume level
862 * very quickly and let the voice die finally. Unlike a normal release
863 * of a voice, a kill process cannot be cancalled and is therefore
864 * usually used for voice stealing and key group conflicts.
865 *
866 * @param itKillEvent - event which caused the voice to be killed
867 */
868 void Voice::Kill(Pool<Event>::Iterator& itKillEvent) {
869 #if CONFIG_DEVMODE
870 if (!itKillEvent) dmsg(1,("gig::Voice::Kill(): ERROR, !itKillEvent !!!\n"));
871 if (itKillEvent && !itKillEvent.isValid()) dmsg(1,("gig::Voice::Kill(): ERROR, itKillEvent invalid !!!\n"));
872 #endif // CONFIG_DEVMODE
873
874 if (itTriggerEvent && itKillEvent->FragmentPos() <= itTriggerEvent->FragmentPos()) return;
875 this->itKillEvent = itKillEvent;
876 }
877
878 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC