39 |
return pow(_1200TH_ROOT_OF_2, Timecents); |
return pow(_1200TH_ROOT_OF_2, Timecents); |
40 |
} |
} |
41 |
|
|
42 |
double ToPermilles(int Centibels) { |
double ToRatio(int Centibels) { |
43 |
if (Centibels == NONE) return NONE; |
if (Centibels == NONE) return NONE; |
44 |
if (Centibels == 0) return 1000.0; |
if (Centibels == 0) return 1.0; |
|
if (Centibels < 0) return 0.0; |
|
45 |
return pow(_200TH_ROOT_OF_10, Centibels); |
return pow(_200TH_ROOT_OF_10, Centibels); |
46 |
} |
} |
47 |
|
|
286 |
delayVibLfo = -12000; |
delayVibLfo = -12000; |
287 |
|
|
288 |
exclusiveClass = 0; |
exclusiveClass = 0; |
289 |
|
|
290 |
|
initialFilterFc = 13500; |
291 |
|
initialFilterQ = 0; |
292 |
} |
} |
293 |
|
|
294 |
int Region::GetUnityNote() { |
int Region::GetUnityNote() { |
295 |
return overridingRootKey != -1 ? overridingRootKey : pSample->OriginalPitch; |
return overridingRootKey != -1 ? overridingRootKey : pSample->OriginalPitch; |
296 |
} |
} |
297 |
|
|
298 |
|
int CheckRange(std::string genName, int min, int max, int& gen) { |
299 |
|
if (gen == NONE) return gen; |
300 |
|
|
301 |
|
if (gen < min) { |
302 |
|
std::cerr << "sf2: " << genName; |
303 |
|
std::cerr << " is below the minimum allowed value (min=" << min << "): " << gen << std::endl; |
304 |
|
gen = min; |
305 |
|
} |
306 |
|
if (gen > max) { |
307 |
|
std::cerr << "sf2: " << genName; |
308 |
|
std::cerr << " is above the maximum allowed value (max=" << max << "): " << gen << std::endl; |
309 |
|
gen = max; |
310 |
|
} |
311 |
|
|
312 |
|
return gen; |
313 |
|
} |
314 |
|
|
315 |
void Region::SetGenerator(sf2::File* pFile, GenList& Gen) { |
void Region::SetGenerator(sf2::File* pFile, GenList& Gen) { |
316 |
switch(Gen.GenOper) { |
switch(Gen.GenOper) { |
337 |
break; |
break; |
338 |
case MOD_LFO_TO_PITCH: |
case MOD_LFO_TO_PITCH: |
339 |
modLfoToPitch = Gen.GenAmount.shAmount; |
modLfoToPitch = Gen.GenAmount.shAmount; |
340 |
|
CheckRange("modLfoToPitch", -12000, 12000, modLfoToPitch); |
341 |
break; |
break; |
342 |
case VIB_LFO_TO_PITCH: |
case VIB_LFO_TO_PITCH: |
343 |
vibLfoToPitch = Gen.GenAmount.shAmount; |
vibLfoToPitch = Gen.GenAmount.shAmount; |
344 |
|
CheckRange("vibLfoToPitch", -12000, 12000, vibLfoToPitch); |
345 |
break; |
break; |
346 |
case MOD_ENV_TO_PITCH: |
case MOD_ENV_TO_PITCH: |
347 |
modEnvToPitch = Gen.GenAmount.shAmount; |
modEnvToPitch = Gen.GenAmount.shAmount; |
348 |
|
CheckRange("modEnvToPitch", -12000, 12000, modEnvToPitch); |
349 |
break; |
break; |
350 |
case INITIAL_FILTER_FC: |
case INITIAL_FILTER_FC: |
351 |
|
initialFilterFc = Gen.GenAmount.wAmount; |
352 |
|
CheckRange("initialFilterFc", 1500, 13500, initialFilterFc); |
353 |
break; |
break; |
354 |
case INITIAL_FILTER_Q: |
case INITIAL_FILTER_Q: |
355 |
|
initialFilterQ = Gen.GenAmount.wAmount; |
356 |
|
CheckRange("initialFilterQ", 0, 960, initialFilterQ); |
357 |
break; |
break; |
358 |
case MOD_LFO_TO_FILTER_FC: |
case MOD_LFO_TO_FILTER_FC: |
359 |
modLfoToFilterFc = Gen.GenAmount.shAmount; |
modLfoToFilterFc = Gen.GenAmount.shAmount; |
360 |
|
CheckRange("modLfoToFilterFc", -12000, 12000, modLfoToFilterFc); |
361 |
break; |
break; |
362 |
case MOD_ENV_TO_FILTER_FC: |
case MOD_ENV_TO_FILTER_FC: |
363 |
modEnvToFilterFc = Gen.GenAmount.shAmount; |
modEnvToFilterFc = Gen.GenAmount.shAmount; |
364 |
|
CheckRange("modEnvToFilterFc", -12000, 12000, modEnvToFilterFc); |
365 |
break; |
break; |
366 |
case END_ADDRS_COARSE_OFFSET: |
case END_ADDRS_COARSE_OFFSET: |
367 |
endAddrsCoarseOffset = Gen.GenAmount.wAmount; |
endAddrsCoarseOffset = Gen.GenAmount.wAmount; |
368 |
break; |
break; |
369 |
case MOD_LFO_TO_VOLUME: |
case MOD_LFO_TO_VOLUME: |
370 |
modLfoToVolume = Gen.GenAmount.shAmount; |
modLfoToVolume = Gen.GenAmount.shAmount; |
371 |
|
CheckRange("modLfoToVolume", -960, 960, modLfoToVolume); |
372 |
break; |
break; |
373 |
case CHORUS_EFFECTS_SEND: |
case CHORUS_EFFECTS_SEND: |
374 |
break; |
break; |
376 |
break; |
break; |
377 |
case PAN: |
case PAN: |
378 |
pan = Gen.GenAmount.shAmount; |
pan = Gen.GenAmount.shAmount; |
379 |
pan * 64; pan /= 500; |
CheckRange("pan", -500, 500, pan); |
380 |
if (pan < -64) pan = -64; |
pan = pan * 64 / 500; |
381 |
if (pan > 63) pan = 63; |
if (pan > 63) pan = 63; |
382 |
break; |
break; |
383 |
case DELAY_MOD_LFO: |
case DELAY_MOD_LFO: |
384 |
delayModLfo = Gen.GenAmount.shAmount; |
delayModLfo = Gen.GenAmount.shAmount; |
385 |
|
CheckRange("delayModLfo", -12000, 5000, delayModLfo); |
386 |
break; |
break; |
387 |
case FREQ_MOD_LFO: |
case FREQ_MOD_LFO: |
388 |
freqModLfo = Gen.GenAmount.shAmount; |
freqModLfo = Gen.GenAmount.shAmount; |
389 |
|
CheckRange("freqModLfo", -16000, 4500, freqModLfo); |
390 |
break; |
break; |
391 |
case DELAY_VIB_LFO: |
case DELAY_VIB_LFO: |
392 |
delayVibLfo = Gen.GenAmount.shAmount; |
delayVibLfo = Gen.GenAmount.shAmount; |
393 |
|
CheckRange("delayVibLfo", -12000, 5000, delayVibLfo); |
394 |
break; |
break; |
395 |
case FREQ_VIB_LFO: |
case FREQ_VIB_LFO: |
396 |
freqVibLfo = Gen.GenAmount.shAmount; |
freqVibLfo = Gen.GenAmount.shAmount; |
397 |
|
CheckRange("freqModLfo", -16000, 4500, freqModLfo); |
398 |
break; |
break; |
399 |
case DELAY_MOD_ENV: |
case DELAY_MOD_ENV: |
400 |
EG2PreAttackDelay = Gen.GenAmount.shAmount; |
EG2PreAttackDelay = Gen.GenAmount.shAmount; |
401 |
|
CheckRange("delayModEnv", -12000, 5000, EG2PreAttackDelay); |
402 |
break; |
break; |
403 |
case ATTACK_MOD_ENV: |
case ATTACK_MOD_ENV: |
404 |
EG2Attack = Gen.GenAmount.shAmount; |
EG2Attack = Gen.GenAmount.shAmount; |
405 |
|
CheckRange("attackModEnv", -12000, 8000, EG2Attack); |
406 |
break; |
break; |
407 |
case HOLD_MOD_ENV: |
case HOLD_MOD_ENV: |
408 |
EG2Hold = Gen.GenAmount.shAmount; |
EG2Hold = Gen.GenAmount.shAmount; |
409 |
|
CheckRange("holdModEnv", -12000, 5000, EG2Hold); |
410 |
break; |
break; |
411 |
case DECAY_MOD_ENV: |
case DECAY_MOD_ENV: |
412 |
EG2Decay = Gen.GenAmount.shAmount; |
EG2Decay = Gen.GenAmount.shAmount; |
413 |
|
CheckRange("decayModEnv", -12000, 8000, EG2Decay); |
414 |
break; |
break; |
415 |
case SUSTAIN_MOD_ENV: |
case SUSTAIN_MOD_ENV: |
416 |
EG2Sustain = Gen.GenAmount.shAmount; |
EG2Sustain = Gen.GenAmount.shAmount; |
417 |
|
CheckRange("sustainModEnv", 0, 1000, EG2Sustain); |
418 |
break; |
break; |
419 |
case RELEASEMODENV: |
case RELEASE_MOD_ENV: |
420 |
EG2Release = Gen.GenAmount.shAmount; |
EG2Release = Gen.GenAmount.shAmount; |
421 |
|
CheckRange("releaseModEnv", -12000, 8000, EG2Release); |
422 |
break; |
break; |
423 |
case KEYNUM_TO_MOD_ENV_HOLD: |
case KEYNUM_TO_MOD_ENV_HOLD: |
424 |
break; |
break; |
426 |
break; |
break; |
427 |
case DELAY_VOL_ENV: |
case DELAY_VOL_ENV: |
428 |
EG1PreAttackDelay = Gen.GenAmount.shAmount; |
EG1PreAttackDelay = Gen.GenAmount.shAmount; |
429 |
|
CheckRange("delayVolEnv", -12000, 5000, EG1PreAttackDelay); |
430 |
break; |
break; |
431 |
case ATTACK_VOL_ENV: |
case ATTACK_VOL_ENV: |
432 |
EG1Attack = Gen.GenAmount.shAmount; |
EG1Attack = Gen.GenAmount.shAmount; |
433 |
|
CheckRange("attackVolEnv", -12000, 8000, EG1Attack); |
434 |
break; |
break; |
435 |
case HOLD_VOL_ENV: |
case HOLD_VOL_ENV: |
436 |
EG1Hold = Gen.GenAmount.shAmount; |
EG1Hold = Gen.GenAmount.shAmount; |
437 |
|
CheckRange("holdVolEnv", -12000, 5000, EG1Hold); |
438 |
break; |
break; |
439 |
case DECAY_VOL_ENV: |
case DECAY_VOL_ENV: |
440 |
EG1Decay = Gen.GenAmount.shAmount; |
EG1Decay = Gen.GenAmount.shAmount; |
441 |
|
CheckRange("decayVolEnv", -12000, 8000, EG1Decay); |
442 |
break; |
break; |
443 |
case SUSTAIN_VOL_ENV: |
case SUSTAIN_VOL_ENV: |
444 |
EG1Sustain = Gen.GenAmount.shAmount; |
EG1Sustain = Gen.GenAmount.shAmount; |
445 |
|
CheckRange("sustainVolEnv", 0, 1440, EG1Sustain); |
446 |
break; |
break; |
447 |
case RELEASE_VOL_ENV: |
case RELEASE_VOL_ENV: |
448 |
EG1Release = Gen.GenAmount.shAmount; |
EG1Release = Gen.GenAmount.shAmount; |
449 |
|
CheckRange("releaseVolEnv", -12000, 8000, EG1Release); |
450 |
break; |
break; |
451 |
case KEYNUM_TO_VOL_ENV_HOLD: |
case KEYNUM_TO_VOL_ENV_HOLD: |
452 |
break; |
break; |
462 |
} |
} |
463 |
case KEY_RANGE: |
case KEY_RANGE: |
464 |
loKey = Gen.GenAmount.ranges.byLo; |
loKey = Gen.GenAmount.ranges.byLo; |
465 |
|
CheckRange("loKey", 0, 127, loKey); |
466 |
hiKey = Gen.GenAmount.ranges.byHi; |
hiKey = Gen.GenAmount.ranges.byHi; |
467 |
|
CheckRange("hiKey", 0, 127, hiKey); |
468 |
break; |
break; |
469 |
case VEL_RANGE: |
case VEL_RANGE: |
470 |
minVel = Gen.GenAmount.ranges.byLo; |
minVel = Gen.GenAmount.ranges.byLo; |
471 |
|
CheckRange("minVel", 0, 127, minVel); |
472 |
maxVel = Gen.GenAmount.ranges.byHi; |
maxVel = Gen.GenAmount.ranges.byHi; |
473 |
|
CheckRange("maxVel", 0, 127, maxVel); |
474 |
break; |
break; |
475 |
case STARTLOOP_ADDRS_COARSE_OFFSET: |
case STARTLOOP_ADDRS_COARSE_OFFSET: |
476 |
startloopAddrsCoarseOffset = Gen.GenAmount.wAmount; |
startloopAddrsCoarseOffset = Gen.GenAmount.wAmount; |
488 |
break; |
break; |
489 |
case COARSE_TUNE: |
case COARSE_TUNE: |
490 |
coarseTune = Gen.GenAmount.shAmount; |
coarseTune = Gen.GenAmount.shAmount; |
491 |
if (coarseTune < -120) coarseTune = -120; |
CheckRange("coarseTune", -120, 120, coarseTune); |
|
if (coarseTune > 120) coarseTune = 120; |
|
492 |
break; |
break; |
493 |
case FINE_TUNE: |
case FINE_TUNE: |
494 |
fineTune = Gen.GenAmount.shAmount; |
fineTune = Gen.GenAmount.shAmount; |
495 |
|
CheckRange("fineTune", -99, 99, fineTune); |
496 |
break; |
break; |
497 |
case SAMPLE_ID: { |
case SAMPLE_ID: { |
498 |
uint16_t sid = Gen.GenAmount.wAmount; |
uint16_t sid = Gen.GenAmount.wAmount; |
525 |
break; |
break; |
526 |
case OVERRIDING_ROOT_KEY: |
case OVERRIDING_ROOT_KEY: |
527 |
overridingRootKey = Gen.GenAmount.shAmount; |
overridingRootKey = Gen.GenAmount.shAmount; |
528 |
|
CheckRange("overridingRootKey", -1, 127, overridingRootKey); |
529 |
break; |
break; |
530 |
} |
} |
531 |
} |
} |
578 |
} |
} |
579 |
|
|
580 |
double Region::GetEG1PreAttackDelay(Region* pPresetRegion) { |
double Region::GetEG1PreAttackDelay(Region* pPresetRegion) { |
581 |
if (pPresetRegion == NULL || pPresetRegion->EG1PreAttackDelay == NONE) return ToSeconds(EG1PreAttackDelay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1PreAttackDelay == NONE) ? |
582 |
return ToSeconds(pPresetRegion->EG1PreAttackDelay + EG1PreAttackDelay); |
EG1PreAttackDelay : pPresetRegion->EG1PreAttackDelay + EG1PreAttackDelay; |
583 |
|
return ToSeconds(CheckRange("GetEG1PreAttackDelay()", -12000, 5000, val)); |
584 |
} |
} |
585 |
|
|
586 |
double Region::GetEG1Attack(Region* pPresetRegion) { |
double Region::GetEG1Attack(Region* pPresetRegion) { |
587 |
if (pPresetRegion == NULL || pPresetRegion->EG1Attack == NONE) return ToSeconds(EG1Attack); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Attack == NONE) ? |
588 |
return ToSeconds(pPresetRegion->EG1Attack + EG1Attack); |
EG1Attack : pPresetRegion->EG1Attack + EG1Attack; |
589 |
|
return ToSeconds(CheckRange("GetEG1Attack()", -12000, 8000, val)); |
590 |
} |
} |
591 |
|
|
592 |
double Region::GetEG1Hold(Region* pPresetRegion) { |
double Region::GetEG1Hold(Region* pPresetRegion) { |
593 |
if (pPresetRegion == NULL || pPresetRegion->EG1Hold == NONE) return ToSeconds(EG1Hold); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Hold == NONE) ? |
594 |
return ToSeconds(pPresetRegion->EG1Hold + EG1Hold); |
EG1Hold : pPresetRegion->EG1Hold + EG1Hold; |
595 |
|
return ToSeconds(CheckRange("GetEG1Hold()", -12000, 5000, val)); |
596 |
} |
} |
597 |
|
|
598 |
double Region::GetEG1Decay(Region* pPresetRegion) { |
double Region::GetEG1Decay(Region* pPresetRegion) { |
599 |
if (pPresetRegion == NULL || pPresetRegion->EG1Decay == NONE) return ToSeconds(EG1Decay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Decay == NONE) ? |
600 |
return ToSeconds(pPresetRegion->EG1Decay + EG1Decay); |
EG1Decay : pPresetRegion->EG1Decay + EG1Decay; |
601 |
|
return ToSeconds(CheckRange("GetEG1Decay()", -12000, 8000, val)); |
602 |
} |
} |
603 |
|
|
604 |
double Region::GetEG1Sustain(Region* pPresetRegion) { |
int Region::GetEG1Sustain(Region* pPresetRegion) { |
605 |
if (pPresetRegion == NULL || pPresetRegion->EG1Sustain == NONE) return ToPermilles(EG1Sustain); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Sustain == NONE) ? |
606 |
return ToPermilles(pPresetRegion->EG1Sustain + EG1Sustain); |
EG1Sustain : pPresetRegion->EG1Sustain + EG1Sustain; |
607 |
|
return CheckRange("GetEG1Sustain()", 0, 1440, val); |
608 |
} |
} |
609 |
|
|
610 |
double Region::GetEG1Release(Region* pPresetRegion) { |
double Region::GetEG1Release(Region* pPresetRegion) { |
611 |
if (pPresetRegion == NULL || pPresetRegion->EG1Release == NONE) return ToSeconds(EG1Release); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Release == NONE) ? |
612 |
return ToSeconds(pPresetRegion->EG1Release + EG1Release); |
EG1Release : pPresetRegion->EG1Release + EG1Release; |
613 |
|
return ToSeconds(CheckRange("GetEG1Release()", -12000, 8000, val)); |
614 |
} |
} |
615 |
|
|
616 |
double Region::GetEG2PreAttackDelay(Region* pPresetRegion) { |
double Region::GetEG2PreAttackDelay(Region* pPresetRegion) { |
617 |
if (pPresetRegion == NULL || pPresetRegion->EG2PreAttackDelay == NONE) return ToSeconds(EG2PreAttackDelay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2PreAttackDelay == NONE) ? |
618 |
return ToSeconds(pPresetRegion->EG2PreAttackDelay + EG2PreAttackDelay); |
EG2PreAttackDelay : pPresetRegion->EG2PreAttackDelay + EG2PreAttackDelay; |
619 |
|
return ToSeconds(CheckRange("GetEG2PreAttackDelay()", -12000, 5000, val)); |
620 |
} |
} |
621 |
|
|
622 |
double Region::GetEG2Attack(Region* pPresetRegion) { |
double Region::GetEG2Attack(Region* pPresetRegion) { |
623 |
if (pPresetRegion == NULL || pPresetRegion->EG2Attack == NONE) return ToSeconds(EG2Attack); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Attack == NONE) ? |
624 |
return ToSeconds(pPresetRegion->EG2Attack + EG2Attack); |
EG2Attack : pPresetRegion->EG2Attack + EG2Attack; |
625 |
|
return ToSeconds(CheckRange("GetEG2Attack()", -12000, 8000, val)); |
626 |
} |
} |
627 |
|
|
628 |
double Region::GetEG2Hold(Region* pPresetRegion) { |
double Region::GetEG2Hold(Region* pPresetRegion) { |
629 |
if (pPresetRegion == NULL || pPresetRegion->EG2Hold == NONE) return ToSeconds(EG2Hold); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Hold == NONE) ? |
630 |
return ToSeconds(pPresetRegion->EG2Hold + EG2Hold); |
EG2Hold : pPresetRegion->EG2Hold + EG2Hold; |
631 |
|
return ToSeconds(CheckRange("GetEG2Hold()", -12000, 5000, val)); |
632 |
} |
} |
633 |
|
|
634 |
double Region::GetEG2Decay(Region* pPresetRegion) { |
double Region::GetEG2Decay(Region* pPresetRegion) { |
635 |
if (pPresetRegion == NULL || pPresetRegion->EG2Decay == NONE) return ToSeconds(EG2Decay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Decay == NONE) ? |
636 |
return ToSeconds(pPresetRegion->EG2Decay + EG2Decay); |
EG2Decay : pPresetRegion->EG2Decay + EG2Decay; |
637 |
|
return ToSeconds(CheckRange("GetEG2Decay()", -12000, 8000, val)); |
638 |
} |
} |
639 |
|
|
640 |
double Region::GetEG2Sustain(Region* pPresetRegion) { |
int Region::GetEG2Sustain(Region* pPresetRegion) { |
641 |
if (pPresetRegion == NULL || pPresetRegion->EG2Sustain == NONE) { |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Sustain == NONE) ? |
642 |
return EG2Sustain == NONE ? NONE : 1000 - EG2Sustain; |
EG2Sustain : pPresetRegion->EG2Sustain + EG2Sustain; |
643 |
} |
return CheckRange("GetEG2Sustain()", 0, 1000, val); |
|
return 1000 - (pPresetRegion->EG2Sustain + EG2Sustain); |
|
644 |
} |
} |
645 |
|
|
646 |
double Region::GetEG2Release(Region* pPresetRegion) { |
double Region::GetEG2Release(Region* pPresetRegion) { |
647 |
if (pPresetRegion == NULL || pPresetRegion->EG2Release == NONE) return ToSeconds(EG2Release); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Release == NONE) ? |
648 |
return ToSeconds(pPresetRegion->EG2Release + EG2Release); |
EG2Release : pPresetRegion->EG2Release + EG2Release; |
649 |
|
return ToSeconds(CheckRange("GetEG2Release()", -12000, 8000, val)); |
650 |
} |
} |
651 |
|
|
652 |
int Region::GetModEnvToPitch(Region* pPresetRegion) { |
int Region::GetModEnvToPitch(Region* pPresetRegion) { |
653 |
return modEnvToPitch + (pPresetRegion ? pPresetRegion->modEnvToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modEnvToPitch == NONE) ? |
654 |
|
modEnvToPitch : pPresetRegion->modEnvToPitch + modEnvToPitch; |
655 |
|
return CheckRange("GetModEnvToPitch()", -12000, 12000, val); |
656 |
} |
} |
657 |
|
|
658 |
int Region::GetModLfoToPitch(Region* pPresetRegion) { |
int Region::GetModLfoToPitch(Region* pPresetRegion) { |
659 |
return modLfoToPitch + (pPresetRegion ? pPresetRegion->modLfoToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToPitch == NONE) ? |
660 |
|
modLfoToPitch : pPresetRegion->modLfoToPitch + modLfoToPitch; |
661 |
|
return CheckRange("GetModLfoToPitch()", -12000, 12000, val); |
662 |
} |
} |
663 |
|
|
664 |
int Region::GetModEnvToFilterFc(Region* pPresetRegion) { |
int Region::GetModEnvToFilterFc(Region* pPresetRegion) { |
665 |
return modEnvToFilterFc + (pPresetRegion ? pPresetRegion->modEnvToFilterFc : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modEnvToFilterFc == NONE) ? |
666 |
|
modEnvToFilterFc : pPresetRegion->modEnvToFilterFc + modEnvToFilterFc; |
667 |
|
return CheckRange("GetModEnvToFilterFc()", -12000, +12000, val); |
668 |
} |
} |
669 |
|
|
670 |
int Region::GetModLfoToFilterFc(Region* pPresetRegion) { |
int Region::GetModLfoToFilterFc(Region* pPresetRegion) { |
671 |
return modLfoToFilterFc + (pPresetRegion ? pPresetRegion->modLfoToFilterFc : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToFilterFc == NONE) ? |
672 |
|
modLfoToFilterFc : pPresetRegion->modLfoToFilterFc + modLfoToFilterFc; |
673 |
|
return CheckRange("GetModLfoToFilterFc()", -12000, +12000, val); |
674 |
} |
} |
675 |
|
|
676 |
double Region::GetModLfoToVolume(Region* pPresetRegion) { |
double Region::GetModLfoToVolume(Region* pPresetRegion) { |
677 |
return ToPermilles(modLfoToVolume + (pPresetRegion ? pPresetRegion->modLfoToVolume : 0)); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToVolume == NONE) ? |
678 |
|
modLfoToVolume : pPresetRegion->modLfoToVolume + modLfoToVolume; |
679 |
|
return CheckRange("GetModLfoToVolume()", -960, 960, val); |
680 |
} |
} |
681 |
|
|
682 |
double Region::GetFreqModLfo(Region* pPresetRegion) { |
double Region::GetFreqModLfo(Region* pPresetRegion) { |
683 |
if (pPresetRegion == NULL || pPresetRegion->freqModLfo == NONE) return ToHz(freqModLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->freqModLfo == NONE) ? |
684 |
return ToHz(pPresetRegion->freqModLfo + freqModLfo); |
freqModLfo : pPresetRegion->freqModLfo + freqModLfo; |
685 |
|
return ToHz(CheckRange("GetFreqModLfo()", -16000, 4500, val)); |
686 |
} |
} |
687 |
|
|
688 |
double Region::GetDelayModLfo(Region* pPresetRegion) { |
double Region::GetDelayModLfo(Region* pPresetRegion) { |
689 |
if (pPresetRegion == NULL || pPresetRegion->delayModLfo == NONE) return ToSeconds(delayModLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->delayModLfo == NONE) ? |
690 |
return ToSeconds(pPresetRegion->delayModLfo + delayModLfo); |
delayModLfo : pPresetRegion->delayModLfo + delayModLfo; |
691 |
|
return ToSeconds(CheckRange("GetDelayModLfo()", -12000, 5000, val)); |
692 |
} |
} |
693 |
|
|
694 |
int Region::GetVibLfoToPitch(Region* pPresetRegion) { |
int Region::GetVibLfoToPitch(Region* pPresetRegion) { |
695 |
return vibLfoToPitch + (pPresetRegion ? pPresetRegion->vibLfoToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->vibLfoToPitch == NONE) ? |
696 |
|
vibLfoToPitch : pPresetRegion->vibLfoToPitch + vibLfoToPitch; |
697 |
|
return CheckRange("GetVibLfoToPitch()", -12000, 12000, val); |
698 |
} |
} |
699 |
|
|
700 |
double Region::GetFreqVibLfo(Region* pPresetRegion) { |
double Region::GetFreqVibLfo(Region* pPresetRegion) { |
701 |
if (pPresetRegion == NULL || pPresetRegion->freqVibLfo == NONE) return ToHz(freqVibLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->freqVibLfo == NONE) ? |
702 |
return ToHz(pPresetRegion->freqVibLfo + freqVibLfo); |
freqVibLfo : pPresetRegion->freqVibLfo + freqVibLfo; |
703 |
|
return ToHz(CheckRange("GetFreqVibLfo()", -16000, 4500, val)); |
704 |
} |
} |
705 |
|
|
706 |
double Region::GetDelayVibLfo(Region* pPresetRegion) { |
double Region::GetDelayVibLfo(Region* pPresetRegion) { |
707 |
if (pPresetRegion == NULL || pPresetRegion->delayVibLfo == NONE) return ToSeconds(delayVibLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->delayVibLfo == NONE) ? |
708 |
return ToSeconds(pPresetRegion->delayVibLfo + delayVibLfo); |
delayVibLfo : pPresetRegion->delayVibLfo + delayVibLfo; |
709 |
|
return ToSeconds(CheckRange("GetDelayVibLfo()", -12000, 5000, val)); |
710 |
|
} |
711 |
|
|
712 |
|
int Region::GetInitialFilterFc(Region* pPresetRegion) { |
713 |
|
if (pPresetRegion == NULL || pPresetRegion->initialFilterFc == NONE) return initialFilterFc; |
714 |
|
int val = pPresetRegion->initialFilterFc + initialFilterFc; |
715 |
|
return CheckRange("GetInitialFilterFc()", 1500, 13500, val); |
716 |
|
} |
717 |
|
|
718 |
|
int Region::GetInitialFilterQ(Region* pPresetRegion) { |
719 |
|
int val = (pPresetRegion == NULL || pPresetRegion->initialFilterQ == NONE) ? |
720 |
|
initialFilterQ : pPresetRegion->initialFilterQ + initialFilterQ; |
721 |
|
return CheckRange("GetInitialFilterQ()", 0, 960, val); |
722 |
} |
} |
723 |
|
|
724 |
InstrumentBase::InstrumentBase(sf2::File* pFile) { |
InstrumentBase::InstrumentBase(sf2::File* pFile) { |
815 |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
816 |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
817 |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
818 |
|
r->initialFilterFc = pGlobalRegion->initialFilterFc; |
819 |
|
r->initialFilterQ = pGlobalRegion->initialFilterQ; |
820 |
|
|
821 |
r->HasLoop = pGlobalRegion->HasLoop; |
r->HasLoop = pGlobalRegion->HasLoop; |
822 |
r->LoopStart = pGlobalRegion->LoopStart; |
r->LoopStart = pGlobalRegion->LoopStart; |
900 |
r->EG1PreAttackDelay = r->EG1Attack = r->EG1Hold = r->EG1Decay = r->EG1Sustain = r->EG1Release = NONE; |
r->EG1PreAttackDelay = r->EG1Attack = r->EG1Hold = r->EG1Decay = r->EG1Sustain = r->EG1Release = NONE; |
901 |
r->EG2PreAttackDelay = r->EG2Attack = r->EG2Hold = r->EG2Decay = r->EG2Sustain = r->EG2Release = NONE; |
r->EG2PreAttackDelay = r->EG2Attack = r->EG2Hold = r->EG2Decay = r->EG2Sustain = r->EG2Release = NONE; |
902 |
r->freqModLfo = r->delayModLfo = r->freqVibLfo = r->delayVibLfo = NONE; |
r->freqModLfo = r->delayModLfo = r->freqVibLfo = r->delayVibLfo = NONE; |
903 |
|
r->initialFilterFc = r->initialFilterQ = NONE; |
904 |
|
|
905 |
if (pGlobalRegion != NULL) { |
if (pGlobalRegion != NULL) { |
906 |
r->pan = pGlobalRegion->pan; |
r->pan = pGlobalRegion->pan; |
931 |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
932 |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
933 |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
934 |
|
r->initialFilterFc = pGlobalRegion->initialFilterFc; |
935 |
|
r->initialFilterQ = pGlobalRegion->initialFilterQ; |
936 |
} |
} |
937 |
|
|
938 |
return r; |
return r; |
1404 |
return (pCkSmpl->GetPos() - (Start * 2)) / 2; |
return (pCkSmpl->GetPos() - (Start * 2)) / 2; |
1405 |
} |
} |
1406 |
|
|
1407 |
/** |
// Actual implementation of Sample::Read*() code. Wrapped into a template for a) runtime effeciency and b) code redundancy reasons. |
1408 |
* Reads \a SampleCount number of sample points from the current |
template<bool CLEAR> |
1409 |
* position into the buffer pointed by \a pBuffer and increments the |
inline unsigned long ReadSample(Sample* pSample, void* pBuffer, unsigned long SampleCount, Sample::buffer_t* tempBuffer = NULL) { |
|
* position within the sample. Use this method |
|
|
* and <i>SetPos()</i> if you don't want to load the sample into RAM, |
|
|
* thus for disk streaming. |
|
|
* |
|
|
* For 16 bit samples, the data in the buffer will be int16_t |
|
|
* (using native endianness). For 24 bit, the buffer will |
|
|
* contain three bytes per sample, little-endian. |
|
|
* |
|
|
* @param pBuffer destination buffer |
|
|
* @param SampleCount number of sample points to read |
|
|
* @returns number of successfully read sample points |
|
|
* @see SetPos() |
|
|
*/ |
|
|
unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) { |
|
1410 |
// TODO: startAddrsCoarseOffset, endAddrsCoarseOffset |
// TODO: startAddrsCoarseOffset, endAddrsCoarseOffset |
1411 |
if (SampleCount == 0) return 0; |
if (SampleCount == 0) return 0; |
1412 |
long pos = GetPos(); |
long pos = pSample->GetPos(); |
1413 |
if (pos + SampleCount > GetTotalFrameCount()) SampleCount = GetTotalFrameCount() - pos; |
if (pos + SampleCount > pSample->GetTotalFrameCount()) |
1414 |
|
SampleCount = pSample->GetTotalFrameCount() - pos; |
1415 |
|
if (!CLEAR) { |
1416 |
|
if (tempBuffer->Size < SampleCount * pSample->GetFrameSize()) { |
1417 |
|
std::cerr << "sf2::Sample error: tempBuffer too small. This is a BUG!" << std::endl; |
1418 |
|
return 0; |
1419 |
|
} |
1420 |
|
} |
1421 |
|
|
1422 |
if (GetFrameSize() / GetChannelCount() == 3 /* 24 bit */) { |
if (pSample->GetFrameSize() / pSample->GetChannelCount() == 3 /* 24 bit */) { |
1423 |
uint8_t* pBuf = (uint8_t*)pBuffer; |
uint8_t* const pTmpBuf = (uint8_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart); |
1424 |
if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) { |
uint8_t* const pBuf = (uint8_t*)pBuffer; |
1425 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) { |
1426 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1427 |
|
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1428 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (int i = SampleCount - 1; i >= 0; i--) { |
1429 |
pBuf[i*3] = pBuf[(SampleCount * 2) + i]; |
pBuf[i*3] = pTmpBuf[(SampleCount * 2) + i]; |
1430 |
pBuf[i*3 + 2] = pBuf[i*2 + 1]; |
pBuf[i*3 + 2] = pTmpBuf[i*2 + 1]; |
1431 |
pBuf[i*3 + 1] = pBuf[i*2]; |
pBuf[i*3 + 1] = pTmpBuf[i*2]; |
1432 |
} |
} |
1433 |
} else if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) { |
} else if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) { |
1434 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1435 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1436 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (int i = SampleCount - 1; i >= 0; i--) { |
1437 |
pBuf[i*6] = pBuf[(SampleCount * 2) + i]; |
pBuf[i*6] = pTmpBuf[(SampleCount * 2) + i]; |
1438 |
pBuf[i*6 + 2] = pBuf[i*2 + 1]; |
pBuf[i*6 + 2] = pTmpBuf[i*2 + 1]; |
1439 |
pBuf[i*6 + 1] = pBuf[i*2]; |
pBuf[i*6 + 1] = pTmpBuf[i*2]; |
1440 |
pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0; |
if (CLEAR) |
1441 |
|
pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0; |
1442 |
} |
} |
1443 |
} else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) { |
} else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) { |
1444 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1445 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1446 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (int i = SampleCount - 1; i >= 0; i--) { |
1447 |
pBuf[i*6 + 3] = pBuf[(SampleCount * 2) + i]; |
pBuf[i*6 + 3] = pTmpBuf[(SampleCount * 2) + i]; |
1448 |
pBuf[i*6 + 5] = pBuf[i*2 + 1]; |
pBuf[i*6 + 5] = pTmpBuf[i*2 + 1]; |
1449 |
pBuf[i*6 + 4] = pBuf[i*2]; |
pBuf[i*6 + 4] = pTmpBuf[i*2]; |
1450 |
pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0; |
if (CLEAR) |
1451 |
|
pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0; |
1452 |
} |
} |
1453 |
} |
} |
1454 |
} else { |
} else { |
1455 |
if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) { |
if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) { |
1456 |
return pCkSmpl->Read(pBuffer, SampleCount, 2); |
return pSample->pCkSmpl->Read(pBuffer, SampleCount, 2); |
1457 |
} |
} |
1458 |
|
|
1459 |
int16_t* pBuf = (int16_t*)pBuffer; |
int16_t* const pTmpBuf = (int16_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart); |
1460 |
if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) { |
int16_t* const pBuf = (int16_t*) pBuffer; |
1461 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) { |
1462 |
|
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1463 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (int i = SampleCount - 1; i >= 0; i--) { |
1464 |
pBuf[i*2] = pBuf[i]; |
pBuf[i*2] = pTmpBuf[i]; |
1465 |
pBuf[i*2 + 1] = 0; |
if (CLEAR) |
1466 |
|
pBuf[i*2 + 1] = 0; |
1467 |
} |
} |
1468 |
} else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) { |
} else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) { |
1469 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1470 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (int i = SampleCount - 1; i >= 0; i--) { |
1471 |
pBuf[i*2] = 0; |
if (CLEAR) |
1472 |
pBuf[i*2 + 1] = pBuf[i]; |
pBuf[i*2] = 0; |
1473 |
|
pBuf[i*2 + 1] = pTmpBuf[i]; |
1474 |
} |
} |
1475 |
} |
} |
1476 |
} |
} |
1477 |
|
|
1478 |
if (pCkSmpl->GetPos() > (End * 2)) { |
if (pSample->pCkSmpl->GetPos() > (pSample->End * 2)) { |
1479 |
std::cerr << "Read after the sample end. This is a BUG!" << std::endl; |
std::cerr << "Read after the sample end. This is a BUG!" << std::endl; |
1480 |
std::cerr << "Current position: " << GetPos() << std::endl; |
std::cerr << "Current position: " << pSample->GetPos() << std::endl; |
1481 |
std::cerr << "Total number of frames: " << GetTotalFrameCount() << std::endl << std::endl; |
std::cerr << "Total number of frames: " << pSample->GetTotalFrameCount() << std::endl << std::endl; |
1482 |
} |
} |
1483 |
return SampleCount; |
return SampleCount; |
1484 |
} |
} |
1485 |
|
|
1486 |
|
/** |
1487 |
|
* Reads \a SampleCount number of sample points from the current |
1488 |
|
* position into the buffer pointed by \a pBuffer and increments the |
1489 |
|
* position within the sample. Use this method |
1490 |
|
* and <i>SetPos()</i> if you don't want to load the sample into RAM, |
1491 |
|
* thus for disk streaming. |
1492 |
|
* |
1493 |
|
* For 16 bit samples, the data in the buffer will be int16_t |
1494 |
|
* (using native endianness). For 24 bit, the buffer will |
1495 |
|
* contain three bytes per sample, little-endian. |
1496 |
|
* |
1497 |
|
* Stereo Samples: stereo samples are stored as a pair of mono samples with |
1498 |
|
* SoundFont 2. Due to historical reasons, this Read() method expects |
1499 |
|
* @a pBuffer to be a stereo buffer, however only the audio channel covered |
1500 |
|
* by the sample data of this sample will be filled. The other audio channel |
1501 |
|
* of @a pBuffer will be set to zero. This is probably not what you want. |
1502 |
|
* So you might want to use ReadNoClear() instead. |
1503 |
|
* |
1504 |
|
* @param pBuffer destination buffer |
1505 |
|
* @param SampleCount number of sample points to read |
1506 |
|
* @returns number of successfully read sample points |
1507 |
|
* @see SetPos(), ReadNoClear() |
1508 |
|
*/ |
1509 |
|
unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) { |
1510 |
|
return ReadSample<true>(this, pBuffer, SampleCount); |
1511 |
|
} |
1512 |
|
|
1513 |
|
/** |
1514 |
|
* Reads \a SampleCount number of sample points from the current |
1515 |
|
* position into the buffer pointed by \a pBuffer and increments the |
1516 |
|
* position within the sample. Use this method |
1517 |
|
* and <i>SetPos()</i> if you don't want to load the sample into RAM, |
1518 |
|
* thus for disk streaming. |
1519 |
|
* |
1520 |
|
* For 16 bit samples, the data in the buffer will be int16_t |
1521 |
|
* (using native endianness). For 24 bit, the buffer will |
1522 |
|
* contain three bytes per sample, little-endian. |
1523 |
|
* |
1524 |
|
* Stereo Samples: stereo samples are stored as a pair of mono samples with |
1525 |
|
* SoundFont 2. This ReadNoClear() method expects @a pBuffer to be a stereo |
1526 |
|
* buffer, however only the audio channel covered by the sample data of this |
1527 |
|
* sample will be filled. The other audio channel |
1528 |
|
* of @a pBuffer will remain untouched. So you might pass the same |
1529 |
|
* @a pBuffer to the other, linked sample to actually get the interleaved |
1530 |
|
* stereo audio stream. To avoid destroying the other audio channel's data |
1531 |
|
* you must pass an external, tempoary working buffer @a tempBuffer, which |
1532 |
|
* should already be allocated to the size required to decode the requested |
1533 |
|
* length of sample data. That @a tempBuffer is only used by ReadNoClear() |
1534 |
|
* to fulfill its work, it does not contain any useful data after this |
1535 |
|
* method returned. |
1536 |
|
* |
1537 |
|
* @param pBuffer destination buffer |
1538 |
|
* @param SampleCount number of sample points to read |
1539 |
|
* @param tempBuffer temporary work buffer (must be pre-allocated large enough) |
1540 |
|
* @returns number of successfully read sample points |
1541 |
|
* @see SetPos(), Read() |
1542 |
|
*/ |
1543 |
|
unsigned long Sample::ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer) { |
1544 |
|
return ReadSample<false>(this, pBuffer, SampleCount, &tempBuffer); |
1545 |
|
} |
1546 |
|
|
1547 |
|
|
1548 |
// *************** functions *************** |
// *************** functions *************** |
1549 |
// * |
// * |