/[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 2249 - (hide annotations) (download)
Fri Aug 19 18:29:29 2011 UTC (12 years, 8 months ago) by iliev
File size: 41870 byte(s)
* sfz engine: implemented opcodes fileg_delay_onccN,
  fileg_start_onccN, fileg_attack_onccN, fileg_hold_onccN,
  fileg_decay_onccN, fileg_sustain_onccN, fileg_release_onccN,
  fileg_depth_onccN, pitcheg_delay_onccN, pitcheg_start_onccN,
  pitcheg_attack_onccN, pitcheg_hold_onccN, pitcheg_decay_onccN,
  pitcheg_sustain_onccN, pitcheg_release_onccN, pitcheg_depth_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 2229 pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate());
297 iliev 2227 }
298    
299    
300 iliev 2221 void LFOv1Unit::Trigger() {
301     LFOUnit::Trigger();
302    
303     lfo.trigger (
304 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
305 iliev 2221 start_level_mid,
306     1, 0, false, GetSampleRate()
307     );
308     lfo.update(0);
309     }
310    
311 iliev 2223
312     LFOv2Unit::LFOv2Unit(SfzSignalUnitRack* rack)
313     : LFOUnit(rack), lfos(8), lfo0(1200.0f), lfo1(1200.0f), lfo2(1200.0f),
314 iliev 2225 lfo3(1200.0f), lfo4(1200.0f), lfo5(1200.0f), lfo6(1200.0f), lfo7(1200.0f),
315 iliev 2233 suVolOnCC(rack), suPitchOnCC(rack), suPanOnCC(rack), suCutoffOnCC(rack), suResOnCC(rack)
316 iliev 2223 {
317     lfos.add(&lfo0);
318     lfos.add(&lfo1);
319     lfos.add(&lfo2);
320     lfos.add(&lfo3);
321     lfos.add(&lfo4);
322     lfos.add(&lfo5);
323     lfos.add(&lfo6);
324     lfos.add(&lfo7);
325     }
326    
327 iliev 2219 void LFOv2Unit::Trigger() {
328     LFOUnit::Trigger();
329    
330 iliev 2223 if (pLfoInfo->wave < 0 || pLfoInfo->wave >= lfos.size()) pLFO = &lfo0;
331     else pLFO = lfos[pLfoInfo->wave];
332    
333     pLFO->Trigger (
334 iliev 2227 pLfoInfo->freq + suFreqOnCC.GetLevel(),
335 iliev 2219 start_level_mid,
336     1, 0, false, GetSampleRate()
337     );
338 iliev 2223 pLFO->Update(0);
339 iliev 2225
340 iliev 2229 float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc);
341 iliev 2225 if (phase != 0) pLFO->SetPhase(phase);
342 iliev 2219 }
343 iliev 2221
344     void AmpLFOUnit::Trigger() {
345     ::sfz::Region* const pRegion = pVoice->pRegion;
346 iliev 2248 pLfoInfo->delay = pRegion->amplfo_delay + GetInfluence(pRegion->amplfo_delay_oncc);
347 iliev 2226 pLfoInfo->freq = pRegion->amplfo_freq;
348 iliev 2248 pLfoInfo->fade = pRegion->amplfo_fade + GetInfluence(pRegion->amplfo_fade_oncc);
349 iliev 2221 pLfoInfo->volume = pRegion->amplfo_depth;
350    
351     LFOv1Unit::Trigger();
352     }
353    
354     void PitchLFOUnit::Trigger() {
355     ::sfz::Region* const pRegion = pVoice->pRegion;
356 iliev 2248 pLfoInfo->delay = pRegion->pitchlfo_delay + GetInfluence(pRegion->pitchlfo_delay_oncc);
357 iliev 2226 pLfoInfo->freq = pRegion->pitchlfo_freq;
358 iliev 2248 pLfoInfo->fade = pRegion->pitchlfo_fade + GetInfluence(pRegion->pitchlfo_fade_oncc);
359 iliev 2221 pLfoInfo->pitch = pRegion->pitchlfo_depth;
360    
361     LFOv1Unit::Trigger();
362     }
363    
364     void FilLFOUnit::Trigger() {
365     ::sfz::Region* const pRegion = pVoice->pRegion;
366 iliev 2248 pLfoInfo->delay = pRegion->fillfo_delay + GetInfluence(pRegion->fillfo_delay_oncc);
367 iliev 2226 pLfoInfo->freq = pRegion->fillfo_freq;
368 iliev 2248 pLfoInfo->fade = pRegion->fillfo_fade + GetInfluence(pRegion->fillfo_fade_oncc);
369 iliev 2221 pLfoInfo->cutoff = pRegion->fillfo_depth;
370    
371     LFOv1Unit::Trigger();
372     }
373 iliev 2224
374 iliev 2227 CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) {
375     pVoice = NULL;
376     }
377 iliev 2224
378     void CCUnit::Trigger() {
379 iliev 2244 RTList<CC>::Iterator ctrl = pCtrls->first();
380     RTList<CC>::Iterator end = pCtrls->end();
381     for(; ctrl != end; ++ctrl) {
382     (*ctrl).Value = pVoice->GetControllerValue((*ctrl).Controller);
383     if ((*ctrl).pSmoother != NULL) (*ctrl).pSmoother->setValue((*ctrl).Value);
384 iliev 2224 }
385     CCSignalUnit::Trigger();
386     }
387    
388 iliev 2244 void CCUnit::SetCCs(::sfz::Array<int>& cc) {
389     RemoveAllCCs();
390     for (int i = 0; i < 128; i++) {
391     if (cc[i] != 0) AddCC(i, cc[i]);
392     }
393     }
394 iliev 2225
395 iliev 2244 void CCUnit::SetCCs(ArrayList< ::sfz::CC>& cc) {
396     RemoveAllCCs();
397     for (int i = 0; i < cc.size(); i++) {
398     if (cc[i].Influence != 0) {
399     short int curve = cc[i].Curve;
400     if (curve >= GetCurveCount()) curve = -1;
401     AddSmoothCC(cc[i].Controller, cc[i].Influence, curve, cc[i].Smooth);
402     }
403     }
404     }
405 iliev 2230
406 iliev 2244 void CCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
407     AddCC(Controller, Influence, Curve);
408     }
409 iliev 2232
410 iliev 2244 int CCUnit::GetCurveCount() {
411     return pVoice->pRegion->GetInstrument()->curves.size();
412     }
413 iliev 2230
414 iliev 2244 ::sfz::Curve* CCUnit::GetCurve(int idx) {
415     return &pVoice->pRegion->GetInstrument()->curves[idx];
416     }
417 iliev 2232
418 iliev 2244 double CCUnit::GetSampleRate() {
419 iliev 2232 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
420     }
421 iliev 2244
422    
423     SmoothCCUnit::~SmoothCCUnit() {
424     if (pSmoothers != NULL) delete pSmoothers;
425     }
426 iliev 2232
427 iliev 2244 void SmoothCCUnit::AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth) {
428     if (Smooth > 0) {
429     if (pSmoothers->poolIsEmpty()) {
430     std::cerr << "Maximum number of smoothers reached" << std::endl;
431     return;
432     }
433     Smoother* smoother = &(*(pSmoothers->allocAppend()));
434     smoother->trigger(Smooth / 1000.0f, GetSampleRate());
435     AddCC(Controller, Influence, Curve, smoother);
436     } else {
437     AddCC(Controller, Influence, Curve);
438     }
439     }
440    
441     void SmoothCCUnit::InitSmoothers(Pool<Smoother>* pSmootherPool) {
442     if (pSmoothers != NULL) delete pSmoothers;
443     pSmoothers = new RTList<Smoother>(pSmootherPool);
444     }
445    
446     void SmoothCCUnit::InitCCList(Pool<CC>* pCCPool, Pool<Smoother>* pSmootherPool) {
447     CurveCCUnit::InitCCList(pCCPool, pSmootherPool);
448     InitSmoothers(pSmootherPool);
449     }
450 iliev 2218
451 iliev 2219
452 iliev 2237 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack)
453     : EndpointSignalUnit(rack), suXFInCC(rack), suXFOutCC(rack), suPanOnCC(rack), pitchVeltrackRatio(0)
454     {
455 iliev 2218
456     }
457    
458     SfzSignalUnitRack* const EndpointUnit::GetRack() {
459     return static_cast<SfzSignalUnitRack* const>(pRack);
460     }
461    
462     void EndpointUnit::Trigger() {
463 iliev 2236 float xfInVelCoeff = 1;
464 iliev 2218
465 iliev 2236 if (pVoice->MIDIVelocity <= pVoice->pRegion->xfin_lovel) {
466     xfInVelCoeff = 0;
467     } else if (pVoice->MIDIVelocity >= pVoice->pRegion->xfin_hivel) {
468     xfInVelCoeff = 1;
469     } else {
470     float xfVelSize = pVoice->pRegion->xfin_hivel - pVoice->pRegion->xfin_lovel;
471     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfin_lovel;
472     xfInVelCoeff = velPos / xfVelSize;
473     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
474     xfInVelCoeff = sin(xfInVelCoeff * M_PI / 2.0);
475     }
476     }
477    
478     float xfOutVelCoeff = 1;
479    
480     if (pVoice->MIDIVelocity >= pVoice->pRegion->xfout_hivel) {
481     if (pVoice->pRegion->xfout_lovel < 127 /* is set */) xfOutVelCoeff = 0;
482     } else if (pVoice->MIDIVelocity <= pVoice->pRegion->xfout_lovel) {
483     xfOutVelCoeff = 1;
484     } else {
485     float xfVelSize = pVoice->pRegion->xfout_hivel - pVoice->pRegion->xfout_lovel;
486     float velPos = pVoice->MIDIVelocity - pVoice->pRegion->xfout_lovel;
487     xfOutVelCoeff = 1.0f - velPos / xfVelSize;
488     if (pVoice->pRegion->xf_velcurve == ::sfz::POWER) {
489     xfOutVelCoeff = sin(xfOutVelCoeff * M_PI / 2.0);
490     }
491     }
492    
493     float xfInKeyCoeff = 1;
494    
495     if (pVoice->MIDIKey <= pVoice->pRegion->xfin_lokey) {
496     if (pVoice->pRegion->xfin_hikey > 0 /* is set */) xfInKeyCoeff = 0;
497     } else if (pVoice->MIDIKey >= pVoice->pRegion->xfin_hikey) {
498     xfInKeyCoeff = 1;
499     } else {
500     float xfKeySize = pVoice->pRegion->xfin_hikey - pVoice->pRegion->xfin_lokey;
501     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfin_lokey;
502     xfInKeyCoeff = keyPos / xfKeySize;
503     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
504     xfInKeyCoeff = sin(xfInKeyCoeff * M_PI / 2.0);
505     }
506     }
507    
508     float xfOutKeyCoeff = 1;
509    
510     if (pVoice->MIDIKey >= pVoice->pRegion->xfout_hikey) {
511     if (pVoice->pRegion->xfout_lokey < 127 /* is set */) xfOutKeyCoeff = 0;
512     } else if (pVoice->MIDIKey <= pVoice->pRegion->xfout_lokey) {
513     xfOutKeyCoeff = 1;
514     } else {
515     float xfKeySize = pVoice->pRegion->xfout_hikey - pVoice->pRegion->xfout_lokey;
516     float keyPos = pVoice->MIDIKey - pVoice->pRegion->xfout_lokey;
517     xfOutKeyCoeff = 1.0f - keyPos / xfKeySize;
518     if (pVoice->pRegion->xf_keycurve == ::sfz::POWER) {
519     xfOutKeyCoeff = sin(xfOutKeyCoeff * M_PI / 2.0);
520     }
521     }
522    
523     xfCoeff = xfInVelCoeff * xfOutVelCoeff * xfInKeyCoeff * xfOutKeyCoeff;
524    
525     suXFInCC.SetCrossFadeCCs(pVoice->pRegion->xfin_locc, pVoice->pRegion->xfin_hicc);
526     suXFOutCC.SetCrossFadeCCs(pVoice->pRegion->xfout_locc, pVoice->pRegion->xfout_hicc);
527 iliev 2237
528     suPanOnCC.SetCCs(pVoice->pRegion->pan_oncc);
529    
530     pitchVeltrackRatio = RTMath::CentsToFreqRatioUnlimited((pVoice->MIDIVelocity / 127.0f) * pVoice->pRegion->pitch_veltrack);
531 iliev 2218 }
532    
533     bool EndpointUnit::Active() {
534     if (GetRack()->suVolEG.Active()) return true;
535    
536     bool b = false;
537     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
538     if (GetRack()->volEGs[i]->Active()) { b = true; break; }
539     }
540    
541     return b;
542     }
543    
544     float EndpointUnit::GetVolume() {
545     float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
546    
547     for (int i = 0; i < GetRack()->volEGs.size(); i++) {
548     EGv2Unit* eg = GetRack()->volEGs[i];
549     if (!eg->Active()) continue;
550 iliev 2229
551 iliev 2235 float dB = eg->suVolOnCC.Active() ? eg->suVolOnCC.GetLevel() : -200;
552     if (dB < -144) dB = eg->pEGInfo->volume;
553     else if (eg->pEGInfo->volume >= -144) dB += eg->pEGInfo->volume;
554    
555     float amp = eg->suAmpOnCC.Active() ? eg->suAmpOnCC.GetLevel() : 0;
556     amp = (amp + eg->pEGInfo->amplitude) / 100.0f;
557    
558     if (dB >= -144) {
559     if (amp == 0 && eg->suAmpOnCC.GetCCCount() == 0) amp = 1.0f;
560 iliev 2244 amp *= ToRatio(dB * 10.0);
561 iliev 2235 }
562    
563     vol += amp * eg->GetLevel();
564 iliev 2218 }
565    
566 iliev 2221 AmpLFOUnit* u = &(GetRack()->suAmpLFO);
567 iliev 2233 CCSignalUnit* u2 = &(GetRack()->suAmpLFO.suDepthOnCC);
568     float f = u2->Active() ? u2->GetLevel() : 0;
569 iliev 2244 vol *= u->Active() ? ToRatio((u->GetLevel() * (u->pLfoInfo->volume + f) * 10.0)) : 1;
570 iliev 2221
571 iliev 2244 vol *= ToRatio(GetRack()->suVolOnCC.GetLevel() * 10.0);
572 iliev 2230
573 iliev 2233 for (int i = 0; i < GetRack()->volLFOs.size(); i++) {
574     LFOv2Unit* lfo = GetRack()->volLFOs[i];
575     if (!lfo->Active()) continue;
576    
577     float f = lfo->suVolOnCC.Active() ? lfo->suVolOnCC.GetLevel() : 0;
578 iliev 2244 vol *= ToRatio(lfo->GetLevel() * (lfo->pLfoInfo->volume + f) * 10.0);
579 iliev 2233 }
580    
581 iliev 2236 if (suXFInCC.Active()) vol *= suXFInCC.GetLevel();
582     if (suXFOutCC.Active()) vol *= suXFOutCC.GetLevel();
583     return vol * xfCoeff;
584 iliev 2218 }
585    
586     float EndpointUnit::GetFilterCutoff() {
587 iliev 2221 float val;
588 iliev 2219
589 iliev 2221 FilLFOUnit* u = &(GetRack()->suFilLFO);
590 iliev 2233 CCSignalUnit* u1 = &(GetRack()->suFilLFO.suDepthOnCC);
591     float f = u1->Active() ? u1->GetLevel() : 0;
592     val = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * (u->pLfoInfo->cutoff + f)) : 1;
593 iliev 2221
594 iliev 2222 FilEGUnit* u2 = &(GetRack()->suFilEG);
595     val *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * u2->depth) : 1;
596    
597 iliev 2235 for (int i = 0; i < GetRack()->filEGs.size(); i++) {
598     EGv2Unit* eg = GetRack()->filEGs[i];
599     if (!eg->Active()) continue;
600    
601     float f = eg->suCutoffOnCC.Active() ? eg->suCutoffOnCC.GetLevel() : 0;
602     f = eg->GetLevel() * (eg->pEGInfo->cutoff + f);
603     val *= RTMath::CentsToFreqRatioUnlimited(f);
604     }
605    
606 iliev 2219 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
607     LFOv2Unit* lfo = GetRack()->filLFOs[i];
608     if (!lfo->Active()) continue;
609    
610 iliev 2233 float f = lfo->suCutoffOnCC.Active() ? lfo->suCutoffOnCC.GetLevel() : 0;
611     f = lfo->GetLevel() * (lfo->pLfoInfo->cutoff + f);
612 iliev 2219 val *= RTMath::CentsToFreqRatioUnlimited(f);
613     }
614    
615     return val;
616 iliev 2218 }
617    
618 iliev 2235 float EndpointUnit::CalculateFilterCutoff(float cutoff) {
619     cutoff *= GetFilterCutoff();
620     float maxCutoff = 0.49 * pVoice->GetSampleRate();
621     return cutoff > maxCutoff ? maxCutoff : cutoff;
622     }
623    
624 iliev 2218 float EndpointUnit::GetPitch() {
625 iliev 2221 double p;
626 iliev 2220 EGv1Unit* u = &(GetRack()->suPitchEG);
627 iliev 2221 p = u->Active() ? RTMath::CentsToFreqRatioUnlimited(u->GetLevel() * u->depth) : 1;
628    
629 iliev 2235 for (int i = 0; i < GetRack()->pitchEGs.size(); i++) {
630     EGv2Unit* eg = GetRack()->pitchEGs[i];
631     if (!eg->Active()) continue;
632    
633     float f = eg->suPitchOnCC.Active() ? eg->suPitchOnCC.GetLevel() : 0;
634     p *= RTMath::CentsToFreqRatioUnlimited(eg->GetLevel() * (eg->pEGInfo->pitch + f));
635     }
636    
637 iliev 2221 PitchLFOUnit* u2 = &(GetRack()->suPitchLFO);
638 iliev 2233 CCSignalUnit* u3 = &(GetRack()->suPitchLFO.suDepthOnCC);
639 iliev 2224 float f = u3->Active() ? u3->GetLevel() : 0;
640     p *= u2->Active() ? RTMath::CentsToFreqRatioUnlimited(u2->GetLevel() * (u2->pLfoInfo->pitch + f)) : 1;
641 iliev 2225
642     for (int i = 0; i < GetRack()->pitchLFOs.size(); i++) {
643     LFOv2Unit* lfo = GetRack()->pitchLFOs[i];
644     if (!lfo->Active()) continue;
645    
646     float f = lfo->suPitchOnCC.Active() ? lfo->suPitchOnCC.GetLevel() : 0;
647     p *= RTMath::CentsToFreqRatioUnlimited(lfo->GetLevel() * (lfo->pLfoInfo->pitch + f));
648     }
649    
650 iliev 2237 return p * pitchVeltrackRatio;
651 iliev 2218 }
652    
653     float EndpointUnit::GetResonance() {
654 iliev 2219 float val = 0;
655    
656 iliev 2235 for (int i = 0; i < GetRack()->resEGs.size(); i++) {
657     EGv2Unit* eg = GetRack()->resEGs[i];
658     if (!eg->Active()) continue;
659    
660     float f = eg->suResOnCC.Active() ? eg->suResOnCC.GetLevel() : 0;
661     val += eg->GetLevel() * (eg->pEGInfo->resonance + f);
662     }
663    
664 iliev 2219 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
665     LFOv2Unit* lfo = GetRack()->resLFOs[i];
666     if (!lfo->Active()) continue;
667    
668 iliev 2233 float f = lfo->suResOnCC.Active() ? lfo->suResOnCC.GetLevel() : 0;
669     val += lfo->GetLevel() * (lfo->pLfoInfo->resonance + f);
670 iliev 2219 }
671    
672     return val;
673 iliev 2218 }
674    
675 iliev 2219 float EndpointUnit::GetPan() {
676 iliev 2237 float pan = suPanOnCC.Active() ? suPanOnCC.GetLevel() : 0;
677 iliev 2219
678 iliev 2237 for (int i = 0; i < GetRack()->panEGs.size(); i++) {
679     EGv2Unit* eg = GetRack()->panEGs[i];
680     if (!eg->Active()) continue;
681    
682     float f = eg->suPanOnCC.Active() ? eg->suPanOnCC.GetLevel() : 0;
683    
684     if (eg->pEGInfo->pan_curve >= 0 && eg->pEGInfo->pan_curve < suPanOnCC.GetCurveCount()) {
685     uint8_t val = eg->GetLevel() * 127;
686     if (val > 127) val = 127;
687     pan += eg->pEGInfo->pan * suPanOnCC.GetCurve(eg->pEGInfo->pan_curve)->v[val] + eg->GetLevel() * f;
688     } else {
689     pan += eg->GetLevel() * (eg->pEGInfo->pan + f);
690     }
691     }
692    
693 iliev 2219 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
694     LFOv2Unit* lfo = GetRack()->panLFOs[i];
695     if (!lfo->Active()) continue;
696    
697 iliev 2233 float f = lfo->suPanOnCC.Active() ? lfo->suPanOnCC.GetLevel() : 0;
698     pan += lfo->GetLevel() * (lfo->pLfoInfo->pan + f);
699 iliev 2219 }
700    
701     if(pan < -100) return -100;
702     if(pan > 100) return 100;
703    
704     return pan;
705     }
706 iliev 2218
707 iliev 2219
708 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
709 iliev 2222 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this), suFilEG(this), suPitchEG(this),
710 iliev 2237 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount), filEGs(maxEgCount), resEGs(maxEgCount), panEGs(maxEgCount), suVolOnCC(this),
711 iliev 2221 suAmpLFO(this), suPitchLFO(this), suFilLFO(this),
712 iliev 2233 LFOs(maxLfoCount), volLFOs(maxLfoCount), pitchLFOs(maxLfoCount),
713     filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
714 iliev 2218 {
715 iliev 2237 suEndpoint.pVoice = suEndpoint.suXFInCC.pVoice = suEndpoint.suXFOutCC.pVoice = suEndpoint.suPanOnCC.pVoice = voice;
716 iliev 2236 suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice;
717 iliev 2230 suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = suVolOnCC.pVoice = voice;
718 iliev 2233 suPitchLFO.suDepthOnCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice;
719     suFilLFO.suFadeEG.pVoice = suFilLFO.suDepthOnCC.pVoice = suFilLFO.suFreqOnCC.pVoice = voice;
720     suAmpLFO.suFadeEG.pVoice = suAmpLFO.suDepthOnCC.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice;
721 iliev 2218
722     for (int i = 0; i < EGs.capacity(); i++) {
723     EGs[i] = new EGv2Unit(this);
724     EGs[i]->pVoice = voice;
725 iliev 2235 EGs[i]->suAmpOnCC.pVoice = voice;
726     EGs[i]->suVolOnCC.pVoice = voice;
727     EGs[i]->suPitchOnCC.pVoice = voice;
728     EGs[i]->suCutoffOnCC.pVoice = voice;
729     EGs[i]->suResOnCC.pVoice = voice;
730 iliev 2237 EGs[i]->suPanOnCC.pVoice = voice;
731 iliev 2218 }
732 iliev 2219
733     for (int i = 0; i < LFOs.capacity(); i++) {
734     LFOs[i] = new LFOv2Unit(this);
735     LFOs[i]->pVoice = voice;
736 iliev 2244 LFOs[i]->suDepthOnCC.pVoice = voice;
737     LFOs[i]->suFreqOnCC.pVoice = voice;
738 iliev 2226 LFOs[i]->suFadeEG.pVoice = voice;
739 iliev 2233 LFOs[i]->suVolOnCC.pVoice = voice;
740 iliev 2225 LFOs[i]->suPitchOnCC.pVoice = voice;
741 iliev 2227 LFOs[i]->suFreqOnCC.pVoice = voice;
742 iliev 2233 LFOs[i]->suPanOnCC.pVoice = voice;
743     LFOs[i]->suCutoffOnCC.pVoice = voice;
744     LFOs[i]->suResOnCC.pVoice = voice;
745 iliev 2219 }
746 iliev 2218 }
747    
748     SfzSignalUnitRack::~SfzSignalUnitRack() {
749 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
750 iliev 2218 delete EGs[i]; EGs[i] = NULL;
751     }
752 iliev 2219
753     for (int i = 0; i < LFOs.capacity(); i++) {
754     delete LFOs[i]; LFOs[i] = NULL;
755     }
756 iliev 2218 }
757    
758 iliev 2244 void SfzSignalUnitRack::InitRTLists() {
759     Pool<CCSignalUnit::CC>* pCCPool = pVoice->pEngine->pCCPool;
760     Pool<Smoother>* pSmootherPool = pVoice->pEngine->pSmootherPool;
761    
762     suVolOnCC.InitCCList(pCCPool, pSmootherPool);
763     suEndpoint.suXFInCC.InitCCList(pCCPool, pSmootherPool);
764     suEndpoint.suXFOutCC.InitCCList(pCCPool, pSmootherPool);
765     suEndpoint.suPanOnCC.InitCCList(pCCPool, pSmootherPool);
766     suPitchLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
767     suPitchLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
768     suFilLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
769     suFilLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
770     suAmpLFO.suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
771     suAmpLFO.suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
772    
773     for (int i = 0; i < EGs.capacity(); i++) {
774     EGs[i]->suAmpOnCC.InitCCList(pCCPool, pSmootherPool);
775     EGs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
776     EGs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
777     EGs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
778     EGs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
779     EGs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
780     }
781    
782     for (int i = 0; i < LFOs.capacity(); i++) {
783     LFOs[i]->suDepthOnCC.InitCCList(pCCPool, pSmootherPool);
784     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
785     LFOs[i]->suVolOnCC.InitCCList(pCCPool, pSmootherPool);
786     LFOs[i]->suPitchOnCC.InitCCList(pCCPool, pSmootherPool);
787     LFOs[i]->suFreqOnCC.InitCCList(pCCPool, pSmootherPool);
788     LFOs[i]->suPanOnCC.InitCCList(pCCPool, pSmootherPool);
789     LFOs[i]->suCutoffOnCC.InitCCList(pCCPool, pSmootherPool);
790     LFOs[i]->suResOnCC.InitCCList(pCCPool, pSmootherPool);
791     }
792     }
793    
794 iliev 2218 void SfzSignalUnitRack::Trigger() {
795     EGs.clear();
796     volEGs.clear();
797     pitchEGs.clear();
798 iliev 2235 filEGs.clear();
799     resEGs.clear();
800 iliev 2237 panEGs.clear();
801 iliev 2218
802 iliev 2219 LFOs.clear();
803 iliev 2233 volLFOs.clear();
804 iliev 2225 pitchLFOs.clear();
805 iliev 2219 filLFOs.clear();
806     resLFOs.clear();
807     panLFOs.clear();
808    
809 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
810    
811 iliev 2230 suVolOnCC.SetCCs(pRegion->volume_oncc);
812    
813 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
814 iliev 2218 if (pRegion->eg[i].node.size() == 0) continue;
815    
816     if(EGs.size() < EGs.capacity()) {
817     EGv2Unit eg(this);
818     eg.pEGInfo = &(pRegion->eg[i]);
819     EGs.increment()->Copy(eg);
820 iliev 2235 EGs[EGs.size() - 1]->suAmpOnCC.SetCCs(pRegion->eg[i].amplitude_oncc);
821     EGs[EGs.size() - 1]->suVolOnCC.SetCCs(pRegion->eg[i].volume_oncc);
822     EGs[EGs.size() - 1]->suPitchOnCC.SetCCs(pRegion->eg[i].pitch_oncc);
823     EGs[EGs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->eg[i].cutoff_oncc);
824     EGs[EGs.size() - 1]->suResOnCC.SetCCs(pRegion->eg[i].resonance_oncc);
825 iliev 2237 EGs[EGs.size() - 1]->suPanOnCC.SetCCs(pRegion->eg[i].pan_oncc);
826 iliev 2218 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
827    
828 iliev 2235 if ( pRegion->eg[i].amplitude > 0 || !pRegion->eg[i].amplitude_oncc.empty() ||
829     pRegion->eg[i].volume > -145 || !pRegion->eg[i].volume_oncc.empty()
830     ) {
831 iliev 2218 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
832     else std::cerr << "Maximum number of EGs reached!" << std::endl;
833     }
834 iliev 2235
835     if (pRegion->eg[i].cutoff != 0 || !pRegion->eg[i].cutoff_oncc.empty()) {
836     if(filEGs.size() < filEGs.capacity()) filEGs.add(EGs[EGs.size() - 1]);
837     else std::cerr << "Maximum number of EGs reached!" << std::endl;
838     }
839    
840     if (pRegion->eg[i].resonance != 0 || !pRegion->eg[i].resonance_oncc.empty()) {
841     if(resEGs.size() < resEGs.capacity()) resEGs.add(EGs[EGs.size() - 1]);
842     else std::cerr << "Maximum number of EGs reached!" << std::endl;
843     }
844    
845     if (pRegion->eg[i].pitch != 0 || !pRegion->eg[i].pitch_oncc.empty()) {
846     if(pitchEGs.size() < pitchEGs.capacity()) pitchEGs.add(EGs[EGs.size() - 1]);
847     else std::cerr << "Maximum number of EGs reached!" << std::endl;
848     }
849 iliev 2237
850     if (pRegion->eg[i].pan != 0 || !pRegion->eg[i].pan_oncc.empty()) {
851     if(panEGs.size() < panEGs.capacity()) panEGs.add(EGs[EGs.size() - 1]);
852     else std::cerr << "Maximum number of EGs reached!" << std::endl;
853     }
854 iliev 2218 }
855    
856     if (pRegion->ampeg_sustain == -1) {
857     if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
858     else pRegion->ampeg_sustain = 100;
859     }
860    
861 iliev 2219 // LFO
862     for (int i = 0; i < pRegion->lfos.size(); i++) {
863     if (pRegion->lfos[i].freq == -1) continue; // Not initialized
864    
865     if(LFOs.size() < LFOs.capacity()) {
866     LFOv2Unit lfo(this);
867     lfo.pLfoInfo = &(pRegion->lfos[i]);
868     LFOs.increment()->Copy(lfo);
869 iliev 2233 LFOs[LFOs.size() - 1]->suVolOnCC.SetCCs(pRegion->lfos[i].volume_oncc);
870 iliev 2225 LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc);
871 iliev 2227 LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc);
872 iliev 2233 LFOs[LFOs.size() - 1]->suPanOnCC.SetCCs(pRegion->lfos[i].pan_oncc);
873     LFOs[LFOs.size() - 1]->suCutoffOnCC.SetCCs(pRegion->lfos[i].cutoff_oncc);
874     LFOs[LFOs.size() - 1]->suResOnCC.SetCCs(pRegion->lfos[i].resonance_oncc);
875 iliev 2219 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
876    
877 iliev 2233 if (pRegion->lfos[i].volume != 0 || !pRegion->lfos[i].volume_oncc.empty()) {
878     if(volLFOs.size() < volLFOs.capacity()) volLFOs.add(LFOs[LFOs.size() - 1]);
879     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
880     }
881    
882 iliev 2225 if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) {
883     if(pitchLFOs.size() < pitchLFOs.capacity()) pitchLFOs.add(LFOs[LFOs.size() - 1]);
884     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
885     }
886    
887 iliev 2233 if (pRegion->lfos[i].cutoff != 0 || !pRegion->lfos[i].cutoff_oncc.empty()) {
888 iliev 2219 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
889     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
890     }
891    
892 iliev 2233 if (pRegion->lfos[i].resonance != 0 || !pRegion->lfos[i].resonance_oncc.empty()) {
893 iliev 2219 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
894     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
895     }
896    
897 iliev 2233 if (pRegion->lfos[i].pan != 0 || !pRegion->lfos[i].pan_oncc.empty()) {
898 iliev 2219 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
899     else std::cerr << "Maximum number of LFOs reached!" << std::endl;
900     }
901     }
902    
903 iliev 2233 suPitchLFO.suDepthOnCC.SetCCs(pRegion->pitchlfo_depthcc);
904 iliev 2227 suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc);
905 iliev 2224
906 iliev 2233 suFilLFO.suDepthOnCC.SetCCs(pRegion->fillfo_depthcc);
907 iliev 2227 suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc);
908    
909 iliev 2233 suAmpLFO.suDepthOnCC.SetCCs(pRegion->amplfo_depthcc);
910 iliev 2227 suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc);
911    
912 iliev 2218 Units.clear();
913    
914 iliev 2230 Units.add(&suVolOnCC);
915    
916 iliev 2218 Units.add(&suVolEG);
917 iliev 2222 Units.add(&suFilEG);
918 iliev 2220 Units.add(&suPitchEG);
919 iliev 2227
920     Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
921 iliev 2221 Units.add(&suPitchLFO);
922 iliev 2233 Units.add(&suPitchLFO.suDepthOnCC);
923 iliev 2226 Units.add(&suPitchLFO.suFadeEG);
924 iliev 2227
925     Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
926 iliev 2233 Units.add(&suAmpLFO.suDepthOnCC);
927 iliev 2221 Units.add(&suAmpLFO);
928 iliev 2226 Units.add(&suAmpLFO.suFadeEG);
929 iliev 2227
930     Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO)
931 iliev 2233 Units.add(&suFilLFO.suDepthOnCC);
932 iliev 2221 Units.add(&suFilLFO);
933 iliev 2226 Units.add(&suFilLFO.suFadeEG);
934 iliev 2218
935 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
936 iliev 2218 Units.add(EGs[i]);
937 iliev 2235 Units.add(&(EGs[i]->suAmpOnCC));
938     Units.add(&(EGs[i]->suVolOnCC));
939     Units.add(&(EGs[i]->suPitchOnCC));
940     Units.add(&(EGs[i]->suCutoffOnCC));
941     Units.add(&(EGs[i]->suResOnCC));
942 iliev 2237 Units.add(&(EGs[i]->suPanOnCC));
943 iliev 2218 }
944    
945 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
946 iliev 2227 Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO)
947 iliev 2219 Units.add(LFOs[i]);
948 iliev 2226 Units.add(&(LFOs[i]->suFadeEG));
949 iliev 2233 Units.add(&(LFOs[i]->suVolOnCC));
950 iliev 2225 Units.add(&(LFOs[i]->suPitchOnCC));
951 iliev 2233 Units.add(&(LFOs[i]->suPanOnCC));
952     Units.add(&(LFOs[i]->suCutoffOnCC));
953     Units.add(&(LFOs[i]->suResOnCC));
954 iliev 2219 }
955    
956 iliev 2218 Units.add(&suEndpoint);
957 iliev 2236 Units.add(&suEndpoint.suXFInCC);
958     Units.add(&suEndpoint.suXFOutCC);
959 iliev 2237 Units.add(&suEndpoint.suPanOnCC);
960 iliev 2218
961     SignalUnitRack::Trigger();
962     }
963    
964     EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
965     return &suEndpoint;
966     }
967    
968     void SfzSignalUnitRack::EnterFadeOutStage() {
969     suVolEG.EG.enterFadeOutStage();
970    
971     for (int i = 0; i < volEGs.size(); i++) {
972     volEGs[i]->EG.enterFadeOutStage();
973     }
974     }
975    
976 iliev 2244 void SfzSignalUnitRack::Reset() {
977     suVolOnCC.RemoveAllCCs();
978     suEndpoint.suXFInCC.RemoveAllCCs();
979     suEndpoint.suXFOutCC.RemoveAllCCs();
980     suEndpoint.suPanOnCC.RemoveAllCCs();
981     suPitchLFO.suDepthOnCC.RemoveAllCCs();
982     suPitchLFO.suFreqOnCC.RemoveAllCCs();
983     suFilLFO.suDepthOnCC.RemoveAllCCs();
984     suFilLFO.suFreqOnCC.RemoveAllCCs();
985     suAmpLFO.suDepthOnCC.RemoveAllCCs();
986     suAmpLFO.suFreqOnCC.RemoveAllCCs();
987    
988     for (int i = 0; i < EGs.capacity(); i++) {
989     EGs[i]->suAmpOnCC.RemoveAllCCs();
990     EGs[i]->suVolOnCC.RemoveAllCCs();
991     EGs[i]->suPitchOnCC.RemoveAllCCs();
992     EGs[i]->suCutoffOnCC.RemoveAllCCs();
993     EGs[i]->suResOnCC.RemoveAllCCs();
994     EGs[i]->suPanOnCC.RemoveAllCCs();
995     }
996    
997     for (int i = 0; i < LFOs.capacity(); i++) {
998     LFOs[i]->suDepthOnCC.RemoveAllCCs();
999     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1000     LFOs[i]->suVolOnCC.RemoveAllCCs();
1001     LFOs[i]->suPitchOnCC.RemoveAllCCs();
1002     LFOs[i]->suFreqOnCC.RemoveAllCCs();
1003     LFOs[i]->suPanOnCC.RemoveAllCCs();
1004     LFOs[i]->suCutoffOnCC.RemoveAllCCs();
1005     LFOs[i]->suResOnCC.RemoveAllCCs();
1006     }
1007     }
1008    
1009 iliev 2218 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC