/[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 2264 - (hide annotations) (download)
Mon Aug 22 10:00:01 2011 UTC (12 years, 8 months ago) by iliev
File size: 43900 byte(s)
* sfz engine: implemented opcodes pitch_onccN,
  pitch_curveccN, pitch_smoothccN, pitch_stepccN

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

  ViewVC Help
Powered by ViewVC