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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4016 - (show annotations) (download)
Mon Jan 3 15:36:02 2022 UTC (2 years, 3 months ago) by schoenebeck
File size: 110649 byte(s)
* sfz.h: Add File::checkFileModified() method allowing to detect file
  changes (e.g. by other apps).

* Bumped version (2.2.0.svn12).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2008 Anders Dahnielson <anders@dahnielson.com> *
6 * Copyright (C) 2009 - 2016 Anders Dahnielson and Grigor Iliev *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "sfz.h"
25
26 #include <iostream>
27 #include <sstream>
28 #include <cctype>
29 #include <cstdio>
30 #include <cstring>
31 #include <sys/stat.h>
32
33 #include "../../common/File.h"
34 #include "../../common/Path.h"
35 #include "LookupTable.h"
36 #include "../../common/global_private.h"
37
38 namespace sfz
39 {
40 template <typename T> T check(std::string name, T min, T max, T val) {
41 if (val < min) {
42 std::cerr << "sfz: The value of opcode '" << name;
43 std::cerr << "' is below the minimum allowed value (min=" << min << "): " << val << std::endl;
44 val = min;
45 }
46 if (val > max) {
47 std::cerr << "sfz: The value of opcode '" << name;
48 std::cerr << "' is above the maximum allowed value (max=" << max << "): " << val << std::endl;
49 val = max;
50 }
51
52 return val;
53 }
54
55 Sample* SampleManager::FindSample(std::string samplePath, uint offset, int end) {
56 std::map<Sample*, std::set<Region*> >::iterator it = sampleMap.begin();
57 for (; it != sampleMap.end(); it++) {
58 if (it->first->GetFile() == samplePath) {
59 /* Because the start of the sample is cached in RAM we treat
60 * same sample with different offset as different samples
61 * // TODO: Ignore offset when the whole sample is cached in RAM?
62 */
63 if (it->first->Offset == offset && it->first->End == end) return it->first;
64 }
65 }
66
67 return NULL;
68 }
69
70 /////////////////////////////////////////////////////////////
71 // class Script
72
73 Script::Script(LinuxSampler::Path path) : m_path(path) {
74 }
75
76 Script::Script(String path) : m_path(LinuxSampler::Path::fromUnknownFS(path)) {
77 }
78
79 Script::~Script() {
80 }
81
82 String Script::Name() const {
83 return m_path.getName();
84 }
85
86 Script::Language_t Script::Language() {
87 return LANGUAGE_NKSP;
88 }
89
90 String Script::GetSourceCode() {
91 std::ifstream f(m_path.toNativeFSPath().c_str());
92 std::string s;
93 // reserve required space on string object
94 f.seekg(0, std::ios::end);
95 s.reserve(f.tellg());
96 f.seekg(0, std::ios::beg);
97 // read entire content from file and assign it to string object
98 s.assign((std::istreambuf_iterator<char>(f)),
99 std::istreambuf_iterator<char>());
100 return s;
101 }
102
103 /////////////////////////////////////////////////////////////
104 // class Articulation
105
106 Articulation::Articulation()
107 {
108 }
109
110 Articulation::~Articulation()
111 {
112 }
113
114 /////////////////////////////////////////////////////////////
115 // class Definition
116
117 Definition::Definition()
118 {
119 }
120
121 Definition::~Definition()
122 {
123 }
124
125 /////////////////////////////////////////////////////////////
126 // class Region
127
128 Region::Region()
129 {
130 pSample = NULL;
131 seq_counter = 1;
132 }
133
134 Region::~Region()
135 {
136 DestroySampleIfNotUsed();
137 }
138
139 Sample* Region::GetSample(bool create)
140 {
141 if (pSample == NULL && create && sample != "*silence") {
142 uint i = offset ? *offset : 0;
143 Sample* sf = GetInstrument()->GetSampleManager()->FindSample(sample, i, end);
144 if (sf != NULL) pSample = sf; // Reuse already created sample
145 else pSample = new Sample(sample, false, i, end);
146 GetInstrument()->GetSampleManager()->AddSampleConsumer(pSample, this);
147 }
148 return pSample;
149 }
150
151 void Region::DestroySampleIfNotUsed() {
152 if (pSample == NULL) return;
153 GetInstrument()->GetSampleManager()->RemoveSampleConsumer(pSample, this);
154 if (!GetInstrument()->GetSampleManager()->HasSampleConsumers(pSample)) {
155 GetInstrument()->GetSampleManager()->RemoveSample(pSample);
156 delete pSample;
157 pSample = NULL;
158 }
159 }
160
161 bool Region::OnKey(const Query& q) {
162 // As the region comes from a LookupTable search on the query,
163 // the following parameters are not checked here: chan, key,
164 // vel, chanaft, polyaft, prog, sw_previous, cc. They are all
165 // handled by the lookup table.
166 bool is_triggered(
167 q.bend >= lobend && q.bend <= hibend &&
168 q.bpm >= lobpm && q.bpm < hibpm &&
169 q.rand >= lorand && q.rand < hirand &&
170 q.timer >= lotimer && q.timer <= hitimer &&
171
172 ( sw_last == -1 ||
173 ((sw_last >= sw_lokey && sw_last <= sw_hikey) ? (q.last_sw_key == sw_last) : false) ) &&
174
175 ( sw_down == -1 ||
176 ((sw_down >= sw_lokey && (sw_hikey == -1 || sw_down <= sw_hikey)) ? (q.sw[sw_down]) : false) ) &&
177
178 ( sw_up == -1 ||
179 ((sw_up >= sw_lokey && (sw_hikey == -1 || sw_up <= sw_hikey)) ? (!q.sw[sw_up]) : true) ) &&
180
181 ((trigger & q.trig) != 0)
182 );
183
184 if (!is_triggered)
185 return false;
186
187 // seq_position has to be checked last, so we know that we
188 // increment the right counter
189 is_triggered = (seq_counter == seq_position);
190 seq_counter = (seq_counter % seq_length) + 1;
191
192 return is_triggered;
193 }
194
195 Articulation*
196 Region::GetArticulation(int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft, uint8_t* cc)
197 {
198 return new Articulation(); //todo: implement GetArticulation()
199 }
200
201 bool Region::HasLoop() {
202 bool b = loop_mode == LOOP_UNSET ? pSample->GetLoops() :
203 (loop_mode == LOOP_CONTINUOUS || loop_mode == LOOP_SUSTAIN);
204 return b && GetLoopEnd() > GetLoopStart();
205 }
206
207 uint Region::GetLoopStart() {
208 return (!loop_start) ? pSample->GetLoopStart() : *loop_start;
209 }
210
211 uint Region::GetLoopEnd() {
212 return (!loop_end) ? pSample->GetLoopEnd() : *loop_end;
213 }
214
215 uint Region::GetLoopCount() {
216 return (!count) ? 0 : *count;
217 }
218
219 /////////////////////////////////////////////////////////////
220 // class Instrument
221
222 Instrument::Instrument(std::string name, SampleManager* pSampleManager) : KeyBindings(128, false), KeySwitchBindings(128, false)
223 {
224 this->name = name;
225 this->pSampleManager = pSampleManager ? pSampleManager : this;
226 pLookupTable = 0;
227
228 // The first 6 curves are defined internally (actually 7 with the one at index 0)
229 Curve c;
230 for (int i = 0; i < 128; i++) c.v[i] = i / 127.0f;
231 curves.add(c); curves.add(c); curves.add(c); curves.add(c);
232 curves.add(c); curves.add(c); curves.add(c);
233 ///////
234 }
235
236 Instrument::~Instrument()
237 {
238 for (int i = 0; i < regions.size(); i++) {
239 delete regions[i];
240 }
241 delete pLookupTable;
242 for (int i = 0 ; i < 128 ; i++) {
243 delete pLookupTableCC[i];
244 }
245 }
246
247 void Query::search(const Instrument* pInstrument) {
248 pRegionList = &pInstrument->pLookupTable->query(*this);
249 regionIndex = 0;
250 }
251
252 void Query::search(const Instrument* pInstrument, int triggercc) {
253 pRegionList = &pInstrument->pLookupTableCC[triggercc]->query(*this);
254 regionIndex = 0;
255 }
256
257 Region* Query::next() {
258 for ( ; regionIndex < pRegionList->size() ; regionIndex++) {
259 if ((*pRegionList)[regionIndex]->OnKey(*this)) {
260 return (*pRegionList)[regionIndex++];
261 }
262 }
263 return 0;
264 }
265
266 bool Instrument::DestroyRegion(Region* pRegion) {
267 for (std::vector<Region*>::iterator it = regions.begin(); it != regions.end(); it++) {
268 if(*it == pRegion) {
269 regions.erase(it);
270 delete pRegion;
271 return true;
272 }
273 }
274
275 return false;
276 }
277
278 bool Instrument::HasKeyBinding(uint8_t key) {
279 if (key > 127) return false;
280 return KeyBindings[key];
281 }
282
283 bool Instrument::HasKeySwitchBinding(uint8_t key) {
284 if (key > 127) return false;
285 return KeySwitchBindings[key];
286 }
287
288 /////////////////////////////////////////////////////////////
289 // class ContainerDefinition
290
291 ContainerDefinition::ContainerDefinition(section_type type)
292 {
293 Reset();
294 level = type;
295 }
296
297 ContainerDefinition::~ContainerDefinition()
298 {
299 }
300
301 void
302 ContainerDefinition::Reset()
303 {
304 // This is where all the default values are set.
305
306 // sample definition default
307 sample = "";
308
309 // input control
310 lochan = 1; hichan = 16;
311 lokey = 0; hikey = 127;
312 lovel = 0; hivel = 127;
313 lobend = -8192; hibend = 8192;
314 lobpm = 0; hibpm = 500;
315 lochanaft = 0; hichanaft = 127;
316 lopolyaft = 0; hipolyaft = 127;
317 loprog = 0; hiprog = 127;
318 lorand = 0.0; hirand = 1.0;
319 lotimer = 0.0; hitimer = 0.0;
320
321 seq_length = 1;
322 seq_position = 1;
323
324 sw_lokey = -1; sw_hikey = -1;
325 sw_last = -1;
326 sw_down = -1;
327 sw_up = -1;
328 sw_previous = -1;
329 sw_vel = VEL_CURRENT;
330
331 trigger = TRIGGER_ATTACK;
332
333 group = 0;
334 off_by = 0;
335 off_mode = OFF_FAST;
336
337 // sample player
338 count = optional<int>::nothing;
339 delay = optional<float>::nothing;
340 delay_random = optional<float>::nothing;
341 delay_beats = optional<int>::nothing;
342 stop_beats = optional<int>::nothing;
343 delay_samples = optional<int>::nothing;
344 end = 0;
345 loop_crossfade = optional<float>::nothing;
346 offset = optional<uint>::nothing;
347 offset_random = optional<int>::nothing;
348 loop_mode = LOOP_UNSET;
349 loop_start = optional<int>::nothing;
350 loop_end = optional<int>::nothing;
351 sync_beats = optional<int>::nothing;
352 sync_offset = optional<int>::nothing;
353
354 // amplifier
355 volume = 0;
356 volume_oncc.clear();
357 volume_curvecc.clear();
358 volume_smoothcc.clear();
359 volume_stepcc.clear();
360 amplitude = 100;
361 pan = 0;
362 pan_oncc.clear();
363 pan_curvecc.clear();
364 pan_smoothcc.clear();
365 pan_stepcc.clear();
366 width = 100;
367 position = 0;
368 amp_keytrack = 0;
369 amp_keycenter = 60;
370 amp_veltrack = 100;
371 amp_random = 0;
372 rt_decay = 0;
373 xfin_lokey = 0; xfin_hikey = 0;
374 xfout_lokey = 127; xfout_hikey = 127;
375 xf_keycurve = POWER;
376 xfin_lovel = 0; xfin_hivel = 0;
377 xfout_lovel = 127; xfout_hivel = 127;
378 xf_velcurve = POWER;
379 xf_cccurve = POWER;
380
381 // pitch
382 transpose = 0;
383 tune = 0;
384 pitch_keycenter = 60;
385 pitch_keytrack = 100;
386 pitch_veltrack = 0;
387 pitch_random = 0;
388 bend_up = 200;
389 bend_down = -200;
390 bend_step = 1;
391
392 pitch_oncc.clear();
393 pitch_smoothcc.clear();
394 pitch_curvecc.clear();
395 pitch_stepcc.clear();
396
397 // filter
398 fil_type = LPF_2P;
399 cutoff = optional<float>::nothing;
400 cutoff_chanaft = 0;
401 cutoff_polyaft = 0;
402 resonance = 0;
403 fil_keytrack = 0;
404 fil_keycenter = 60;
405 fil_veltrack = 0;
406 fil_random = 0;
407
408 fil2_type = LPF_2P;
409 cutoff2 = optional<float>::nothing;
410 cutoff2_chanaft = 0;
411 cutoff2_polyaft = 0;
412 resonance2 = 0;
413 fil2_keytrack = 0;
414 fil2_keycenter = 60;
415 fil2_veltrack = 0;
416 fil2_random = 0;
417
418 cutoff_oncc.clear();
419 cutoff_smoothcc.clear();
420 cutoff_curvecc.clear();
421 cutoff_stepcc.clear();
422 cutoff2_oncc.clear();
423 cutoff2_smoothcc.clear();
424 cutoff2_curvecc.clear();
425 cutoff2_stepcc.clear();
426
427 resonance_oncc.clear();
428 resonance_smoothcc.clear();
429 resonance_curvecc.clear();
430 resonance_stepcc.clear();
431 resonance2_oncc.clear();
432 resonance2_smoothcc.clear();
433 resonance2_curvecc.clear();
434 resonance2_stepcc.clear();
435
436 // per voice equalizer
437 eq1_freq = 50;
438 eq2_freq = 500;
439 eq3_freq = 5000;
440 eq1_vel2freq = 0;
441 eq2_vel2freq = 0;
442 eq3_vel2freq = 0;
443 eq1_bw = 1;
444 eq2_bw = 1;
445 eq3_bw = 1;
446 eq1_gain = 0;
447 eq2_gain = 0;
448 eq3_gain = 0;
449 eq1_vel2gain = 0;
450 eq2_vel2gain = 0;
451 eq3_vel2gain = 0;
452
453 // CCs
454 for (int i = 0; i < 128; ++i)
455 {
456 // input control
457 locc.set(i, 0);
458 hicc.set(i, 127);
459 start_locc.set(i, -1);
460 start_hicc.set(i, -1);
461 stop_locc.set(i, -1);
462 stop_hicc.set(i, -1);
463 on_locc.set(i, -1);
464 on_hicc.set(i, -1);
465
466 // sample player
467 delay_oncc.set(i, optional<float>::nothing);
468 delay_samples_oncc.set(i, optional<int>::nothing);
469 offset_oncc.set(i, optional<int>::nothing);
470
471 // amplifier
472 amp_velcurve.set(i, -1);
473 gain_oncc.set(i, 0);
474 xfin_locc.set(i, 0);
475 xfin_hicc.set(i, 0);
476 xfout_locc.set(i, 0);
477 xfout_hicc.set(i, 0);
478
479 // per voice equalizer
480 eq1_freq_oncc.set(i, 0);
481 eq2_freq_oncc.set(i, 0);
482 eq3_freq_oncc.set(i, 0);
483 eq1_bw_oncc.set(i, 0);
484 eq2_bw_oncc.set(i, 0);
485 eq3_bw_oncc.set(i, 0);
486 eq1_gain_oncc.set(i, 0);
487 eq2_gain_oncc.set(i, 0);
488 eq3_gain_oncc.set(i, 0);
489 }
490
491 eg.clear();
492 lfos.clear();
493
494 // deprecated
495 ampeg_delay = 0;
496 ampeg_start = 0; //in percentage
497 ampeg_attack = 0;
498 ampeg_hold = 0;
499 ampeg_decay = 0;
500 ampeg_sustain = -1; // in percentage
501 ampeg_release = 0;
502
503 ampeg_vel2delay = 0;
504 ampeg_vel2attack = 0;
505 ampeg_vel2hold = 0;
506 ampeg_vel2decay = 0;
507 ampeg_vel2sustain = 0;
508 ampeg_vel2release = 0;
509
510 ampeg_delaycc.clear();
511 ampeg_startcc.clear();
512 ampeg_attackcc.clear();
513 ampeg_holdcc.clear();
514 ampeg_decaycc.clear();
515 ampeg_sustaincc.clear();
516 ampeg_releasecc.clear();
517
518 fileg_delay = 0;
519 fileg_start = 0; //in percentage
520 fileg_attack = 0;
521 fileg_hold = 0;
522 fileg_decay = 0;
523 fileg_sustain = 100; // in percentage
524 fileg_release = 0;
525
526 fileg_vel2delay = 0;
527 fileg_vel2attack = 0;
528 fileg_vel2hold = 0;
529 fileg_vel2decay = 0;
530 fileg_vel2sustain = 0;
531 fileg_vel2release = 0;
532 fileg_depth = 0;
533
534 fileg_delay_oncc.clear();
535 fileg_start_oncc.clear();
536 fileg_attack_oncc.clear();
537 fileg_hold_oncc.clear();
538 fileg_decay_oncc.clear();
539 fileg_sustain_oncc.clear();
540 fileg_release_oncc.clear();
541 fileg_depth_oncc.clear();
542
543 pitcheg_delay = 0;
544 pitcheg_start = 0; //in percentage
545 pitcheg_attack = 0;
546 pitcheg_hold = 0;
547 pitcheg_decay = 0;
548 pitcheg_sustain = 100; // in percentage
549 pitcheg_release = 0;
550 pitcheg_depth = 0;
551
552 pitcheg_vel2delay = 0;
553 pitcheg_vel2attack = 0;
554 pitcheg_vel2hold = 0;
555 pitcheg_vel2decay = 0;
556 pitcheg_vel2sustain = 0;
557 pitcheg_vel2release = 0;
558
559 pitcheg_delay_oncc.clear();
560 pitcheg_start_oncc.clear();
561 pitcheg_attack_oncc.clear();
562 pitcheg_hold_oncc.clear();
563 pitcheg_decay_oncc.clear();
564 pitcheg_sustain_oncc.clear();
565 pitcheg_release_oncc.clear();
566 pitcheg_depth_oncc.clear();
567
568 amplfo_delay = 0;
569 amplfo_fade = 0;
570 amplfo_freq = -1; /* -1 is used to determine whether the LFO was initialized */
571 amplfo_depth = 0;
572 amplfo_delay_oncc.clear();
573 amplfo_fade_oncc.clear();
574 amplfo_depthcc.clear();
575 amplfo_freqcc.clear();
576
577 fillfo_delay = 0;
578 fillfo_fade = 0;
579 fillfo_freq = -1; /* -1 is used to determine whether the LFO was initialized */
580 fillfo_depth = 0;
581 fillfo_delay_oncc.clear();
582 fillfo_fade_oncc.clear();
583 fillfo_depthcc.clear();
584 fillfo_freqcc.clear();
585
586 pitchlfo_delay = 0;
587 pitchlfo_fade = 0;
588 pitchlfo_freq = -1; /* -1 is used to determine whether the LFO was initialized */
589 pitchlfo_depth = 0;
590 pitchlfo_delay_oncc.clear();
591 pitchlfo_fade_oncc.clear();
592 pitchlfo_depthcc.clear();
593 pitchlfo_freqcc.clear();
594 }
595
596 void ContainerDefinition::CopyValuesToDefinition(Definition* definition)
597 {
598 // This is where the current settings are copied to the new definition.
599
600 // sample definition
601 definition->sample = sample;
602
603 // input control
604 definition->lochan = lochan;
605 definition->hichan = hichan;
606 definition->lokey = lokey;
607 definition->hikey = hikey;
608 definition->lovel = lovel;
609 definition->hivel = hivel;
610 definition->locc = locc;
611 definition->hicc = hicc;
612 definition->lobend = lobend;
613 definition->hibend = hibend;
614 definition->lobpm = lobpm;
615 definition->hibpm = hibpm;
616 definition->lochanaft = lochanaft;
617 definition->hichanaft = hichanaft;
618 definition->lopolyaft = lopolyaft;
619 definition->hipolyaft = hipolyaft;
620 definition->loprog = loprog;
621 definition->hiprog = hiprog;
622 definition->lorand = lorand;
623 definition->hirand = hirand;
624 definition->lotimer = lotimer;
625 definition->hitimer = hitimer;
626 definition->seq_length = seq_length;
627 definition->seq_position = seq_position;
628 definition->start_locc = start_locc;
629 definition->start_hicc = start_hicc;
630 definition->stop_locc = stop_locc;
631 definition->stop_hicc = stop_hicc;
632 definition->sw_lokey = sw_lokey;
633 definition->sw_hikey = sw_hikey;
634 definition->sw_last = sw_last;
635 definition->sw_down = sw_down;
636 definition->sw_up = sw_up;
637 definition->sw_previous = sw_previous;
638 definition->sw_vel = sw_vel;
639 definition->trigger = trigger;
640 definition->group = group;
641 definition->off_by = off_by;
642 definition->off_mode = off_mode;
643 definition->on_locc = on_locc;
644 definition->on_hicc = on_hicc;
645
646 // sample player
647 definition->count = count;
648 definition->delay = delay;
649 definition->delay_random = delay_random;
650 definition->delay_oncc = delay_oncc;
651 definition->delay_beats = delay_beats;
652 definition->stop_beats = stop_beats;
653 definition->delay_samples = delay_samples;
654 definition->delay_samples_oncc = delay_samples_oncc;
655 definition->end = end;
656 definition->loop_crossfade = loop_crossfade;
657 definition->offset = offset;
658 definition->offset_random = offset_random;
659 definition->offset_oncc = offset_oncc;
660 definition->loop_mode = loop_mode;
661 definition->loop_start = loop_start;
662 definition->loop_end = loop_end;
663 definition->sync_beats = sync_beats;
664 definition->sync_offset = sync_offset;
665
666 // amplifier
667 definition->volume = volume;
668 definition->volume_oncc = volume_oncc;
669 definition->volume_curvecc = volume_curvecc;
670 definition->volume_smoothcc = volume_smoothcc;
671 definition->volume_stepcc = volume_stepcc;
672 definition->amplitude = amplitude;
673 definition->pan = pan;
674 definition->pan_oncc = pan_oncc;
675 definition->pan_curvecc = pan_curvecc;
676 definition->pan_smoothcc = pan_smoothcc;
677 definition->pan_stepcc = pan_stepcc;
678 definition->width = width;
679 definition->position = position;
680 definition->amp_keytrack = amp_keytrack;
681 definition->amp_keycenter = amp_keycenter;
682 definition->amp_veltrack = amp_veltrack;
683 definition->amp_velcurve = amp_velcurve;
684 definition->amp_random = amp_random;
685 definition->rt_decay = rt_decay;
686 definition->gain_oncc = gain_oncc;
687 definition->xfin_lokey = xfin_lokey;
688 definition->xfin_hikey = xfin_hikey;
689 definition->xfout_lokey = xfout_lokey;
690 definition->xfout_hikey = xfout_hikey;
691 definition->xf_keycurve = xf_keycurve;
692 definition->xfin_lovel = xfin_lovel;
693 definition->xfin_hivel = xfin_hivel;
694 definition->xfout_lovel = xfout_lovel;
695 definition->xfout_hivel = xfout_hivel;
696 definition->xf_velcurve = xf_velcurve;
697 definition->xfin_locc = xfin_locc;
698 definition->xfin_hicc = xfin_hicc;
699 definition->xfout_locc = xfout_locc;
700 definition->xfout_hicc = xfout_hicc;
701 definition->xf_cccurve = xf_cccurve;
702
703 // pitch
704 definition->transpose = transpose;
705 definition->tune = tune;
706 definition->pitch_keycenter = pitch_keycenter;
707 definition->pitch_keytrack = pitch_keytrack;
708 definition->pitch_veltrack = pitch_veltrack;
709 definition->pitch_random = pitch_random;
710 definition->bend_up = bend_up;
711 definition->bend_down = bend_down;
712 definition->bend_step = bend_step;
713
714 definition->pitch_oncc = pitch_oncc;
715 definition->pitch_smoothcc = pitch_smoothcc;
716 definition->pitch_curvecc = pitch_curvecc;
717 definition->pitch_stepcc = pitch_stepcc;
718
719 // filter
720 definition->fil_type = fil_type;
721 definition->cutoff = cutoff;
722 definition->cutoff_oncc = cutoff_oncc;
723 definition->cutoff_smoothcc = cutoff_smoothcc;
724 definition->cutoff_stepcc = cutoff_stepcc;
725 definition->cutoff_curvecc = cutoff_curvecc;
726 definition->cutoff_chanaft = cutoff_chanaft;
727 definition->cutoff_polyaft = cutoff_polyaft;
728 definition->resonance = resonance;
729 definition->resonance_oncc = resonance_oncc;
730 definition->resonance_smoothcc = resonance_smoothcc;
731 definition->resonance_stepcc = resonance_stepcc;
732 definition->resonance_curvecc = resonance_curvecc;
733 definition->fil_keytrack = fil_keytrack;
734 definition->fil_keycenter = fil_keycenter;
735 definition->fil_veltrack = fil_veltrack;
736 definition->fil_random = fil_random;
737
738 definition->fil2_type = fil2_type;
739 definition->cutoff2 = cutoff2;
740 definition->cutoff2_oncc = cutoff2_oncc;
741 definition->cutoff2_smoothcc = cutoff2_smoothcc;
742 definition->cutoff2_stepcc = cutoff2_stepcc;
743 definition->cutoff2_curvecc = cutoff2_curvecc;
744 definition->cutoff2_chanaft = cutoff2_chanaft;
745 definition->cutoff2_polyaft = cutoff2_polyaft;
746 definition->resonance2 = resonance2;
747 definition->resonance2_oncc = resonance2_oncc;
748 definition->resonance2_smoothcc = resonance2_smoothcc;
749 definition->resonance2_stepcc = resonance2_stepcc;
750 definition->resonance2_curvecc = resonance2_curvecc;
751 definition->fil2_keytrack = fil2_keytrack;
752 definition->fil2_keycenter = fil2_keycenter;
753 definition->fil2_veltrack = fil2_veltrack;
754 definition->fil2_random = fil2_random;
755
756 // per voice equalizer
757 definition->eq1_freq = eq1_freq;
758 definition->eq2_freq = eq2_freq;
759 definition->eq3_freq = eq3_freq;
760 definition->eq1_freq_oncc = eq1_freq_oncc;
761 definition->eq2_freq_oncc = eq2_freq_oncc;
762 definition->eq3_freq_oncc = eq3_freq_oncc;
763 definition->eq1_vel2freq = eq1_vel2freq;
764 definition->eq2_vel2freq = eq2_vel2freq;
765 definition->eq3_vel2freq = eq3_vel2freq;
766 definition->eq1_bw = eq1_bw;
767 definition->eq2_bw = eq2_bw;
768 definition->eq3_bw = eq3_bw;
769 definition->eq1_bw_oncc = eq1_bw_oncc;
770 definition->eq2_bw_oncc = eq2_bw_oncc;
771 definition->eq3_bw_oncc = eq3_bw_oncc;
772 definition->eq1_gain = eq1_gain;
773 definition->eq2_gain = eq2_gain;
774 definition->eq3_gain = eq3_gain;
775 definition->eq1_gain_oncc = eq1_gain_oncc;
776 definition->eq2_gain_oncc = eq2_gain_oncc;
777 definition->eq3_gain_oncc = eq3_gain_oncc;
778 definition->eq1_vel2gain = eq1_vel2gain;
779 definition->eq2_vel2gain = eq2_vel2gain;
780 definition->eq3_vel2gain = eq3_vel2gain;
781
782 // envelope generator
783 definition->eg = eg;
784
785 // deprecated
786 definition->ampeg_delay = ampeg_delay;
787 definition->ampeg_start = ampeg_start;
788 definition->ampeg_attack = ampeg_attack;
789 definition->ampeg_hold = ampeg_hold;
790 definition->ampeg_decay = ampeg_decay;
791 definition->ampeg_sustain = ampeg_sustain;
792 definition->ampeg_release = ampeg_release;
793
794 definition->ampeg_vel2delay = ampeg_vel2delay;
795 definition->ampeg_vel2attack = ampeg_vel2attack;
796 definition->ampeg_vel2hold = ampeg_vel2hold;
797 definition->ampeg_vel2decay = ampeg_vel2decay;
798 definition->ampeg_vel2sustain = ampeg_vel2sustain;
799 definition->ampeg_vel2release = ampeg_vel2release;
800
801 definition->ampeg_delaycc = ampeg_delaycc;
802 definition->ampeg_startcc = ampeg_startcc;
803 definition->ampeg_attackcc = ampeg_attackcc;
804 definition->ampeg_holdcc = ampeg_holdcc;
805 definition->ampeg_decaycc = ampeg_decaycc;
806 definition->ampeg_sustaincc = ampeg_sustaincc;
807 definition->ampeg_releasecc = ampeg_releasecc;
808
809 definition->fileg_delay = fileg_delay;
810 definition->fileg_start = fileg_start;
811 definition->fileg_attack = fileg_attack;
812 definition->fileg_hold = fileg_hold;
813 definition->fileg_decay = fileg_decay;
814 definition->fileg_sustain = fileg_sustain;
815 definition->fileg_release = fileg_release;
816 definition->fileg_depth = fileg_depth;
817
818 definition->fileg_vel2delay = fileg_vel2delay;
819 definition->fileg_vel2attack = fileg_vel2attack;
820 definition->fileg_vel2hold = fileg_vel2hold;
821 definition->fileg_vel2decay = fileg_vel2decay;
822 definition->fileg_vel2sustain = fileg_vel2sustain;
823 definition->fileg_vel2release = fileg_vel2release;
824
825 definition->fileg_delay_oncc = fileg_delay_oncc;
826 definition->fileg_start_oncc = fileg_start_oncc;
827 definition->fileg_attack_oncc = fileg_attack_oncc;
828 definition->fileg_hold_oncc = fileg_hold_oncc;
829 definition->fileg_decay_oncc = fileg_decay_oncc;
830 definition->fileg_sustain_oncc = fileg_sustain_oncc;
831 definition->fileg_release_oncc = fileg_release_oncc;
832 definition->fileg_depth_oncc = fileg_depth_oncc;
833
834 definition->pitcheg_delay = pitcheg_delay;
835 definition->pitcheg_start = pitcheg_start;
836 definition->pitcheg_attack = pitcheg_attack;
837 definition->pitcheg_hold = pitcheg_hold;
838 definition->pitcheg_decay = pitcheg_decay;
839 definition->pitcheg_sustain = pitcheg_sustain;
840 definition->pitcheg_release = pitcheg_release;
841 definition->pitcheg_depth = pitcheg_depth;
842
843 definition->pitcheg_vel2delay = pitcheg_vel2delay;
844 definition->pitcheg_vel2attack = pitcheg_vel2attack;
845 definition->pitcheg_vel2hold = pitcheg_vel2hold;
846 definition->pitcheg_vel2decay = pitcheg_vel2decay;
847 definition->pitcheg_vel2sustain = pitcheg_vel2sustain;
848 definition->pitcheg_vel2release = pitcheg_vel2release;
849
850 definition->pitcheg_delay_oncc = pitcheg_delay_oncc;
851 definition->pitcheg_start_oncc = pitcheg_start_oncc;
852 definition->pitcheg_attack_oncc = pitcheg_attack_oncc;
853 definition->pitcheg_hold_oncc = pitcheg_hold_oncc;
854 definition->pitcheg_decay_oncc = pitcheg_decay_oncc;
855 definition->pitcheg_sustain_oncc = pitcheg_sustain_oncc;
856 definition->pitcheg_release_oncc = pitcheg_release_oncc;
857 definition->pitcheg_depth_oncc = pitcheg_depth_oncc;
858
859 definition->amplfo_delay = amplfo_delay;
860 definition->amplfo_fade = amplfo_fade;
861 definition->amplfo_freq = amplfo_freq;
862 definition->amplfo_depth = amplfo_depth;
863
864 definition->amplfo_delay_oncc = amplfo_delay_oncc;
865 definition->amplfo_fade_oncc = amplfo_fade_oncc;
866 definition->amplfo_depthcc = amplfo_depthcc;
867 definition->amplfo_freqcc = amplfo_freqcc;
868
869 definition->fillfo_delay = fillfo_delay;
870 definition->fillfo_fade = fillfo_fade;
871 definition->fillfo_freq = fillfo_freq;
872 definition->fillfo_depth = fillfo_depth;
873
874 definition->fillfo_delay_oncc = fillfo_delay_oncc;
875 definition->fillfo_fade_oncc = fillfo_fade_oncc;
876 definition->fillfo_depthcc = fillfo_depthcc;
877 definition->fillfo_freqcc = fillfo_freqcc;
878
879 definition->pitchlfo_delay = pitchlfo_delay;
880 definition->pitchlfo_fade = pitchlfo_fade;
881 definition->pitchlfo_freq = pitchlfo_freq;
882 definition->pitchlfo_depth = pitchlfo_depth;
883
884 definition->pitchlfo_delay_oncc = pitchlfo_delay_oncc;
885 definition->pitchlfo_fade_oncc = pitchlfo_fade_oncc;
886 definition->pitchlfo_depthcc = pitchlfo_depthcc;
887 definition->pitchlfo_freqcc = pitchlfo_freqcc;
888
889 definition->eg = eg;
890 definition->lfos = lfos;
891 }
892
893 /////////////////////////////////////////////////////////////
894 // class File
895
896 const std::string File::MACRO_NAME_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
897 const std::string File::MACRO_VALUE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_. /\\";
898
899 File::File(std::string file, SampleManager* pSampleManager) :
900 rootFile(file),
901 _current_section(GLOBAL),
902 id(0),
903 default_path(""),
904 octave_offset(0),
905 note_offset(0)
906 {
907 _instrument = new Instrument(LinuxSampler::Path::getBaseName(file), pSampleManager);
908 ContainerDefinition* defaultGlobalContainer = new ContainerDefinition(ContainerDefinition::GLOBAL);
909 _current_containers.push(defaultGlobalContainer);
910 pCurDef = defaultGlobalContainer;
911
912 parseFile(file,pSampleManager);
913
914 std::set<float*> velcurves;
915 for (int i = 0; i < _instrument->regions.size(); i++) {
916 ::sfz::Region* pRegion = _instrument->regions[i];
917 int low = pRegion->lokey;
918 int high = pRegion->hikey;
919 if (low != -1) { // lokey -1 means region doesn't play on note-on
920 // hikey -1 is the same as no limit, except that it
921 // also enables on_locc/on_hicc
922 if (high == -1) high = 127;
923 if (low < 0 || low > 127 || high < 0 || high > 127 || low > high) {
924 std::cerr << "Invalid key range: " << low << " - " << high << std::endl;
925 } else {
926 for (int j = low; j <= high; j++) _instrument->KeyBindings[j] = true;
927 }
928 }
929
930 // get keyswitches
931 low = pRegion->sw_lokey;
932 if (low < 0) low = 0;
933 high = pRegion->sw_hikey;
934 if (high == -1) {
935 // Key switches not defined, so nothing to do
936 } else if (low >= 0 && low <= 127 && high >= 0 && high <= 127 && high >= low) {
937 for (int j = low; j <= high; j++) _instrument->KeySwitchBindings[j] = true;
938 } else {
939 std::cerr << "Invalid key switch range: " << low << " - " << high << std::endl;
940 }
941
942 // create velocity response curve
943
944 // don't use copy-on-write here, instead change the actual
945 // unique buffers in memory
946 float* velcurve = const_cast<float*>(&pRegion->amp_velcurve[0]);
947 if (velcurves.insert(velcurve).second) {
948 int prev = 0;
949 float prevvalue = 0;
950 for (int v = 0 ; v < 128 ; v++) {
951 if (velcurve[v] >= 0) {
952 float step = (velcurve[v] - prevvalue) / (v - prev);
953 for ( ; prev < v ; prev++) {
954 velcurve[prev] = prevvalue;
955 prevvalue += step;
956 }
957 }
958 }
959 if (prev) {
960 float step = (1 - prevvalue) / (127 - prev);
961 for ( ; prev < 128 ; prev++) {
962 velcurve[prev] = prevvalue;
963 prevvalue += step;
964 }
965 } else {
966 // default curve
967 for (int v = 0 ; v < 128 ; v++) {
968 velcurve[v] = v * v / (127.0 * 127.0);
969 }
970 }
971 }
972 }
973
974 _instrument->pLookupTable = new LookupTable(_instrument);
975
976 // create separate lookup tables for controller triggered
977 // regions, one for each CC
978 for (int i = 0 ; i < 128 ; i++) {
979 _instrument->pLookupTableCC[i] = new LookupTable(_instrument, i);
980 }
981
982 for (int i = 0; i < _instrument->regions.size(); i++) {
983 Region* r = _instrument->regions[i];
984
985 copyCurves(r->volume_curvecc, r->volume_oncc);
986 r->volume_curvecc.clear();
987
988 copySmoothValues(r->volume_smoothcc, r->volume_oncc);
989 r->volume_smoothcc.clear();
990
991 copyStepValues(r->volume_stepcc, r->volume_oncc);
992 r->volume_stepcc.clear();
993
994 copyCurves(r->pitch_curvecc, r->pitch_oncc);
995 r->pitch_curvecc.clear();
996
997 copySmoothValues(r->pitch_smoothcc, r->pitch_oncc);
998 r->pitch_smoothcc.clear();
999
1000 copyStepValues(r->pitch_stepcc, r->pitch_oncc);
1001 r->pitch_stepcc.clear();
1002
1003 copyCurves(r->pan_curvecc, r->pan_oncc);
1004 r->pan_curvecc.clear();
1005
1006 copySmoothValues(r->pan_smoothcc, r->pan_oncc);
1007 r->pan_smoothcc.clear();
1008
1009 copyStepValues(r->pan_stepcc, r->pan_oncc);
1010 r->pan_stepcc.clear();
1011
1012 copyCurves(r->cutoff_curvecc, r->cutoff_oncc);
1013 r->cutoff_curvecc.clear();
1014
1015 copySmoothValues(r->cutoff_smoothcc, r->cutoff_oncc);
1016 r->cutoff_smoothcc.clear();
1017
1018 copyStepValues(r->cutoff_stepcc, r->cutoff_oncc);
1019 r->cutoff_stepcc.clear();
1020
1021 copyCurves(r->cutoff2_curvecc, r->cutoff2_oncc);
1022 r->cutoff2_curvecc.clear();
1023
1024 copySmoothValues(r->cutoff2_smoothcc, r->cutoff2_oncc);
1025 r->cutoff2_smoothcc.clear();
1026
1027 copyStepValues(r->cutoff2_stepcc, r->cutoff2_oncc);
1028 r->cutoff2_stepcc.clear();
1029
1030 copyCurves(r->resonance_curvecc, r->resonance_oncc);
1031 r->resonance_curvecc.clear();
1032
1033 copySmoothValues(r->resonance_smoothcc, r->resonance_oncc);
1034 r->resonance_smoothcc.clear();
1035
1036 copyStepValues(r->resonance_stepcc, r->resonance_oncc);
1037 r->resonance_stepcc.clear();
1038
1039 copyCurves(r->resonance2_curvecc, r->resonance2_oncc);
1040 r->resonance2_curvecc.clear();
1041
1042 copySmoothValues(r->resonance2_smoothcc, r->resonance2_oncc);
1043 r->resonance2_smoothcc.clear();
1044
1045 copyStepValues(r->resonance2_stepcc, r->resonance2_oncc);
1046 r->resonance2_stepcc.clear();
1047
1048 for (int j = 0; j < r->eg.size(); j++) {
1049 copyCurves(r->eg[j].pan_curvecc, r->eg[j].pan_oncc);
1050 r->eg[j].pan_curvecc.clear();
1051 }
1052
1053 for (int j = 0; j < r->lfos.size(); j++) {
1054 r->lfos[j].copySmoothValues();
1055 r->lfos[j].copyStepValues();
1056
1057 copySmoothValues(r->lfos[j].volume_smoothcc, r->lfos[j].volume_oncc);
1058 r->lfos[j].volume_smoothcc.clear();
1059
1060 copyStepValues(r->lfos[j].volume_stepcc, r->lfos[j].volume_oncc);
1061 r->lfos[j].volume_stepcc.clear();
1062
1063 copySmoothValues(r->lfos[j].freq_smoothcc, r->lfos[j].freq_oncc);
1064 r->lfos[j].freq_smoothcc.clear();
1065
1066 copyStepValues(r->lfos[j].freq_stepcc, r->lfos[j].freq_oncc);
1067 r->lfos[j].freq_stepcc.clear();
1068
1069 copySmoothValues(r->lfos[j].pitch_smoothcc, r->lfos[j].pitch_oncc);
1070 r->lfos[j].pitch_smoothcc.clear();
1071
1072 copyStepValues(r->lfos[j].pitch_stepcc, r->lfos[j].pitch_oncc);
1073 r->lfos[j].pitch_stepcc.clear();
1074
1075 copySmoothValues(r->lfos[j].pan_smoothcc, r->lfos[j].pan_oncc);
1076 r->lfos[j].pan_smoothcc.clear();
1077
1078 copyStepValues(r->lfos[j].pan_stepcc, r->lfos[j].pan_oncc);
1079 r->lfos[j].pan_stepcc.clear();
1080
1081 copySmoothValues(r->lfos[j].cutoff_smoothcc, r->lfos[j].cutoff_oncc);
1082 r->lfos[j].cutoff_smoothcc.clear();
1083
1084 copyStepValues(r->lfos[j].cutoff_stepcc, r->lfos[j].cutoff_oncc);
1085 r->lfos[j].cutoff_stepcc.clear();
1086
1087 copySmoothValues(r->lfos[j].resonance_smoothcc, r->lfos[j].resonance_oncc);
1088 r->lfos[j].resonance_smoothcc.clear();
1089
1090 copyStepValues(r->lfos[j].resonance_stepcc, r->lfos[j].resonance_oncc);
1091 r->lfos[j].resonance_stepcc.clear();
1092 }
1093 }
1094 }
1095
1096 void File::parseFile(std::string file, SampleManager* pSampleManager){
1097 enum token_type_t { HEADER, OPCODE };
1098 token_type_t token_type = (token_type_t) -1;
1099 std::string token_string;
1100
1101 std::ifstream fs(file.c_str());
1102 currentDir = LinuxSampler::Path::stripLastName(file);
1103 std::string token;
1104 std::string line;
1105 currentLine = 0;
1106
1107 // remember latest modification time of file
1108 checkFileModified(file);
1109
1110 while (std::getline(fs, line))
1111 {
1112 currentLine++;
1113 // COMMENT
1114 std::string::size_type slash_index = line.find("//");
1115 if (slash_index != std::string::npos)
1116 line.resize(slash_index);
1117
1118 // #include
1119 if (line.find("#include ") == 0) {
1120 size_t fname_start = line.find("\"");
1121 if (fname_start == std::string::npos) continue;
1122
1123 size_t fname_end = line.find("\"", fname_start + 1);
1124 if (fname_end == std::string::npos || fname_start == fname_end)
1125 continue;
1126 std::string fname = line.substr(fname_start + 1, fname_end - fname_start - 1);
1127
1128 if (!currentDir.empty() && !LinuxSampler::Path(fname).isAbsolute())
1129 fname = currentDir + LinuxSampler::File::DirSeparator + fname;
1130
1131 std::string cd = currentDir; // backup current dir
1132 int cl = currentLine;
1133 parseFile(fname, pSampleManager);
1134 currentDir = cd; // restore currentDir (since altered by parsefile())
1135 currentLine = cl;
1136 continue;
1137 }
1138 // #define
1139 else if (line.find("#define") == 0)
1140 {
1141
1142 size_t varname_start = line.find_first_not_of("\t ", std::strlen("#define"));
1143 size_t varname_end = line.find_first_of("\t ", varname_start + 1);
1144 size_t value_start = line.find_first_not_of("\t ", varname_end + 1);
1145
1146 std::string varname = line.substr(varname_start, varname_end - varname_start);
1147 std::string value = line.substr(value_start, std::string::npos);
1148
1149 if (varname.size() == 0 || value.size() == 0)
1150 {
1151 std::cerr << "sfz error: Malformed #define statement on line " << currentLine << std::endl;
1152 continue;
1153 }
1154
1155 // Deal with DOS EOLs
1156 if (value[value.size() - 1] == '\r')
1157 {
1158 value.erase(value.size() - 1);
1159 }
1160
1161 // Check varname
1162 if (varname[0] != '$')
1163 {
1164 std::cerr << "sfz error: Macro name '" << varname;
1165 std::cerr << "' doesn't start with '$'." << std::endl;
1166 continue;
1167 }
1168 // Invalid chars
1169 if (varname.find_first_not_of(MACRO_NAME_CHARS, 1) != std::string::npos)
1170 {
1171 std::cerr << "sfz error: Macro name '" << varname;
1172 std::cerr << "' contains invalid characters." << std::endl;
1173 }
1174
1175 // Check value
1176 // Match alphanumeric, underscore, and decimal point.
1177 if (value.find_first_not_of(MACRO_VALUE_CHARS) != std::string::npos)
1178 {
1179 std::cerr << "sfz error: Macro value '" << value;
1180 std::cerr << "' contains invalid characters." << std::endl;
1181 continue;
1182 }
1183
1184 _defined_macros[varname] = value;
1185
1186 continue;
1187 }
1188 // script=path/to/scriptfile
1189 else if (line.find("script") == 0) {
1190 size_t eq = line.find_first_of("=");
1191 if (eq == std::string::npos) {
1192 std::cerr << "sfz error: opcode 'script' misses '=' character\n";
1193 continue;
1194 }
1195 std::string value = trim( line.substr(eq+1, std::string::npos) );
1196 if (value.empty()) {
1197 std::cerr << "sfz error: empty path assigned to opcode 'script'\n";
1198 continue;
1199 }
1200 LinuxSampler::Path path = LinuxSampler::Path::fromUnknownFS(value);
1201 if (!currentDir.empty() && !path.isAbsolute())
1202 path = LinuxSampler::Path::fromUnknownFS(currentDir) + path;
1203 LinuxSampler::File file(path);
1204 if (!file.Exist()) {
1205 std::cerr << "sfz error: script file '" << value << "' does not exist\n";
1206 continue;
1207 }
1208 if (!file.IsFile()) {
1209 std::cerr << "sfz error: script '" << value << "' is not a file\n";
1210 continue;
1211 }
1212 Script script(path);
1213 _instrument->scripts.push_back(script);
1214
1215 continue;
1216 }
1217
1218 // DEFINITION
1219 std::stringstream linestream(line);
1220 int spaces = 0;
1221 while (linestream >> token)
1222 {
1223 linestream >> std::noskipws;
1224 if (token[0] == '<') {
1225 std::string::size_type p = token.find('>', 1);
1226 if (p != std::string::npos && p < (token.size() - 1)) {
1227 linestream.seekg(p + 1 - token.size(), std::stringstream::cur);
1228 token.erase(p + 1);
1229 }
1230 }
1231 if (token[0] == '<' && token[token.size()-1] == '>')
1232 {
1233 // HEAD
1234 if (!token_string.empty())
1235 {
1236 switch (token_type)
1237 {
1238 case HEADER:
1239 push_header(token_string);
1240 break;
1241 case OPCODE:
1242 push_opcode(token_string);
1243 break;
1244 }
1245 token_string.erase();
1246 }
1247 token_string.append(token);
1248 token_type = HEADER;
1249 }
1250 else if (token.find('=') != std::string::npos)
1251 {
1252 // HEAD
1253 if (!token_string.empty())
1254 {
1255 switch (token_type)
1256 {
1257 case HEADER:
1258 push_header(token_string);
1259 break;
1260 case OPCODE:
1261 push_opcode(token_string);
1262 break;
1263 }
1264 token_string.erase();
1265 }
1266 token_string.append(token);
1267 token_type = OPCODE;
1268 }
1269 else
1270 {
1271 // TAIL
1272 token_string.append(spaces, ' ');
1273 token_string.append(token);
1274 }
1275 spaces = 0;
1276 while (isspace(linestream.peek())) {
1277 linestream.ignore();
1278 spaces++;
1279 }
1280 }
1281
1282 // EOL
1283 if (!token_string.empty())
1284 {
1285 switch (token_type)
1286 {
1287 case HEADER:
1288 push_header(token_string);
1289 break;
1290 case OPCODE:
1291 push_opcode(token_string);
1292 break;
1293 }
1294 token_string.erase();
1295 }
1296 }
1297 }
1298
1299 optional<File::Time> File::getModTimeOfFile(std::string filename) {
1300 struct stat st;
1301
1302 if (stat(filename.c_str(), &st))
1303 return optional<File::Time>::nothing;
1304
1305 return (Time) {
1306 #if defined(WIN32)
1307 .sec = (intmax_t) st.st_mtime,
1308 .nsec = (uint32_t) 0
1309 #elif defined(__APPLE__)
1310 .sec = (intmax_t) st.st_mtimespec.tv_sec,
1311 .nsec = (uint32_t) st.st_mtimespec.tv_nsec
1312 #else
1313 .sec = (intmax_t) st.st_mtim.tv_sec,
1314 .nsec = (uint32_t) st.st_mtim.tv_nsec
1315 #endif
1316 };
1317 }
1318
1319 bool File::checkFileModified(std::string filename) {
1320 if (filename.empty()) {
1321 bool res = false;
1322 for (const auto& mod_time : mod_times) {
1323 res |= checkFileModified(mod_time.first);
1324 }
1325 return res;
1326 }
1327 optional<Time> mod_time = getModTimeOfFile(filename);
1328 if (!mod_time) return false;
1329 Time& prevTime = mod_times[filename];
1330 const bool res = *mod_time != prevTime;
1331 prevTime = *mod_time; // remember changed mtime
1332 return res;
1333 }
1334
1335 File::~File()
1336 {
1337 for (int i = 0; i < _current_containers.size(); i++)
1338 {
1339 delete _current_containers.top();
1340 _current_containers.pop();
1341 }
1342 delete _instrument;
1343 }
1344
1345 std::string File::filename() const {
1346 return rootFile;
1347 }
1348
1349 Instrument*
1350 File::GetInstrument()
1351 {
1352 return _instrument;
1353 }
1354
1355 void File::copyCurves(LinuxSampler::ArrayList<CC>& curves, LinuxSampler::ArrayList<CC>& dest) {
1356 for (int i = 0; i < curves.size(); i++) {
1357 for (int j = 0; j < dest.size(); j++) {
1358 if (curves[i].Controller == dest[j].Controller) {
1359 dest[j].Curve = curves[i].Curve;
1360 }
1361 }
1362 }
1363 }
1364
1365 void File::copySmoothValues(LinuxSampler::ArrayList<CC>& smooths, LinuxSampler::ArrayList<CC>& dest) {
1366 for (int i = 0; i < smooths.size(); i++) {
1367 for (int j = 0; j < dest.size(); j++) {
1368 if (smooths[i].Controller == dest[j].Controller) {
1369 dest[j].Smooth = smooths[i].Smooth;
1370 }
1371 }
1372 }
1373 }
1374
1375 void File::copyStepValues(LinuxSampler::ArrayList<CC>& steps, LinuxSampler::ArrayList<CC>& dest) {
1376 for (int i = 0; i < steps.size(); i++) {
1377 for (int j = 0; j < dest.size(); j++) {
1378 if (steps[i].Controller == dest[j].Controller) {
1379 dest[j].Step = steps[i].Step;
1380 }
1381 }
1382 }
1383 }
1384
1385 int File::ToInt(const std::string& s) throw(LinuxSampler::Exception) {
1386 int i;
1387 std::istringstream iss(s);
1388 if(!(iss >> i)) {
1389 std::ostringstream oss;
1390 oss << "Line " << currentLine << ": Expected an integer";
1391 throw LinuxSampler::Exception(oss.str());
1392 }
1393 return i;
1394 }
1395
1396 float File::ToFloat(const std::string& s) throw(LinuxSampler::Exception) {
1397 float i;
1398 std::istringstream iss(s);
1399 if(!(iss >> i)) {
1400 std::ostringstream oss;
1401 oss << "Line " << currentLine << ": Expected a floating-point number";
1402 throw LinuxSampler::Exception(oss.str());
1403 }
1404 return i;
1405 }
1406
1407 void
1408 File::push_header(std::string token)
1409 {
1410 if (token == "<global>" ||
1411 token == "<master>" ||
1412 token == "<group>")
1413 {
1414 ContainerDefinition::section_type level = ContainerDefinition::GLOBAL; // initialized only to avoid an irrelevant compiler warning
1415
1416 if (token == "<global>")
1417 {
1418 _current_section = GLOBAL;
1419 level = ContainerDefinition::GLOBAL;
1420 }
1421 else if (token == "<master>")
1422 {
1423 _current_section = MASTER;
1424 level = ContainerDefinition::MASTER;
1425 }
1426 else if (token == "<group>")
1427 {
1428 _current_section = GROUP;
1429 level = ContainerDefinition::GROUP;
1430 }
1431
1432 ContainerDefinition* newContainer = new ContainerDefinition(level);
1433
1434 while (_current_containers.size() > 0 && _current_containers.top()->level <= level)
1435 {
1436 delete _current_containers.top();
1437 _current_containers.pop();
1438 }
1439
1440 //If the new header is a <global>, there won't be anything left in _current_containers
1441 //to copy from.
1442 if (_current_containers.size() > 0)
1443 {
1444 _current_containers.top()->CopyValuesToDefinition(newContainer);
1445 }
1446 _current_containers.push(newContainer);
1447 pCurDef = newContainer;
1448 }
1449 else if (token == "<region>")
1450 {
1451 _current_section = REGION;
1452 _current_region = new Region();
1453 _current_region->id = id++;
1454 _current_containers.top()->CopyValuesToDefinition(_current_region);
1455 pCurDef = _current_region;
1456 _instrument->regions.push_back(_current_region);
1457 _current_region->SetInstrument(_instrument);
1458 }
1459 else if (token == "<control>")
1460 {
1461 _current_section = CONTROL;
1462 default_path = "";
1463 octave_offset = 0;
1464 note_offset = 0;
1465 }
1466 else if (token == "<curve>")
1467 {
1468 _current_section = CURVE;
1469 _instrument->curves.add(Curve());
1470 _current_curve = &_instrument->curves[_instrument->curves.size() - 1];
1471 }
1472 else
1473 {
1474 _current_section = UNKNOWN;
1475 std::cerr << "The header '" << token << "' is unsupported by libsfz!" << std::endl;
1476 }
1477 }
1478
1479 void
1480 File::push_opcode(std::string token)
1481 {
1482 if (_current_section == UNKNOWN)
1483 return;
1484
1485 std::string::size_type delimiter_index = token.find('=');
1486 std::string key = token.substr(0, delimiter_index);
1487 std::string value = token.substr(delimiter_index + 1);
1488 int x, y, z;
1489
1490 // Apply macros
1491 size_t macro_start = 0;
1492 size_t macro_end = 0;
1493 std::string macro_value;
1494 while ((macro_start = value.find("$", macro_start + macro_value.size())) != std::string::npos)
1495 {
1496 macro_end = value.find_first_not_of(MACRO_NAME_CHARS, macro_start + 1);
1497 size_t macro_len = macro_end - macro_start;
1498 std::string macro_name = value.substr(macro_start, macro_len);
1499 if (_defined_macros.count(macro_name) != 0)
1500 {
1501 macro_value = _defined_macros[macro_name];
1502 value.replace(macro_start, macro_len, macro_value);
1503 }
1504 else
1505 {
1506 std::cerr << "Macro '" << macro_name << "' referenced on line ";
1507 std::cerr << currentLine << " is undefined." << std::endl;
1508 return;
1509 }
1510 }
1511
1512 if (_current_section == CURVE) {
1513 if (sscanf(key.c_str(), "v%d", &x)) {
1514 if (x < 0 || x > 127) {
1515 std::cerr << "Invalid curve index: " << x << std::endl;
1516 }
1517 _current_curve->v[x] = check(key, 0.0f, 1.0f, ToFloat(value));
1518 } else {
1519 std::cerr << "The opcode '" << key << "' in section <curve> is unsupported by libsfz!" << std::endl;
1520 }
1521
1522 return;
1523 }
1524
1525 // sample definition
1526 if ("sample" == key)
1527 {
1528 // handle built-in sample types ...
1529 if (value == "*silence") {
1530 pCurDef->sample = value;
1531 return;
1532 } else if (value.length() >= 1 && value[0] == '*') {
1533 std::cerr << "Unknown or unsupported built-in sample type '" << value << "'!" << std::endl;
1534 return;
1535 }
1536
1537 // handle external samples ...
1538 std::string path = default_path + value;
1539 #ifndef WIN32
1540 for (int i = 0; i < path.length(); i++) if (path[i] == '\\') path[i] = '/';
1541 bool absolute = path[0] == '/';
1542 #else
1543 bool absolute = path[0] == '/' || path[0] == '\\' ||
1544 (path.length() >= 2 && isalpha(path[0]) && path[1] == ':');
1545 #endif
1546 if (!absolute) path = currentDir + LinuxSampler::File::DirSeparator + path;
1547 if(pCurDef) pCurDef->sample = path;
1548 return;
1549 }
1550
1551 // control header directives
1552 else if ("default_path" == key)
1553 {
1554 switch (_current_section)
1555 {
1556 case CONTROL:
1557 default_path = value;
1558 break;
1559 default:
1560 ; // noop
1561 }
1562 return;
1563 }
1564 else if ("octave_offset" == key)
1565 {
1566 switch (_current_section)
1567 {
1568 case CONTROL:
1569 octave_offset = ToInt(value);
1570 break;
1571 default:
1572 ; // noop
1573 }
1574 return;
1575 }
1576 else if ("note_offset" == key)
1577 {
1578 switch (_current_section)
1579 {
1580 case CONTROL:
1581 note_offset = ToInt(value);
1582 break;
1583 default:
1584 ; // noop
1585 }
1586 return;
1587 }
1588
1589 // input controls
1590 else if ("lochan" == key) pCurDef->lochan = ToInt(value);
1591 else if ("hichan" == key) pCurDef->hichan = ToInt(value);
1592 else if ("lokey" == key) pCurDef->lokey = parseKey(value);
1593 else if ("hikey" == key) pCurDef->hikey = parseKey(value);
1594 else if ("key" == key)
1595 {
1596 pCurDef->lokey = pCurDef->hikey = pCurDef->pitch_keycenter = parseKey(value);
1597 }
1598 else if ("lovel" == key) pCurDef->lovel = ToInt(value);
1599 else if ("hivel" == key) pCurDef->hivel = ToInt(value);
1600 else if ("lobend" == key) pCurDef->lobend = ToInt(value);
1601 else if ("hibend" == key) pCurDef->hibend = ToInt(value);
1602 else if ("lobpm" == key) pCurDef->lobpm = ToFloat(value);
1603 else if ("hibpm" == key) pCurDef->hibpm = ToFloat(value);
1604 else if ("lochanaft" == key) pCurDef->lochanaft = ToInt(value);
1605 else if ("hichanaft" == key) pCurDef->hichanaft = ToInt(value);
1606 else if ("lopolyaft" == key) pCurDef->lopolyaft = ToInt(value);
1607 else if ("hipolyaft" == key) pCurDef->hipolyaft = ToInt(value);
1608 else if ("loprog" == key) pCurDef->loprog = ToInt(value);
1609 else if ("hiprog" == key) pCurDef->hiprog = ToInt(value);
1610 else if ("lorand" == key) pCurDef->lorand = ToFloat(value);
1611 else if ("hirand" == key) pCurDef->hirand = ToFloat(value);
1612 else if ("lotimer" == key) pCurDef->lotimer = ToFloat(value);
1613 else if ("hitimer" == key) pCurDef->hitimer = ToFloat(value);
1614 else if ("seq_length" == key) pCurDef->seq_length = ToInt(value);
1615 else if ("seq_position" == key) pCurDef->seq_position = ToInt(value);
1616 else if ("sw_lokey" == key) pCurDef->sw_lokey = parseKey(value);
1617 else if ("sw_hikey" == key) pCurDef->sw_hikey = parseKey(value);
1618 else if ("sw_last" == key) pCurDef->sw_last = parseKey(value);
1619 else if ("sw_down" == key) pCurDef->sw_down = parseKey(value);
1620 else if ("sw_up" == key) pCurDef->sw_up = parseKey(value);
1621 else if ("sw_previous" == key) pCurDef->sw_previous = parseKey(value);
1622 else if ("sw_vel" == key)
1623 {
1624 if (value == "current") pCurDef->sw_vel = VEL_CURRENT;
1625 else if (value == "previous") pCurDef->sw_vel = VEL_PREVIOUS;
1626 }
1627 else if ("trigger" == key)
1628 {
1629 if (value == "attack") pCurDef->trigger = TRIGGER_ATTACK;
1630 else if (value == "release") pCurDef->trigger = TRIGGER_RELEASE;
1631 else if (value == "first") pCurDef->trigger = TRIGGER_FIRST;
1632 else if (value == "legato") pCurDef->trigger = TRIGGER_LEGATO;
1633 }
1634 else if ("group" == key) pCurDef->group = ToInt(value);
1635 else if ("off_by" == key || "offby" == key) pCurDef->off_by = ToInt(value);
1636 else if ("off_mode" == key || "offmode" == key)
1637 {
1638 if (value == "fast") pCurDef->off_mode = OFF_FAST;
1639 else if (value == "normal") pCurDef->off_mode = OFF_NORMAL;
1640 }
1641
1642 // sample player
1643 else if ("count" == key) { pCurDef->count = ToInt(value); pCurDef->loop_mode = ONE_SHOT; }
1644 else if ("delay" == key) pCurDef->delay = ToFloat(value);
1645 else if ("delay_random" == key) pCurDef->delay_random = ToFloat(value);
1646 else if ("delay_beats" == key) pCurDef->delay_beats = ToInt(value);
1647 else if ("stop_beats" == key) pCurDef->stop_beats = ToInt(value);
1648 else if ("delay_samples" == key) pCurDef->delay_samples = ToInt(value);
1649 else if ("end" == key) pCurDef->end = ToInt(value);
1650 else if ("loop_crossfade" == key) pCurDef->loop_crossfade = ToFloat(value);
1651 else if ("offset_random" == key) pCurDef->offset_random = ToInt(value);
1652 else if ("loop_mode" == key || "loopmode" == key)
1653 {
1654 if (value == "no_loop") pCurDef->loop_mode = NO_LOOP;
1655 else if (value == "one_shot") pCurDef->loop_mode = ONE_SHOT;
1656 else if (value == "loop_continuous") pCurDef->loop_mode = LOOP_CONTINUOUS;
1657 else if (value == "loop_sustain") pCurDef->loop_mode = LOOP_SUSTAIN;
1658 }
1659 else if ("loop_start" == key) pCurDef->loop_start = ToInt(value);
1660 else if ("loopstart" == key) pCurDef->loop_start = ToInt(value); // nonstandard
1661 else if ("loop_end" == key) pCurDef->loop_end = ToInt(value);
1662 else if ("loopend" == key) pCurDef->loop_end = ToInt(value); // nonstandard
1663 else if ("offset" == key) pCurDef->offset = ToInt(value);
1664 else if ("sync_beats" == key) pCurDef->sync_beats = ToInt(value);
1665 else if ("sync_offset" == key) pCurDef->sync_offset = ToInt(value);
1666
1667 // amplifier
1668 else if ("volume" == key) pCurDef->volume = ToFloat(value);
1669 else if ("amplitude" == key) pCurDef->amplitude = ToFloat(value);
1670 else if ("pan" == key) pCurDef->pan = ToFloat(value);
1671 else if ("width" == key) pCurDef->width = ToFloat(value);
1672 else if ("position" == key) pCurDef->position = ToFloat(value);
1673 else if ("amp_keytrack" == key) pCurDef->amp_keytrack = ToFloat(value);
1674 else if ("amp_keycenter" == key) pCurDef->amp_keycenter = parseKey(value);
1675 else if ("amp_veltrack" == key) pCurDef->amp_veltrack = ToFloat(value);
1676 else if ("amp_random" == key) pCurDef->amp_random = ToFloat(value);
1677 else if ("rt_decay" == key || "rtdecay" == key) pCurDef->rt_decay = ToFloat(value);
1678 else if ("xfin_lokey" == key) pCurDef->xfin_lokey = parseKey(value);
1679 else if ("xfin_hikey" == key) pCurDef->xfin_hikey = parseKey(value);
1680 else if ("xfout_lokey" == key) pCurDef->xfout_lokey = parseKey(value);
1681 else if ("xfout_hikey" == key) pCurDef->xfout_hikey = parseKey(value);
1682 else if ("xf_keycurve" == key)
1683 {
1684 if (value == "gain") pCurDef->xf_keycurve = GAIN;
1685 else if (value == "power") pCurDef->xf_keycurve = POWER;
1686 }
1687 else if ("xfin_lovel" == key) pCurDef->xfin_lovel = ToInt(value);
1688 else if ("xfin_hivel" == key) pCurDef->xfin_hivel = ToInt(value);
1689 else if ("xfout_lovel" == key) pCurDef->xfout_lovel = ToInt(value);
1690 else if ("xfout_hivel" == key) pCurDef->xfout_hivel = ToInt(value);
1691 else if ("xf_velcurve" == key)
1692 {
1693 if (value == "gain") pCurDef->xf_velcurve = GAIN;
1694 else if (value == "power") pCurDef->xf_velcurve = POWER;
1695 }
1696 else if ("xf_cccurve" == key)
1697 {
1698 if (value == "gain") pCurDef->xf_cccurve = GAIN;
1699 else if (value == "power") pCurDef->xf_cccurve = POWER;
1700 }
1701
1702 // pitch
1703 else if ("transpose" == key) pCurDef->transpose = ToInt(value);
1704 else if ("tune" == key) pCurDef->tune = ToInt(value);
1705 else if ("pitch_keycenter" == key) pCurDef->pitch_keycenter = parseKey(value);
1706 else if ("pitch_keytrack" == key) pCurDef->pitch_keytrack = ToInt(value);
1707 else if ("pitch_veltrack" == key) pCurDef->pitch_veltrack = ToInt(value);
1708 else if ("pitch_random" == key) pCurDef->pitch_random = ToInt(value);
1709 else if ("bend_up" == key || "bendup" == key) pCurDef->bend_up = ToInt(value);
1710 else if ("bend_down" == key || "benddown" == key) pCurDef->bend_down = ToInt(value);
1711 else if ("bend_step" == key || "bendstep" == key) pCurDef->bend_step = ToInt(value);
1712
1713 // filter
1714 else if ("fil_type" == key || "filtype" == key)
1715 {
1716 if (value == "lpf_1p") pCurDef->fil_type = LPF_1P;
1717 else if (value == "hpf_1p") pCurDef->fil_type = HPF_1P;
1718 else if (value == "bpf_1p") pCurDef->fil_type = BPF_1P;
1719 else if (value == "brf_1p") pCurDef->fil_type = BRF_1P;
1720 else if (value == "apf_1p") pCurDef->fil_type = APF_1P;
1721 else if (value == "lpf_2p") pCurDef->fil_type = LPF_2P;
1722 else if (value == "hpf_2p") pCurDef->fil_type = HPF_2P;
1723 else if (value == "bpf_2p") pCurDef->fil_type = BPF_2P;
1724 else if (value == "brf_2p") pCurDef->fil_type = BRF_2P;
1725 else if (value == "pkf_2p") pCurDef->fil_type = PKF_2P;
1726 else if (value == "lpf_4p") pCurDef->fil_type = LPF_4P;
1727 else if (value == "hpf_4p") pCurDef->fil_type = HPF_4P;
1728 else if (value == "lpf_6p") pCurDef->fil_type = LPF_6P;
1729 else if (value == "hpf_6p") pCurDef->fil_type = HPF_6P;
1730 }
1731 else if ("fil2_type" == key)
1732 {
1733 if (value == "lpf_1p") pCurDef->fil2_type = LPF_1P;
1734 else if (value == "hpf_1p") pCurDef->fil2_type = HPF_1P;
1735 else if (value == "bpf_1p") pCurDef->fil2_type = BPF_1P;
1736 else if (value == "brf_1p") pCurDef->fil2_type = BRF_1P;
1737 else if (value == "apf_1p") pCurDef->fil2_type = APF_1P;
1738 else if (value == "lpf_2p") pCurDef->fil2_type = LPF_2P;
1739 else if (value == "hpf_2p") pCurDef->fil2_type = HPF_2P;
1740 else if (value == "bpf_2p") pCurDef->fil2_type = BPF_2P;
1741 else if (value == "brf_2p") pCurDef->fil2_type = BRF_2P;
1742 else if (value == "pkf_2p") pCurDef->fil2_type = PKF_2P;
1743 else if (value == "lpf_4p") pCurDef->fil2_type = LPF_4P;
1744 else if (value == "hpf_4p") pCurDef->fil2_type = HPF_4P;
1745 else if (value == "lpf_6p") pCurDef->fil2_type = LPF_6P;
1746 else if (value == "hpf_6p") pCurDef->fil2_type = HPF_6P;
1747 }
1748 else if ("cutoff" == key) pCurDef->cutoff = ToFloat(value);
1749 else if ("cutoff2" == key) pCurDef->cutoff2 = ToFloat(value);
1750 else if ("cutoff_chanaft" == key) {
1751 pCurDef->cutoff_chanaft = check(key, -9600, 9600, ToInt(value));
1752 pCurDef->cutoff_oncc.add( CC(128, check(key, -9600, 9600, ToInt(value))) );
1753 } else if ("cutoff2_chanaft" == key) pCurDef->cutoff2_chanaft = ToInt(value);
1754 else if ("cutoff_polyaft" == key) pCurDef->cutoff_polyaft = ToInt(value);
1755 else if ("cutoff2_polyaft" == key) pCurDef->cutoff2_polyaft = ToInt(value);
1756 else if ("resonance" == key) pCurDef->resonance = ToFloat(value);
1757 else if ("resonance2" == key) pCurDef->resonance2 = ToFloat(value);
1758 else if ("fil_keytrack" == key) pCurDef->fil_keytrack = ToInt(value);
1759 else if ("fil2_keytrack" == key) pCurDef->fil2_keytrack = ToInt(value);
1760 else if ("fil_keycenter" == key) pCurDef->fil_keycenter = parseKey(value);
1761 else if ("fil2_keycenter" == key) pCurDef->fil2_keycenter = parseKey(value);
1762 else if ("fil_veltrack" == key) pCurDef->fil_veltrack = ToInt(value);
1763 else if ("fil2_veltrack" == key) pCurDef->fil2_veltrack = ToInt(value);
1764 else if ("fil_random" == key) pCurDef->fil_random = ToInt(value);
1765 else if ("fil2_random" == key) pCurDef->fil2_random = ToInt(value);
1766
1767 // per voice equalizer
1768 else if ("eq1_freq" == key) pCurDef->eq1_freq = ToFloat(value);
1769 else if ("eq2_freq" == key) pCurDef->eq2_freq = ToFloat(value);
1770 else if ("eq3_freq" == key) pCurDef->eq3_freq = ToFloat(value);
1771 else if ("eq1_vel2freq" == key) pCurDef->eq1_vel2freq = ToFloat(value);
1772 else if ("eq2_vel2freq" == key) pCurDef->eq2_vel2freq = ToFloat(value);
1773 else if ("eq3_vel2freq" == key) pCurDef->eq3_vel2freq = ToFloat(value);
1774 else if ("eq1_bw" == key) pCurDef->eq1_bw = ToFloat(value);
1775 else if ("eq2_bw" == key) pCurDef->eq2_bw = ToFloat(value);
1776 else if ("eq3_bw" == key) pCurDef->eq3_bw = ToFloat(value);
1777 else if ("eq1_gain" == key) pCurDef->eq1_gain = ToFloat(value);
1778 else if ("eq2_gain" == key) pCurDef->eq2_gain = ToFloat(value);
1779 else if ("eq3_gain" == key) pCurDef->eq3_gain = ToFloat(value);
1780 else if ("eq1_vel2gain" == key) pCurDef->eq1_vel2gain = ToFloat(value);
1781 else if ("eq2_vel2gain" == key) pCurDef->eq2_vel2gain = ToFloat(value);
1782 else if ("eq3_vel2gain" == key) pCurDef->eq3_vel2gain = ToFloat(value);
1783
1784 else if (sscanf(key.c_str(), "amp_velcurve_%d", &x)) {
1785 pCurDef->amp_velcurve.set(x, ToFloat(value));
1786 }
1787
1788 // v2 envelope generators
1789 else if (sscanf(key.c_str(), "eg%d%n", &x, &y)) {
1790 const char* s = key.c_str() + y;
1791 if (sscanf(s, "_time%d%n", &y, &z)) {
1792 const char* s2 = s + z;
1793 if (strcmp(s2, "") == 0) egnode(x, y).time = check(key, 0.0f, 100.0f, ToFloat(value));
1794 else if (sscanf(s2, "_oncc%d", &z)) egnode(x, y).time_oncc.add( CC(z, check(key, 0.0f, 100.0f, ToFloat(value))) );
1795 } else if (sscanf(s, "_level%d%n", &y, &z)) {
1796 const char* s2 = s + z;
1797 if (strcmp(s2, "") == 0) egnode(x, y).level = check(key, 0.0f, 1.0f, ToFloat(value));
1798 else if (sscanf(s2, "_oncc%d", &z)) egnode(x, y).level_oncc.add( CC(z, check(key, 0.0f, 1.0f, ToFloat(value))) );
1799 }
1800 else if (sscanf(s, "_shape%d", &y)) egnode(x, y).shape = ToFloat(value);
1801 else if (sscanf(s, "_curve%d", &y)) egnode(x, y).curve = ToFloat(value);
1802 else if (strcmp(s, "_sustain") == 0) eg(x).sustain = ToInt(value);
1803 else if (strcmp(s, "_loop") == 0) eg(x).loop = ToInt(value);
1804 else if (strcmp(s, "_loop_count") == 0) eg(x).loop_count = ToInt(value);
1805 else if (strcmp(s, "_amplitude") == 0) eg(x).amplitude = ToFloat(value);
1806 else if (sscanf(s, "_amplitude_oncc%d", &y)) eg(x).amplitude_oncc.add( CC(y, check(key, 0.0f, 100.0f, ToFloat(value))) );
1807 else if (strcmp(s, "_volume") == 0) eg(x).volume = check(key, -144.0f, 6.0f, ToFloat(value));
1808 else if (sscanf(s, "_volume_oncc%d", &y)) eg(x).volume_oncc.add( CC(y, check(key, -144.0f, 6.0f, ToFloat(value))) );
1809 else if (strcmp(s, "_cutoff") == 0) eg(x).cutoff = ToFloat(value);
1810 else if (sscanf(s, "_cutoff_oncc%d", &y)) eg(x).cutoff_oncc.add( CC(y, check(key, -9600, 9600, ToInt(value))) );
1811 else if (strcmp(s, "_pitch") == 0) eg(x).pitch = check(key, -9600, 9600, ToInt(value));
1812 else if (sscanf(s, "_pitch_oncc%d", &y)) eg(x).pitch_oncc.add( CC(y, check(key, -9600, 9600, ToInt(value))) );
1813 else if (strcmp(s, "_resonance") == 0) eg(x).resonance = check(key, 0.0f, 40.0f, ToFloat(value));
1814 else if (sscanf(s, "_resonance_oncc%d", &y)) eg(x).resonance_oncc.add( CC(y, check(key, 0.0f, 40.0f, ToFloat(value))) );
1815 else if (strcmp(s, "_pan") == 0) eg(x).pan = check(key, -100.0f, 100.0f, ToFloat(value));
1816 else if (strcmp(s, "_pan_curve") == 0) eg(x).pan_curve = check(key, 0, 30000, ToInt(value));
1817 else if (sscanf(s, "_pan_oncc%d", &y)) eg(x).pan_oncc.add( CC(y, check(key, -100.0f, 100.0f, ToFloat(value))) );
1818 else if (sscanf(s, "_pan_curvecc%d", &y)) eg(x).pan_curvecc.add( CC(y, 0.0f, check(key, 0, 30000, ToInt(value))) );
1819 else if (strcmp(s, "_eq1freq") == 0) eg(x).eq1freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1820 else if (strcmp(s, "_eq2freq") == 0) eg(x).eq2freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1821 else if (strcmp(s, "_eq3freq") == 0) eg(x).eq3freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1822 else if (strcmp(s, "_eq1bw") == 0) eg(x).eq1bw = check(key, 0.001f, 4.0f, ToFloat(value));
1823 else if (strcmp(s, "_eq2bw") == 0) eg(x).eq2bw = check(key, 0.001f, 4.0f, ToFloat(value));
1824 else if (strcmp(s, "_eq3bw") == 0) eg(x).eq3bw = check(key, 0.001f, 4.0f, ToFloat(value));
1825 else if (strcmp(s, "_eq1gain") == 0) eg(x).eq1gain = check(key, -96.0f, 24.0f, ToFloat(value));
1826 else if (strcmp(s, "_eq2gain") == 0) eg(x).eq2gain = check(key, -96.0f, 24.0f, ToFloat(value));
1827 else if (strcmp(s, "_eq3gain") == 0) eg(x).eq3gain = check(key, -96.0f, 24.0f, ToFloat(value));
1828 else if (sscanf(s, "_eq1freq_oncc%d", &y)) eg(x).eq1freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1829 else if (sscanf(s, "_eq2freq_oncc%d", &y)) eg(x).eq2freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1830 else if (sscanf(s, "_eq3freq_oncc%d", &y)) eg(x).eq3freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1831 else if (sscanf(s, "_eq1bw_oncc%d", &y)) eg(x).eq1bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1832 else if (sscanf(s, "_eq2bw_oncc%d", &y)) eg(x).eq2bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1833 else if (sscanf(s, "_eq3bw_oncc%d", &y)) eg(x).eq3bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1834 else if (sscanf(s, "_eq1gain_oncc%d", &y)) eg(x).eq1gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1835 else if (sscanf(s, "_eq2gain_oncc%d", &y)) eg(x).eq2gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1836 else if (sscanf(s, "_eq3gain_oncc%d", &y)) eg(x).eq3gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1837 else std::cerr << "The opcode '" << key << "' is unsupported by libsfz!" << std::endl;
1838 }
1839
1840 // v1 envelope generators
1841 else if ("ampeg_delay" == key) pCurDef->ampeg_delay = ToFloat(value);
1842 else if ("ampeg_start" == key) pCurDef->ampeg_start = ToFloat(value);
1843 else if ("ampeg_attack" == key) pCurDef->ampeg_attack = ToFloat(value);
1844 else if ("ampeg_hold" == key) pCurDef->ampeg_hold = ToFloat(value);
1845 else if ("ampeg_decay" == key) pCurDef->ampeg_decay = ToFloat(value);
1846 else if ("ampeg_sustain" == key) pCurDef->ampeg_sustain = ToFloat(value);
1847 else if ("ampeg_release" == key) pCurDef->ampeg_release = ToFloat(value);
1848 else if ("ampeg_vel2delay" == key) pCurDef->ampeg_vel2delay = ToFloat(value);
1849 else if ("ampeg_vel2attack" == key) pCurDef->ampeg_vel2attack = ToFloat(value);
1850 else if ("ampeg_vel2hold" == key) pCurDef->ampeg_vel2hold = ToFloat(value);
1851 else if ("ampeg_vel2decay" == key) pCurDef->ampeg_vel2decay = ToFloat(value);
1852 else if ("ampeg_vel2sustain" == key) pCurDef->ampeg_vel2sustain = ToFloat(value);
1853 else if ("ampeg_vel2release" == key) pCurDef->ampeg_vel2release = ToFloat(value);
1854 else if ("fileg_delay" == key) pCurDef->fileg_delay = ToFloat(value);
1855 else if ("fileg_start" == key) pCurDef->fileg_start = ToFloat(value);
1856 else if ("fileg_attack" == key) pCurDef->fileg_attack = ToFloat(value);
1857 else if ("fileg_hold" == key) pCurDef->fileg_hold = ToFloat(value);
1858 else if ("fileg_decay" == key) pCurDef->fileg_decay = ToFloat(value);
1859 else if ("fileg_sustain" == key) pCurDef->fileg_sustain = ToFloat(value);
1860 else if ("fileg_release" == key) pCurDef->fileg_release = ToFloat(value);
1861 else if ("fileg_depth" == key) pCurDef->fileg_depth = check(key, -12000, 12000, ToInt(value));
1862 else if ("fileg_vel2delay" == key) pCurDef->fileg_vel2delay = check(key, -100.0f, 100.0f, ToFloat(value));
1863 else if ("fileg_vel2attack" == key) pCurDef->fileg_vel2attack = ToFloat(value);
1864 else if ("fileg_vel2hold" == key) pCurDef->fileg_vel2hold = ToFloat(value);
1865 else if ("fileg_vel2decay" == key) pCurDef->fileg_vel2decay = ToFloat(value);
1866 else if ("fileg_vel2sustain" == key) pCurDef->fileg_vel2sustain = ToFloat(value);
1867 else if ("fileg_vel2release" == key) pCurDef->fileg_vel2release = ToFloat(value);
1868 else if ("pitcheg_delay" == key) pCurDef->pitcheg_delay = ToFloat(value);
1869 else if ("pitcheg_start" == key) pCurDef->pitcheg_start = ToFloat(value);
1870 else if ("pitcheg_attack" == key) pCurDef->pitcheg_attack = ToFloat(value);
1871 else if ("pitcheg_hold" == key) pCurDef->pitcheg_hold = ToFloat(value);
1872 else if ("pitcheg_decay" == key) pCurDef->pitcheg_decay = ToFloat(value);
1873 else if ("pitcheg_sustain" == key) pCurDef->pitcheg_sustain = ToFloat(value);
1874 else if ("pitcheg_release" == key) pCurDef->pitcheg_release = ToFloat(value);
1875 else if ("pitcheg_depth" == key) pCurDef->pitcheg_depth = check(key, -12000, 12000, ToInt(value));
1876 else if ("pitcheg_vel2delay" == key) pCurDef->pitcheg_vel2delay = check(key, -100.0f, 100.0f, ToFloat(value));
1877 else if ("pitcheg_vel2attack" == key) pCurDef->pitcheg_vel2attack = ToFloat(value);
1878 else if ("pitcheg_vel2hold" == key) pCurDef->pitcheg_vel2hold = ToFloat(value);
1879 else if ("pitcheg_vel2decay" == key) pCurDef->pitcheg_vel2decay = ToFloat(value);
1880 else if ("pitcheg_vel2sustain" == key) pCurDef->pitcheg_vel2sustain = ToFloat(value);
1881 else if ("pitcheg_vel2release" == key) pCurDef->pitcheg_vel2release = ToFloat(value);
1882
1883
1884 // v1 LFO
1885 else if ("amplfo_delay" == key) pCurDef->amplfo_delay = ToFloat(value);
1886 else if ("amplfo_fade" == key) pCurDef->amplfo_fade = ToFloat(value);
1887 else if ("amplfo_freq" == key) pCurDef->amplfo_freq = ToFloat(value);
1888 else if ("amplfo_freqchanaft" == key) pCurDef->amplfo_freqcc.add( CC(128, check(key, -200.0f, 200.0f, ToFloat(value))) );
1889 else if ("amplfo_depth" == key) pCurDef->amplfo_depth = ToFloat(value);
1890 else if ("amplfo_depthchanaft" == key) pCurDef->amplfo_depthcc.add( CC(128, check(key, -10.0f, 10.0f, ToFloat(value))) );
1891 else if ("fillfo_delay" == key) pCurDef->fillfo_delay = ToFloat(value);
1892 else if ("fillfo_fade" == key) pCurDef->fillfo_fade = ToFloat(value);
1893 else if ("fillfo_freq" == key) pCurDef->fillfo_freq = ToFloat(value);
1894 else if ("fillfo_freqchanaft" == key) pCurDef->fillfo_freqcc.add( CC(128, check(key, -200.0f, 200.0f, ToFloat(value))) );
1895 else if ("fillfo_depth" == key) pCurDef->fillfo_depth = ToFloat(value);
1896 else if ("fillfo_depthchanaft" == key) pCurDef->fillfo_depthcc.add( CC(128, check(key, -1200, 1200, ToInt(value))) );
1897 else if ("pitchlfo_delay" == key) pCurDef->pitchlfo_delay = ToFloat(value);
1898 else if ("pitchlfo_fade" == key) pCurDef->pitchlfo_fade = ToFloat(value);
1899 else if ("pitchlfo_freq" == key) pCurDef->pitchlfo_freq = ToFloat(value);
1900 else if ("pitchlfo_freqchanaft" == key) pCurDef->pitchlfo_freqcc.add( CC(128, check(key, -200.0f, 200.0f, ToFloat(value))) );
1901 else if ("pitchlfo_depth" == key) pCurDef->pitchlfo_depth = ToInt(value);
1902 else if ("pitchlfo_depthchanaft" == key) pCurDef->pitchlfo_depthcc.add( CC(128, check(key, -1200, 1200, ToInt(value))) );
1903
1904
1905 // v2 LFO
1906 else if (sscanf(key.c_str(), "lfo%d%n", &x, &y)) {
1907 const char* s = key.c_str() + y;
1908 if (strcmp(s, "_freq") == 0) lfo(x).freq = check(key, 0.0f, 20.0f, ToFloat(value));
1909 else if (sscanf(s, "_freq_oncc%d", &y)) lfo(x).freq_oncc.add( CC(y, check(key, 0.0f, 20.0f, ToFloat(value))) );
1910 else if (sscanf(s, "_freq_smoothcc%d", &y)) lfo(x).freq_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1911 else if (sscanf(s, "_freq_stepcc%d", &y)) lfo(x).freq_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 20.0f, ToFloat(value))) );
1912 else if (strcmp(s, "_wave") == 0) lfo(x).wave = ToInt(value);
1913 else if (strcmp(s, "_delay") == 0) lfo(x).delay = check(key, 0.0f, 100.0f, ToFloat(value));
1914 else if (sscanf(s, "_delay_oncc%d", &y)) lfo(x).delay_oncc.add( CC(y, check(key, 0.0f, 100.0f, ToFloat(value))) );
1915 else if (strcmp(s, "_fade") == 0) lfo(x).fade = check(key, 0.0f, 100.0f, ToFloat(value));
1916 else if (sscanf(s, "_fade_oncc%d", &y)) lfo(x).fade_oncc.add( CC(y, check(key, 0.0f, 100.0f, ToFloat(value))) );
1917 else if (strcmp(s, "_phase") == 0) lfo(x).phase = check(key, 0.0f, 360.0f, ToFloat(value));
1918 else if (sscanf(s, "_phase_oncc%d", &y)) lfo(x).phase_oncc.add( CC(y, check(key, 0.0f, 360.0f, ToFloat(value))) );
1919 else if (strcmp(s, "_volume") == 0) lfo(x).volume = check(key, -144.0f, 6.0f, ToFloat(value));
1920 else if (sscanf(s, "_volume_oncc%d", &y)) lfo(x).volume_oncc.add( CC(y, check(key, -144.0f, 6.0f, ToFloat(value))) );
1921 else if (sscanf(s, "_volume_smoothcc%d", &y)) lfo(x).volume_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1922 else if (sscanf(s, "_volume_stepcc%d", &y)) lfo(x).volume_stepcc.add( CC(y, 0, -1, 0, check(key, -20.0f, 20.0f, ToFloat(value))) );
1923 else if (strcmp(s, "_pitch") == 0) lfo(x).pitch = check(key, -9600, 9600, ToInt(value));
1924 else if (sscanf(s, "_pitch_oncc%d", &y)) lfo(x).pitch_oncc.add( CC(y, check(key, -9600, 9600, ToInt(value))) );
1925 else if (sscanf(s, "_pitch_smoothcc%d", &y)) lfo(x).pitch_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1926 else if (sscanf(s, "_pitch_stepcc%d", &y)) lfo(x).pitch_stepcc.add( CC(y, 0, -1, 0, check(key, -9600, 9600, ToInt(value))) );
1927 else if (strcmp(s, "_cutoff") == 0) lfo(x).cutoff = check(key, -9600, 9600, ToInt(value));
1928 else if (sscanf(s, "_cutoff_oncc%d", &y)) lfo(x).cutoff_oncc.add( CC(y, check(key, -9600, 9600, ToInt(value))) );
1929 else if (sscanf(s, "_cutoff_smoothcc%d", &y)) lfo(x).cutoff_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1930 else if (sscanf(s, "_cutoff_stepcc%d", &y)) lfo(x).cutoff_stepcc.add( CC(y, 0, -1, 0, check(key, -9600, 9600, ToInt(value))) );
1931 else if (strcmp(s, "_resonance") == 0) lfo(x).resonance = check(key, 0.0f, 40.0f, ToFloat(value));
1932 else if (sscanf(s, "_resonance_oncc%d", &y)) lfo(x).resonance_oncc.add( CC(y, check(key, 0.0f, 40.0f, ToFloat(value))) );
1933 else if (sscanf(s, "_resonance_smoothcc%d", &y)) lfo(x).resonance_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1934 else if (sscanf(s, "_resonance_stepcc%d", &y)) lfo(x).resonance_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 40.0f, ToFloat(value))) );
1935 else if (strcmp(s, "_pan") == 0) lfo(x).pan = check(key, -100.0f, 100.0f, ToFloat(value));
1936 else if (sscanf(s, "_pan_oncc%d", &y)) lfo(x).pan_oncc.add( CC(y, check(key, -100.0f, 100.0f, ToFloat(value))) );
1937 else if (sscanf(s, "_pan_smoothcc%d", &y)) lfo(x).pan_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1938 else if (sscanf(s, "_pan_stepcc%d", &y)) lfo(x).pan_stepcc.add( CC(y, 0, -1, 0, check(key, -100.0f, 100.0f, ToFloat(value))) );
1939 else if (strcmp(s, "_eq1freq") == 0) lfo(x).eq1freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1940 else if (strcmp(s, "_eq2freq") == 0) lfo(x).eq2freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1941 else if (strcmp(s, "_eq3freq") == 0) lfo(x).eq3freq = check(key, 0.0f, 30000.0f, ToFloat(value));
1942 else if (strcmp(s, "_eq1bw") == 0) lfo(x).eq1bw = check(key, 0.001f, 4.0f, ToFloat(value));
1943 else if (strcmp(s, "_eq2bw") == 0) lfo(x).eq2bw = check(key, 0.001f, 4.0f, ToFloat(value));
1944 else if (strcmp(s, "_eq3bw") == 0) lfo(x).eq3bw = check(key, 0.001f, 4.0f, ToFloat(value));
1945 else if (strcmp(s, "_eq1gain") == 0) lfo(x).eq1gain = check(key, -96.0f, 24.0f, ToFloat(value));
1946 else if (strcmp(s, "_eq2gain") == 0) lfo(x).eq2gain = check(key, -96.0f, 24.0f, ToFloat(value));
1947 else if (strcmp(s, "_eq3gain") == 0) lfo(x).eq3gain = check(key, -96.0f, 24.0f, ToFloat(value));
1948 else if (sscanf(s, "_eq1freq_oncc%d", &y)) lfo(x).eq1freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1949 else if (sscanf(s, "_eq1freq_smoothcc%d", &y)) lfo(x).eq1freq_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1950 else if (sscanf(s, "_eq1freq_stepcc%d", &y)) lfo(x).eq1freq_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1951 else if (sscanf(s, "_eq2freq_oncc%d", &y)) lfo(x).eq2freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1952 else if (sscanf(s, "_eq2freq_smoothcc%d", &y)) lfo(x).eq2freq_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1953 else if (sscanf(s, "_eq2freq_stepcc%d", &y)) lfo(x).eq2freq_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1954 else if (sscanf(s, "_eq3freq_oncc%d", &y)) lfo(x).eq3freq_oncc.add( CC(y, check(key, 0.0f, 30000.0f, ToFloat(value))) );
1955 else if (sscanf(s, "_eq3freq_smoothcc%d", &y)) lfo(x).eq3freq_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1956 else if (sscanf(s, "_eq3freq_stepcc%d", &y)) lfo(x).eq3freq_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1957 else if (sscanf(s, "_eq1bw_oncc%d", &y)) lfo(x).eq1bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1958 else if (sscanf(s, "_eq1bw_smoothcc%d", &y)) lfo(x).eq1bw_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1959 else if (sscanf(s, "_eq1bw_stepcc%d", &y)) lfo(x).eq1bw_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1960 else if (sscanf(s, "_eq2bw_oncc%d", &y)) lfo(x).eq2bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1961 else if (sscanf(s, "_eq2bw_smoothcc%d", &y)) lfo(x).eq2bw_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1962 else if (sscanf(s, "_eq2bw_stepcc%d", &y)) lfo(x).eq2bw_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1963 else if (sscanf(s, "_eq3bw_oncc%d", &y)) lfo(x).eq3bw_oncc.add( CC(y, check(key, 0.001f, 4.0f, ToFloat(value))) );
1964 else if (sscanf(s, "_eq3bw_smoothcc%d", &y)) lfo(x).eq3bw_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1965 else if (sscanf(s, "_eq3bw_stepcc%d", &y)) lfo(x).eq3bw_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1966 else if (sscanf(s, "_eq1gain_oncc%d", &y)) lfo(x).eq1gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1967 else if (sscanf(s, "_eq1gain_smoothcc%d", &y)) lfo(x).eq1gain_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1968 else if (sscanf(s, "_eq1gain_stepcc%d", &y)) lfo(x).eq1gain_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1969 else if (sscanf(s, "_eq2gain_oncc%d", &y)) lfo(x).eq2gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1970 else if (sscanf(s, "_eq2gain_smoothcc%d", &y)) lfo(x).eq2gain_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1971 else if (sscanf(s, "_eq2gain_stepcc%d", &y)) lfo(x).eq2gain_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1972 else if (sscanf(s, "_eq3gain_oncc%d", &y)) lfo(x).eq3gain_oncc.add( CC(y, check(key, -96.0f, 24.0f, ToFloat(value))) );
1973 else if (sscanf(s, "_eq3gain_smoothcc%d", &y)) lfo(x).eq3gain_smoothcc.add( CC(y, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
1974 else if (sscanf(s, "_eq3gain_stepcc%d", &y)) lfo(x).eq3gain_stepcc.add( CC(y, 0, -1, 0, check(key, 0.0f, 4294967296.0f, ToFloat(value))) );
1975 else std::cerr << "The opcode '" << key << "' is unsupported by libsfz!" << std::endl;
1976 }
1977
1978 // CCs
1979 else if (key.find("cc") != std::string::npos)
1980 {
1981 std::string::size_type delimiter_index = key.find("cc");
1982 std::string key_cc = key.substr(0, delimiter_index);
1983 if (key_cc.size() > 3 && !strcmp(key_cc.c_str() + (key_cc.size() - 3), "_on")) {
1984 key_cc = key_cc.substr(0, key_cc.size() - 3);
1985 }
1986
1987 // Apply macros
1988 std::string num_cc_str = key.substr(delimiter_index + 2);
1989
1990 if (num_cc_str[0] == '$')
1991 {
1992 if (_defined_macros.count(num_cc_str) == 0)
1993 {
1994 std::cerr << "Macro '" << value << "' referenced on line ";
1995 std::cerr << currentLine << " is undefined." << std::endl;
1996 return;
1997 }
1998
1999 num_cc_str = _defined_macros[num_cc_str];
2000 }
2001
2002 int num_cc = ToInt(num_cc_str);
2003 if (num_cc < 0 || num_cc > 127) {
2004 std::cerr << "sfz: WARNING: CC " << num_cc << " of opcode '" << key;
2005 std::cerr << "' is an invalid MIDI controller number." << std::endl;
2006 }
2007
2008 // input controls
2009 if ("lo" == key_cc) pCurDef->locc.set(num_cc, ToInt(value));
2010 else if ("hi" == key_cc) pCurDef->hicc.set(num_cc, ToInt(value));
2011 else if ("start_lo" == key_cc) pCurDef->start_locc.set(num_cc, ToInt(value));
2012 else if ("start_hi" == key_cc) pCurDef->start_hicc.set(num_cc, ToInt(value));
2013 else if ("stop_lo" == key_cc) pCurDef->stop_locc.set(num_cc, ToInt(value));
2014 else if ("stop_hi" == key_cc) pCurDef->stop_hicc.set(num_cc, ToInt(value));
2015 else if ("on_lo" == key_cc) pCurDef->on_locc.set(num_cc, ToInt(value));
2016 else if ("on_hi" == key_cc) pCurDef->on_hicc.set(num_cc, ToInt(value));
2017
2018 // sample player
2019 else if ("delay" == key_cc) pCurDef->delay_oncc.set(num_cc, ToFloat(value));
2020 else if ("delay_samples" == key_cc) pCurDef->delay_samples_oncc.set(num_cc, ToInt(value));
2021 else if ("offset" == key_cc) pCurDef->offset_oncc.set(num_cc, ToInt(value));
2022
2023 // amplifier
2024 else if ("gain" == key_cc || "gain_" == key_cc) pCurDef->gain_oncc.set(num_cc, ToFloat(value));
2025 else if ("xfin_lo" == key_cc) pCurDef->xfin_locc.set(num_cc, ToInt(value));
2026 else if ("xfin_hi" == key_cc) pCurDef->xfin_hicc.set(num_cc, ToInt(value));
2027 else if ("xfout_lo" == key_cc) pCurDef->xfout_locc.set(num_cc, ToInt(value));
2028 else if ("xfout_hi" == key_cc) pCurDef->xfout_hicc.set(num_cc, ToInt(value));
2029
2030 // pitch
2031 else if ("pitch" == key_cc) pCurDef->pitch_oncc.add( CC(num_cc, check(key, -9600, 9600, ToInt(value))) );
2032 else if ("pitch_smooth" == key_cc) pCurDef->pitch_smoothcc.add( CC(num_cc, 0, -1, check(key, 0.0f, 100000.0f /* max? */, ToFloat(value))) );
2033 else if ("pitch_curve" == key_cc) pCurDef->pitch_curvecc.add( CC(num_cc, 0, check(key, 0, 30000, ToInt(value))) );
2034 else if ("pitch_step" == key_cc) pCurDef->pitch_stepcc.add( CC(num_cc, 0, -1, 0, check(key, 0, 1200, ToInt(value))) );
2035
2036 // filter
2037 else if ("cutoff" == key_cc || "cutoff_" == key_cc) {
2038 pCurDef->cutoff_oncc.add( CC(num_cc, check(key, -9600, 9600, ToInt(value))) );
2039 } else if ("cutoff2" == key_cc) pCurDef->cutoff2_oncc.add( CC(num_cc, check(key, -9600, 9600, ToInt(value))) );
2040 else if ("cutoff_smooth" == key_cc) pCurDef->cutoff_smoothcc.add( CC(num_cc, 0, -1, check(key, 0.0f, 100000.0f /* max? */, ToFloat(value))) );
2041 else if ("cutoff2_smooth" == key_cc) pCurDef->cutoff2_smoothcc.add( CC(num_cc, 0, -1, check(key, 0.0f, 100000.0f /* max? */, ToFloat(value))) );
2042 else if ("cutoff_step" == key_cc) pCurDef->cutoff_stepcc.add( CC(num_cc, 0, -1, 0, check(key, -1200, 1200, ToInt(value))) );
2043 else if ("cutoff2_step" == key_cc) pCurDef->cutoff2_stepcc.add( CC(num_cc, 0, -1, 0, check(key, -1200, 1200, ToInt(value))) );
2044 else if ("cutoff_curve" == key_cc) pCurDef->cutoff_curvecc.add( CC(num_cc, 0, check(key, 0, 30000, ToInt(value))) );
2045 else if ("cutoff2_curve" == key_cc) pCurDef->cutoff2_curvecc.add( CC(num_cc, 0, check(key, 0, 30000, ToInt(value))) );
2046 else if ("resonance" == key_cc) pCurDef->resonance_oncc.add( CC(num_cc, check(key, 0.0f, 40.0f, ToFloat(value))) );
2047 else if ("resonance2" == key_cc) pCurDef->resonance2_oncc.add( CC(num_cc, check(key, 0.0f, 40.0f, ToFloat(value))) );
2048 else if ("resonance_smooth" == key_cc) pCurDef->resonance_smoothcc.add( CC(num_cc, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
2049 else if ("resonance2_smooth" == key_cc) pCurDef->resonance2_smoothcc.add( CC(num_cc, 0, -1, check(key, 0, 100000 /* max? */, ToInt(value))) );
2050 else if ("resonance_step" == key_cc) pCurDef->resonance_stepcc.add( CC(num_cc, 0, -1, 0, check(key, 0.0f, 40.0f, ToFloat(value))) );
2051 else if ("resonance2_step" == key_cc) pCurDef->resonance2_stepcc.add( CC(num_cc, 0, -1, 0, check(key, 0.0f, 40.0f, ToFloat(value))) );
2052 else if ("resonance_curve" == key_cc) pCurDef->resonance_curvecc.add( CC(num_cc, 0.0f, check(key, 0, 30000, ToInt(value))) );
2053 else if ("resonance2_curve" == key_cc) pCurDef->resonance2_curvecc.add( CC(num_cc, 0.0f, check(key, 0, 30000, ToInt(value))) );
2054
2055 // per voice equalizer
2056 else if ("eq1_freq" == key_cc) pCurDef->eq1_freq_oncc.set(num_cc, ToInt(value));
2057 else if ("eq2_freq" == key_cc) pCurDef->eq2_freq_oncc.set(num_cc, ToInt(value));
2058 else if ("eq3_freq" == key_cc) pCurDef->eq3_freq_oncc.set(num_cc, ToInt(value));
2059 else if ("eq1_bw" == key_cc) pCurDef->eq1_bw_oncc.set(num_cc, ToInt(value));
2060 else if ("eq2_bw" == key_cc) pCurDef->eq2_bw_oncc.set(num_cc, ToInt(value));
2061 else if ("eq3_bw" == key_cc) pCurDef->eq3_bw_oncc.set(num_cc, ToInt(value));
2062 else if ("eq1_gain" == key_cc) pCurDef->eq1_gain_oncc.set(num_cc, ToInt(value));
2063 else if ("eq2_gain" == key_cc) pCurDef->eq2_gain_oncc.set(num_cc, ToInt(value));
2064 else if ("eq3_gain" == key_cc) pCurDef->eq3_gain_oncc.set(num_cc, ToInt(value));
2065
2066 else if ("ampeg_delay" == key_cc) pCurDef->ampeg_delaycc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2067 else if ("ampeg_start" == key_cc) pCurDef->ampeg_startcc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2068 else if ("ampeg_attack" == key_cc) pCurDef->ampeg_attackcc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2069 else if ("ampeg_hold" == key_cc) pCurDef->ampeg_holdcc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2070 else if ("ampeg_decay" == key_cc) pCurDef->ampeg_decaycc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2071 else if ("ampeg_sustain" == key_cc) pCurDef->ampeg_sustaincc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2072 else if ("ampeg_release" == key_cc) pCurDef->ampeg_releasecc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2073
2074 else if ("fileg_delay" == key_cc) pCurDef->fileg_delay_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2075 else if ("fileg_start" == key_cc) pCurDef->fileg_start_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2076 else if ("fileg_attack" == key_cc) pCurDef->fileg_attack_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2077 else if ("fileg_hold" == key_cc) pCurDef->fileg_hold_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2078 else if ("fileg_decay" == key_cc) pCurDef->fileg_decay_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2079 else if ("fileg_sustain" == key_cc) pCurDef->fileg_sustain_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2080 else if ("fileg_release" == key_cc) pCurDef->fileg_release_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2081 else if ("fileg_depth" == key_cc) pCurDef->fileg_depth_oncc.add( CC(num_cc, check(key, -12000, 12000, ToInt(value))) );
2082
2083 else if ("pitcheg_delay" == key_cc) pCurDef->pitcheg_delay_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2084 else if ("pitcheg_start" == key_cc) pCurDef->pitcheg_start_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2085 else if ("pitcheg_attack" == key_cc) pCurDef->pitcheg_attack_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2086 else if ("pitcheg_hold" == key_cc) pCurDef->pitcheg_hold_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2087 else if ("pitcheg_decay" == key_cc) pCurDef->pitcheg_decay_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2088 else if ("pitcheg_sustain" == key_cc) pCurDef->pitcheg_sustain_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2089 else if ("pitcheg_release" == key_cc) pCurDef->pitcheg_release_oncc.add( CC(num_cc, check(key, -100.0f, 100.0f, ToFloat(value))) );
2090 else if ("pitcheg_depth" == key_cc) pCurDef->pitcheg_depth_oncc.add( CC(num_cc, check(key, -12000, 12000, ToInt(value))) );
2091
2092 else if ("pitchlfo_delay" == key_cc) pCurDef->pitchlfo_delay_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2093 else if ("pitchlfo_fade" == key_cc) pCurDef->pitchlfo_fade_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2094 else if ("pitchlfo_depth" == key_cc) pCurDef->pitchlfo_depthcc.add( CC(num_cc, check(key, -1200, 1200, ToInt(value))) );
2095 else if ("pitchlfo_freq" == key_cc) pCurDef->pitchlfo_freqcc.add( CC(num_cc, check(key, -200.0f, 200.0f, ToFloat(value))) );
2096 else if ("fillfo_delay" == key_cc) pCurDef->fillfo_delay_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2097 else if ("fillfo_fade" == key_cc) pCurDef->fillfo_fade_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2098 else if ("fillfo_depth" == key_cc) pCurDef->fillfo_depthcc.add( CC(num_cc, check(key, -1200, 1200, ToInt(value))) );
2099 else if ("fillfo_freq" == key_cc) pCurDef->fillfo_freqcc.add( CC(num_cc, check(key, -200.0f, 200.0f, ToFloat(value))) );
2100 else if ("amplfo_delay" == key_cc) pCurDef->amplfo_delay_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2101 else if ("amplfo_fade" == key_cc) pCurDef->amplfo_fade_oncc.add( CC(num_cc, check(key, 0.0f, 100.0f, ToFloat(value))) );
2102 else if ("amplfo_depth" == key_cc) pCurDef->amplfo_depthcc.add( CC(num_cc, check(key, -10.0f, 10.0f, ToFloat(value))) );
2103 else if ("amplfo_freq" == key_cc) pCurDef->amplfo_freqcc.add( CC(num_cc, check(key, -200.0f, 200.0f, ToFloat(value))) );
2104 else if ("volume" == key_cc) pCurDef->volume_oncc.add( CC(num_cc, check(key, -144.0f, 100.0f, ToFloat(value))) );
2105 else if ("volume_curve" == key_cc) pCurDef->volume_curvecc.add( CC(num_cc, 0, check(key, 0, 30000, ToInt(value))) );
2106 else if ("volume_smooth" == key_cc) pCurDef->volume_smoothcc.add( CC(num_cc, 0, -1, check(key, 0.0f, 100000.0f /* max? */, ToFloat(value))) );
2107 else if ("volume_step" == key_cc) pCurDef->volume_stepcc.add( CC(num_cc, 0, -1, 0, check(key, -20.0f, 20.0f, ToFloat(value))) );
2108 else if ("pan" == key_cc) pCurDef->pan_oncc.add( CC(num_cc, check(key, -200.0f, 200.0f, ToFloat(value))) );
2109 else if ("pan_curve" == key_cc) pCurDef->pan_curvecc.add( CC(num_cc, 0, check(key, 0, 30000, ToInt(value))) );
2110 else if ("pan_smooth" == key_cc) pCurDef->pan_smoothcc.add( CC(num_cc, 0, -1, check(key, 0.0f, 100000.0f /* max? */, ToFloat(value))) );
2111 else if ("pan_step" == key_cc) pCurDef->pan_stepcc.add( CC(num_cc, 0, -1, 0, check(key, -100.0f, 100.0f, ToFloat(value))) );
2112 else if ("set_" == key_cc) _instrument->initialCCValues[num_cc] = (num_cc < 128) ? check(key, 0, 127, ToInt(value)) : ToInt(value);
2113 else std::cerr << "The opcode '" << key << "' is unsupported by libsfz!" << std::endl;
2114 }
2115
2116 else {
2117 std::cerr << "The opcode '" << key << "' is unsupported by libsfz!" << std::endl;
2118 }
2119 }
2120
2121 int File::parseKey(const std::string& s) {
2122 int i;
2123 std::istringstream iss(s);
2124 if (isdigit(iss.peek())) {
2125 iss >> i;
2126 } else {
2127 switch (tolower(iss.get())) {
2128 case 'c': i = 0; break;
2129 case 'd': i = 2; break;
2130 case 'e': i = 4; break;
2131 case 'f': i = 5; break;
2132 case 'g': i = 7; break;
2133 case 'a': i = 9; break;
2134 case 'b': i = 11; break;
2135 case '-': if (s == "-1") return -1;
2136 default:
2137 std::cerr << "Not a note: " << s << std::endl;
2138 return 0;
2139 }
2140 if (iss.peek() == '#') {
2141 i++;
2142 iss.get();
2143 } else if (tolower(iss.peek()) == 'b') {
2144 i--;
2145 iss.get();
2146 }
2147 int octave;
2148 if (!(iss >> octave)) {
2149 std::cerr << "Not a note: " << s << std::endl;
2150 return 0;
2151 }
2152 i += (octave + 1) * 12;
2153 }
2154 return i + note_offset + 12 * octave_offset;
2155 }
2156
2157 EGNode::EGNode() : time(0), level(0), shape(0), curve(0) {
2158 }
2159
2160 void EGNode::Copy(const EGNode& egNode) {
2161 time = egNode.time;
2162 level = egNode.level;
2163 shape = egNode.shape;
2164 curve = egNode.curve;
2165
2166 time_oncc = egNode.time_oncc;
2167 level_oncc = egNode.level_oncc;
2168 }
2169
2170 EG::EG() :
2171 sustain(0), loop(0), loop_count(0), amplitude(0), volume(-200), /* less than -144 dB is considered unset */
2172 cutoff(0), pitch(0), resonance(0), pan(0), pan_curve(-1)
2173 { }
2174
2175 void EG::Copy(const EG& eg) {
2176 EqImpl::Copy(static_cast<const EqImpl>(eg));
2177
2178 sustain = eg.sustain;
2179 loop = eg.loop;
2180 loop_count = eg.loop_count;
2181 amplitude = eg.amplitude;
2182 volume = eg.volume;
2183 cutoff = eg.cutoff;
2184 pitch = eg.pitch;
2185 resonance = eg.resonance;
2186 pan = eg.pan;
2187 pan_curve = eg.pan_curve;
2188 node = eg.node;
2189
2190 amplitude_oncc = eg.amplitude_oncc;
2191 volume_oncc = eg.volume_oncc;
2192 cutoff_oncc = eg.cutoff_oncc;
2193 pitch_oncc = eg.pitch_oncc;
2194 resonance_oncc = eg.resonance_oncc;
2195 pan_oncc = eg.pan_oncc;
2196 pan_curvecc = eg.pan_curvecc;
2197 }
2198
2199 LFO::LFO():
2200 delay(0),
2201 freq(-1), /* -1 is used to determine whether the LFO was initialized */
2202 fade(0), phase(0), wave(0), volume(0), pitch(0), cutoff(0), resonance(0), pan(0)
2203 {
2204 }
2205
2206 void LFO::Copy(const LFO& lfo) {
2207 EqSmoothStepImpl::Copy(static_cast<const EqSmoothStepImpl>(lfo));
2208
2209 delay = lfo.delay;
2210 freq = lfo.freq;
2211 fade = lfo.fade;
2212 phase = lfo.phase;
2213 wave = lfo.wave;
2214 volume = lfo.volume;
2215 pitch = lfo.pitch;
2216 cutoff = lfo.cutoff;
2217 resonance = lfo.resonance;
2218 pan = lfo.pan;
2219
2220 delay_oncc = lfo.delay_oncc;
2221 freq_oncc = lfo.freq_oncc;
2222 freq_smoothcc = lfo.freq_smoothcc;
2223 freq_stepcc = lfo.freq_stepcc;
2224 fade_oncc = lfo.fade_oncc;
2225 phase_oncc = lfo.phase_oncc;
2226 pitch_oncc = lfo.pitch_oncc;
2227 pitch_smoothcc = lfo.pitch_smoothcc;
2228 pitch_stepcc = lfo.pitch_stepcc;
2229 volume_oncc = lfo.volume_oncc;
2230 volume_smoothcc = lfo.volume_smoothcc;
2231 volume_stepcc = lfo.volume_stepcc;
2232 pan_oncc = lfo.pan_oncc;
2233 pan_smoothcc = lfo.pan_smoothcc;
2234 pan_stepcc = lfo.pan_stepcc;
2235 cutoff_oncc = lfo.cutoff_oncc;
2236 cutoff_smoothcc = lfo.cutoff_smoothcc;
2237 cutoff_stepcc = lfo.cutoff_stepcc;
2238 resonance_oncc = lfo.resonance_oncc;
2239 resonance_smoothcc = lfo.resonance_smoothcc;
2240 resonance_stepcc = lfo.resonance_stepcc;
2241 }
2242
2243 EqImpl::EqImpl() {
2244 eq1freq = eq2freq = eq3freq = 0;
2245 eq1bw = eq2bw = eq3bw = 0;
2246 eq1gain = eq2gain = eq3gain = 0;
2247 }
2248
2249 void EqImpl::Copy(const EqImpl& eq) {
2250 eq1freq = eq.eq1freq;
2251 eq2freq = eq.eq2freq;
2252 eq3freq = eq.eq3freq;
2253 eq1bw = eq.eq1bw;
2254 eq2bw = eq.eq2bw;
2255 eq3bw = eq.eq3bw;
2256 eq1gain = eq.eq1gain;
2257 eq2gain = eq.eq2gain;
2258 eq3gain = eq.eq3gain;
2259
2260 eq1freq_oncc = eq.eq1freq_oncc;
2261 eq2freq_oncc = eq.eq2freq_oncc;
2262 eq3freq_oncc = eq.eq3freq_oncc;
2263 eq1bw_oncc = eq.eq1bw_oncc;
2264 eq2bw_oncc = eq.eq2bw_oncc;
2265 eq3bw_oncc = eq.eq3bw_oncc;
2266 eq1gain_oncc = eq.eq1gain_oncc;
2267 eq2gain_oncc = eq.eq2gain_oncc;
2268 eq3gain_oncc = eq.eq3gain_oncc;
2269 }
2270
2271 bool EqImpl::HasEq() {
2272 return eq1freq || eq2freq || eq3freq || eq1bw || eq2bw || eq3bw ||
2273 eq1gain || eq2gain || eq3gain || !eq1gain_oncc.empty() ||
2274 !eq2gain_oncc.empty() || !eq3gain_oncc.empty() ||
2275 !eq1freq_oncc.empty() || !eq2freq_oncc.empty() || !eq3freq_oncc.empty() ||
2276 !eq1bw_oncc.empty() || !eq2bw_oncc.empty() || !eq3bw_oncc.empty();
2277 }
2278
2279 void EqSmoothStepImpl::Copy(const EqSmoothStepImpl& eq) {
2280 EqImpl::Copy(eq);
2281
2282 eq1freq_smoothcc = eq.eq1freq_smoothcc;
2283 eq2freq_smoothcc = eq.eq2freq_smoothcc;
2284 eq3freq_smoothcc = eq.eq3freq_smoothcc;
2285 eq1bw_smoothcc = eq.eq1bw_smoothcc;
2286 eq2bw_smoothcc = eq.eq2bw_smoothcc;
2287 eq3bw_smoothcc = eq.eq3bw_smoothcc;
2288 eq1gain_smoothcc = eq.eq1gain_smoothcc;
2289 eq2gain_smoothcc = eq.eq2gain_smoothcc;
2290 eq3gain_smoothcc = eq.eq3gain_smoothcc;
2291
2292 eq1freq_stepcc = eq.eq1freq_stepcc;
2293 eq2freq_stepcc = eq.eq2freq_stepcc;
2294 eq3freq_stepcc = eq.eq3freq_stepcc;
2295 eq1bw_stepcc = eq.eq1bw_stepcc;
2296 eq2bw_stepcc = eq.eq2bw_stepcc;
2297 eq3bw_stepcc = eq.eq3bw_stepcc;
2298 eq1gain_stepcc = eq.eq1gain_stepcc;
2299 eq2gain_stepcc = eq.eq2gain_stepcc;
2300 eq3gain_stepcc = eq.eq3gain_stepcc;
2301 }
2302
2303 void EqSmoothStepImpl::copySmoothValues() {
2304 File::copySmoothValues(eq1freq_smoothcc, eq1freq_oncc);
2305 eq1freq_smoothcc.clear();
2306
2307 File::copySmoothValues(eq2freq_smoothcc, eq2freq_oncc);
2308 eq2freq_smoothcc.clear();
2309
2310 File::copySmoothValues(eq3freq_smoothcc, eq3freq_oncc);
2311 eq3freq_smoothcc.clear();
2312
2313 File::copySmoothValues(eq1bw_smoothcc, eq1bw_oncc);
2314 eq1bw_smoothcc.clear();
2315
2316 File::copySmoothValues(eq2bw_smoothcc, eq2bw_oncc);
2317 eq2bw_smoothcc.clear();
2318
2319 File::copySmoothValues(eq3bw_smoothcc, eq3bw_oncc);
2320 eq3bw_smoothcc.clear();
2321
2322 File::copySmoothValues(eq1gain_smoothcc, eq1gain_oncc);
2323 eq1gain_smoothcc.clear();
2324
2325 File::copySmoothValues(eq2gain_smoothcc, eq2gain_oncc);
2326 eq2gain_smoothcc.clear();
2327
2328 File::copySmoothValues(eq3gain_smoothcc, eq3gain_oncc);
2329 eq3gain_smoothcc.clear();
2330 }
2331
2332 void EqSmoothStepImpl::copyStepValues() {
2333 File::copyStepValues(eq1freq_stepcc, eq1freq_oncc);
2334 eq1freq_stepcc.clear();
2335
2336 File::copyStepValues(eq2freq_stepcc, eq2freq_oncc);
2337 eq2freq_stepcc.clear();
2338
2339 File::copyStepValues(eq3freq_stepcc, eq3freq_oncc);
2340 eq3freq_stepcc.clear();
2341
2342 File::copyStepValues(eq1bw_stepcc, eq1bw_oncc);
2343 eq1bw_stepcc.clear();
2344
2345 File::copyStepValues(eq2bw_stepcc, eq2bw_oncc);
2346 eq2bw_stepcc.clear();
2347
2348 File::copyStepValues(eq3bw_stepcc, eq3bw_oncc);
2349 eq3bw_stepcc.clear();
2350
2351 File::copyStepValues(eq1gain_stepcc, eq1gain_oncc);
2352 eq1gain_stepcc.clear();
2353
2354 File::copyStepValues(eq2gain_stepcc, eq2gain_oncc);
2355 eq2gain_stepcc.clear();
2356
2357 File::copyStepValues(eq3gain_stepcc, eq3gain_oncc);
2358 eq3gain_stepcc.clear();
2359 }
2360
2361 EG& File::eg(int x) {
2362 while (pCurDef->eg.size() <= x) {
2363 pCurDef->eg.add(EG());
2364 }
2365 return pCurDef->eg[x];
2366 }
2367
2368 EGNode& File::egnode(int x, int y) {
2369 EG& e = eg(x);
2370 while (e.node.size() <= y) {
2371 e.node.add(EGNode());
2372 }
2373 return e.node[y];
2374 }
2375
2376 LFO& File::lfo(int x) {
2377 while (pCurDef->lfos.size() <= x) {
2378 pCurDef->lfos.add(LFO());
2379 }
2380 return pCurDef->lfos[x];
2381 }
2382
2383 } // !namespace sfz

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC