/[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 2252 - (hide annotations) (download)
Sat Aug 20 14:01:36 2011 UTC (12 years, 8 months ago) by iliev
File size: 43178 byte(s)
* sfz engine: implemented opcodes resonance_onccN, resonance_smoothccN,
  resonance_curveccN, cutoff_smoothccN, cutoff_curveccN

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     if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);
403 iliev 2224 }
404     CCSignalUnit::Trigger();
405     }
406    
407 iliev 2244 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
408     RemoveAllCCs();
409     for (int i = 0; i < 128; i++) {
410     if (cc[i] != 0) AddCC(i, cc[i]);
411     }
412     }
413 iliev 2225
414 iliev 2244 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
415     RemoveAllCCs();
416     for (int i = 0; i < cc.size(); i++) {
417     if (cc[i].Influence != 0) {
418     short int curve = cc[i].Curve;
419     if (curve >= GetCurveCount()) curve = -1;
420     AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
421     }
422     }
423     }
424 iliev 2230
425 iliev 2244 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
426     AddCC(Controller, Influence, Curve);
427     }
428 iliev 2232
429 iliev 2244 int CCUnit::GetCurveCount() {
430     return pVoice->pRegion->GetInstrument()->curves.size();
431     }
432 iliev 2230
433 iliev 2244 ::sfz::Curve* CCUnit::GetCurve(int idx) {
434     return &pVoice->pRegion->GetInstrument()->curves[idx];
435     }
436 iliev 2232
437 iliev 2244 double CCUnit::GetSampleRate() {
438 iliev 2232 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
439     }
440 iliev 2244
441    
442     SmoothCCUnit::~SmoothCCUnit() {
443     if (pSmoothers != NULL) delete pSmoothers;
444     }
445 iliev 2232
446 iliev 2244 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
447     if (Smooth > 0) {
448     if (pSmoothers->poolIsEmpty()) {
449     std::cerr << "Maximum number of smoothers reached" << std::endl;
450     return;
451     }
452     Smoother* smoother = &(*(pSmoothers->allocAppend()));
453     smoother->trigger(Smooth / 1000.0f, GetSampleRate());
454     AddCC(Controller, Influence, Curve, smoother);
455     } else {
456     AddCC(Controller, Influence, Curve);
457     }
458     }
459    
460     void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
461     if (pSmoothers != NULL) delete pSmoothers;
462     pSmoothers = new RTList<Smoother>(pSmootherPool);
463     }
464    
465     void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
466     CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
467     InitSmoothers(pSmootherPool);
468     }
469 iliev 2218
470 iliev 2219
471 iliev 2237 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
472     : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
473     {
474 iliev 2218
475     }
476    
477     SfzSignalUnitRack* const EndpointUnit::GetRack() {
478     return static_cast<SfzSignalUnitRack* const>(pRack);
479     }
480    
481     void EndpointUnit::Trigger() {
482 iliev 2236 float xfInVelCoeff = 1;
483 iliev 2218
484 iliev 2236 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
485     xfInVelCoeff = 0;
486     } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
487     xfInVelCoeff = 1;
488     } else {
489     float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
490     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
491     xfInVelCoeff = velPos / xfVelSize;
492     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
493     xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
494     }
495     }
496    
497     float xfOutVelCoeff = 1;
498    
499     if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
500     if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
501     } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
502     xfOutVelCoeff = 1;
503     } else {
504     float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
505     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
506     xfOutVelCoeff = 1.0f - velPos / xfVelSize;
507     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
508     xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
509     }
510     }
511    
512     float xfInKeyCoeff = 1;
513    
514     if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
515     if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
516     } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
517     xfInKeyCoeff = 1;
518     } else {
519     float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
520     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
521     xfInKeyCoeff = keyPos / xfKeySize;
522     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
523     xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
524     }
525     }
526    
527     float xfOutKeyCoeff = 1;
528    
529     if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
530     if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
531     } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
532     xfOutKeyCoeff = 1;
533     } else {
534     float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
535     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
536     xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
537     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
538     xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
539     }
540     }
541    
542     xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
543    
544     suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
545     suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
546 iliev 2237
547     suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
548    
549     pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
550 iliev 2218 }
551    
552     bool EndpointUnit::Active() {
553     if (GetRack()->suVolEG.Active()) return true;
554    
555     bool b = false;
556     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
557     if (GetRack()->volEGs[i]->Active()) { b = true; break; }
558     }
559    
560     return b;
561     }
562    
563     float EndpointUnit::GetVolume() {
564     float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
565    
566     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
567     EGv2Unit* eg = GetRack()->volEGs[i];
568     if (!eg->Active()) continue;
569 iliev 2229
570 iliev 2235 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
571     if (dB < -144) dB = eg->pEGInfo->volume;
572     else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
573    
574     float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
575     amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
576    
577     if (dB >= -144) {
578     if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
579 iliev 2244 amp *= ToRatio(dB * 10.0);
580 iliev 2235 }
581    
582     vol += amp * eg->GetLevel();
583 iliev 2218 }
584    
585 iliev 2221 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
586 iliev 2233 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
587     float f = u2->Active() ? u2->GetLevel() : 0;
588 iliev 2244 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
589 iliev 2221
590 iliev 2244 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
591 iliev 2230
592 iliev 2233 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
593     LFOv2Unit* lfo = GetRack()->volLFOs[i];
594     if (!lfo->Active()) continue;
595    
596     float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
597 iliev 2244 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
598 iliev 2233 }
599    
600 iliev 2236 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
601     if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
602     return vol * xfCoeff;
603 iliev 2218 }
604    
605     float EndpointUnit::GetFilterCutoff() {
606 iliev 2252 float val = GetRack()->suCutoffOnCC.Active() ? RTMath::CentsToFreqRatioUnlimited(GetRack()->suCutoffOnCC.GetLevel()) : 1;
607 iliev 2219
608 iliev 2221 FilLFOUnit* u = &(GetRack()->suFilLFO);
609 iliev 2233 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
610     float f = u1->Active() ? u1->GetLevel() : 0;
611 iliev 2252 val *= u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
612 iliev 2221
613 iliev 2222 FilEGUnit* u2 = &(GetRack()->suFilEG);
614     val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
615    
616 iliev 2235 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
617     EGv2Unit* eg = GetRack()->filEGs[i];
618     if (!eg->Active()) continue;
619    
620     float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
621     f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
622     val *= RTMath::CentsToFreqRatioUnlimited(f);
623     }
624    
625 iliev 2219 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
626     LFOv2Unit* lfo = GetRack()->filLFOs[i];
627     if (!lfo->Active()) continue;
628    
629 iliev 2233 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
630     f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
631 iliev 2219 val *= RTMath::CentsToFreqRatioUnlimited(f);
632     }
633    
634     return val;
635 iliev 2218 }
636    
637 iliev 2235 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
638 iliev 2252 cutoff *= GetFilterCutoff();
639     float maxCutoff = 0.49 * pVoice->GetSampleRate();
640     return cutoff > maxCutoff ? maxCutoff : cutoff;
641 iliev 2235 }
642    
643 iliev 2218 float EndpointUnit::GetPitch() {
644 iliev 2221 double p;
645 iliev 2220 EGv1Unit* u = &(GetRack()->suPitchEG);
646 iliev 2221 p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
647    
648 iliev 2235 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
649     EGv2Unit* eg = GetRack()->pitchEGs[i];
650     if (!eg->Active()) continue;
651    
652     float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
653     p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
654     }
655    
656 iliev 2221 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
657 iliev 2233 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
658 iliev 2224 float f = u3->Active() ? u3->GetLevel() : 0;
659     p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
660 iliev 2225
661     for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
662     LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
663     if (!lfo->Active()) continue;
664    
665     float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
666     p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
667     }
668    
669 iliev 2237 return p * pitchVeltrackRatio;
670 iliev 2218 }
671    
672     float EndpointUnit::GetResonance() {
673 iliev 2252 float val = GetRack()->suResOnCC.Active() ? GetRack()->suResOnCC.GetLevel() : 0;
674 iliev 2219
675 iliev 2235 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
676     EGv2Unit* eg = GetRack()->resEGs[i];
677     if (!eg->Active()) continue;
678    
679     float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
680     val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
681     }
682    
683 iliev 2219 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
684     LFOv2Unit* lfo = GetRack()->resLFOs[i];
685     if (!lfo->Active()) continue;
686    
687 iliev 2233 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
688     val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
689 iliev 2219 }
690    
691     return val;
692 iliev 2218 }
693    
694 iliev 2219 float EndpointUnit::GetPan() {
695 iliev 2237 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
696 iliev 2219
697 iliev 2237 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
698     EGv2Unit* eg = GetRack()->panEGs[i];
699     if (!eg->Active()) continue;
700    
701     float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
702    
703     if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
704     uint8_t val = eg->GetLevel() * 127;
705     if (val > 127) val = 127;
706     pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
707     } else {
708     pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
709     }
710     }
711    
712 iliev 2219 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
713     LFOv2Unit* lfo = GetRack()->panLFOs[i];
714     if (!lfo->Active()) continue;
715    
716 iliev 2233 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
717     pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
718 iliev 2219 }
719    
720     if(pan < -100) return -100;
721     if(pan > 100) return 100;
722    
723     return pan;
724     }
725 iliev 2218
726 iliev 2219
727 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
728 iliev 2222 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
729 iliev 2252 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount),
730     suVolOnCC(this), suCutoffOnCC(this), suResOnCC(this),
731 iliev 2221 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
732 iliev 2233 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
733     filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
734 iliev 2218 {
735 iliev 2237 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
736 iliev 2236 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
737 iliev 2252 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = suCutoffOnCC.pVoice = suResOnCC.pVoice = voice;
738 iliev 2233 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
739     suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
740     suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
741 iliev 2218
742     for (int i = 0; i < EGs.capacity(); i++) {
743     EGs[i] = new EGv2Unit(this);
744     EGs[i]->pVoice = voice;
745 iliev 2235 EGs[i]->suAmpOnCC.pVoice = voice;
746     EGs[i]->suVolOnCC.pVoice = voice;
747     EGs[i]->suPitchOnCC.pVoice = voice;
748     EGs[i]->suCutoffOnCC.pVoice = voice;
749     EGs[i]->suResOnCC.pVoice = voice;
750 iliev 2237 EGs[i]->suPanOnCC.pVoice = voice;
751 iliev 2218 }
752 iliev 2219
753     for (int i = 0; i < LFOs.capacity(); i++) {
754     LFOs[i] = new LFOv2Unit(this);
755     LFOs[i]->pVoice = voice;
756 iliev 2244 LFOs[i]->suDepthOnCC.pVoice = voice;
757     LFOs[i]->suFreqOnCC.pVoice = voice;
758 iliev 2226 LFOs[i]->suFadeEG.pVoice = voice;
759 iliev 2233 LFOs[i]->suVolOnCC.pVoice = voice;
760 iliev 2225 LFOs[i]->suPitchOnCC.pVoice = voice;
761 iliev 2227 LFOs[i]->suFreqOnCC.pVoice = voice;
762 iliev 2233 LFOs[i]->suPanOnCC.pVoice = voice;
763     LFOs[i]->suCutoffOnCC.pVoice = voice;
764     LFOs[i]->suResOnCC.pVoice = voice;
765 iliev 2219 }
766 iliev 2218 }
767    
768     SfzSignalUnitRack::~SfzSignalUnitRack() {
769 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
770 iliev 2218 delete EGs[i]; EGs[i] = NULL;
771     }
772 iliev 2219
773     for (int i = 0; i < LFOs.capacity(); i++) {
774     delete LFOs[i]; LFOs[i] = NULL;
775     }
776 iliev 2218 }
777    
778 iliev 2244 void SfzSignalUnitRack::InitRTLists() {
779     Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
780     Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
781    
782     suVolOnCC.InitCCList(pCCPool, pSmootherPool);
783 iliev 2252 suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
784     suResOnCC.InitCCList(pCCPool, pSmootherPool);
785 iliev 2244 suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
786     suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
787     suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
788     suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
789     suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
790     suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
791     suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
792     suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
793     suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
794    
795     for (int i = 0; i < EGs.capacity(); i++) {
796     EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
797     EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
798     EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
799     EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
800     EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
801     EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
802     }
803    
804     for (int i = 0; i < LFOs.capacity(); i++) {
805     LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
806     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
807     LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
808     LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
809     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
810     LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
811     LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
812     LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
813     }
814     }
815    
816 iliev 2218 void SfzSignalUnitRack::Trigger() {
817     EGs.clear();
818     volEGs.clear();
819     pitchEGs.clear();
820 iliev 2235 filEGs.clear();
821     resEGs.clear();
822 iliev 2237 panEGs.clear();
823 iliev 2218
824 iliev 2219 LFOs.clear();
825 iliev 2233 volLFOs.clear();
826 iliev 2225 pitchLFOs.clear();
827 iliev 2219 filLFOs.clear();
828     resLFOs.clear();
829     panLFOs.clear();
830    
831 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
832    
833 iliev 2230 suVolOnCC.SetCCs(pRegion->volume_oncc);
834 iliev 2252 suCutoffOnCC.SetCCs(pRegion->cutoff_oncc);
835     suResOnCC.SetCCs(pRegion->resonance_oncc);
836 iliev 2230
837 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
838 iliev 2218 if (pRegion->eg[i].node.size() == 0) continue;
839    
840     if(EGs.size() < EGs.capacity()) {
841     EGv2Unit eg(this);
842     eg.pEGInfo = &(pRegion->eg[i]);
843     EGs.increment()->Copy(eg);
844 iliev 2235 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
845     EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
846     EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
847     EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
848     EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
849 iliev 2237 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
850 iliev 2218 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
851    
852 iliev 2235 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
853     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
854     ) {
855 iliev 2218 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
856     else std::cerr << "Maximum number of EGs reached!" << std::endl;
857     }
858 iliev 2235
859     if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
860     if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
861     else std::cerr << "Maximum number of EGs reached!" << std::endl;
862     }
863    
864     if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
865     if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
866     else std::cerr << "Maximum number of EGs reached!" << std::endl;
867     }
868    
869     if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
870     if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
871     else std::cerr << "Maximum number of EGs reached!" << std::endl;
872     }
873 iliev 2237
874     if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
875     if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
876     else std::cerr << "Maximum number of EGs reached!" << std::endl;
877     }
878 iliev 2218 }
879    
880     if (pRegion->ampeg_sustain == -1) {
881     if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
882     else pRegion->ampeg_sustain = 100;
883     }
884    
885 iliev 2219 // LFO
886     for (int i = 0; i < pRegion->lfos.size(); i++) {
887 iliev 2251 if (pRegion->lfos[i].freq <= 0) {
888     if (pRegion->lfos[i].freq_oncc.empty()) continue; // Not initialized
889     else pRegion->lfos[i].freq = 0;
890     }
891 iliev 2219
892     if(LFOs.size() < LFOs.capacity()) {
893     LFOv2Unit lfo(this);
894     lfo.pLfoInfo = &(pRegion->lfos[i]);
895     LFOs.increment()->Copy(lfo);
896 iliev 2233 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
897 iliev 2225 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
898 iliev 2227 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
899 iliev 2233 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
900     LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
901     LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
902 iliev 2219 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
903    
904 iliev 2233 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
905     if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
906     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
907     }
908    
909 iliev 2225 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
910     if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
911     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
912     }
913    
914 iliev 2233 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
915 iliev 2219 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
916     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
917     }
918    
919 iliev 2233 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
920 iliev 2219 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
921     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
922     }
923    
924 iliev 2233 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
925 iliev 2219 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
926     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
927     }
928     }
929    
930 iliev 2233 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
931 iliev 2227 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
932 iliev 2224
933 iliev 2233 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
934 iliev 2227 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
935    
936 iliev 2233 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
937 iliev 2227 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
938    
939 iliev 2218 Units.clear();
940    
941 iliev 2230 Units.add(&suVolOnCC);
942 iliev 2252 Units.add(&suCutoffOnCC);
943     Units.add(&suResOnCC);
944 iliev 2230
945 iliev 2218 Units.add(&suVolEG);
946 iliev 2222 Units.add(&suFilEG);
947 iliev 2220 Units.add(&suPitchEG);
948 iliev 2227
949     Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
950 iliev 2221 Units.add(&suPitchLFO);
951 iliev 2233 Units.add(&suPitchLFO.suDepthOnCC);
952 iliev 2226 Units.add(&suPitchLFO.suFadeEG);
953 iliev 2227
954     Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
955 iliev 2233 Units.add(&suAmpLFO.suDepthOnCC);
956 iliev 2221 Units.add(&suAmpLFO);
957 iliev 2226 Units.add(&suAmpLFO.suFadeEG);
958 iliev 2227
959     Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
960 iliev 2233 Units.add(&suFilLFO.suDepthOnCC);
961 iliev 2221 Units.add(&suFilLFO);
962 iliev 2226 Units.add(&suFilLFO.suFadeEG);
963 iliev 2218
964 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
965 iliev 2218 Units.add(EGs[i]);
966 iliev 2235 Units.add(&(EGs[i]->suAmpOnCC));
967     Units.add(&(EGs[i]->suVolOnCC));
968     Units.add(&(EGs[i]->suPitchOnCC));
969     Units.add(&(EGs[i]->suCutoffOnCC));
970     Units.add(&(EGs[i]->suResOnCC));
971 iliev 2237 Units.add(&(EGs[i]->suPanOnCC));
972 iliev 2218 }
973    
974 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
975 iliev 2227 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
976 iliev 2219 Units.add(LFOs[i]);
977 iliev 2226 Units.add(&(LFOs[i]->suFadeEG));
978 iliev 2233 Units.add(&(LFOs[i]->suVolOnCC));
979 iliev 2225 Units.add(&(LFOs[i]->suPitchOnCC));
980 iliev 2233 Units.add(&(LFOs[i]->suPanOnCC));
981     Units.add(&(LFOs[i]->suCutoffOnCC));
982     Units.add(&(LFOs[i]->suResOnCC));
983 iliev 2219 }
984    
985 iliev 2218 Units.add(&suEndpoint);
986 iliev 2236 Units.add(&suEndpoint.suXFInCC);
987     Units.add(&suEndpoint.suXFOutCC);
988 iliev 2237 Units.add(&suEndpoint.suPanOnCC);
989 iliev 2218
990     SignalUnitRack::Trigger();
991     }
992    
993     EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
994     return &suEndpoint;
995     }
996    
997     void SfzSignalUnitRack::EnterFadeOutStage() {
998     suVolEG.EG.enterFadeOutStage();
999    
1000     for (int i = 0; i < volEGs.size(); i++) {
1001     volEGs[i]->EG.enterFadeOutStage();
1002     }
1003     }
1004    
1005 iliev 2244 void SfzSignalUnitRack::Reset() {
1006     suVolOnCC.RemoveAllCCs();
1007 iliev 2252 suCutoffOnCC.RemoveAllCCs();
1008     suResOnCC.RemoveAllCCs();
1009 iliev 2244 suEndpoint.suXFInCC.RemoveAllCCs();
1010     suEndpoint.suXFOutCC.RemoveAllCCs();
1011     suEndpoint.suPanOnCC.RemoveAllCCs();
1012     suPitchLFO.suDepthOnCC.RemoveAllCCs();
1013     suPitchLFO.suFreqOnCC.RemoveAllCCs();
1014     suFilLFO.suDepthOnCC.RemoveAllCCs();
1015     suFilLFO.suFreqOnCC.RemoveAllCCs();
1016     suAmpLFO.suDepthOnCC.RemoveAllCCs();
1017     suAmpLFO.suFreqOnCC.RemoveAllCCs();
1018    
1019     for (int i = 0; i < EGs.capacity(); i++) {
1020     EGs[i]->suAmpOnCC.RemoveAllCCs();
1021     EGs[i]->suVolOnCC.RemoveAllCCs();
1022     EGs[i]->suPitchOnCC.RemoveAllCCs();
1023     EGs[i]->suCutoffOnCC.RemoveAllCCs();
1024     EGs[i]->suResOnCC.RemoveAllCCs();
1025     EGs[i]->suPanOnCC.RemoveAllCCs();
1026     }
1027    
1028     for (int i = 0; i < LFOs.capacity(); i++) {
1029     LFOs[i]->suDepthOnCC.RemoveAllCCs();
1030     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1031     LFOs[i]->suVolOnCC.RemoveAllCCs();
1032     LFOs[i]->suPitchOnCC.RemoveAllCCs();
1033     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1034     LFOs[i]->suPanOnCC.RemoveAllCCs();
1035     LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1036     LFOs[i]->suResOnCC.RemoveAllCCs();
1037     }
1038     }
1039    
1040 iliev 2218 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC