21 |
* MA 02111-1307 USA * |
* MA 02111-1307 USA * |
22 |
***************************************************************************/ |
***************************************************************************/ |
23 |
|
|
|
#include <vector> |
|
|
|
|
24 |
#include "RIFF.h" |
#include "RIFF.h" |
25 |
|
|
26 |
#include "SF.h" |
#include "SF.h" |
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 |
|
|
147 |
::LoadString(ck, s); // function from helper.h |
::LoadString(ck, s); // function from helper.h |
148 |
} |
} |
149 |
|
|
150 |
Sample::Sample(RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24) { |
Sample::Sample(File* file, RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24) { |
151 |
|
this->pFile = file; |
152 |
this->pCkSmpl = pCkSmpl; |
this->pCkSmpl = pCkSmpl; |
153 |
this->pCkSm24 = pCkSm24; |
this->pCkSm24 = pCkSm24; |
154 |
|
|
287 |
delayVibLfo = -12000; |
delayVibLfo = -12000; |
288 |
|
|
289 |
exclusiveClass = 0; |
exclusiveClass = 0; |
290 |
|
|
291 |
|
initialFilterFc = 13500; |
292 |
|
initialFilterQ = 0; |
293 |
} |
} |
294 |
|
|
295 |
int Region::GetUnityNote() { |
int Region::GetUnityNote() { |
296 |
return overridingRootKey != -1 ? overridingRootKey : pSample->OriginalPitch; |
return overridingRootKey != -1 ? overridingRootKey : pSample->OriginalPitch; |
297 |
} |
} |
298 |
|
|
299 |
|
int CheckRange(std::string genName, int min, int max, int& gen) { |
300 |
|
if (gen == NONE) return gen; |
301 |
|
|
302 |
|
if (gen < min) { |
303 |
|
std::cerr << "sf2: " << genName; |
304 |
|
std::cerr << " is below the minimum allowed value (min=" << min << "): " << gen << std::endl; |
305 |
|
gen = min; |
306 |
|
} |
307 |
|
if (gen > max) { |
308 |
|
std::cerr << "sf2: " << genName; |
309 |
|
std::cerr << " is above the maximum allowed value (max=" << max << "): " << gen << std::endl; |
310 |
|
gen = max; |
311 |
|
} |
312 |
|
|
313 |
|
return gen; |
314 |
|
} |
315 |
|
|
316 |
void Region::SetGenerator(sf2::File* pFile, GenList& Gen) { |
void Region::SetGenerator(sf2::File* pFile, GenList& Gen) { |
317 |
switch(Gen.GenOper) { |
switch(Gen.GenOper) { |
338 |
break; |
break; |
339 |
case MOD_LFO_TO_PITCH: |
case MOD_LFO_TO_PITCH: |
340 |
modLfoToPitch = Gen.GenAmount.shAmount; |
modLfoToPitch = Gen.GenAmount.shAmount; |
341 |
|
CheckRange("modLfoToPitch", -12000, 12000, modLfoToPitch); |
342 |
break; |
break; |
343 |
case VIB_LFO_TO_PITCH: |
case VIB_LFO_TO_PITCH: |
344 |
vibLfoToPitch = Gen.GenAmount.shAmount; |
vibLfoToPitch = Gen.GenAmount.shAmount; |
345 |
|
CheckRange("vibLfoToPitch", -12000, 12000, vibLfoToPitch); |
346 |
break; |
break; |
347 |
case MOD_ENV_TO_PITCH: |
case MOD_ENV_TO_PITCH: |
348 |
modEnvToPitch = Gen.GenAmount.shAmount; |
modEnvToPitch = Gen.GenAmount.shAmount; |
349 |
|
CheckRange("modEnvToPitch", -12000, 12000, modEnvToPitch); |
350 |
break; |
break; |
351 |
case INITIAL_FILTER_FC: |
case INITIAL_FILTER_FC: |
352 |
|
initialFilterFc = Gen.GenAmount.wAmount; |
353 |
|
CheckRange("initialFilterFc", 1500, 13500, initialFilterFc); |
354 |
break; |
break; |
355 |
case INITIAL_FILTER_Q: |
case INITIAL_FILTER_Q: |
356 |
|
initialFilterQ = Gen.GenAmount.wAmount; |
357 |
|
CheckRange("initialFilterQ", 0, 960, initialFilterQ); |
358 |
break; |
break; |
359 |
case MOD_LFO_TO_FILTER_FC: |
case MOD_LFO_TO_FILTER_FC: |
360 |
modLfoToFilterFc = Gen.GenAmount.shAmount; |
modLfoToFilterFc = Gen.GenAmount.shAmount; |
361 |
|
CheckRange("modLfoToFilterFc", -12000, 12000, modLfoToFilterFc); |
362 |
break; |
break; |
363 |
case MOD_ENV_TO_FILTER_FC: |
case MOD_ENV_TO_FILTER_FC: |
364 |
modEnvToFilterFc = Gen.GenAmount.shAmount; |
modEnvToFilterFc = Gen.GenAmount.shAmount; |
365 |
|
CheckRange("modEnvToFilterFc", -12000, 12000, modEnvToFilterFc); |
366 |
break; |
break; |
367 |
case END_ADDRS_COARSE_OFFSET: |
case END_ADDRS_COARSE_OFFSET: |
368 |
endAddrsCoarseOffset = Gen.GenAmount.wAmount; |
endAddrsCoarseOffset = Gen.GenAmount.wAmount; |
369 |
break; |
break; |
370 |
case MOD_LFO_TO_VOLUME: |
case MOD_LFO_TO_VOLUME: |
371 |
modLfoToVolume = Gen.GenAmount.shAmount; |
modLfoToVolume = Gen.GenAmount.shAmount; |
372 |
|
CheckRange("modLfoToVolume", -960, 960, modLfoToVolume); |
373 |
break; |
break; |
374 |
case CHORUS_EFFECTS_SEND: |
case CHORUS_EFFECTS_SEND: |
375 |
break; |
break; |
377 |
break; |
break; |
378 |
case PAN: |
case PAN: |
379 |
pan = Gen.GenAmount.shAmount; |
pan = Gen.GenAmount.shAmount; |
380 |
pan * 64; pan /= 500; |
CheckRange("pan", -500, 500, pan); |
381 |
if (pan < -64) pan = -64; |
pan = pan * 64 / 500; |
382 |
if (pan > 63) pan = 63; |
if (pan > 63) pan = 63; |
383 |
break; |
break; |
384 |
case DELAY_MOD_LFO: |
case DELAY_MOD_LFO: |
385 |
delayModLfo = Gen.GenAmount.shAmount; |
delayModLfo = Gen.GenAmount.shAmount; |
386 |
|
CheckRange("delayModLfo", -12000, 5000, delayModLfo); |
387 |
break; |
break; |
388 |
case FREQ_MOD_LFO: |
case FREQ_MOD_LFO: |
389 |
freqModLfo = Gen.GenAmount.shAmount; |
freqModLfo = Gen.GenAmount.shAmount; |
390 |
|
CheckRange("freqModLfo", -16000, 4500, freqModLfo); |
391 |
break; |
break; |
392 |
case DELAY_VIB_LFO: |
case DELAY_VIB_LFO: |
393 |
delayVibLfo = Gen.GenAmount.shAmount; |
delayVibLfo = Gen.GenAmount.shAmount; |
394 |
|
CheckRange("delayVibLfo", -12000, 5000, delayVibLfo); |
395 |
break; |
break; |
396 |
case FREQ_VIB_LFO: |
case FREQ_VIB_LFO: |
397 |
freqVibLfo = Gen.GenAmount.shAmount; |
freqVibLfo = Gen.GenAmount.shAmount; |
398 |
|
CheckRange("freqModLfo", -16000, 4500, freqModLfo); |
399 |
break; |
break; |
400 |
case DELAY_MOD_ENV: |
case DELAY_MOD_ENV: |
401 |
EG2PreAttackDelay = Gen.GenAmount.shAmount; |
EG2PreAttackDelay = Gen.GenAmount.shAmount; |
402 |
|
CheckRange("delayModEnv", -12000, 5000, EG2PreAttackDelay); |
403 |
break; |
break; |
404 |
case ATTACK_MOD_ENV: |
case ATTACK_MOD_ENV: |
405 |
EG2Attack = Gen.GenAmount.shAmount; |
EG2Attack = Gen.GenAmount.shAmount; |
406 |
|
CheckRange("attackModEnv", -12000, 8000, EG2Attack); |
407 |
break; |
break; |
408 |
case HOLD_MOD_ENV: |
case HOLD_MOD_ENV: |
409 |
EG2Hold = Gen.GenAmount.shAmount; |
EG2Hold = Gen.GenAmount.shAmount; |
410 |
|
CheckRange("holdModEnv", -12000, 5000, EG2Hold); |
411 |
break; |
break; |
412 |
case DECAY_MOD_ENV: |
case DECAY_MOD_ENV: |
413 |
EG2Decay = Gen.GenAmount.shAmount; |
EG2Decay = Gen.GenAmount.shAmount; |
414 |
|
CheckRange("decayModEnv", -12000, 8000, EG2Decay); |
415 |
break; |
break; |
416 |
case SUSTAIN_MOD_ENV: |
case SUSTAIN_MOD_ENV: |
417 |
EG2Sustain = Gen.GenAmount.shAmount; |
EG2Sustain = Gen.GenAmount.shAmount; |
418 |
|
CheckRange("sustainModEnv", 0, 1000, EG2Sustain); |
419 |
break; |
break; |
420 |
case RELEASEMODENV: |
case RELEASE_MOD_ENV: |
421 |
EG2Release = Gen.GenAmount.shAmount; |
EG2Release = Gen.GenAmount.shAmount; |
422 |
|
CheckRange("releaseModEnv", -12000, 8000, EG2Release); |
423 |
break; |
break; |
424 |
case KEYNUM_TO_MOD_ENV_HOLD: |
case KEYNUM_TO_MOD_ENV_HOLD: |
425 |
break; |
break; |
427 |
break; |
break; |
428 |
case DELAY_VOL_ENV: |
case DELAY_VOL_ENV: |
429 |
EG1PreAttackDelay = Gen.GenAmount.shAmount; |
EG1PreAttackDelay = Gen.GenAmount.shAmount; |
430 |
|
CheckRange("delayVolEnv", -12000, 5000, EG1PreAttackDelay); |
431 |
break; |
break; |
432 |
case ATTACK_VOL_ENV: |
case ATTACK_VOL_ENV: |
433 |
EG1Attack = Gen.GenAmount.shAmount; |
EG1Attack = Gen.GenAmount.shAmount; |
434 |
|
CheckRange("attackVolEnv", -12000, 8000, EG1Attack); |
435 |
break; |
break; |
436 |
case HOLD_VOL_ENV: |
case HOLD_VOL_ENV: |
437 |
EG1Hold = Gen.GenAmount.shAmount; |
EG1Hold = Gen.GenAmount.shAmount; |
438 |
|
CheckRange("holdVolEnv", -12000, 5000, EG1Hold); |
439 |
break; |
break; |
440 |
case DECAY_VOL_ENV: |
case DECAY_VOL_ENV: |
441 |
EG1Decay = Gen.GenAmount.shAmount; |
EG1Decay = Gen.GenAmount.shAmount; |
442 |
|
CheckRange("decayVolEnv", -12000, 8000, EG1Decay); |
443 |
break; |
break; |
444 |
case SUSTAIN_VOL_ENV: |
case SUSTAIN_VOL_ENV: |
445 |
EG1Sustain = Gen.GenAmount.shAmount; |
EG1Sustain = Gen.GenAmount.shAmount; |
446 |
|
CheckRange("sustainVolEnv", 0, 1440, EG1Sustain); |
447 |
break; |
break; |
448 |
case RELEASE_VOL_ENV: |
case RELEASE_VOL_ENV: |
449 |
EG1Release = Gen.GenAmount.shAmount; |
EG1Release = Gen.GenAmount.shAmount; |
450 |
|
CheckRange("releaseVolEnv", -12000, 8000, EG1Release); |
451 |
break; |
break; |
452 |
case KEYNUM_TO_VOL_ENV_HOLD: |
case KEYNUM_TO_VOL_ENV_HOLD: |
453 |
break; |
break; |
463 |
} |
} |
464 |
case KEY_RANGE: |
case KEY_RANGE: |
465 |
loKey = Gen.GenAmount.ranges.byLo; |
loKey = Gen.GenAmount.ranges.byLo; |
466 |
|
CheckRange("loKey", 0, 127, loKey); |
467 |
hiKey = Gen.GenAmount.ranges.byHi; |
hiKey = Gen.GenAmount.ranges.byHi; |
468 |
|
CheckRange("hiKey", 0, 127, hiKey); |
469 |
break; |
break; |
470 |
case VEL_RANGE: |
case VEL_RANGE: |
471 |
minVel = Gen.GenAmount.ranges.byLo; |
minVel = Gen.GenAmount.ranges.byLo; |
472 |
|
CheckRange("minVel", 0, 127, minVel); |
473 |
maxVel = Gen.GenAmount.ranges.byHi; |
maxVel = Gen.GenAmount.ranges.byHi; |
474 |
|
CheckRange("maxVel", 0, 127, maxVel); |
475 |
break; |
break; |
476 |
case STARTLOOP_ADDRS_COARSE_OFFSET: |
case STARTLOOP_ADDRS_COARSE_OFFSET: |
477 |
startloopAddrsCoarseOffset = Gen.GenAmount.wAmount; |
startloopAddrsCoarseOffset = Gen.GenAmount.wAmount; |
489 |
break; |
break; |
490 |
case COARSE_TUNE: |
case COARSE_TUNE: |
491 |
coarseTune = Gen.GenAmount.shAmount; |
coarseTune = Gen.GenAmount.shAmount; |
492 |
if (coarseTune < -120) coarseTune = -120; |
CheckRange("coarseTune", -120, 120, coarseTune); |
|
if (coarseTune > 120) coarseTune = 120; |
|
493 |
break; |
break; |
494 |
case FINE_TUNE: |
case FINE_TUNE: |
495 |
fineTune = Gen.GenAmount.shAmount; |
fineTune = Gen.GenAmount.shAmount; |
496 |
|
CheckRange("fineTune", -99, 99, fineTune); |
497 |
break; |
break; |
498 |
case SAMPLE_ID: { |
case SAMPLE_ID: { |
499 |
uint16_t sid = Gen.GenAmount.wAmount; |
uint16_t sid = Gen.GenAmount.wAmount; |
526 |
break; |
break; |
527 |
case OVERRIDING_ROOT_KEY: |
case OVERRIDING_ROOT_KEY: |
528 |
overridingRootKey = Gen.GenAmount.shAmount; |
overridingRootKey = Gen.GenAmount.shAmount; |
529 |
|
CheckRange("overridingRootKey", -1, 127, overridingRootKey); |
530 |
break; |
break; |
531 |
} |
} |
532 |
} |
} |
579 |
} |
} |
580 |
|
|
581 |
double Region::GetEG1PreAttackDelay(Region* pPresetRegion) { |
double Region::GetEG1PreAttackDelay(Region* pPresetRegion) { |
582 |
if (pPresetRegion == NULL || pPresetRegion->EG1PreAttackDelay == NONE) return ToSeconds(EG1PreAttackDelay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1PreAttackDelay == NONE) ? |
583 |
return ToSeconds(pPresetRegion->EG1PreAttackDelay + EG1PreAttackDelay); |
EG1PreAttackDelay : pPresetRegion->EG1PreAttackDelay + EG1PreAttackDelay; |
584 |
|
return ToSeconds(CheckRange("GetEG1PreAttackDelay()", -12000, 5000, val)); |
585 |
} |
} |
586 |
|
|
587 |
double Region::GetEG1Attack(Region* pPresetRegion) { |
double Region::GetEG1Attack(Region* pPresetRegion) { |
588 |
if (pPresetRegion == NULL || pPresetRegion->EG1Attack == NONE) return ToSeconds(EG1Attack); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Attack == NONE) ? |
589 |
return ToSeconds(pPresetRegion->EG1Attack + EG1Attack); |
EG1Attack : pPresetRegion->EG1Attack + EG1Attack; |
590 |
|
return ToSeconds(CheckRange("GetEG1Attack()", -12000, 8000, val)); |
591 |
} |
} |
592 |
|
|
593 |
double Region::GetEG1Hold(Region* pPresetRegion) { |
double Region::GetEG1Hold(Region* pPresetRegion) { |
594 |
if (pPresetRegion == NULL || pPresetRegion->EG1Hold == NONE) return ToSeconds(EG1Hold); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Hold == NONE) ? |
595 |
return ToSeconds(pPresetRegion->EG1Hold + EG1Hold); |
EG1Hold : pPresetRegion->EG1Hold + EG1Hold; |
596 |
|
return ToSeconds(CheckRange("GetEG1Hold()", -12000, 5000, val)); |
597 |
} |
} |
598 |
|
|
599 |
double Region::GetEG1Decay(Region* pPresetRegion) { |
double Region::GetEG1Decay(Region* pPresetRegion) { |
600 |
if (pPresetRegion == NULL || pPresetRegion->EG1Decay == NONE) return ToSeconds(EG1Decay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Decay == NONE) ? |
601 |
return ToSeconds(pPresetRegion->EG1Decay + EG1Decay); |
EG1Decay : pPresetRegion->EG1Decay + EG1Decay; |
602 |
|
return ToSeconds(CheckRange("GetEG1Decay()", -12000, 8000, val)); |
603 |
} |
} |
604 |
|
|
605 |
double Region::GetEG1Sustain(Region* pPresetRegion) { |
int Region::GetEG1Sustain(Region* pPresetRegion) { |
606 |
if (pPresetRegion == NULL || pPresetRegion->EG1Sustain == NONE) return ToPermilles(EG1Sustain); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Sustain == NONE) ? |
607 |
return ToPermilles(pPresetRegion->EG1Sustain + EG1Sustain); |
EG1Sustain : pPresetRegion->EG1Sustain + EG1Sustain; |
608 |
|
return CheckRange("GetEG1Sustain()", 0, 1440, val); |
609 |
} |
} |
610 |
|
|
611 |
double Region::GetEG1Release(Region* pPresetRegion) { |
double Region::GetEG1Release(Region* pPresetRegion) { |
612 |
if (pPresetRegion == NULL || pPresetRegion->EG1Release == NONE) return ToSeconds(EG1Release); |
int val = (pPresetRegion == NULL || pPresetRegion->EG1Release == NONE) ? |
613 |
return ToSeconds(pPresetRegion->EG1Release + EG1Release); |
EG1Release : pPresetRegion->EG1Release + EG1Release; |
614 |
|
return ToSeconds(CheckRange("GetEG1Release()", -12000, 8000, val)); |
615 |
} |
} |
616 |
|
|
617 |
double Region::GetEG2PreAttackDelay(Region* pPresetRegion) { |
double Region::GetEG2PreAttackDelay(Region* pPresetRegion) { |
618 |
if (pPresetRegion == NULL || pPresetRegion->EG2PreAttackDelay == NONE) return ToSeconds(EG2PreAttackDelay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2PreAttackDelay == NONE) ? |
619 |
return ToSeconds(pPresetRegion->EG2PreAttackDelay + EG2PreAttackDelay); |
EG2PreAttackDelay : pPresetRegion->EG2PreAttackDelay + EG2PreAttackDelay; |
620 |
|
return ToSeconds(CheckRange("GetEG2PreAttackDelay()", -12000, 5000, val)); |
621 |
} |
} |
622 |
|
|
623 |
double Region::GetEG2Attack(Region* pPresetRegion) { |
double Region::GetEG2Attack(Region* pPresetRegion) { |
624 |
if (pPresetRegion == NULL || pPresetRegion->EG2Attack == NONE) return ToSeconds(EG2Attack); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Attack == NONE) ? |
625 |
return ToSeconds(pPresetRegion->EG2Attack + EG2Attack); |
EG2Attack : pPresetRegion->EG2Attack + EG2Attack; |
626 |
|
return ToSeconds(CheckRange("GetEG2Attack()", -12000, 8000, val)); |
627 |
} |
} |
628 |
|
|
629 |
double Region::GetEG2Hold(Region* pPresetRegion) { |
double Region::GetEG2Hold(Region* pPresetRegion) { |
630 |
if (pPresetRegion == NULL || pPresetRegion->EG2Hold == NONE) return ToSeconds(EG2Hold); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Hold == NONE) ? |
631 |
return ToSeconds(pPresetRegion->EG2Hold + EG2Hold); |
EG2Hold : pPresetRegion->EG2Hold + EG2Hold; |
632 |
|
return ToSeconds(CheckRange("GetEG2Hold()", -12000, 5000, val)); |
633 |
} |
} |
634 |
|
|
635 |
double Region::GetEG2Decay(Region* pPresetRegion) { |
double Region::GetEG2Decay(Region* pPresetRegion) { |
636 |
if (pPresetRegion == NULL || pPresetRegion->EG2Decay == NONE) return ToSeconds(EG2Decay); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Decay == NONE) ? |
637 |
return ToSeconds(pPresetRegion->EG2Decay + EG2Decay); |
EG2Decay : pPresetRegion->EG2Decay + EG2Decay; |
638 |
|
return ToSeconds(CheckRange("GetEG2Decay()", -12000, 8000, val)); |
639 |
} |
} |
640 |
|
|
641 |
double Region::GetEG2Sustain(Region* pPresetRegion) { |
int Region::GetEG2Sustain(Region* pPresetRegion) { |
642 |
if (pPresetRegion == NULL || pPresetRegion->EG2Sustain == NONE) { |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Sustain == NONE) ? |
643 |
return EG2Sustain == NONE ? NONE : 1000 - EG2Sustain; |
EG2Sustain : pPresetRegion->EG2Sustain + EG2Sustain; |
644 |
} |
return CheckRange("GetEG2Sustain()", 0, 1000, val); |
|
return 1000 - (pPresetRegion->EG2Sustain + EG2Sustain); |
|
645 |
} |
} |
646 |
|
|
647 |
double Region::GetEG2Release(Region* pPresetRegion) { |
double Region::GetEG2Release(Region* pPresetRegion) { |
648 |
if (pPresetRegion == NULL || pPresetRegion->EG2Release == NONE) return ToSeconds(EG2Release); |
int val = (pPresetRegion == NULL || pPresetRegion->EG2Release == NONE) ? |
649 |
return ToSeconds(pPresetRegion->EG2Release + EG2Release); |
EG2Release : pPresetRegion->EG2Release + EG2Release; |
650 |
|
return ToSeconds(CheckRange("GetEG2Release()", -12000, 8000, val)); |
651 |
} |
} |
652 |
|
|
653 |
int Region::GetModEnvToPitch(Region* pPresetRegion) { |
int Region::GetModEnvToPitch(Region* pPresetRegion) { |
654 |
return modEnvToPitch + (pPresetRegion ? pPresetRegion->modEnvToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modEnvToPitch == NONE) ? |
655 |
|
modEnvToPitch : pPresetRegion->modEnvToPitch + modEnvToPitch; |
656 |
|
return CheckRange("GetModEnvToPitch()", -12000, 12000, val); |
657 |
} |
} |
658 |
|
|
659 |
int Region::GetModLfoToPitch(Region* pPresetRegion) { |
int Region::GetModLfoToPitch(Region* pPresetRegion) { |
660 |
return modLfoToPitch + (pPresetRegion ? pPresetRegion->modLfoToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToPitch == NONE) ? |
661 |
|
modLfoToPitch : pPresetRegion->modLfoToPitch + modLfoToPitch; |
662 |
|
return CheckRange("GetModLfoToPitch()", -12000, 12000, val); |
663 |
} |
} |
664 |
|
|
665 |
int Region::GetModEnvToFilterFc(Region* pPresetRegion) { |
int Region::GetModEnvToFilterFc(Region* pPresetRegion) { |
666 |
return modEnvToFilterFc + (pPresetRegion ? pPresetRegion->modEnvToFilterFc : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modEnvToFilterFc == NONE) ? |
667 |
|
modEnvToFilterFc : pPresetRegion->modEnvToFilterFc + modEnvToFilterFc; |
668 |
|
return CheckRange("GetModEnvToFilterFc()", -12000, +12000, val); |
669 |
} |
} |
670 |
|
|
671 |
int Region::GetModLfoToFilterFc(Region* pPresetRegion) { |
int Region::GetModLfoToFilterFc(Region* pPresetRegion) { |
672 |
return modLfoToFilterFc + (pPresetRegion ? pPresetRegion->modLfoToFilterFc : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToFilterFc == NONE) ? |
673 |
|
modLfoToFilterFc : pPresetRegion->modLfoToFilterFc + modLfoToFilterFc; |
674 |
|
return CheckRange("GetModLfoToFilterFc()", -12000, +12000, val); |
675 |
} |
} |
676 |
|
|
677 |
double Region::GetModLfoToVolume(Region* pPresetRegion) { |
double Region::GetModLfoToVolume(Region* pPresetRegion) { |
678 |
return ToPermilles(modLfoToVolume + (pPresetRegion ? pPresetRegion->modLfoToVolume : 0)); |
int val = (pPresetRegion == NULL || pPresetRegion->modLfoToVolume == NONE) ? |
679 |
|
modLfoToVolume : pPresetRegion->modLfoToVolume + modLfoToVolume; |
680 |
|
return CheckRange("GetModLfoToVolume()", -960, 960, val); |
681 |
} |
} |
682 |
|
|
683 |
double Region::GetFreqModLfo(Region* pPresetRegion) { |
double Region::GetFreqModLfo(Region* pPresetRegion) { |
684 |
if (pPresetRegion == NULL || pPresetRegion->freqModLfo == NONE) return ToHz(freqModLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->freqModLfo == NONE) ? |
685 |
return ToHz(pPresetRegion->freqModLfo + freqModLfo); |
freqModLfo : pPresetRegion->freqModLfo + freqModLfo; |
686 |
|
return ToHz(CheckRange("GetFreqModLfo()", -16000, 4500, val)); |
687 |
} |
} |
688 |
|
|
689 |
double Region::GetDelayModLfo(Region* pPresetRegion) { |
double Region::GetDelayModLfo(Region* pPresetRegion) { |
690 |
if (pPresetRegion == NULL || pPresetRegion->delayModLfo == NONE) return ToSeconds(delayModLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->delayModLfo == NONE) ? |
691 |
return ToSeconds(pPresetRegion->delayModLfo + delayModLfo); |
delayModLfo : pPresetRegion->delayModLfo + delayModLfo; |
692 |
|
return ToSeconds(CheckRange("GetDelayModLfo()", -12000, 5000, val)); |
693 |
} |
} |
694 |
|
|
695 |
int Region::GetVibLfoToPitch(Region* pPresetRegion) { |
int Region::GetVibLfoToPitch(Region* pPresetRegion) { |
696 |
return vibLfoToPitch + (pPresetRegion ? pPresetRegion->vibLfoToPitch : 0); |
int val = (pPresetRegion == NULL || pPresetRegion->vibLfoToPitch == NONE) ? |
697 |
|
vibLfoToPitch : pPresetRegion->vibLfoToPitch + vibLfoToPitch; |
698 |
|
return CheckRange("GetVibLfoToPitch()", -12000, 12000, val); |
699 |
} |
} |
700 |
|
|
701 |
double Region::GetFreqVibLfo(Region* pPresetRegion) { |
double Region::GetFreqVibLfo(Region* pPresetRegion) { |
702 |
if (pPresetRegion == NULL || pPresetRegion->freqVibLfo == NONE) return ToHz(freqVibLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->freqVibLfo == NONE) ? |
703 |
return ToHz(pPresetRegion->freqVibLfo + freqVibLfo); |
freqVibLfo : pPresetRegion->freqVibLfo + freqVibLfo; |
704 |
|
return ToHz(CheckRange("GetFreqVibLfo()", -16000, 4500, val)); |
705 |
} |
} |
706 |
|
|
707 |
double Region::GetDelayVibLfo(Region* pPresetRegion) { |
double Region::GetDelayVibLfo(Region* pPresetRegion) { |
708 |
if (pPresetRegion == NULL || pPresetRegion->delayVibLfo == NONE) return ToSeconds(delayVibLfo); |
int val = (pPresetRegion == NULL || pPresetRegion->delayVibLfo == NONE) ? |
709 |
return ToSeconds(pPresetRegion->delayVibLfo + delayVibLfo); |
delayVibLfo : pPresetRegion->delayVibLfo + delayVibLfo; |
710 |
|
return ToSeconds(CheckRange("GetDelayVibLfo()", -12000, 5000, val)); |
711 |
|
} |
712 |
|
|
713 |
|
int Region::GetInitialFilterFc(Region* pPresetRegion) { |
714 |
|
if (pPresetRegion == NULL || pPresetRegion->initialFilterFc == NONE) return initialFilterFc; |
715 |
|
int val = pPresetRegion->initialFilterFc + initialFilterFc; |
716 |
|
return CheckRange("GetInitialFilterFc()", 1500, 13500, val); |
717 |
|
} |
718 |
|
|
719 |
|
int Region::GetInitialFilterQ(Region* pPresetRegion) { |
720 |
|
int val = (pPresetRegion == NULL || pPresetRegion->initialFilterQ == NONE) ? |
721 |
|
initialFilterQ : pPresetRegion->initialFilterQ + initialFilterQ; |
722 |
|
return CheckRange("GetInitialFilterQ()", 0, 960, val); |
723 |
} |
} |
724 |
|
|
725 |
InstrumentBase::InstrumentBase(sf2::File* pFile) { |
InstrumentBase::InstrumentBase(sf2::File* pFile) { |
729 |
|
|
730 |
InstrumentBase::~InstrumentBase() { |
InstrumentBase::~InstrumentBase() { |
731 |
if (pGlobalRegion) delete pGlobalRegion; |
if (pGlobalRegion) delete pGlobalRegion; |
732 |
for (int i = regions.size() - 1; i >= 0; i--) { |
for (ssize_t i = regions.size() - 1; i >= 0; i--) { |
733 |
if (regions[i]) delete (regions[i]); |
if (regions[i]) delete (regions[i]); |
734 |
} |
} |
735 |
} |
} |
736 |
|
|
737 |
int InstrumentBase::GetRegionCount() { |
int InstrumentBase::GetRegionCount() { |
738 |
return regions.size(); |
return (int) regions.size(); |
739 |
} |
} |
740 |
|
|
741 |
Region* InstrumentBase::GetRegion(int idx) { |
Region* InstrumentBase::GetRegion(int idx) { |
746 |
return regions[idx]; |
return regions[idx]; |
747 |
} |
} |
748 |
|
|
749 |
std::vector<Region*> InstrumentBase::GetRegionsOnKey(int key, uint8_t vel) { |
Query::Query(InstrumentBase& instrument) : instrument(instrument) { |
750 |
std::vector<Region*> v; |
i = 0; |
751 |
for (int i = 0; i < GetRegionCount(); i++) { |
} |
752 |
Region* r = GetRegion(i); |
|
753 |
if ( |
Region* Query::next() { |
754 |
((r->loKey == NONE && r->hiKey == NONE) || (key >= r->loKey && key <= r->hiKey)) && |
while (i < instrument.GetRegionCount()) { |
755 |
((r->minVel == NONE && r->maxVel == NONE) || (vel >= r->minVel && vel <= r->maxVel)) |
Region* r = instrument.GetRegion(i++); |
756 |
) { |
if (((r->loKey == NONE && r->hiKey == NONE) || (key >= r->loKey && key <= r->hiKey)) && |
757 |
v.push_back(r); |
((r->minVel == NONE && r->maxVel == NONE) || (vel >= r->minVel && vel <= r->maxVel))) { |
758 |
|
return r; |
759 |
} |
} |
760 |
} |
} |
761 |
|
return 0; |
|
return v; |
|
762 |
} |
} |
763 |
|
|
764 |
Instrument::Instrument(sf2::File* pFile, RIFF::Chunk* ck) : InstrumentBase(pFile) { |
Instrument::Instrument(sf2::File* pFile, RIFF::Chunk* ck) : InstrumentBase(pFile) { |
816 |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
817 |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
818 |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
819 |
|
r->initialFilterFc = pGlobalRegion->initialFilterFc; |
820 |
|
r->initialFilterQ = pGlobalRegion->initialFilterQ; |
821 |
|
|
822 |
r->HasLoop = pGlobalRegion->HasLoop; |
r->HasLoop = pGlobalRegion->HasLoop; |
823 |
r->LoopStart = pGlobalRegion->LoopStart; |
r->LoopStart = pGlobalRegion->LoopStart; |
901 |
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; |
902 |
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; |
903 |
r->freqModLfo = r->delayModLfo = r->freqVibLfo = r->delayVibLfo = NONE; |
r->freqModLfo = r->delayModLfo = r->freqVibLfo = r->delayVibLfo = NONE; |
904 |
|
r->initialFilterFc = r->initialFilterQ = NONE; |
905 |
|
|
906 |
if (pGlobalRegion != NULL) { |
if (pGlobalRegion != NULL) { |
907 |
r->pan = pGlobalRegion->pan; |
r->pan = pGlobalRegion->pan; |
932 |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
r->vibLfoToPitch = pGlobalRegion->vibLfoToPitch; |
933 |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
r->freqVibLfo = pGlobalRegion->freqVibLfo; |
934 |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
r->delayVibLfo = pGlobalRegion->delayVibLfo; |
935 |
|
r->initialFilterFc = pGlobalRegion->initialFilterFc; |
936 |
|
r->initialFilterQ = pGlobalRegion->initialFilterQ; |
937 |
} |
} |
938 |
|
|
939 |
return r; |
return r; |
1013 |
throw Exception("Broken SF2 file (broken phdr)"); |
throw Exception("Broken SF2 file (broken phdr)"); |
1014 |
} |
} |
1015 |
|
|
1016 |
int count = ck->GetSize() / 38; |
int count = (int) ck->GetSize() / 38; |
1017 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1018 |
Presets.push_back(new Preset(this, ck)); |
Presets.push_back(new Preset(this, ck)); |
1019 |
} |
} |
1023 |
throw Exception("Broken SF2 file (broken pbag)"); |
throw Exception("Broken SF2 file (broken pbag)"); |
1024 |
} |
} |
1025 |
|
|
1026 |
count = ck->GetSize() / 4; |
count = int(ck->GetSize() / 4); |
1027 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1028 |
PresetBag pb; |
PresetBag pb; |
1029 |
pb.GenNdx = ck->ReadInt16(); |
pb.GenNdx = ck->ReadInt16(); |
1037 |
throw Exception("Broken SF2 file (broken pmod)"); |
throw Exception("Broken SF2 file (broken pmod)"); |
1038 |
} |
} |
1039 |
|
|
1040 |
count = ck->GetSize() / 10; |
count = int(ck->GetSize() / 10); |
1041 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1042 |
ModList ml; |
ModList ml; |
1043 |
ml.ModSrcOper = ck->ReadInt16(); |
ml.ModSrcOper = ck->ReadInt16(); |
1054 |
throw Exception("Broken SF2 file (broken pgen)"); |
throw Exception("Broken SF2 file (broken pgen)"); |
1055 |
} |
} |
1056 |
|
|
1057 |
count = ck->GetSize() / 4; |
count = int(ck->GetSize() / 4); |
1058 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1059 |
GenList gl; |
GenList gl; |
1060 |
gl.GenOper = ck->ReadInt16(); |
gl.GenOper = ck->ReadInt16(); |
1067 |
if (ck->GetSize() < (22 * 2) || (ck->GetSize() % 22)) { |
if (ck->GetSize() < (22 * 2) || (ck->GetSize() % 22)) { |
1068 |
throw Exception("Broken SF2 file (broken inst)"); |
throw Exception("Broken SF2 file (broken inst)"); |
1069 |
} |
} |
1070 |
count = ck->GetSize() / 22; |
count = int(ck->GetSize() / 22); |
1071 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1072 |
Instruments.push_back(new Instrument(this, ck)); |
Instruments.push_back(new Instrument(this, ck)); |
1073 |
} |
} |
1077 |
throw Exception("Broken SF2 file (broken ibag)"); |
throw Exception("Broken SF2 file (broken ibag)"); |
1078 |
} |
} |
1079 |
|
|
1080 |
count = ck->GetSize() / 4; |
count = int(ck->GetSize() / 4); |
1081 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1082 |
InstBag ib; |
InstBag ib; |
1083 |
ib.InstGenNdx = ck->ReadInt16(); |
ib.InstGenNdx = ck->ReadInt16(); |
1091 |
throw Exception("Broken SF2 file (broken imod)"); |
throw Exception("Broken SF2 file (broken imod)"); |
1092 |
} |
} |
1093 |
|
|
1094 |
count = ck->GetSize() / 10; |
count = int(ck->GetSize() / 10); |
1095 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1096 |
ModList ml; |
ModList ml; |
1097 |
ml.ModSrcOper = ck->ReadInt16(); |
ml.ModSrcOper = ck->ReadInt16(); |
1108 |
throw Exception("Broken SF2 file (broken igen)"); |
throw Exception("Broken SF2 file (broken igen)"); |
1109 |
} |
} |
1110 |
|
|
1111 |
count = ck->GetSize() / 4; |
count = int(ck->GetSize() / 4); |
1112 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1113 |
GenList gl; |
GenList gl; |
1114 |
gl.GenOper = ck->ReadInt16(); |
gl.GenOper = ck->ReadInt16(); |
1121 |
if ((ck->GetSize() % 46)) { |
if ((ck->GetSize() % 46)) { |
1122 |
throw Exception("Broken SF2 file (broken shdr)"); |
throw Exception("Broken SF2 file (broken shdr)"); |
1123 |
} |
} |
1124 |
count = ck->GetSize() / 46; |
count = int(ck->GetSize() / 46); |
1125 |
for (int i = 0; i < count; i++) { |
for (int i = 0; i < count; i++) { |
1126 |
Samples.push_back(new Sample(ck, pCkSmpl, pCkSm24)); |
Samples.push_back(new Sample(this, ck, pCkSmpl, pCkSm24)); |
1127 |
} |
} |
1128 |
|
|
1129 |
// Loading instrument regions |
// Loading instrument regions |
1153 |
|
|
1154 |
File::~File() { |
File::~File() { |
1155 |
delete pInfo; |
delete pInfo; |
1156 |
for (int i = Presets.size() - 1; i >= 0; i--) { |
for (ssize_t i = Presets.size() - 1; i >= 0; i--) { |
1157 |
if (Presets[i]) delete (Presets[i]); |
if (Presets[i]) delete (Presets[i]); |
1158 |
} |
} |
1159 |
for (int i = Instruments.size() - 1; i >= 0; i--) { |
for (ssize_t i = Instruments.size() - 1; i >= 0; i--) { |
1160 |
if (Instruments[i]) delete (Instruments[i]); |
if (Instruments[i]) delete (Instruments[i]); |
1161 |
} |
} |
1162 |
for (int i = Samples.size() - 1; i >= 0; i--) { |
for (ssize_t i = Samples.size() - 1; i >= 0; i--) { |
1163 |
if (Samples[i]) delete (Samples[i]); |
if (Samples[i]) delete (Samples[i]); |
1164 |
} |
} |
1165 |
} |
} |
1166 |
|
|
1167 |
int File::GetPresetCount() { |
int File::GetPresetCount() { |
1168 |
return Presets.size() - 1; // exclude terminal preset (EOP) |
return (int) Presets.size() - 1; // exclude terminal preset (EOP) |
1169 |
} |
} |
1170 |
|
|
1171 |
Preset* File::GetPreset(int idx) { |
Preset* File::GetPreset(int idx) { |
1177 |
} |
} |
1178 |
|
|
1179 |
int File::GetInstrumentCount() { |
int File::GetInstrumentCount() { |
1180 |
return Instruments.size() - 1; // exclude terminal instrument (EOI) |
return (int) Instruments.size() - 1; // exclude terminal instrument (EOI) |
1181 |
} |
} |
1182 |
|
|
1183 |
Instrument* File::GetInstrument(int idx) { |
Instrument* File::GetInstrument(int idx) { |
1189 |
} |
} |
1190 |
|
|
1191 |
void File::DeleteInstrument(Instrument* pInstrument) { |
void File::DeleteInstrument(Instrument* pInstrument) { |
1192 |
|
if (!pInstrument) return; |
1193 |
|
|
1194 |
for (int i = 0; i < GetPresetCount(); i++) { |
for (int i = 0; i < GetPresetCount(); i++) { |
1195 |
Preset* p = GetPreset(i); |
Preset* p = GetPreset(i); |
1196 |
if (p == NULL) continue; |
if (p == NULL) continue; |
1205 |
if (GetInstrument(i) == pInstrument) { |
if (GetInstrument(i) == pInstrument) { |
1206 |
Instruments[i] = NULL; |
Instruments[i] = NULL; |
1207 |
delete pInstrument; |
delete pInstrument; |
1208 |
|
// an instrument instance only exists once in the list, so stop |
1209 |
|
// here (which also silences a clang sanatizer warning about |
1210 |
|
// potential multiple memory releases of pInstrument above) |
1211 |
|
return; |
1212 |
} |
} |
1213 |
} |
} |
1214 |
} |
} |
1215 |
|
|
1216 |
int File::GetSampleCount() { |
int File::GetSampleCount() { |
1217 |
return Samples.size() - 1; // exclude terminal sample (EOS) |
return (int) Samples.size() - 1; // exclude terminal sample (EOS) |
1218 |
} |
} |
1219 |
|
|
1220 |
Sample* File::GetSample(int idx) { |
Sample* File::GetSample(int idx) { |
1258 |
return false; |
return false; |
1259 |
} |
} |
1260 |
|
|
1261 |
|
RIFF::File* File::GetRiffFile() { |
1262 |
|
return pRIFF; |
1263 |
|
} |
1264 |
|
|
1265 |
/** |
/** |
1266 |
* Loads the whole sample wave into RAM. Use |
* Loads the whole sample wave into RAM. Use |
1267 |
* ReleaseSampleData() to free the memory if you don't need the cached |
* ReleaseSampleData() to free the memory if you don't need the cached |
1415 |
return (pCkSmpl->GetPos() - (Start * 2)) / 2; |
return (pCkSmpl->GetPos() - (Start * 2)) / 2; |
1416 |
} |
} |
1417 |
|
|
1418 |
/** |
// Actual implementation of Sample::Read*() code. Wrapped into a template for a) runtime effeciency and b) code redundancy reasons. |
1419 |
* Reads \a SampleCount number of sample points from the current |
template<bool CLEAR> |
1420 |
* 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) { |
|
1421 |
// TODO: startAddrsCoarseOffset, endAddrsCoarseOffset |
// TODO: startAddrsCoarseOffset, endAddrsCoarseOffset |
1422 |
if (SampleCount == 0) return 0; |
if (SampleCount == 0) return 0; |
1423 |
long pos = GetPos(); |
long pos = pSample->GetPos(); |
1424 |
if (pos + SampleCount > GetTotalFrameCount()) SampleCount = GetTotalFrameCount() - pos; |
if (pos + SampleCount > pSample->GetTotalFrameCount()) |
1425 |
|
SampleCount = pSample->GetTotalFrameCount() - pos; |
1426 |
|
if (!CLEAR) { |
1427 |
|
if (tempBuffer->Size < SampleCount * pSample->GetFrameSize()) { |
1428 |
|
std::cerr << "sf2::Sample error: tempBuffer too small. This is a BUG!" << std::endl; |
1429 |
|
return 0; |
1430 |
|
} |
1431 |
|
} |
1432 |
|
|
1433 |
if (GetFrameSize() / GetChannelCount() == 3 /* 24 bit */) { |
if (pSample->GetFrameSize() / pSample->GetChannelCount() == 3 /* 24 bit */) { |
1434 |
uint8_t* pBuf = (uint8_t*)pBuffer; |
uint8_t* const pTmpBuf = (uint8_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart); |
1435 |
if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) { |
uint8_t* const pBuf = (uint8_t*)pBuffer; |
1436 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) { |
1437 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1438 |
for (int i = SampleCount - 1; i >= 0; i--) { |
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1439 |
pBuf[i*3] = pBuf[(SampleCount * 2) + i]; |
for (long i = SampleCount - 1; i >= 0; i--) { |
1440 |
pBuf[i*3 + 2] = pBuf[i*2 + 1]; |
pBuf[i*3] = pTmpBuf[(SampleCount * 2) + i]; |
1441 |
pBuf[i*3 + 1] = pBuf[i*2]; |
pBuf[i*3 + 2] = pTmpBuf[i*2 + 1]; |
1442 |
|
pBuf[i*3 + 1] = pTmpBuf[i*2]; |
1443 |
} |
} |
1444 |
} else if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) { |
} else if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) { |
1445 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1446 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1447 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (long i = SampleCount - 1; i >= 0; i--) { |
1448 |
pBuf[i*6] = pBuf[(SampleCount * 2) + i]; |
pBuf[i*6] = pTmpBuf[(SampleCount * 2) + i]; |
1449 |
pBuf[i*6 + 2] = pBuf[i*2 + 1]; |
pBuf[i*6 + 2] = pTmpBuf[i*2 + 1]; |
1450 |
pBuf[i*6 + 1] = pBuf[i*2]; |
pBuf[i*6 + 1] = pTmpBuf[i*2]; |
1451 |
pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0; |
if (CLEAR) |
1452 |
|
pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0; |
1453 |
} |
} |
1454 |
} else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) { |
} else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) { |
1455 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1456 |
pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1); |
pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1); |
1457 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (long i = SampleCount - 1; i >= 0; i--) { |
1458 |
pBuf[i*6 + 3] = pBuf[(SampleCount * 2) + i]; |
pBuf[i*6 + 3] = pTmpBuf[(SampleCount * 2) + i]; |
1459 |
pBuf[i*6 + 5] = pBuf[i*2 + 1]; |
pBuf[i*6 + 5] = pTmpBuf[i*2 + 1]; |
1460 |
pBuf[i*6 + 4] = pBuf[i*2]; |
pBuf[i*6 + 4] = pTmpBuf[i*2]; |
1461 |
pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0; |
if (CLEAR) |
1462 |
|
pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0; |
1463 |
} |
} |
1464 |
} |
} |
1465 |
} else { |
} else { |
1466 |
if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) { |
if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) { |
1467 |
return pCkSmpl->Read(pBuffer, SampleCount, 2); |
return pSample->pCkSmpl->Read(pBuffer, SampleCount, 2); |
1468 |
} |
} |
1469 |
|
|
1470 |
int16_t* pBuf = (int16_t*)pBuffer; |
int16_t* const pTmpBuf = (int16_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart); |
1471 |
if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) { |
int16_t* const pBuf = (int16_t*) pBuffer; |
1472 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) { |
1473 |
for (int i = SampleCount - 1; i >= 0; i--) { |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1474 |
pBuf[i*2] = pBuf[i]; |
for (long i = SampleCount - 1; i >= 0; i--) { |
1475 |
pBuf[i*2 + 1] = 0; |
pBuf[i*2] = pTmpBuf[i]; |
1476 |
|
if (CLEAR) |
1477 |
|
pBuf[i*2 + 1] = 0; |
1478 |
} |
} |
1479 |
} else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) { |
} else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) { |
1480 |
pCkSmpl->Read(pBuf, SampleCount, 2); |
pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2); |
1481 |
for (int i = SampleCount - 1; i >= 0; i--) { |
for (long i = SampleCount - 1; i >= 0; i--) { |
1482 |
pBuf[i*2] = 0; |
if (CLEAR) |
1483 |
pBuf[i*2 + 1] = pBuf[i]; |
pBuf[i*2] = 0; |
1484 |
|
pBuf[i*2 + 1] = pTmpBuf[i]; |
1485 |
} |
} |
1486 |
} |
} |
1487 |
} |
} |
1488 |
|
|
1489 |
if (pCkSmpl->GetPos() > (End * 2)) { |
if (pSample->pCkSmpl->GetPos() > (pSample->End * 2)) { |
1490 |
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; |
1491 |
std::cerr << "Current position: " << GetPos() << std::endl; |
std::cerr << "Current position: " << pSample->GetPos() << std::endl; |
1492 |
std::cerr << "Total number of frames: " << GetTotalFrameCount() << std::endl << std::endl; |
std::cerr << "Total number of frames: " << pSample->GetTotalFrameCount() << std::endl << std::endl; |
1493 |
} |
} |
1494 |
return SampleCount; |
return SampleCount; |
1495 |
} |
} |
1496 |
|
|
1497 |
|
/** |
1498 |
|
* Reads \a SampleCount number of sample points from the current |
1499 |
|
* position into the buffer pointed by \a pBuffer and increments the |
1500 |
|
* position within the sample. Use this method |
1501 |
|
* and <i>SetPos()</i> if you don't want to load the sample into RAM, |
1502 |
|
* thus for disk streaming. |
1503 |
|
* |
1504 |
|
* For 16 bit samples, the data in the buffer will be int16_t |
1505 |
|
* (using native endianness). For 24 bit, the buffer will |
1506 |
|
* contain three bytes per sample, little-endian. |
1507 |
|
* |
1508 |
|
* Stereo Samples: stereo samples are stored as a pair of mono samples with |
1509 |
|
* SoundFont 2. Due to historical reasons, this Read() method expects |
1510 |
|
* @a pBuffer to be a stereo buffer, however only the audio channel covered |
1511 |
|
* by the sample data of this sample will be filled. The other audio channel |
1512 |
|
* of @a pBuffer will be set to zero. This is probably not what you want. |
1513 |
|
* So you might want to use ReadNoClear() instead. |
1514 |
|
* |
1515 |
|
* @param pBuffer destination buffer |
1516 |
|
* @param SampleCount number of sample points to read |
1517 |
|
* @returns number of successfully read sample points |
1518 |
|
* @see SetPos(), ReadNoClear() |
1519 |
|
*/ |
1520 |
|
unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) { |
1521 |
|
return ReadSample<true>(this, pBuffer, SampleCount); |
1522 |
|
} |
1523 |
|
|
1524 |
|
/** |
1525 |
|
* Reads \a SampleCount number of sample points from the current |
1526 |
|
* position into the buffer pointed by \a pBuffer and increments the |
1527 |
|
* position within the sample. Use this method |
1528 |
|
* and <i>SetPos()</i> if you don't want to load the sample into RAM, |
1529 |
|
* thus for disk streaming. |
1530 |
|
* |
1531 |
|
* For 16 bit samples, the data in the buffer will be int16_t |
1532 |
|
* (using native endianness). For 24 bit, the buffer will |
1533 |
|
* contain three bytes per sample, little-endian. |
1534 |
|
* |
1535 |
|
* Stereo Samples: stereo samples are stored as a pair of mono samples with |
1536 |
|
* SoundFont 2. This ReadNoClear() method expects @a pBuffer to be a stereo |
1537 |
|
* buffer, however only the audio channel covered by the sample data of this |
1538 |
|
* sample will be filled. The other audio channel |
1539 |
|
* of @a pBuffer will remain untouched. So you might pass the same |
1540 |
|
* @a pBuffer to the other, linked sample to actually get the interleaved |
1541 |
|
* stereo audio stream. To avoid destroying the other audio channel's data |
1542 |
|
* you must pass an external, tempoary working buffer @a tempBuffer, which |
1543 |
|
* should already be allocated to the size required to decode the requested |
1544 |
|
* length of sample data. That @a tempBuffer is only used by ReadNoClear() |
1545 |
|
* to fulfill its work, it does not contain any useful data after this |
1546 |
|
* method returned. |
1547 |
|
* |
1548 |
|
* @param pBuffer destination buffer |
1549 |
|
* @param SampleCount number of sample points to read |
1550 |
|
* @param tempBuffer temporary work buffer (must be pre-allocated large enough) |
1551 |
|
* @returns number of successfully read sample points |
1552 |
|
* @see SetPos(), Read() |
1553 |
|
*/ |
1554 |
|
unsigned long Sample::ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer) { |
1555 |
|
return ReadSample<false>(this, pBuffer, SampleCount, &tempBuffer); |
1556 |
|
} |
1557 |
|
|
1558 |
|
|
1559 |
// *************** functions *************** |
// *************** functions *************** |
1560 |
// * |
// * |