/[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 2016 by iliev, Tue Oct 27 18:34:06 2009 UTC revision 2026 by iliev, Tue Nov 3 19:08:44 2009 UTC
# Line 36  Line 36 
36    
37  namespace sf2 {  namespace sf2 {
38      double ToSeconds(int Timecents) {      double ToSeconds(int Timecents) {
39            if (Timecents == NONE) return NONE;
40          if (Timecents == 0) return 1.0;          if (Timecents == 0) return 1.0;
41          if (Timecents == -32768) return 0.0;          if (Timecents == -32768) return 0.0;
42          return pow(_1200TH_ROOT_OF_2, Timecents);          return pow(_1200TH_ROOT_OF_2, Timecents);
43      }      }
44    
45      double ToPermilles(int Centibels) {      double ToPermilles(int Centibels) {
46            if (Centibels == NONE) return NONE;
47          if (Centibels == 0) return 1000.0;          if (Centibels == 0) return 1000.0;
48          if (Centibels < 0) return 0.0;          if (Centibels < 0) return 0.0;
49          return pow(_200TH_ROOT_OF_10, Centibels);          return pow(_200TH_ROOT_OF_10, Centibels);
50      }      }
51    
52        double ToHz(int cents) {
53            if (cents == NONE) return NONE;
54            if (cents == 0) return 8.176;
55            return pow(_1200TH_ROOT_OF_2, cents) * 8.176;
56        }
57    
58      RIFF::Chunk* GetMandatoryChunk(RIFF::List* list, uint32_t chunkId) {      RIFF::Chunk* GetMandatoryChunk(RIFF::List* list, uint32_t chunkId) {
59          RIFF::Chunk* ck = list->GetSubChunk(chunkId);          RIFF::Chunk* ck = list->GetSubChunk(chunkId);
60          if(ck == NULL) throw Exception("Mandatory chunk in RIFF list chunk not found: " + ToString(chunkId));          if(ck == NULL) throw Exception("Mandatory chunk in RIFF list chunk not found: " + ToString(chunkId));
# Line 229  namespace sf2 { Line 237  namespace sf2 {
237      unsigned long Sample::ReadAndLoop (      unsigned long Sample::ReadAndLoop (
238          void*           pBuffer,          void*           pBuffer,
239          unsigned long   FrameCount,          unsigned long   FrameCount,
240          PlaybackState*  pPlaybackState          PlaybackState*  pPlaybackState,
241            Region*         pRegion
242      ) {      ) {
243            // TODO: startAddrsCoarseOffset, endAddrsCoarseOffset
244            unsigned long samplestoread = FrameCount, totalreadsamples = 0, readsamples, samplestoloopend;
245            uint8_t* pDst = (uint8_t*) pBuffer;
246          SetPos(pPlaybackState->position);          SetPos(pPlaybackState->position);
247          long frames = Read(pBuffer, FrameCount);          if (pRegion->HasLoop) {
248                do {
249                    samplestoloopend  = pRegion->LoopEnd - GetPos();
250                    readsamples       = Read(&pDst[totalreadsamples * GetFrameSize()], Min(samplestoread, samplestoloopend));
251                    samplestoread    -= readsamples;
252                    totalreadsamples += readsamples;
253                    if (readsamples == samplestoloopend) {
254                        SetPos(pRegion->LoopStart);
255                    }
256                } while (samplestoread && readsamples);
257            } else {
258                totalreadsamples = Read(pBuffer, FrameCount);
259            }
260    
261          pPlaybackState->position = GetPos();          pPlaybackState->position = GetPos();
262          // TODO: Implement looping  
263          return frames;          return totalreadsamples;
264      }      }
265    
266      Region::Region() {      Region::Region() {
267          pSample = NULL;          pSample = NULL;
268          pInstrument = NULL;          pInstrument = NULL;
269            pParentInstrument = NULL;
270          loKey = hiKey = NONE;          loKey = hiKey = NONE;
271          minVel = maxVel = NONE;          minVel = maxVel = NONE;
272          startAddrsOffset = startAddrsCoarseOffset = endAddrsOffset = 0;          startAddrsOffset = startAddrsCoarseOffset = endAddrsOffset = endAddrsCoarseOffset = 0;
273          startloopAddrsOffset = endloopAddrsOffset = 0;          startloopAddrsOffset = startloopAddrsCoarseOffset = endloopAddrsOffset = endloopAddrsCoarseOffset = 0;
274          pan = fineTune = 0;          pan = fineTune = coarseTune = 0;
275            overridingRootKey = -1; // -1 means not used
276    
277            HasLoop = false;
278            LoopStart = LoopEnd = 0;
279    
280          EG1PreAttackDelay = EG1Attack = EG1Hold = EG1Decay = EG1Release = ToSeconds(-12000);          EG1PreAttackDelay = EG1Attack = EG1Hold = EG1Decay = EG1Release = -12000;
281          EG1Sustain = 0;          EG1Sustain = 0;
282          EG2PreAttackDelay = EG2Attack = EG2Hold = EG2Decay = EG2Release = ToSeconds(-12000);          EG2PreAttackDelay = EG2Attack = EG2Hold = EG2Decay = EG2Release = -12000;
283          EG2Sustain = 0;          EG2Sustain = 0;
284    
285            modEnvToPitch = modLfoToPitch = modEnvToFilterFc = modLfoToFilterFc = modLfoToVolume = 0;
286            freqModLfo = 0;
287            delayModLfo = -12000;
288            vibLfoToPitch = 0;
289            freqVibLfo = 0;
290            delayVibLfo = -12000;
291    
292            exclusiveClass = 0;
293        }
294    
295        int Region::GetUnityNote() {
296            return overridingRootKey != -1 ? overridingRootKey : pSample->OriginalPitch;
297      }      }
298    
299      void Region::SetGenerator(sf2::File* pFile, GenList& Gen) {      void Region::SetGenerator(sf2::File* pFile, GenList& Gen) {
# Line 267  namespace sf2 { Line 310  namespace sf2 {
310                  break;                  break;
311              case STARTLOOP_ADDRS_OFFSET:              case STARTLOOP_ADDRS_OFFSET:
312                  startloopAddrsOffset = Gen.GenAmount.shAmount;                  startloopAddrsOffset = Gen.GenAmount.shAmount;
313                    LoopStart += startloopAddrsOffset;
314                  break;                  break;
315              case ENDLOOP_ADDRS_OFFSET:              case ENDLOOP_ADDRS_OFFSET:
316                  endloopAddrsOffset = Gen.GenAmount.shAmount;                  endloopAddrsOffset = Gen.GenAmount.shAmount;
317                    LoopEnd += endloopAddrsOffset;
318                  break;                  break;
319              case START_ADDRS_COARSE_OFFSET:              case START_ADDRS_COARSE_OFFSET:
320                  startAddrsCoarseOffset = Gen.GenAmount.wAmount;                  startAddrsCoarseOffset = Gen.GenAmount.wAmount;
321                  break;                  break;
322              case MOD_LFO_TO_PITCH:              case MOD_LFO_TO_PITCH:
323                    modLfoToPitch = Gen.GenAmount.shAmount;
324                  break;                  break;
325              case VIB_LFO_TO_PITCH:              case VIB_LFO_TO_PITCH:
326                    vibLfoToPitch = Gen.GenAmount.shAmount;
327                  break;                  break;
328              case MOD_ENV_TO_PITCH:              case MOD_ENV_TO_PITCH:
329                    modEnvToPitch = Gen.GenAmount.shAmount;
330                  break;                  break;
331              case INITIAL_FILTER_FC:              case INITIAL_FILTER_FC:
332                  break;                  break;
333              case INITIAL_FILTER_Q:              case INITIAL_FILTER_Q:
334                  break;                  break;
335              case MOD_LFO_TO_FILTER_FC:              case MOD_LFO_TO_FILTER_FC:
336                    modLfoToFilterFc = Gen.GenAmount.shAmount;
337                  break;                  break;
338              case MOD_ENV_TO_FILTER_FC:              case MOD_ENV_TO_FILTER_FC:
339                    modEnvToFilterFc = Gen.GenAmount.shAmount;
340                  break;                  break;
341              case END_ADDRS_COARSE_OFFSET:              case END_ADDRS_COARSE_OFFSET:
342                    endAddrsCoarseOffset = Gen.GenAmount.wAmount;
343                  break;                  break;
344              case MOD_LFO_TO_VOLUME:              case MOD_LFO_TO_VOLUME:
345                    modLfoToVolume = Gen.GenAmount.shAmount;
346                  break;                  break;
347              case CHORUS_EFFECTS_SEND:              case CHORUS_EFFECTS_SEND:
348                  break;                  break;
# Line 303  namespace sf2 { Line 355  namespace sf2 {
355                  if (pan >  63) pan =  63;                  if (pan >  63) pan =  63;
356                  break;                  break;
357              case DELAY_MOD_LFO:              case DELAY_MOD_LFO:
358                    delayModLfo = Gen.GenAmount.shAmount;
359                  break;                  break;
360              case FREQ_MOD_LFO:              case FREQ_MOD_LFO:
361                    freqModLfo = Gen.GenAmount.shAmount;
362                  break;                  break;
363              case DELAY_VIB_LFO:              case DELAY_VIB_LFO:
364                    delayVibLfo = Gen.GenAmount.shAmount;
365                  break;                  break;
366              case FREQ_VIB_LFO:              case FREQ_VIB_LFO:
367                    freqVibLfo = Gen.GenAmount.shAmount;
368                  break;                  break;
369              case DELAY_MOD_ENV:              case DELAY_MOD_ENV:
370                  EG2PreAttackDelay = ToSeconds(Gen.GenAmount.shAmount);                  EG2PreAttackDelay = Gen.GenAmount.shAmount;
371                  break;                  break;
372              case ATTACK_MOD_ENV:              case ATTACK_MOD_ENV:
373                  EG2Attack = ToSeconds(Gen.GenAmount.shAmount);                  EG2Attack = Gen.GenAmount.shAmount;
374                  break;                  break;
375              case HOLD_MOD_ENV:              case HOLD_MOD_ENV:
376                  EG2Hold = ToSeconds(Gen.GenAmount.shAmount);                  EG2Hold = Gen.GenAmount.shAmount;
377                  break;                  break;
378              case DECAY_MOD_ENV:              case DECAY_MOD_ENV:
379                  EG2Decay = ToSeconds(Gen.GenAmount.shAmount);                  EG2Decay = Gen.GenAmount.shAmount;
380                  break;                  break;
381              case SUSTAIN_MOD_ENV:              case SUSTAIN_MOD_ENV:
382                  EG2Sustain = 1000 - Gen.GenAmount.shAmount;                  EG2Sustain = Gen.GenAmount.shAmount;
383                  break;                  break;
384              case RELEASEMODENV:              case RELEASEMODENV:
385                  EG2Release = ToSeconds(Gen.GenAmount.shAmount);                  EG2Release = Gen.GenAmount.shAmount;
386                  break;                  break;
387              case KEYNUM_TO_MOD_ENV_HOLD:              case KEYNUM_TO_MOD_ENV_HOLD:
388                  break;                  break;
389              case KEYNUM_TO_MOD_ENV_DECAY:              case KEYNUM_TO_MOD_ENV_DECAY:
390                  break;                  break;
391              case DELAY_VOL_ENV:              case DELAY_VOL_ENV:
392                  EG1PreAttackDelay = ToSeconds(Gen.GenAmount.shAmount);                  EG1PreAttackDelay = Gen.GenAmount.shAmount;
393                  break;                  break;
394              case ATTACK_VOL_ENV:              case ATTACK_VOL_ENV:
395                  EG1Attack = ToSeconds(Gen.GenAmount.shAmount);                  EG1Attack = Gen.GenAmount.shAmount;
396                  break;                  break;
397              case HOLD_VOL_ENV:              case HOLD_VOL_ENV:
398                  EG1Hold = ToSeconds(Gen.GenAmount.shAmount);                  EG1Hold = Gen.GenAmount.shAmount;
399                  break;                  break;
400              case DECAY_VOL_ENV:              case DECAY_VOL_ENV:
401                  EG1Decay = ToSeconds(Gen.GenAmount.shAmount);                  EG1Decay = Gen.GenAmount.shAmount;
402                  break;                  break;
403              case SUSTAIN_VOL_ENV:              case SUSTAIN_VOL_ENV:
404                  EG1Sustain = ToPermilles(Gen.GenAmount.shAmount);                  EG1Sustain = Gen.GenAmount.shAmount;
405                  break;                  break;
406              case RELEASE_VOL_ENV:              case RELEASE_VOL_ENV:
407                  EG1Release = ToSeconds(Gen.GenAmount.shAmount);                  EG1Release = Gen.GenAmount.shAmount;
408                  break;                  break;
409              case KEYNUM_TO_VOL_ENV_HOLD:              case KEYNUM_TO_VOL_ENV_HOLD:
410                  break;                  break;
# Line 371  namespace sf2 { Line 427  namespace sf2 {
427                  maxVel = Gen.GenAmount.ranges.byHi;                  maxVel = Gen.GenAmount.ranges.byHi;
428                  break;                  break;
429              case STARTLOOP_ADDRS_COARSE_OFFSET:              case STARTLOOP_ADDRS_COARSE_OFFSET:
430                    startloopAddrsCoarseOffset = Gen.GenAmount.wAmount;
431                    LoopStart += startloopAddrsCoarseOffset * 32768;
432                  break;                  break;
433              case KEYNUM:              case KEYNUM:
434                  break;                  break;
# Line 379  namespace sf2 { Line 437  namespace sf2 {
437              case INITIAL_ATTENUATION:              case INITIAL_ATTENUATION:
438                  break;                  break;
439              case ENDLOOP_ADDRS_COARSE_OFFSET:              case ENDLOOP_ADDRS_COARSE_OFFSET:
440                    endloopAddrsCoarseOffset = Gen.GenAmount.wAmount;
441                    LoopEnd += endloopAddrsCoarseOffset * 32768;
442                  break;                  break;
443              case COARSE_TUNE:              case COARSE_TUNE:
444                    coarseTune = Gen.GenAmount.shAmount;
445                    if (coarseTune < -120) coarseTune = -120;
446                    if (coarseTune >  120) coarseTune =  120;
447                  break;                  break;
448              case FINE_TUNE:              case FINE_TUNE:
449                  fineTune = Gen.GenAmount.shAmount;                  fineTune = Gen.GenAmount.shAmount;
# Line 391  namespace sf2 { Line 454  namespace sf2 {
454                      throw Exception("Broken SF2 file (missing samples)");                      throw Exception("Broken SF2 file (missing samples)");
455                  }                  }
456                  pSample = pFile->Samples[sid];                  pSample = pFile->Samples[sid];
457    
458                    if (HasLoop) {
459                        LoopStart += pSample->StartLoop;
460                        LoopEnd   += pSample->EndLoop;
461                        if ( LoopStart < pSample->Start || LoopStart > pSample->End ||
462                             LoopStart > LoopEnd        || LoopEnd   > pSample->End    ) {
463                            throw Exception("Broken SF2 file (invalid loops)");
464                        }
465                        LoopStart -= pSample->Start; // Relative to the sample start
466                        LoopEnd   -= pSample->Start; // Relative to the sample start
467                    }
468                  break;                  break;
469              }              }
470              case SAMPLE_MODES:              case SAMPLE_MODES:
471                    HasLoop = Gen.GenAmount.wAmount & 1;
472                    // TODO: 3 indicates a sound which loops for the duration of key depression
473                    //       then proceeds to play the remainder of the sample.
474                  break;                  break;
475              case SCALE_TUNING:              case SCALE_TUNING:
476                  break;                  break;
477              case EXCLUSIVE_CLASS:              case EXCLUSIVE_CLASS:
478                    exclusiveClass = Gen.GenAmount.wAmount;
479                  break;                  break;
480              case OVERRIDING_ROOT_KEY:              case OVERRIDING_ROOT_KEY:
481                    overridingRootKey = Gen.GenAmount.shAmount;
482                  break;                  break;
483          }          }
484      }      }
# Line 427  namespace sf2 { Line 506  namespace sf2 {
506          }*/          }*/
507      }      }
508    
509        int Region::GetPan(Region* pPresetRegion) {
510            if (pPresetRegion == NULL) return pan;
511            int p = pPresetRegion->pan + pan;
512            if (p < -64) p = -64;
513            if (p >  63) p =  63;
514            return p;
515        }
516    
517        int Region::GetFineTune(Region* pPresetRegion) {
518            if (pPresetRegion == NULL) return fineTune;
519            int t = pPresetRegion->fineTune + fineTune;
520            if (t < -99) t = -99;
521            if (t >  99) t =  99;
522            return t;
523        }
524    
525        int Region::GetCoarseTune(Region* pPresetRegion) {
526             if (pPresetRegion == NULL) return coarseTune;
527            int t = pPresetRegion->coarseTune + coarseTune;
528            if (t < -120) t = -120;
529            if (t >  120) t =  120;
530            return t;
531        }
532    
533        double Region::GetEG1PreAttackDelay(Region* pPresetRegion) {
534            if (pPresetRegion == NULL || pPresetRegion->EG1PreAttackDelay == NONE) return ToSeconds(EG1PreAttackDelay);
535            return ToSeconds(pPresetRegion->EG1PreAttackDelay + EG1PreAttackDelay);
536        }
537    
538        double Region::GetEG1Attack(Region* pPresetRegion) {
539            if (pPresetRegion == NULL || pPresetRegion->EG1Attack == NONE) return ToSeconds(EG1Attack);
540            return ToSeconds(pPresetRegion->EG1Attack + EG1Attack);
541        }
542    
543        double Region::GetEG1Hold(Region* pPresetRegion) {
544            if (pPresetRegion == NULL || pPresetRegion->EG1Hold == NONE) return ToSeconds(EG1Hold);
545            return ToSeconds(pPresetRegion->EG1Hold + EG1Hold);
546        }
547    
548        double Region::GetEG1Decay(Region* pPresetRegion) {
549            if (pPresetRegion == NULL || pPresetRegion->EG1Decay == NONE) return ToSeconds(EG1Decay);
550            return ToSeconds(pPresetRegion->EG1Decay + EG1Decay);
551        }
552    
553        double Region::GetEG1Sustain(Region* pPresetRegion) {
554            if (pPresetRegion == NULL || pPresetRegion->EG1Sustain == NONE) return ToPermilles(EG1Sustain);
555            return ToPermilles(pPresetRegion->EG1Sustain + EG1Sustain);
556        }
557    
558        double Region::GetEG1Release(Region* pPresetRegion) {
559            if (pPresetRegion == NULL || pPresetRegion->EG1Release == NONE) return ToSeconds(EG1Release);
560            return ToSeconds(pPresetRegion->EG1Release + EG1Release);
561        }
562    
563        double Region::GetEG2PreAttackDelay(Region* pPresetRegion) {
564            if (pPresetRegion == NULL || pPresetRegion->EG2PreAttackDelay == NONE) return ToSeconds(EG2PreAttackDelay);
565            return ToSeconds(pPresetRegion->EG2PreAttackDelay + EG2PreAttackDelay);
566        }
567    
568        double Region::GetEG2Attack(Region* pPresetRegion) {
569            if (pPresetRegion == NULL || pPresetRegion->EG2Attack == NONE) return ToSeconds(EG2Attack);
570            return ToSeconds(pPresetRegion->EG2Attack + EG2Attack);
571        }
572    
573        double Region::GetEG2Hold(Region* pPresetRegion) {
574            if (pPresetRegion == NULL || pPresetRegion->EG2Hold == NONE) return ToSeconds(EG2Hold);
575            return ToSeconds(pPresetRegion->EG2Hold + EG2Hold);
576        }
577    
578        double Region::GetEG2Decay(Region* pPresetRegion) {
579            if (pPresetRegion == NULL || pPresetRegion->EG2Decay == NONE) return ToSeconds(EG2Decay);
580            return ToSeconds(pPresetRegion->EG2Decay + EG2Decay);
581        }
582    
583        double Region::GetEG2Sustain(Region* pPresetRegion) {
584            if (pPresetRegion == NULL || pPresetRegion->EG2Sustain == NONE) {
585                return EG2Sustain == NONE ? NONE : 1000 - EG2Sustain;
586            }
587            return 1000 - (pPresetRegion->EG2Sustain + EG2Sustain);
588        }
589    
590        double Region::GetEG2Release(Region* pPresetRegion) {
591            if (pPresetRegion == NULL || pPresetRegion->EG2Release == NONE) return ToSeconds(EG2Release);
592            return ToSeconds(pPresetRegion->EG2Release + EG2Release);
593        }
594    
595        int Region::GetModEnvToPitch(Region* pPresetRegion) {
596            return modEnvToPitch + (pPresetRegion ? pPresetRegion->modEnvToPitch : 0);
597        }
598    
599        int Region::GetModLfoToPitch(Region* pPresetRegion) {
600            return modLfoToPitch + (pPresetRegion ? pPresetRegion->modLfoToPitch : 0);
601        }
602    
603        int Region::GetModEnvToFilterFc(Region* pPresetRegion) {
604            return modEnvToFilterFc + (pPresetRegion ? pPresetRegion->modEnvToFilterFc : 0);
605        }
606    
607        int Region::GetModLfoToFilterFc(Region* pPresetRegion) {
608            return modLfoToFilterFc + (pPresetRegion ? pPresetRegion->modLfoToFilterFc : 0);
609        }
610    
611        double Region::GetModLfoToVolume(Region* pPresetRegion) {
612            return ToPermilles(modLfoToVolume + (pPresetRegion ? pPresetRegion->modLfoToVolume : 0));
613        }
614    
615        double Region::GetFreqModLfo(Region* pPresetRegion) {
616            if (pPresetRegion == NULL || pPresetRegion->freqModLfo == NONE) return ToHz(freqModLfo);
617            return ToHz(pPresetRegion->freqModLfo + freqModLfo);
618        }
619        
620        double Region::GetDelayModLfo(Region* pPresetRegion) {
621            if (pPresetRegion == NULL || pPresetRegion->delayModLfo == NONE) return ToSeconds(delayModLfo);
622            return ToSeconds(pPresetRegion->delayModLfo + delayModLfo);
623        }
624    
625        int Region::GetVibLfoToPitch(Region* pPresetRegion) {
626            return vibLfoToPitch + (pPresetRegion ? pPresetRegion->vibLfoToPitch : 0);
627        }
628    
629        double Region::GetFreqVibLfo(Region* pPresetRegion) {
630            if (pPresetRegion == NULL || pPresetRegion->freqVibLfo == NONE) return ToHz(freqVibLfo);
631            return ToHz(pPresetRegion->freqVibLfo + freqVibLfo);
632        }
633    
634        double Region::GetDelayVibLfo(Region* pPresetRegion) {
635            if (pPresetRegion == NULL || pPresetRegion->delayVibLfo == NONE) return ToSeconds(delayVibLfo);
636            return ToSeconds(pPresetRegion->delayVibLfo + delayVibLfo);
637        }
638    
639      InstrumentBase::InstrumentBase(sf2::File* pFile) {      InstrumentBase::InstrumentBase(sf2::File* pFile) {
640          this->pFile = pFile;          this->pFile = pFile;
641          pGlobalRegion = NULL;          pGlobalRegion = NULL;
# Line 440  namespace sf2 { Line 649  namespace sf2 {
649      }      }
650    
651      int InstrumentBase::GetRegionCount() {      int InstrumentBase::GetRegionCount() {
652          return regions.size() - 1; // exclude terminal region          return regions.size();
653      }      }
654    
655      Region* InstrumentBase::GetRegion(int idx) {      Region* InstrumentBase::GetRegion(int idx) {
# Line 456  namespace sf2 { Line 665  namespace sf2 {
665          for (int i = 0; i < GetRegionCount(); i++) {          for (int i = 0; i < GetRegionCount(); i++) {
666              Region* r = GetRegion(i);              Region* r = GetRegion(i);
667              if (              if (
668                  key >= r->loKey && key <= r->hiKey &&                  ((r->loKey  == NONE && r->hiKey  == NONE) || (key >= r->loKey && key <= r->hiKey)) &&
669                  ((r->minVel == NONE && r->maxVel == NONE) || (vel >= r->minVel && vel <= r->maxVel))                  ((r->minVel == NONE && r->maxVel == NONE) || (vel >= r->minVel && vel <= r->maxVel))
670              ) {              ) {
671                  v.push_back(r);                  v.push_back(r);
# Line 476  namespace sf2 { Line 685  namespace sf2 {
685                    
686      }      }
687    
688        Region* Instrument::CreateRegion() {
689            Region* r = new Region;
690            r->pParentInstrument = this;
691    
692            if (pGlobalRegion != NULL) {
693                r->loKey       = pGlobalRegion->loKey;
694                r->hiKey       = pGlobalRegion->hiKey;
695                r->minVel      = pGlobalRegion->minVel;
696                r->maxVel      = pGlobalRegion->maxVel;
697                r->pan         = pGlobalRegion->pan;
698                r->fineTune    = pGlobalRegion->fineTune;
699                r->coarseTune  = pGlobalRegion->coarseTune;
700                r->overridingRootKey = pGlobalRegion->overridingRootKey;
701                r->startAddrsOffset            = pGlobalRegion->startAddrsOffset;
702                r->startAddrsCoarseOffset      = pGlobalRegion->startAddrsCoarseOffset;
703                r->endAddrsOffset              = pGlobalRegion->endAddrsOffset;
704                r->endAddrsCoarseOffset        = pGlobalRegion->endAddrsCoarseOffset;
705                r->startloopAddrsOffset        = pGlobalRegion->startloopAddrsOffset;
706                r->startloopAddrsCoarseOffset  = pGlobalRegion->startloopAddrsCoarseOffset;
707                r->endloopAddrsOffset          = pGlobalRegion->endloopAddrsOffset;
708                r->endloopAddrsCoarseOffset    = pGlobalRegion->endloopAddrsCoarseOffset;
709    
710                r->EG1PreAttackDelay  = pGlobalRegion->EG1PreAttackDelay;
711                r->EG1Attack          = pGlobalRegion->EG1Attack;
712                r->EG1Hold            = pGlobalRegion->EG1Hold;
713                r->EG1Decay           = pGlobalRegion->EG1Decay;
714                r->EG1Sustain         = pGlobalRegion->EG1Sustain;
715                r->EG1Release         = pGlobalRegion->EG1Release;
716    
717                r->EG2PreAttackDelay  = pGlobalRegion->EG2PreAttackDelay;
718                r->EG2Attack          = pGlobalRegion->EG2Attack;
719                r->EG2Hold            = pGlobalRegion->EG2Hold;
720                r->EG2Decay           = pGlobalRegion->EG2Decay;
721                r->EG2Sustain         = pGlobalRegion->EG2Sustain;
722                r->EG2Release         = pGlobalRegion->EG2Release;
723    
724                r->modEnvToPitch     = pGlobalRegion->modEnvToPitch;
725                r->modLfoToPitch     = pGlobalRegion->modLfoToPitch;
726                r->modEnvToFilterFc  = pGlobalRegion->modEnvToFilterFc;
727                r->modLfoToFilterFc  = pGlobalRegion->modLfoToFilterFc;
728                r->modLfoToVolume    = pGlobalRegion->modLfoToVolume;
729                r->freqModLfo        = pGlobalRegion->freqModLfo;
730                r->delayModLfo       = pGlobalRegion->delayModLfo;
731                r->vibLfoToPitch     = pGlobalRegion->vibLfoToPitch;
732                r->freqVibLfo        = pGlobalRegion->freqVibLfo;
733                r->delayVibLfo       = pGlobalRegion->delayVibLfo;
734    
735                r->HasLoop    = pGlobalRegion->HasLoop;
736                r->LoopStart  = pGlobalRegion->LoopStart;
737                r->LoopEnd    = pGlobalRegion->LoopEnd;
738    
739                r->exclusiveClass = pGlobalRegion->exclusiveClass;
740            }
741    
742            return r;
743        }
744    
745        void Instrument::DeleteRegion(Region* pRegion) {
746            for (int i = 0; i < regions.size(); i++) {
747                if (regions[i] == pRegion) {
748                    delete pRegion;
749                    regions[i] = NULL;
750                    return;
751                }
752            }
753    
754            std::cerr << "Can't remove unknown Region" << std::endl;
755        }
756    
757      void Instrument::LoadRegions(int idx1, int idx2) {      void Instrument::LoadRegions(int idx1, int idx2) {
758          for (int i = idx1; i < idx2 - 1; i++) {          for (int i = idx1; i < idx2; i++) {
759              int gIdx1 = pFile->InstBags[i].InstGenNdx;              int gIdx1 = pFile->InstBags[i].InstGenNdx;
760              int gIdx2 = pFile->InstBags[i + 1].InstGenNdx;              int gIdx2 = pFile->InstBags[i + 1].InstGenNdx;
761    
# Line 492  namespace sf2 { Line 770  namespace sf2 {
770                  throw Exception("Broken SF2 file (invalid InstModNdx)");                  throw Exception("Broken SF2 file (invalid InstModNdx)");
771              }              }
772    
773              Region* reg = new Region;              Region* reg = CreateRegion();
774                            
775              for (int j = gIdx1; j < gIdx2; j++) {              for (int j = gIdx1; j < gIdx2; j++) {
776                  reg->SetGenerator(pFile, pFile->InstGenLists[j]);                  reg->SetGenerator(pFile, pFile->InstGenLists[j]);
# Line 504  namespace sf2 { Line 782  namespace sf2 {
782              }              }
783    
784              if (reg->pSample == NULL) {              if (reg->pSample == NULL) {
785                  if (i == idx1) {                  if (i == idx1 && idx2 - idx1 > 1) {
786                      pGlobalRegion = reg;  // global zone                      pGlobalRegion = reg;  // global zone
787                  } else {                  } else {
788                      std::cerr << "Ignoring instrument's region without sample" << std::endl;                      std::cerr << "Ignoring instrument's region without sample" << std::endl;
# Line 531  namespace sf2 { Line 809  namespace sf2 {
809                    
810      }      }
811    
812        Region* Preset::CreateRegion() {
813            Region* r = new Region;
814    
815            r->EG1PreAttackDelay = r->EG1Attack = r->EG1Hold = r->EG1Decay = r->EG1Sustain = r->EG1Release = NONE;
816            r->EG2PreAttackDelay = r->EG2Attack = r->EG2Hold = r->EG2Decay = r->EG2Sustain = r->EG2Release = NONE;
817            r->freqModLfo = r->delayModLfo = r->freqVibLfo = r->delayVibLfo = NONE;
818    
819            if (pGlobalRegion != NULL) {
820                r->pan         = pGlobalRegion->pan;
821                r->fineTune    = pGlobalRegion->fineTune;
822                r->coarseTune  = pGlobalRegion->coarseTune;
823    
824                r->EG1PreAttackDelay  = pGlobalRegion->EG1PreAttackDelay;
825                r->EG1Attack          = pGlobalRegion->EG1Attack;
826                r->EG1Hold            = pGlobalRegion->EG1Hold;
827                r->EG1Decay           = pGlobalRegion->EG1Decay;
828                r->EG1Sustain         = pGlobalRegion->EG1Sustain;
829                r->EG1Release         = pGlobalRegion->EG1Release;
830    
831                r->EG2PreAttackDelay  = pGlobalRegion->EG2PreAttackDelay;
832                r->EG2Attack          = pGlobalRegion->EG2Attack;
833                r->EG2Hold            = pGlobalRegion->EG2Hold;
834                r->EG2Decay           = pGlobalRegion->EG2Decay;
835                r->EG2Sustain         = pGlobalRegion->EG2Sustain;
836                r->EG2Release         = pGlobalRegion->EG2Release;
837    
838                r->modEnvToPitch     = pGlobalRegion->modEnvToPitch;
839                r->modLfoToPitch     = pGlobalRegion->modLfoToPitch;
840                r->modEnvToFilterFc  = pGlobalRegion->modEnvToFilterFc;
841                r->modLfoToFilterFc  = pGlobalRegion->modLfoToFilterFc;
842                r->modLfoToVolume    = pGlobalRegion->modLfoToVolume;
843                r->freqModLfo        = pGlobalRegion->freqModLfo;
844                r->delayModLfo       = pGlobalRegion->delayModLfo;
845                r->vibLfoToPitch     = pGlobalRegion->vibLfoToPitch;
846                r->freqVibLfo        = pGlobalRegion->freqVibLfo;
847                r->delayVibLfo       = pGlobalRegion->delayVibLfo;
848            }
849    
850            return r;
851        }
852    
853      void Preset::LoadRegions(int idx1, int idx2) {      void Preset::LoadRegions(int idx1, int idx2) {
854          for (int i = idx1; i < idx2 - 1; i++) {          for (int i = idx1; i < idx2; i++) {
855              int gIdx1 = pFile->PresetBags[i].GenNdx;              int gIdx1 = pFile->PresetBags[i].GenNdx;
856              int gIdx2 = pFile->PresetBags[i + 1].GenNdx;              int gIdx2 = pFile->PresetBags[i + 1].GenNdx;
857    
# Line 540  namespace sf2 { Line 859  namespace sf2 {
859                  throw Exception("Broken SF2 file (invalid PresetGenNdx)");                  throw Exception("Broken SF2 file (invalid PresetGenNdx)");
860              }              }
861    
862              Region* reg = new Region;              Region* reg = CreateRegion();
863    
864              for (int j = gIdx1; j < gIdx2; j++) {              for (int j = gIdx1; j < gIdx2; j++) {
865                  reg->SetGenerator(pFile, pFile->PresetGenLists[j]);                  reg->SetGenerator(pFile, pFile->PresetGenLists[j]);
866              }              }
867              if (reg->pInstrument == NULL) {              if (reg->pInstrument == NULL) {
868                  if (i == idx1) {                  if (i == idx1 && idx2 - idx1 > 1) {
869                      pGlobalRegion = reg;  // global zone                      pGlobalRegion = reg;  // global zone
870                  } else {                  } else {
871                      std::cerr << "Ignoring preset's region without instrument" << std::endl;                      std::cerr << "Ignoring preset's region without instrument" << std::endl;
# Line 780  namespace sf2 { Line 1099  namespace sf2 {
1099          return Instruments[idx];          return Instruments[idx];
1100      }      }
1101    
1102        void File::DeleteInstrument(Instrument* pInstrument) {
1103            for (int i = 0; i < GetPresetCount(); i++) {
1104                Preset* p = GetPreset(i);
1105                if (p == NULL) continue;
1106                for (int j = p->GetRegionCount() - 1; j >= 0 ; j--) {
1107                    if (p->GetRegion(j) && p->GetRegion(j)->pInstrument == pInstrument) {
1108                        p->GetRegion(j)->pInstrument = NULL;
1109                    }
1110                }
1111            }
1112    
1113            for (int i = 0; i < GetInstrumentCount(); i++) {
1114                if (GetInstrument(i) == pInstrument) {
1115                    Instruments[i] = NULL;
1116                    delete pInstrument;
1117                }
1118            }
1119        }
1120    
1121      int File::GetSampleCount() {      int File::GetSampleCount() {
1122          return Samples.size() - 1; // exclude terminal sample (EOS)          return Samples.size() - 1; // exclude terminal sample (EOS)
1123      }      }
# Line 793  namespace sf2 { Line 1131  namespace sf2 {
1131      }      }
1132    
1133      void File::DeleteSample(Sample* pSample) {      void File::DeleteSample(Sample* pSample) {
1134            // Sanity check
1135            for (int i = GetInstrumentCount() - 1; i >= 0; i--) {
1136                Instrument* pInstr = GetInstrument(i);
1137                if (pInstr == NULL) continue;
1138    
1139                for (int j = pInstr->GetRegionCount() - 1; j >= 0 ; j--) {
1140                    if (pInstr->GetRegion(j) && pInstr->GetRegion(j)->GetSample() == pSample) {
1141                        std::cerr << "Deleting sample which is still in use" << std::endl;
1142                    }
1143                }
1144            }
1145            ///////
1146    
1147          for (int i = 0; i < GetSampleCount(); i++) {          for (int i = 0; i < GetSampleCount(); i++) {
1148              if (Samples[i] == pSample) {              if (Samples[i] == pSample) {
1149                  delete pSample;                  delete pSample;
# Line 982  namespace sf2 { Line 1333  namespace sf2 {
1333       * @see                SetPos()       * @see                SetPos()
1334       */       */
1335      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
1336            // TODO: startAddrsCoarseOffset, endAddrsCoarseOffset
1337          if (SampleCount == 0) return 0;          if (SampleCount == 0) return 0;
1338          long pos = GetPos();          long pos = GetPos();
1339          if (pos + SampleCount > GetTotalFrameCount()) SampleCount = GetTotalFrameCount() - pos;          if (pos + SampleCount > GetTotalFrameCount()) SampleCount = GetTotalFrameCount() - pos;
# Line 989  namespace sf2 { Line 1341  namespace sf2 {
1341          if (GetFrameSize() / GetChannelCount() == 3 /* 24 bit */) {          if (GetFrameSize() / GetChannelCount() == 3 /* 24 bit */) {
1342              uint8_t* pBuf = (uint8_t*)pBuffer;              uint8_t* pBuf = (uint8_t*)pBuffer;
1343              if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) {              if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) {
1344                  for (int i = 0; i < SampleCount; i++) {                  pCkSmpl->Read(pBuf, SampleCount, 2);
1345                      pBuf[i*3] = pCkSmpl->ReadInt16();                  pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);
1346                      pBuf[i*3 + 2] = pCkSm24->ReadInt8();                  for (int i = SampleCount - 1; i >= 0; i--) {
1347                        pBuf[i*3] = pBuf[(SampleCount * 2) + i];
1348                        pBuf[i*3 + 2] = pBuf[i*2 + 1];
1349                        pBuf[i*3 + 1] = pBuf[i*2];
1350                  }                  }
1351              } else if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) {              } else if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) {
1352                  for (int i = 0; i < SampleCount; i++) {                  pCkSmpl->Read(pBuf, SampleCount, 2);
1353                      pBuf[i*6] = pCkSmpl->ReadInt16();                  pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);
1354                      pBuf[i*6 + 2] = pCkSm24->ReadInt8();                  for (int i = SampleCount - 1; i >= 0; i--) {
1355                        pBuf[i*6] = pBuf[(SampleCount * 2) + i];
1356                        pBuf[i*6 + 2] = pBuf[i*2 + 1];
1357                        pBuf[i*6 + 1] = pBuf[i*2];
1358                      pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0;                      pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0;
1359                  }                  }
1360              } else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) {              } else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) {
1361                  for (int i = 0; i < SampleCount; i++) {                  pCkSmpl->Read(pBuf, SampleCount, 2);
1362                    pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);
1363                    for (int i = SampleCount - 1; i >= 0; i--) {
1364                        pBuf[i*6 + 3] = pBuf[(SampleCount * 2) + i];
1365                        pBuf[i*6 + 5] = pBuf[i*2 + 1];
1366                        pBuf[i*6 + 4] = pBuf[i*2];
1367                      pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0;                      pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0;
                     pBuf[i*6 + 3] = pCkSmpl->ReadInt16();  
                     pBuf[i*6 + 5] = pCkSm24->ReadInt8();  
1368                  }                  }
1369              }              }
1370          } else {          } else {

Legend:
Removed from v.2016  
changed lines
  Added in v.2026

  ViewVC Help
Powered by ViewVC