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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2297 - (hide annotations) (download)
Fri Dec 9 15:04:55 2011 UTC (12 years, 4 months ago) by iliev
File size: 49514 byte(s)
* implemented opcodes delay, delay_onccN, delay_random,
  delay_samples, delay_samples_onccN

1 iliev 2218 /***************************************************************************
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 iliev 2244 #include "Engine.h"
25 iliev 2218
26 iliev 2244 #define _200TH_ROOT_OF_10 1.011579454259899
27    
28 iliev 2218 namespace LinuxSampler { namespace sfz {
29    
30 iliev 2244 double ToRatio(int Centibels) {
31     if (Centibels == 0) return 1.0;
32     return pow(_200TH_ROOT_OF_10, Centibels);
33     }
34    
35 iliev 2218 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
36    
37     }
38    
39     double SfzSignalUnit::GetSampleRate() {
40     return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
41     }
42    
43 iliev 2229 float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) {
44     float f = 0;
45     for (int i = 0; i < cc.size(); i++) {
46     int val = pVoice->GetControllerValue(cc[i].Controller);
47     f += (val / 127.0f) * cc[i].Influence;
48     }
49     return f;
50 iliev 2218 }
51    
52 iliev 2236 void XFInCCUnit::SetCrossFadeCCs(::sfz::Array<int>& loCCs, ::sfz::Array<int>& hiCCs) {
53     RemoveAllCCs();
54    
55     for (int cc = 0; cc < 128; cc++) {
56     if (loCCs[cc] == 0 && hiCCs[cc] == 0) continue;
57     int i = loCCs[cc];
58     int j = hiCCs[cc];
59     if (j == 0) j = 127;
60     i += j << 8; // workaround to keep both values in the Influence parameter
61     AddCC(cc, i);
62     }
63     }
64 iliev 2220
65 iliev 2236 void XFInCCUnit::Calculate() {
66     float l = 1;
67    
68 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
69     RTList<CC>::Iterator end = pCtrls->end();
70     for(; ctrl != end; ++ctrl) {
71 iliev 2236 float c = 1;
72 iliev 2244 int influence = (*ctrl).Influence;
73 iliev 2236 int lo = influence & 0xff;
74     int hi = influence >> 8;
75 iliev 2244 if ((*ctrl).Value <= lo) {
76 iliev 2236 c = 0;
77 iliev 2244 } else if ((*ctrl).Value >= hi) {
78 iliev 2236 c = 1;
79     } else {
80     float xfVelSize = hi - lo;
81 iliev 2244 float velPos = (*ctrl).Value - lo;
82 iliev 2236 c = velPos / xfVelSize;
83     if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
84     c = sin(c * M_PI / 2.0);
85     }
86     }
87    
88     l *= c;
89     }
90    
91     if (Level != l) {
92     Level = l;
93     if (pListener != NULL) pListener->ValueChanged(this);
94     }
95     }
96    
97    
98     void XFOutCCUnit::Calculate() {
99     float l = 1;
100    
101 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
102     RTList<CC>::Iterator end = pCtrls->end();
103     for(; ctrl != end; ++ctrl) {
104 iliev 2236 float c = 1;
105 iliev 2244 int influence = (*ctrl).Influence;
106 iliev 2236 int lo = influence & 0xff;
107     int hi = influence >> 8;
108 iliev 2244 if ((*ctrl).Value >= hi) {
109 iliev 2236 c = 0;
110 iliev 2244 } else if ((*ctrl).Value <= lo) {
111 iliev 2236 c = 1;
112     } else {
113     float xfVelSize = hi - lo;
114 iliev 2244 float velPos = (*ctrl).Value - lo;
115 iliev 2236 c = 1.0f - velPos / xfVelSize;
116     if (pVoice->pRegion->xf_cccurve == ::sfz::POWER) {
117     c = sin(c * M_PI / 2.0);
118     }
119     }
120    
121     l *= c;
122     }
123    
124     if (Level != l) {
125     Level = l;
126     if (pListener != NULL) pListener->ValueChanged(this);
127     }
128     }
129    
130    
131 iliev 2235 EGv2Unit::EGv2Unit(SfzSignalUnitRack* rack)
132 iliev 2237 : EGUnit< ::LinuxSampler::sfz::EG>(rack), suAmpOnCC(rack), suVolOnCC(rack),
133     suPitchOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack), suPanOnCC(rack)
134 iliev 2235 { }
135    
136 iliev 2218 void EGv2Unit::Trigger() {
137 iliev 2229 egInfo = *pEGInfo;
138     for (int i = 0; i < egInfo.node.size(); i++) {
139     float f = GetInfluence(egInfo.node[i].level_oncc);
140     egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f);
141    
142     f = GetInfluence(egInfo.node[i].time_oncc);
143     egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f);
144     }
145     EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity);
146 iliev 2218 }
147 iliev 2219
148 iliev 2220
149     void PitchEGUnit::Trigger() {
150     ::sfz::Region* const pRegion = pVoice->pRegion;
151 iliev 2249 depth = pRegion->pitcheg_depth + GetInfluence(pRegion->pitcheg_depth_oncc);
152 iliev 2220
153     // the length of the decay and release curves are dependent on the velocity
154     const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
155 iliev 2218
156 iliev 2220 // set the delay trigger
157 iliev 2249 float delay = pRegion->pitcheg_delay + pRegion->pitcheg_vel2delay * velrelease;
158     delay += GetInfluence(pRegion->pitcheg_delay_oncc);
159     uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
160 iliev 2220
161 iliev 2249 float start = (pRegion->pitcheg_start + GetInfluence(pRegion->pitcheg_start_oncc)) * 10;
162    
163     float attack = pRegion->pitcheg_attack + pRegion->pitcheg_vel2attack * velrelease;
164     attack = std::max(0.0f, attack + GetInfluence(pRegion->pitcheg_attack_oncc));
165    
166     float hold = pRegion->pitcheg_hold + pRegion->pitcheg_vel2hold * velrelease;
167     hold = std::max(0.0f, hold + GetInfluence(pRegion->pitcheg_hold_oncc));
168    
169     float decay = pRegion->pitcheg_decay + pRegion->pitcheg_vel2decay * velrelease;
170     decay = std::max(0.0f, decay + GetInfluence(pRegion->pitcheg_decay_oncc));
171    
172     float sustain = pRegion->pitcheg_sustain + pRegion->pitcheg_vel2sustain * velrelease;
173     sustain = 10 * (sustain + GetInfluence(pRegion->pitcheg_sustain_oncc));
174    
175     float release = pRegion->pitcheg_release + pRegion->pitcheg_vel2release * velrelease;
176     release = std::max(0.0f, release + GetInfluence(pRegion->pitcheg_release_oncc));
177    
178     EG.trigger (
179     uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
180     uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
181     );
182 iliev 2220 }
183    
184 iliev 2222
185     void FilEGUnit::Trigger() {
186     ::sfz::Region* const pRegion = pVoice->pRegion;
187 iliev 2249 depth = pRegion->fileg_depth + GetInfluence(pRegion->fileg_depth_oncc);
188 iliev 2222
189     // the length of the decay and release curves are dependent on the velocity
190     const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
191 iliev 2220
192 iliev 2222 // set the delay trigger
193 iliev 2249 float delay = pRegion->fileg_delay + pRegion->fileg_vel2delay * velrelease;
194     delay += GetInfluence(pRegion->fileg_delay_oncc);
195     uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
196 iliev 2222
197 iliev 2249 float start = (pRegion->fileg_start + GetInfluence(pRegion->fileg_start_oncc)) * 10;
198    
199     float attack = pRegion->fileg_attack + pRegion->fileg_vel2attack * velrelease;
200     attack = std::max(0.0f, attack + GetInfluence(pRegion->fileg_attack_oncc));
201    
202     float hold = pRegion->fileg_hold + pRegion->fileg_vel2hold * velrelease;
203     hold = std::max(0.0f, hold + GetInfluence(pRegion->fileg_hold_oncc));
204    
205     float decay = pRegion->fileg_decay + pRegion->fileg_vel2decay * velrelease;
206     decay = std::max(0.0f, decay + GetInfluence(pRegion->fileg_decay_oncc));
207    
208     float sustain = pRegion->fileg_sustain + pRegion->fileg_vel2sustain * velrelease;
209     sustain = 10 * (sustain + GetInfluence(pRegion->fileg_sustain_oncc));
210    
211     float release = pRegion->fileg_release + pRegion->fileg_vel2release * velrelease;
212     release = std::max(0.0f, release + GetInfluence(pRegion->fileg_release_oncc));
213    
214     EG.trigger (
215     uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
216     uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
217     );
218 iliev 2222 }
219    
220 iliev 2226
221 iliev 2229 void AmpEGUnit::Trigger() {
222     ::sfz::Region* const pRegion = pVoice->pRegion;
223    
224     // the length of the decay and release curves are dependent on the velocity
225     const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
226    
227     // set the delay trigger
228     float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease;
229     delay += GetInfluence(pRegion->ampeg_delaycc);
230     uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate();
231    
232     float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10;
233    
234     float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease;
235     attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc));
236    
237     float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease;
238     hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc));
239    
240     float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease;
241     decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc));
242    
243     float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease;
244     sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc));
245    
246     float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease;
247     release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc));
248    
249     EG.trigger (
250     uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay,
251     uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate()
252     );
253     }
254    
255    
256 iliev 2227 LFOUnit::LFOUnit(SfzSignalUnitRack* rack)
257     : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL),
258 iliev 2233 suFadeEG(rack), suFreqOnCC(rack, this), suDepthOnCC(rack)
259 iliev 2227 { }
260    
261     LFOUnit::LFOUnit(const LFOUnit& Unit)
262     : SfzSignalUnit(Unit), suFadeEG(static_cast<SfzSignalUnitRack*>(Unit.pRack)),
263 iliev 2233 suFreqOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack), this),
264     suDepthOnCC(static_cast<SfzSignalUnitRack*>(Unit.pRack))
265 iliev 2227 {
266 iliev 2226 Copy(Unit);
267     }
268 iliev 2222
269 iliev 2219 void LFOUnit::Increment() {
270     if (DelayStage()) return;
271    
272     SignalUnit::Increment();
273    
274 iliev 2223 Level = pLFO->Render();
275 iliev 2226 if (suFadeEG.Active()) Level *= suFadeEG.GetLevel();
276 iliev 2219 }
277    
278     void LFOUnit::Trigger() {
279     //reset
280     Level = 0;
281    
282     // set the delay trigger
283 iliev 2233 uiDelayTrigger = (pLfoInfo->delay + GetInfluence(pLfoInfo->delay_oncc)) * GetSampleRate();
284 iliev 2226 if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) {
285     float f = pLfoInfo->fade;
286 iliev 2229 f += GetInfluence(pLfoInfo->fade_oncc);
287 iliev 2226
288     if (f != 0) {
289     suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
290     suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate());
291     }
292     }
293 iliev 2219 }
294    
295 iliev 2227 void LFOUnit::ValueChanged(CCSignalUnit* pUnit) {
296 iliev 2251 if (pLFO == NULL) return;
297 iliev 2229 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
298 iliev 2227 }
299    
300    
301 iliev 2221 void LFOv1Unit::Trigger() {
302     LFOUnit::Trigger();
303    
304     lfo.trigger (
305 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
306 iliev 2221 start_level_mid,
307     1, 0, false, GetSampleRate()
308     );
309     lfo.update(0);
310     }
311    
312 iliev 2223
313     LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
314     : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
315 iliev 2225 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
316 iliev 2233 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
317 iliev 2223 {
318     lfos.add(&lfo0);
319     lfos.add(&lfo1);
320     lfos.add(&lfo2);
321     lfos.add(&lfo3);
322     lfos.add(&lfo4);
323     lfos.add(&lfo5);
324     lfos.add(&lfo6);
325     lfos.add(&lfo7);
326     }
327    
328 iliev 2219 void LFOv2Unit::Trigger() {
329     LFOUnit::Trigger();
330    
331 iliev 2223 if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
332     else pLFO = lfos[pLfoInfo->wave];
333    
334     pLFO->Trigger (
335 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
336 iliev 2219 start_level_mid,
337     1, 0, false, GetSampleRate()
338     );
339 iliev 2223 pLFO->Update(0);
340 iliev 2225
341 iliev 2229 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
342 iliev 2225 if (phase != 0) pLFO->SetPhase(phase);
343 iliev 2219 }
344 iliev 2221
345     void AmpLFOUnit::Trigger() {
346 iliev 2251 bActive = true;
347 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
348 iliev 2248 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
349 iliev 2226 pLfoInfo->freq = pRegion->amplfo_freq;
350 iliev 2248 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
351 iliev 2221 pLfoInfo->volume = pRegion->amplfo_depth;
352    
353 iliev 2251 if (pLfoInfo->freq <= 0) {
354     if (!pRegion->amplfo_freqcc.empty()) pLfoInfo->freq = 0;
355     else bActive = false;
356     }
357    
358 iliev 2221 LFOv1Unit::Trigger();
359     }
360    
361     void PitchLFOUnit::Trigger() {
362 iliev 2251 bActive = true;
363 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
364 iliev 2248 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
365 iliev 2226 pLfoInfo->freq = pRegion->pitchlfo_freq;
366 iliev 2248 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
367 iliev 2221 pLfoInfo->pitch = pRegion->pitchlfo_depth;
368    
369 iliev 2251 if (pLfoInfo->freq <= 0) {
370     if (!pRegion->pitchlfo_freqcc.empty()) pLfoInfo->freq = 0;
371     else bActive = false;
372     }
373    
374 iliev 2221 LFOv1Unit::Trigger();
375     }
376    
377     void FilLFOUnit::Trigger() {
378 iliev 2251 bActive = true;
379 iliev 2221 ::sfz::Region* const pRegion = pVoice->pRegion;
380 iliev 2248 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
381 iliev 2226 pLfoInfo->freq = pRegion->fillfo_freq;
382 iliev 2248 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
383 iliev 2221 pLfoInfo->cutoff = pRegion->fillfo_depth;
384    
385 iliev 2251 if (pLfoInfo->freq <= 0) {
386     if (!pRegion->fillfo_freqcc.empty()) pLfoInfo->freq = 0;
387     else bActive = false;
388     }
389    
390 iliev 2221 LFOv1Unit::Trigger();
391     }
392 iliev 2224
393 iliev 2227 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
394     pVoice = NULL;
395     }
396 iliev 2224
397     void CCUnit::Trigger() {
398 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
399     RTList<CC>::Iterator end = pCtrls->end();
400     for(; ctrl != end; ++ctrl) {
401     (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
402 iliev 2264 if ((*ctrl).pSmoother != NULL) {
403     if ((*ctrl).Step > 0) {
404     float val = Normalize((*ctrl).Value, (*ctrl).Curve) * (*ctrl).Influence;
405     (*ctrl).pSmoother->setValue( ((int) (val / (*ctrl).Step)) * (*ctrl).Step );
406     } else {
407     (*ctrl).pSmoother->setValue((*ctrl).Value);
408     }
409     }
410 iliev 2224 }
411     CCSignalUnit::Trigger();
412     }
413    
414 iliev 2244 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
415     RemoveAllCCs();
416     for (int i = 0; i < 128; i++) {
417     if (cc[i] != 0) AddCC(i, cc[i]);
418     }
419     }
420 iliev 2225
421 iliev 2296 void CCUnit::SetCCs(::sfz::Array<float>& cc) {
422     RemoveAllCCs();
423     for (int i = 0; i < 128; i++) {
424     if (cc[i] != 0) AddCC(i, cc[i]);
425     }
426     }
427    
428 iliev 2244 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
429     RemoveAllCCs();
430     for (int i = 0; i < cc.size(); i++) {
431     if (cc[i].Influence != 0) {
432     short int curve = cc[i].Curve;
433     if (curve >= GetCurveCount()) curve = -1;
434 iliev 2264 AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth, cc[i].Step);
435 iliev 2244 }
436     }
437     }
438 iliev 2230
439 iliev 2264 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
440     AddCC(Controller, Influence, Curve, NULL, Step);
441 iliev 2244 }
442 iliev 2232
443 iliev 2244 int CCUnit::GetCurveCount() {
444     return pVoice->pRegion->GetInstrument()->curves.size();
445     }
446 iliev 2230
447 iliev 2244 ::sfz::Curve* CCUnit::GetCurve(int idx) {
448     return &pVoice->pRegion->GetInstrument()->curves[idx];
449     }
450 iliev 2232
451 iliev 2244 double CCUnit::GetSampleRate() {
452 iliev 2232 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
453     }
454 iliev 2244
455    
456     SmoothCCUnit::~SmoothCCUnit() {
457     if (pSmoothers != NULL) delete pSmoothers;
458     }
459 iliev 2232
460 iliev 2264 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth, float Step) {
461 iliev 2244 if (Smooth > 0) {
462     if (pSmoothers->poolIsEmpty()) {
463     std::cerr << "Maximum number of smoothers reached" << std::endl;
464     return;
465     }
466     Smoother* smoother = &(*(pSmoothers->allocAppend()));
467     smoother->trigger(Smooth / 1000.0f, GetSampleRate());
468 iliev 2264 AddCC(Controller, Influence, Curve, smoother, Step);
469 iliev 2244 } else {
470 iliev 2264 AddCC(Controller, Influence, Curve, NULL, Step);
471 iliev 2244 }
472     }
473    
474     void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
475     if (pSmoothers != NULL) delete pSmoothers;
476     pSmoothers = new RTList<Smoother>(pSmootherPool);
477     }
478    
479     void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
480     CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
481     InitSmoothers(pSmootherPool);
482     }
483 iliev 2218
484 iliev 2219
485 iliev 2237 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
486     : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
487     {
488 iliev 2218
489     }
490    
491 iliev 2297 float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<float> >& cc) {
492     float f = 0;
493     for (int i = 0; i < 128; i++) {
494     if (cc[i]) {
495     f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
496     }
497     }
498     return f;
499     }
500    
501     float EndpointUnit::GetInfluence(::sfz::Array< ::sfz::optional<int> >& cc) {
502     float f = 0;
503     for (int i = 0; i < 128; i++) {
504     if (cc[i]) {
505     f += (pVoice->GetControllerValue(i) / 127.0f) * (*cc[i]);
506     }
507     }
508     return f;
509     }
510    
511 iliev 2218 SfzSignalUnitRack* const EndpointUnit::GetRack() {
512     return static_cast<SfzSignalUnitRack* const>(pRack);
513     }
514    
515     void EndpointUnit::Trigger() {
516 iliev 2297 uiDelayTrigger = (uint)GetInfluence(pVoice->pRegion->delay_samples_oncc);
517     if (pVoice->pRegion->delay_samples) uiDelayTrigger += *pVoice->pRegion->delay_samples;
518    
519     if (pVoice->pRegion->delay) {
520     /* here we use the device sample rate */
521     uiDelayTrigger += (uint)( (*pVoice->pRegion->delay) * pVoice->GetSampleRate() );
522     }
523    
524     if (pVoice->pRegion->delay_random) {
525     float r = pVoice->GetEngine()->Random();
526     uiDelayTrigger += (uint)( r * (*pVoice->pRegion->delay_random) * pVoice->GetSampleRate() );
527     }
528    
529     uiDelayTrigger += (uint)(GetInfluence(pVoice->pRegion->delay_oncc) * pVoice->GetSampleRate());
530    
531 iliev 2236 float xfInVelCoeff = 1;
532 iliev 2218
533 iliev 2236 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
534     xfInVelCoeff = 0;
535     } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
536     xfInVelCoeff = 1;
537     } else {
538     float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
539     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
540     xfInVelCoeff = velPos / xfVelSize;
541     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
542     xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
543     }
544     }
545    
546     float xfOutVelCoeff = 1;
547    
548     if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
549     if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
550     } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
551     xfOutVelCoeff = 1;
552     } else {
553     float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
554     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
555     xfOutVelCoeff = 1.0f - velPos / xfVelSize;
556     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
557     xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
558     }
559     }
560    
561     float xfInKeyCoeff = 1;
562    
563     if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
564     if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
565     } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
566     xfInKeyCoeff = 1;
567     } else {
568     float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
569     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
570     xfInKeyCoeff = keyPos / xfKeySize;
571     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
572     xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
573     }
574     }
575    
576     float xfOutKeyCoeff = 1;
577    
578     if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
579     if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
580     } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
581     xfOutKeyCoeff = 1;
582     } else {
583     float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
584     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
585     xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
586     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
587     xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
588     }
589     }
590    
591     xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
592    
593     suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
594     suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
595 iliev 2237
596     suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
597    
598     pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
599 iliev 2218 }
600    
601     bool EndpointUnit::Active() {
602 iliev 2297 if (pRack->isReleaseStageEntered() && uiDelayTrigger) {
603     return false; // The key was released before the delay end, so the voice won't play at all.
604     }
605    
606 iliev 2218 if (GetRack()->suVolEG.Active()) return true;
607    
608     bool b = false;
609     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
610     if (GetRack()->volEGs[i]->Active()) { b = true; break; }
611     }
612    
613     return b;
614     }
615    
616     float EndpointUnit::GetVolume() {
617     float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
618    
619     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
620     EGv2Unit* eg = GetRack()->volEGs[i];
621     if (!eg->Active()) continue;
622 iliev 2229
623 iliev 2235 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
624     if (dB < -144) dB = eg->pEGInfo->volume;
625     else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
626    
627     float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
628     amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
629    
630     if (dB >= -144) {
631     if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
632 iliev 2244 amp *= ToRatio(dB * 10.0);
633 iliev 2235 }
634    
635     vol += amp * eg->GetLevel();
636 iliev 2218 }
637    
638 iliev 2221 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
639 iliev 2233 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
640     float f = u2->Active() ? u2->GetLevel() : 0;
641 iliev 2244 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
642 iliev 2221
643 iliev 2244 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
644 iliev 2230
645 iliev 2233 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
646     LFOv2Unit* lfo = GetRack()->volLFOs[i];
647     if (!lfo->Active()) continue;
648    
649     float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
650 iliev 2244 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
651 iliev 2233 }
652    
653 iliev 2236 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
654     if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
655     return vol * xfCoeff;
656 iliev 2218 }
657    
658     float EndpointUnit::GetFilterCutoff() {
659 iliev 2252 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
660 iliev 2219
661 iliev 2221 FilLFOUnit* u = &(GetRack()->suFilLFO);
662 iliev 2233 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
663     float f = u1->Active() ? u1->GetLevel() : 0;
664 iliev 2252 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
665 iliev 2221
666 iliev 2222 FilEGUnit* u2 = &(GetRack()->suFilEG);
667     val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
668    
669 iliev 2235 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
670     EGv2Unit* eg = GetRack()->filEGs[i];
671     if (!eg->Active()) continue;
672    
673     float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
674     f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
675     val *= RTMath::CentsToFreqRatioUnlimited(f);
676     }
677    
678 iliev 2219 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
679     LFOv2Unit* lfo = GetRack()->filLFOs[i];
680     if (!lfo->Active()) continue;
681    
682 iliev 2233 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
683     f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
684 iliev 2219 val *= RTMath::CentsToFreqRatioUnlimited(f);
685     }
686    
687     return val;
688 iliev 2218 }
689    
690 iliev 2235 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
691 iliev 2252 cutoff *= GetFilterCutoff();
692     float maxCutoff = 0.49 * pVoice->GetSampleRate();
693     return cutoff > maxCutoff ? maxCutoff : cutoff;
694 iliev 2235 }
695    
696 iliev 2218 float EndpointUnit::GetPitch() {
697 iliev 2264 double p = GetRack()->suPitchOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suPitchOnCC.GetLevel()) : 1;
698    
699 iliev 2220 EGv1Unit* u = &(GetRack()->suPitchEG);
700 iliev 2264 p *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
701 iliev 2221
702 iliev 2235 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
703     EGv2Unit* eg = GetRack()->pitchEGs[i];
704     if (!eg->Active()) continue;
705    
706     float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
707     p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
708     }
709    
710 iliev 2221 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
711 iliev 2233 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
712 iliev 2224 float f = u3->Active() ? u3->GetLevel() : 0;
713     p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
714 iliev 2225
715     for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
716     LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
717     if (!lfo->Active()) continue;
718    
719     float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
720     p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
721     }
722    
723 iliev 2237 return p * pitchVeltrackRatio;
724 iliev 2218 }
725    
726     float EndpointUnit::GetResonance() {
727 iliev 2252 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
728 iliev 2219
729 iliev 2235 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
730     EGv2Unit* eg = GetRack()->resEGs[i];
731     if (!eg->Active()) continue;
732    
733     float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
734     val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
735     }
736    
737 iliev 2219 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
738     LFOv2Unit* lfo = GetRack()->resLFOs[i];
739     if (!lfo->Active()) continue;
740    
741 iliev 2233 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
742     val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
743 iliev 2219 }
744    
745     return val;
746 iliev 2218 }
747    
748 iliev 2219 float EndpointUnit::GetPan() {
749 iliev 2237 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
750 iliev 2219
751 iliev 2237 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
752     EGv2Unit* eg = GetRack()->panEGs[i];
753     if (!eg->Active()) continue;
754    
755     float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
756    
757     if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
758     uint8_t val = eg->GetLevel() * 127;
759     if (val > 127) val = 127;
760     pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
761     } else {
762     pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
763     }
764     }
765    
766 iliev 2219 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
767     LFOv2Unit* lfo = GetRack()->panLFOs[i];
768     if (!lfo->Active()) continue;
769    
770 iliev 2233 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
771     pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
772 iliev 2219 }
773    
774     if(pan < -100) return -100;
775     if(pan > 100) return 100;
776    
777     return pan;
778     }
779 iliev 2218
780 iliev 2219
781 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
782 iliev 2222 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
783 iliev 2252 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
784 iliev 2296 suEq1GainOnCC(this), suEq2GainOnCC(this), suEq3GainOnCC(this),
785     suEq1FreqOnCC(this), suEq2FreqOnCC(this), suEq3FreqOnCC(this),
786     suEq1BwOnCC(this), suEq2BwOnCC(this), suEq3BwOnCC(this),
787 iliev 2264 suVolOnCC(this), suPitchOnCC(this), suCutoffOnCC(this), suResOnCC(this),
788 iliev 2221 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
789 iliev 2233 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
790     filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
791 iliev 2218 {
792 iliev 2237 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
793 iliev 2236 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
794 iliev 2264 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice;
795 iliev 2296
796     suEq1GainOnCC.pVoice = suEq2GainOnCC.pVoice = suEq3GainOnCC.pVoice = voice;
797     suEq1FreqOnCC.pVoice = suEq2FreqOnCC.pVoice = suEq3FreqOnCC.pVoice = voice;
798     suEq1BwOnCC.pVoice = suEq2BwOnCC.pVoice = suEq3BwOnCC.pVoice = voice;
799    
800 iliev 2264 suVolOnCC.pVoice = suPitchOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
801 iliev 2233 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
802     suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
803     suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
804 iliev 2218
805     for (int i = 0; i < EGs.capacity(); i++) {
806     EGs[i] = new EGv2Unit(this);
807     EGs[i]->pVoice = voice;
808 iliev 2235 EGs[i]->suAmpOnCC.pVoice = voice;
809     EGs[i]->suVolOnCC.pVoice = voice;
810     EGs[i]->suPitchOnCC.pVoice = voice;
811     EGs[i]->suCutoffOnCC.pVoice = voice;
812     EGs[i]->suResOnCC.pVoice = voice;
813 iliev 2237 EGs[i]->suPanOnCC.pVoice = voice;
814 iliev 2218 }
815 iliev 2219
816     for (int i = 0; i < LFOs.capacity(); i++) {
817     LFOs[i] = new LFOv2Unit(this);
818     LFOs[i]->pVoice = voice;
819 iliev 2244 LFOs[i]->suDepthOnCC.pVoice = voice;
820     LFOs[i]->suFreqOnCC.pVoice = voice;
821 iliev 2226 LFOs[i]->suFadeEG.pVoice = voice;
822 iliev 2233 LFOs[i]->suVolOnCC.pVoice = voice;
823 iliev 2225 LFOs[i]->suPitchOnCC.pVoice = voice;
824 iliev 2227 LFOs[i]->suFreqOnCC.pVoice = voice;
825 iliev 2233 LFOs[i]->suPanOnCC.pVoice = voice;
826     LFOs[i]->suCutoffOnCC.pVoice = voice;
827     LFOs[i]->suResOnCC.pVoice = voice;
828 iliev 2219 }
829 iliev 2218 }
830    
831     SfzSignalUnitRack::~SfzSignalUnitRack() {
832 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
833 iliev 2218 delete EGs[i]; EGs[i] = NULL;
834     }
835 iliev 2219
836     for (int i = 0; i < LFOs.capacity(); i++) {
837     delete LFOs[i]; LFOs[i] = NULL;
838     }
839 iliev 2218 }
840    
841 iliev 2244 void SfzSignalUnitRack::InitRTLists() {
842     Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
843     Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
844    
845 iliev 2296 suEq1GainOnCC.InitCCList(pCCPool, pSmootherPool);
846     suEq2GainOnCC.InitCCList(pCCPool, pSmootherPool);
847     suEq3GainOnCC.InitCCList(pCCPool, pSmootherPool);
848     suEq1FreqOnCC.InitCCList(pCCPool, pSmootherPool);
849     suEq2FreqOnCC.InitCCList(pCCPool, pSmootherPool);
850     suEq3FreqOnCC.InitCCList(pCCPool, pSmootherPool);
851     suEq1BwOnCC.InitCCList(pCCPool, pSmootherPool);
852     suEq2BwOnCC.InitCCList(pCCPool, pSmootherPool);
853     suEq3BwOnCC.InitCCList(pCCPool, pSmootherPool);
854    
855 iliev 2244 suVolOnCC.InitCCList(pCCPool, pSmootherPool);
856 iliev 2264 suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
857 iliev 2252 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
858     suResOnCC.InitCCList(pCCPool, pSmootherPool);
859 iliev 2244 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
860     suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
861     suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
862     suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
863     suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
864     suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
865     suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
866     suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
867     suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
868    
869     for (int i = 0; i < EGs.capacity(); i++) {
870     EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
871     EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
872     EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
873     EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
874     EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
875     EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
876     }
877    
878     for (int i = 0; i < LFOs.capacity(); i++) {
879     LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
880     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
881     LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
882     LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
883     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
884     LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
885     LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
886     LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
887     }
888     }
889    
890 iliev 2218 void SfzSignalUnitRack::Trigger() {
891     EGs.clear();
892     volEGs.clear();
893     pitchEGs.clear();
894 iliev 2235 filEGs.clear();
895     resEGs.clear();
896 iliev 2237 panEGs.clear();
897 iliev 2218
898 iliev 2219 LFOs.clear();
899 iliev 2233 volLFOs.clear();
900 iliev 2225 pitchLFOs.clear();
901 iliev 2219 filLFOs.clear();
902     resLFOs.clear();
903     panLFOs.clear();
904    
905 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
906    
907 iliev 2296 suEq1GainOnCC.SetCCs(pRegion->eq1_gain_oncc);
908     suEq2GainOnCC.SetCCs(pRegion->eq2_gain_oncc);
909     suEq3GainOnCC.SetCCs(pRegion->eq3_gain_oncc);
910     suEq1FreqOnCC.SetCCs(pRegion->eq1_freq_oncc);
911     suEq2FreqOnCC.SetCCs(pRegion->eq2_freq_oncc);
912     suEq3FreqOnCC.SetCCs(pRegion->eq3_freq_oncc);
913     suEq1BwOnCC.SetCCs(pRegion->eq1_bw_oncc);
914     suEq2BwOnCC.SetCCs(pRegion->eq2_bw_oncc);
915     suEq3BwOnCC.SetCCs(pRegion->eq3_bw_oncc);
916    
917     bHasEq = pRegion->eq1_gain || pRegion->eq2_gain || pRegion->eq3_gain ||
918     suEq1GainOnCC.HasCCs() || suEq2GainOnCC.HasCCs() || suEq3GainOnCC.HasCCs();
919    
920 iliev 2230 suVolOnCC.SetCCs(pRegion->volume_oncc);
921 iliev 2264 suPitchOnCC.SetCCs(pRegion->pitch_oncc);
922 iliev 2252 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
923     suResOnCC.SetCCs(pRegion->resonance_oncc);
924 iliev 2230
925 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
926 iliev 2218 if (pRegion->eg[i].node.size() == 0) continue;
927    
928     if(EGs.size() < EGs.capacity()) {
929     EGv2Unit eg(this);
930     eg.pEGInfo = &(pRegion->eg[i]);
931     EGs.increment()->Copy(eg);
932 iliev 2235 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
933     EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
934     EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
935     EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
936     EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
937 iliev 2237 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
938 iliev 2218 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
939    
940 iliev 2235 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
941     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
942     ) {
943 iliev 2218 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
944     else std::cerr << "Maximum number of EGs reached!" << std::endl;
945     }
946 iliev 2235
947     if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
948     if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
949     else std::cerr << "Maximum number of EGs reached!" << std::endl;
950     }
951    
952     if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
953     if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
954     else std::cerr << "Maximum number of EGs reached!" << std::endl;
955     }
956    
957     if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
958     if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
959     else std::cerr << "Maximum number of EGs reached!" << std::endl;
960     }
961 iliev 2237
962     if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
963     if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
964     else std::cerr << "Maximum number of EGs reached!" << std::endl;
965     }
966 iliev 2218 }
967    
968     if (pRegion->ampeg_sustain == -1) {
969     if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
970     else pRegion->ampeg_sustain = 100;
971     }
972    
973 iliev 2219 // LFO
974     for (int i = 0; i < pRegion->lfos.size(); i++) {
975 iliev 2251 if (pRegion->lfos[i].freq <= 0) {
976     if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
977     else pRegion->lfos[i].freq = 0;
978     }
979 iliev 2219
980     if(LFOs.size() < LFOs.capacity()) {
981     LFOv2Unit lfo(this);
982     lfo.pLfoInfo = &(pRegion->lfos[i]);
983     LFOs.increment()->Copy(lfo);
984 iliev 2233 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
985 iliev 2225 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
986 iliev 2227 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
987 iliev 2233 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
988     LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
989     LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
990 iliev 2219 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
991    
992 iliev 2233 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
993     if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
994     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
995     }
996    
997 iliev 2225 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
998     if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
999     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1000     }
1001    
1002 iliev 2233 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
1003 iliev 2219 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
1004     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1005     }
1006    
1007 iliev 2233 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
1008 iliev 2219 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
1009     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1010     }
1011    
1012 iliev 2233 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
1013 iliev 2219 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
1014     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
1015     }
1016     }
1017    
1018 iliev 2233 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
1019 iliev 2227 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
1020 iliev 2224
1021 iliev 2233 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
1022 iliev 2227 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
1023    
1024 iliev 2233 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
1025 iliev 2227 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
1026    
1027 iliev 2218 Units.clear();
1028    
1029 iliev 2296 Units.add(&suEq1GainOnCC);
1030     Units.add(&suEq2GainOnCC);
1031     Units.add(&suEq3GainOnCC);
1032     Units.add(&suEq1FreqOnCC);
1033     Units.add(&suEq2FreqOnCC);
1034     Units.add(&suEq3FreqOnCC);
1035     Units.add(&suEq1BwOnCC);
1036     Units.add(&suEq2BwOnCC);
1037     Units.add(&suEq3BwOnCC);
1038    
1039 iliev 2230 Units.add(&suVolOnCC);
1040 iliev 2264 Units.add(&suPitchOnCC);
1041 iliev 2252 Units.add(&suCutoffOnCC);
1042     Units.add(&suResOnCC);
1043 iliev 2230
1044 iliev 2218 Units.add(&suVolEG);
1045 iliev 2222 Units.add(&suFilEG);
1046 iliev 2220 Units.add(&suPitchEG);
1047 iliev 2227
1048     Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1049 iliev 2221 Units.add(&suPitchLFO);
1050 iliev 2233 Units.add(&suPitchLFO.suDepthOnCC);
1051 iliev 2226 Units.add(&suPitchLFO.suFadeEG);
1052 iliev 2227
1053     Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1054 iliev 2233 Units.add(&suAmpLFO.suDepthOnCC);
1055 iliev 2221 Units.add(&suAmpLFO);
1056 iliev 2226 Units.add(&suAmpLFO.suFadeEG);
1057 iliev 2227
1058     Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
1059 iliev 2233 Units.add(&suFilLFO.suDepthOnCC);
1060 iliev 2221 Units.add(&suFilLFO);
1061 iliev 2226 Units.add(&suFilLFO.suFadeEG);
1062 iliev 2218
1063 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
1064 iliev 2218 Units.add(EGs[i]);
1065 iliev 2235 Units.add(&(EGs[i]->suAmpOnCC));
1066     Units.add(&(EGs[i]->suVolOnCC));
1067     Units.add(&(EGs[i]->suPitchOnCC));
1068     Units.add(&(EGs[i]->suCutoffOnCC));
1069     Units.add(&(EGs[i]->suResOnCC));
1070 iliev 2237 Units.add(&(EGs[i]->suPanOnCC));
1071 iliev 2218 }
1072    
1073 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
1074 iliev 2227 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
1075 iliev 2219 Units.add(LFOs[i]);
1076 iliev 2226 Units.add(&(LFOs[i]->suFadeEG));
1077 iliev 2233 Units.add(&(LFOs[i]->suVolOnCC));
1078 iliev 2225 Units.add(&(LFOs[i]->suPitchOnCC));
1079 iliev 2233 Units.add(&(LFOs[i]->suPanOnCC));
1080     Units.add(&(LFOs[i]->suCutoffOnCC));
1081     Units.add(&(LFOs[i]->suResOnCC));
1082 iliev 2219 }
1083    
1084 iliev 2218 Units.add(&suEndpoint);
1085 iliev 2236 Units.add(&suEndpoint.suXFInCC);
1086     Units.add(&suEndpoint.suXFOutCC);
1087 iliev 2237 Units.add(&suEndpoint.suPanOnCC);
1088 iliev 2218
1089     SignalUnitRack::Trigger();
1090     }
1091    
1092     EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
1093     return &suEndpoint;
1094     }
1095    
1096     void SfzSignalUnitRack::EnterFadeOutStage() {
1097     suVolEG.EG.enterFadeOutStage();
1098    
1099     for (int i = 0; i < volEGs.size(); i++) {
1100     volEGs[i]->EG.enterFadeOutStage();
1101     }
1102     }
1103    
1104 iliev 2244 void SfzSignalUnitRack::Reset() {
1105 iliev 2296 suEq1GainOnCC.RemoveAllCCs();
1106     suEq2GainOnCC.RemoveAllCCs();
1107     suEq3GainOnCC.RemoveAllCCs();
1108     suEq1FreqOnCC.RemoveAllCCs();
1109     suEq2FreqOnCC.RemoveAllCCs();
1110     suEq3FreqOnCC.RemoveAllCCs();
1111     suEq1BwOnCC.RemoveAllCCs();
1112     suEq2BwOnCC.RemoveAllCCs();
1113     suEq3BwOnCC.RemoveAllCCs();
1114    
1115 iliev 2244 suVolOnCC.RemoveAllCCs();
1116 iliev 2264 suPitchOnCC.RemoveAllCCs();
1117 iliev 2252 suCutoffOnCC.RemoveAllCCs();
1118     suResOnCC.RemoveAllCCs();
1119 iliev 2244 suEndpoint.suXFInCC.RemoveAllCCs();
1120     suEndpoint.suXFOutCC.RemoveAllCCs();
1121     suEndpoint.suPanOnCC.RemoveAllCCs();
1122     suPitchLFO.suDepthOnCC.RemoveAllCCs();
1123     suPitchLFO.suFreqOnCC.RemoveAllCCs();
1124     suFilLFO.suDepthOnCC.RemoveAllCCs();
1125     suFilLFO.suFreqOnCC.RemoveAllCCs();
1126     suAmpLFO.suDepthOnCC.RemoveAllCCs();
1127     suAmpLFO.suFreqOnCC.RemoveAllCCs();
1128    
1129     for (int i = 0; i < EGs.capacity(); i++) {
1130     EGs[i]->suAmpOnCC.RemoveAllCCs();
1131     EGs[i]->suVolOnCC.RemoveAllCCs();
1132     EGs[i]->suPitchOnCC.RemoveAllCCs();
1133     EGs[i]->suCutoffOnCC.RemoveAllCCs();
1134     EGs[i]->suResOnCC.RemoveAllCCs();
1135     EGs[i]->suPanOnCC.RemoveAllCCs();
1136     }
1137    
1138     for (int i = 0; i < LFOs.capacity(); i++) {
1139     LFOs[i]->suDepthOnCC.RemoveAllCCs();
1140     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1141     LFOs[i]->suVolOnCC.RemoveAllCCs();
1142     LFOs[i]->suPitchOnCC.RemoveAllCCs();
1143     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1144     LFOs[i]->suPanOnCC.RemoveAllCCs();
1145     LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1146     LFOs[i]->suResOnCC.RemoveAllCCs();
1147     }
1148     }
1149    
1150 iliev 2296 void SfzSignalUnitRack::UpdateEqSettings(EqSupport* pEqSupport) {
1151     if (!pEqSupport->HasSupport()) return;
1152     if (pEqSupport->GetBandCount() < 3) {
1153     std::cerr << "SfzSignalUnitRack::UpdateEqSettings: EQ should have at least 3 bands\n";
1154     return;
1155     }
1156    
1157     ::sfz::Region* const pRegion = pVoice->pRegion;
1158    
1159     float dB = (suEq1GainOnCC.Active() ? suEq1GainOnCC.GetLevel() : 0) + pRegion->eq1_gain;
1160     pEqSupport->SetGain(0, dB);
1161    
1162     dB = (suEq2GainOnCC.Active() ? suEq2GainOnCC.GetLevel() : 0) + pRegion->eq2_gain;
1163     pEqSupport->SetGain(1, dB);
1164    
1165     dB = (suEq3GainOnCC.Active() ? suEq3GainOnCC.GetLevel() : 0) + pRegion->eq3_gain;
1166     pEqSupport->SetGain(2, dB);
1167    
1168     float freq = (suEq1FreqOnCC.Active() ? suEq1FreqOnCC.GetLevel() : 0) + pRegion->eq1_freq;
1169     pEqSupport->SetFreq(0, freq);
1170    
1171     freq = (suEq2FreqOnCC.Active() ? suEq2FreqOnCC.GetLevel() : 0) + pRegion->eq2_freq;
1172     pEqSupport->SetFreq(1, freq);
1173    
1174     freq = (suEq3FreqOnCC.Active() ? suEq3FreqOnCC.GetLevel() : 0) + pRegion->eq3_freq;
1175     pEqSupport->SetFreq(2, freq);
1176    
1177     float bw = (suEq1BwOnCC.Active() ? suEq1BwOnCC.GetLevel() : 0) + pRegion->eq1_bw;
1178     pEqSupport->SetBandwidth(0, bw);
1179    
1180     bw = (suEq2BwOnCC.Active() ? suEq2BwOnCC.GetLevel() : 0) + pRegion->eq2_bw;
1181     pEqSupport->SetBandwidth(1, bw);
1182    
1183     bw = (suEq3BwOnCC.Active() ? suEq3BwOnCC.GetLevel() : 0) + pRegion->eq3_bw;
1184     pEqSupport->SetBandwidth(2, bw);
1185     }
1186    
1187 iliev 2218 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC