/[svn]/libgig/trunk/src/SF.cpp
ViewVC logotype

Diff of /libgig/trunk/src/SF.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2044 by persson, Sun Jan 10 12:58:51 2010 UTC revision 3900 by schoenebeck, Wed May 12 17:25:27 2021 UTC
# Line 21  Line 21 
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"
# Line 41  namespace sf2 { Line 39  namespace sf2 {
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    
# Line 150  namespace sf2 { Line 147  namespace sf2 {
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    
# Line 289  namespace sf2 { Line 287  namespace sf2 {
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) {
# Line 320  namespace sf2 { Line 338  namespace sf2 {
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;
# Line 349  namespace sf2 { Line 377  namespace sf2 {
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;
# Line 389  namespace sf2 { Line 427  namespace sf2 {
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;
# Line 419  namespace sf2 { Line 463  namespace sf2 {
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;
# Line 441  namespace sf2 { Line 489  namespace sf2 {
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;
# Line 478  namespace sf2 { Line 526  namespace sf2 {
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      }      }
# Line 530  namespace sf2 { Line 579  namespace sf2 {
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) {
# Line 642  namespace sf2 { Line 729  namespace sf2 {
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) {
# Line 659  namespace sf2 { Line 746  namespace sf2 {
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) {
# Line 729  namespace sf2 { Line 816  namespace sf2 {
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;
# Line 812  namespace sf2 { Line 901  namespace sf2 {
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;
# Line 842  namespace sf2 { Line 932  namespace sf2 {
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;
# Line 921  namespace sf2 { Line 1013  namespace sf2 {
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          }          }
# Line 931  namespace sf2 { Line 1023  namespace sf2 {
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();
# Line 945  namespace sf2 { Line 1037  namespace sf2 {
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();
# Line 962  namespace sf2 { Line 1054  namespace sf2 {
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();
# Line 975  namespace sf2 { Line 1067  namespace sf2 {
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          }          }
# Line 985  namespace sf2 { Line 1077  namespace sf2 {
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();
# Line 999  namespace sf2 { Line 1091  namespace sf2 {
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();
# Line 1016  namespace sf2 { Line 1108  namespace sf2 {
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();
# Line 1029  namespace sf2 { Line 1121  namespace sf2 {
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
# Line 1061  namespace sf2 { Line 1153  namespace sf2 {
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) {
# Line 1085  namespace sf2 { Line 1177  namespace sf2 {
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) {
# Line 1097  namespace sf2 { Line 1189  namespace sf2 {
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;
# Line 1111  namespace sf2 { Line 1205  namespace sf2 {
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) {
# Line 1160  namespace sf2 { Line 1258  namespace sf2 {
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
# Line 1313  namespace sf2 { Line 1415  namespace sf2 {
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  // *  // *

Legend:
Removed from v.2044  
changed lines
  Added in v.3900

  ViewVC Help
Powered by ViewVC