/[svn]/linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2227 - (show annotations) (download)
Wed Aug 3 17:11:40 2011 UTC (12 years, 8 months ago) by iliev
File size: 19781 byte(s)
* sfz engine: implemented opcodes fillfo_freqccN,
  pitchlfo_freqccN, amplfo_freqccN, lfoN_freq_onccX

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "SfzSignalUnitRack.h"
24 #include "Voice.h"
25 #include <SF.h>
26
27 namespace LinuxSampler { namespace sfz {
28
29 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
30
31 }
32
33 double SfzSignalUnit::GetSampleRate() {
34 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
35 }
36
37
38 void EGv1Unit::Trigger() {
39 ::sfz::Region* const pRegion = pVoice->pRegion;
40
41 // the length of the decay and release curves are dependent on the velocity
42 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
43
44 // set the delay trigger
45 uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate();
46
47 EG.trigger(uint(pRegion->ampeg_start * 10),
48 std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),
49 std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),
50 std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),
51 uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),
52 std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),
53 GetSampleRate());
54 }
55
56
57 void EGv2Unit::Trigger() {
58 EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);
59 }
60
61
62 void PitchEGUnit::Trigger() {
63 ::sfz::Region* const pRegion = pVoice->pRegion;
64 depth = pRegion->pitcheg_depth;
65
66 // the length of the decay and release curves are dependent on the velocity
67 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
68
69 // set the delay trigger
70 uiDelayTrigger = (pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease) * GetSampleRate();
71
72 EG.trigger(uint(pRegion->pitcheg_start * 10),
73 std::max(0.0, pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease),
74 std::max(0.0, pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease),
75 std::max(0.0, pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease),
76 uint(std::min(std::max(0.0, 10 * (pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease)), 1000.0)),
77 std::max(0.0, pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease),
78 GetSampleRate());
79 }
80
81
82 void FilEGUnit::Trigger() {
83 ::sfz::Region* const pRegion = pVoice->pRegion;
84 depth = pRegion->fileg_depth;
85
86 // the length of the decay and release curves are dependent on the velocity
87 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
88
89 // set the delay trigger
90 uiDelayTrigger = (pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease) * GetSampleRate();
91
92 EG.trigger(uint(pRegion->fileg_start * 10),
93 std::max(0.0, pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease),
94 std::max(0.0, pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease),
95 std::max(0.0, pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease),
96 uint(std::min(std::max(0.0, 10 * (pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease)), 1000.0)),
97 std::max(0.0, pRegion->fileg_release + pRegion->fileg_vel2release * velrelease),
98 GetSampleRate());
99 }
100
101
102 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
103 : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
104 suFadeEG(rack), suFreqOnCC(rack, this)
105 { }
106
107 LFOUnit::LFOUnit(const LFOUnit& Unit)
108 : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
109 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this)
110 {
111 Copy(Unit);
112 }
113
114 void LFOUnit::Increment() {
115 if (DelayStage()) return;
116
117 SignalUnit::Increment();
118
119 Level = pLFO->Render();
120 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
121 }
122
123 void LFOUnit::Trigger() {
124 //reset
125 Level = 0;
126
127 // set the delay trigger
128 uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
129 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
130 float f = pLfoInfo->fade;
131 for (int i = 0; i < pLfoInfo->fade_oncc.size(); i++) {
132 int val = pVoice->GetControllerValue(pLfoInfo->fade_oncc[i].Controller);
133 f += (val / 127.0f) * pLfoInfo->fade_oncc[i].Influence;
134 }
135
136 if (f != 0) {
137 suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
138 suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
139 }
140 }
141 }
142
143 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
144 pLFO->SetFrequency(suFreqOnCC.GetLevel() + pLfoInfo->freq, GetSampleRate());
145 }
146
147
148 void LFOv1Unit::Trigger() {
149 LFOUnit::Trigger();
150
151 lfo.trigger (
152 pLfoInfo->freq + suFreqOnCC.GetLevel(),
153 start_level_mid,
154 1, 0, false, GetSampleRate()
155 );
156 lfo.update(0);
157 }
158
159
160 LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
161 : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
162 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
163 suPitchOnCC(rack)
164 {
165 lfos.add(&lfo0);
166 lfos.add(&lfo1);
167 lfos.add(&lfo2);
168 lfos.add(&lfo3);
169 lfos.add(&lfo4);
170 lfos.add(&lfo5);
171 lfos.add(&lfo6);
172 lfos.add(&lfo7);
173 }
174
175 void LFOv2Unit::Trigger() {
176 LFOUnit::Trigger();
177
178 if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
179 else pLFO = lfos[pLfoInfo->wave];
180
181 pLFO->Trigger (
182 pLfoInfo->freq + suFreqOnCC.GetLevel(),
183 start_level_mid,
184 1, 0, false, GetSampleRate()
185 );
186 pLFO->Update(0);
187
188 float phase = pLfoInfo->phase;
189 for (int i = 0; i < pLfoInfo->phase_oncc.size(); i++) {
190 int val = pVoice->GetControllerValue(pLfoInfo->phase_oncc[i].Controller);
191 phase += (val / 127.0f) * pLfoInfo->phase_oncc[i].Influence;
192 }
193 if (phase != 0) pLFO->SetPhase(phase);
194 }
195
196 void AmpLFOUnit::Trigger() {
197 ::sfz::Region* const pRegion = pVoice->pRegion;
198 pLfoInfo->delay = pRegion->amplfo_delay;
199 pLfoInfo->freq = pRegion->amplfo_freq;
200 pLfoInfo->fade = pRegion->amplfo_fade;
201 pLfoInfo->volume = pRegion->amplfo_depth;
202
203 LFOv1Unit::Trigger();
204 }
205
206 void PitchLFOUnit::Trigger() {
207 ::sfz::Region* const pRegion = pVoice->pRegion;
208 pLfoInfo->delay = pRegion->pitchlfo_delay;
209 pLfoInfo->freq = pRegion->pitchlfo_freq;
210 pLfoInfo->fade = pRegion->pitchlfo_fade;
211 pLfoInfo->pitch = pRegion->pitchlfo_depth;
212
213 LFOv1Unit::Trigger();
214 }
215
216 void FilLFOUnit::Trigger() {
217 ::sfz::Region* const pRegion = pVoice->pRegion;
218 pLfoInfo->delay = pRegion->fillfo_delay;
219 pLfoInfo->freq = pRegion->fillfo_freq;
220 pLfoInfo->fade = pRegion->fillfo_fade;
221 pLfoInfo->cutoff = pRegion->fillfo_depth;
222
223 LFOv1Unit::Trigger();
224 }
225
226 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
227 pVoice = NULL;
228 }
229
230 void CCUnit::Trigger() {
231 for (int i = 0; i < Ctrls.size(); i++) {
232 Ctrls[i].Value = pVoice->GetControllerValue(Ctrls[i].Controller);
233 }
234 CCSignalUnit::Trigger();
235 }
236
237 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
238 RemoveAllCCs();
239 for (int i = 0; i < 128; i++) {
240 if (cc[i] != 0) AddCC(i, cc[i]);
241 }
242 }
243
244 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
245 RemoveAllCCs();
246 for (int i = 0; i < cc.size(); i++) {
247 if (cc[i].Influence != 0) AddCC(cc[i].Controller, cc[i].Influence);
248 }
249 }
250
251
252 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {
253
254 }
255
256 SfzSignalUnitRack* const EndpointUnit::GetRack() {
257 return static_cast<SfzSignalUnitRack* const>(pRack);
258 }
259
260 void EndpointUnit::Trigger() {
261
262 }
263
264 bool EndpointUnit::Active() {
265 if (GetRack()->suVolEG.Active()) return true;
266
267 bool b = false;
268 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
269 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
270 }
271
272 return b;
273 }
274
275 float EndpointUnit::GetVolume() {
276 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
277
278 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
279 EGv2Unit* eg = GetRack()->volEGs[i];
280 if (!eg->Active()) continue;
281 vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);
282 }
283
284 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
285 vol *= u->Active() ? ::sf2::ToRatio((u->GetLevel() * u->pLfoInfo->volume) * 10.0) : 1;
286
287 return vol;
288 }
289
290 float EndpointUnit::GetFilterCutoff() {
291 float val;
292
293 FilLFOUnit* u = &(GetRack()->suFilLFO);
294 val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->pLfoInfo->cutoff) : 1;
295
296 FilEGUnit* u2 = &(GetRack()->suFilEG);
297 val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
298
299 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
300 LFOv2Unit* lfo = GetRack()->filLFOs[i];
301 if (!lfo->Active()) continue;
302
303 float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;
304 val *= RTMath::CentsToFreqRatioUnlimited(f);
305 }
306
307 return val;
308 }
309
310 float EndpointUnit::GetPitch() {
311 double p;
312 EGv1Unit* u = &(GetRack()->suPitchEG);
313 p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
314
315 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
316 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthCC);
317 float f = u3->Active() ? u3->GetLevel() : 0;
318 p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
319
320 for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
321 LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
322 if (!lfo->Active()) continue;
323
324 float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
325 p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
326 }
327
328 return p;
329 }
330
331 float EndpointUnit::GetResonance() {
332 float val = 0;
333
334 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
335 LFOv2Unit* lfo = GetRack()->resLFOs[i];
336 if (!lfo->Active()) continue;
337
338 val += lfo->GetLevel() * lfo->pLfoInfo->resonance;
339 }
340
341 return val;
342 }
343
344 float EndpointUnit::GetPan() {
345 float pan = 0;
346
347 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
348 LFOv2Unit* lfo = GetRack()->panLFOs[i];
349 if (!lfo->Active()) continue;
350
351 pan += lfo->GetLevel() * lfo->pLfoInfo->pan;
352 }
353
354 if(pan < -100) return -100;
355 if(pan > 100) return 100;
356
357 return pan;
358 }
359
360
361 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
362 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
363 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),
364 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
365 LFOs(maxLfoCount), pitchLFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
366 {
367 suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
368 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
369 suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
370 suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
371 suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
372
373 for (int i = 0; i < EGs.capacity(); i++) {
374 EGs[i] = new EGv2Unit(this);
375 EGs[i]->pVoice = voice;
376 }
377
378 for (int i = 0; i < LFOs.capacity(); i++) {
379 LFOs[i] = new LFOv2Unit(this);
380 LFOs[i]->pVoice = voice;
381 LFOs[i]->suFadeEG.pVoice = voice;
382 LFOs[i]->suPitchOnCC.pVoice = voice;
383 LFOs[i]->suFreqOnCC.pVoice = voice;
384 }
385 }
386
387 SfzSignalUnitRack::~SfzSignalUnitRack() {
388 for (int i = 0; i < EGs.capacity(); i++) {
389 delete EGs[i]; EGs[i] = NULL;
390 }
391
392 for (int i = 0; i < LFOs.capacity(); i++) {
393 delete LFOs[i]; LFOs[i] = NULL;
394 }
395 }
396
397 void SfzSignalUnitRack::Trigger() {
398 EGs.clear();
399 volEGs.clear();
400 pitchEGs.clear();
401
402 LFOs.clear();
403 pitchLFOs.clear();
404 filLFOs.clear();
405 resLFOs.clear();
406 panLFOs.clear();
407
408 ::sfz::Region* const pRegion = pVoice->pRegion;
409
410 for (int i = 0; i < pRegion->eg.size(); i++) {
411 if (pRegion->eg[i].node.size() == 0) continue;
412
413 if(EGs.size() < EGs.capacity()) {
414 EGv2Unit eg(this);
415 eg.pEGInfo = &(pRegion->eg[i]);
416 EGs.increment()->Copy(eg);
417 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
418
419 if (pRegion->eg[i].amplitude > 0) {
420 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
421 else std::cerr << "Maximum number of EGs reached!" << std::endl;
422 }
423 }
424
425 if (pRegion->ampeg_sustain == -1) {
426 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
427 else pRegion->ampeg_sustain = 100;
428 }
429
430 // LFO
431 for (int i = 0; i < pRegion->lfos.size(); i++) {
432 if (pRegion->lfos[i].freq == -1) continue; // Not initialized
433
434 if(LFOs.size() < LFOs.capacity()) {
435 LFOv2Unit lfo(this);
436 lfo.pLfoInfo = &(pRegion->lfos[i]);
437 LFOs.increment()->Copy(lfo);
438 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
439 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
440 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
441
442 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
443 if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
444 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
445 }
446
447 if (pRegion->lfos[i].cutoff != 0) {
448 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
449 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
450 }
451
452 if (pRegion->lfos[i].resonance != 0) {
453 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
454 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
455 }
456
457 if (pRegion->lfos[i].pan != 0) {
458 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
459 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
460 }
461 }
462
463 suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc);
464 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
465
466 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
467
468 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
469
470 Units.clear();
471
472 Units.add(&suVolEG);
473 Units.add(&suFilEG);
474 Units.add(&suPitchEG);
475
476 Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
477 Units.add(&suPitchLFO);
478 Units.add(&suPitchLFO.suDepthCC);
479 Units.add(&suPitchLFO.suFadeEG);
480
481 Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
482 Units.add(&suAmpLFO);
483 Units.add(&suAmpLFO.suFadeEG);
484
485 Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
486 Units.add(&suFilLFO);
487 Units.add(&suFilLFO.suFadeEG);
488
489 for (int i = 0; i < EGs.size(); i++) {
490 Units.add(EGs[i]);
491 }
492
493 for (int i = 0; i < LFOs.size(); i++) {
494 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
495 Units.add(LFOs[i]);
496 Units.add(&(LFOs[i]->suFadeEG));
497 Units.add(&(LFOs[i]->suPitchOnCC));
498 }
499
500 Units.add(&suEndpoint);
501
502 SignalUnitRack::Trigger();
503 }
504
505 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
506 return &suEndpoint;
507 }
508
509 void SfzSignalUnitRack::EnterFadeOutStage() {
510 suVolEG.EG.enterFadeOutStage();
511
512 for (int i = 0; i < volEGs.size(); i++) {
513 volEGs[i]->EG.enterFadeOutStage();
514 }
515 }
516
517 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC