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

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

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

revision 2 by schoenebeck, Sat Oct 25 20:15:04 2003 UTC revision 21 by schoenebeck, Thu Dec 25 01:09:08 2003 UTC
# Line 45  namespace gig { Line 45  namespace gig {
45          Product           = smpl->ReadInt32();          Product           = smpl->ReadInt32();
46          SamplePeriod      = smpl->ReadInt32();          SamplePeriod      = smpl->ReadInt32();
47          MIDIUnityNote     = smpl->ReadInt32();          MIDIUnityNote     = smpl->ReadInt32();
48          MIDIPitchFraction = smpl->ReadInt32();          FineTune          = smpl->ReadInt32();
49          smpl->Read(&SMPTEFormat, 1, 4);          smpl->Read(&SMPTEFormat, 1, 4);
50          SMPTEOffset       = smpl->ReadInt32();          SMPTEOffset       = smpl->ReadInt32();
51          Loops             = smpl->ReadInt32();          Loops             = smpl->ReadInt32();
52            uint32_t manufByt = smpl->ReadInt32();
53          LoopID            = smpl->ReadInt32();          LoopID            = smpl->ReadInt32();
54          smpl->Read(&LoopType, 1, 4);          smpl->Read(&LoopType, 1, 4);
55          LoopStart         = smpl->ReadInt32();          LoopStart         = smpl->ReadInt32();
# Line 71  namespace gig { Line 72  namespace gig {
72              }              }
73          }          }
74          FrameOffset = 0; // just for streaming compressed samples          FrameOffset = 0; // just for streaming compressed samples
75    
76            LoopStart /= FrameSize; // convert to sample points
77            LoopEnd   /= FrameSize; // convert to sample points
78            LoopSize   = LoopEnd - LoopStart;
79      }      }
80    
81      /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).      /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
# Line 323  namespace gig { Line 328  namespace gig {
328       * @see                SetPos()       * @see                SetPos()
329       */       */
330      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
331          if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize);          if (SampleCount == 0) return 0;
332            if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize); //FIXME: channel inversion due to endian correction?
333          else { //FIXME: no support for mono compressed samples yet, are there any?          else { //FIXME: no support for mono compressed samples yet, are there any?
334                if (this->SamplePos >= this->SamplesTotal) return 0;
335              //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate              //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate
336              // best case needed buffer size (all frames compressed)              // best case needed buffer size (all frames compressed)
337              unsigned long assumedsize      = (SampleCount << 1)  + // *2 (16 Bit, stereo, but assume all frames compressed)              unsigned long assumedsize      = (SampleCount << 1)  + // *2 (16 Bit, stereo, but assume all frames compressed)
# Line 353  namespace gig { Line 360  namespace gig {
360                  // reload from disk to local buffer if needed                  // reload from disk to local buffer if needed
361                  if (remainingbytes < 8194) {                  if (remainingbytes < 8194) {
362                      if (pCkData->GetState() != RIFF::stream_ready) {                      if (pCkData->GetState() != RIFF::stream_ready) {
363                          this->SamplePos += (SampleCount - remainingsamples);                          this->SamplePos = this->SamplesTotal;
                         //if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;  
364                          return (SampleCount - remainingsamples);                          return (SampleCount - remainingsamples);
365                      }                      }
366                      assumedsize    = remainingsamples;                      assumedsize    = remainingsamples;
# Line 474  namespace gig { Line 480  namespace gig {
480                  }                  }
481              }              }
482              this->SamplePos += (SampleCount - remainingsamples);              this->SamplePos += (SampleCount - remainingsamples);
483              //if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;              if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
484              return (SampleCount - remainingsamples);              return (SampleCount - remainingsamples);
485          }          }
486      }      }
# Line 491  namespace gig { Line 497  namespace gig {
497  // *************** DimensionRegion ***************  // *************** DimensionRegion ***************
498  // *  // *
499    
500        uint                               DimensionRegion::Instances       = 0;
501        DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
502    
503      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
504            Instances++;
505    
506          memcpy(&Crossfade, &SamplerOptions, 4);          memcpy(&Crossfade, &SamplerOptions, 4);
507            if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
508    
509          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
510          _3ewa->ReadInt32(); // unknown, allways 0x0000008C ?          _3ewa->ReadInt32(); // unknown, allways 0x0000008C ?
# Line 644  namespace gig { Line 656  namespace gig {
656          VCFVelocityDynamicRange = vcfvelocity % 5;          VCFVelocityDynamicRange = vcfvelocity % 5;
657          VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);          VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
658          VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());          VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
659    
660            // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
661            uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
662            if (pVelocityTables->count(tableKey)) { // if key exists
663                pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
664            }
665            else {
666                pVelocityAttenuationTable = new double[128];
667                switch (VelocityResponseCurve) { // calculate the new table
668                    case curve_type_nonlinear:
669                        for (int velocity = 0; velocity < 128; velocity++) {
670                            pVelocityAttenuationTable[velocity] =
671                                GIG_VELOCITY_TRANSFORM_NONLINEAR((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
672                            if      (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
673                            else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
674                         }
675                         break;
676                    case curve_type_linear:
677                        for (int velocity = 0; velocity < 128; velocity++) {
678                            pVelocityAttenuationTable[velocity] =
679                                GIG_VELOCITY_TRANSFORM_LINEAR((double)velocity,(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
680                            if      (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
681                            else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
682                        }
683                        break;
684                    case curve_type_special:
685                        for (int velocity = 0; velocity < 128; velocity++) {
686                            pVelocityAttenuationTable[velocity] =
687                                GIG_VELOCITY_TRANSFORM_SPECIAL((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
688                            if      (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
689                            else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
690                        }
691                        break;
692                    case curve_type_unknown:
693                    default:
694                        throw gig::Exception("Unknown transform curve type.");
695                }
696                (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
697            }
698        }
699    
700        DimensionRegion::~DimensionRegion() {
701            Instances--;
702            if (!Instances) {
703                // delete the velocity->volume tables
704                VelocityTableMap::iterator iter;
705                for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
706                    double* pTable = iter->second;
707                    if (pTable) delete[] pTable;
708                }
709                pVelocityTables->clear();
710                delete pVelocityTables;
711                pVelocityTables = NULL;
712            }
713        }
714    
715        /**
716         * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
717         * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
718         * and VelocityResponseCurveScaling) involved are taken into account to
719         * calculate the amplitude factor. Use this method when a key was
720         * triggered to get the volume with which the sample should be played
721         * back.
722         *
723         * @param    MIDI velocity value of the triggered key (between 0 and 127)
724         * @returns  amplitude factor (between 0.0 and 1.0)
725         */
726        double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
727            return pVelocityAttenuationTable[MIDIKeyVelocity];
728      }      }
729    
730    
# Line 995  namespace gig { Line 1076  namespace gig {
1076          return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;          return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1077      }      }
1078    
1079        /**
1080         * Returns the instrument with the given index.
1081         *
1082         * @returns  sought instrument or NULL if there's no such instrument
1083         */
1084        Instrument* File::GetInstrument(uint index) {
1085            if (!pInstruments) LoadInstruments();
1086            if (!pInstruments) return NULL;
1087            InstrumentsIterator = pInstruments->begin();
1088            for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
1089                if (i == index) return *InstrumentsIterator;
1090                InstrumentsIterator++;
1091            }
1092            return NULL;
1093        }
1094    
1095      void File::LoadInstruments() {      void File::LoadInstruments() {
1096          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1097          if (lstInstruments) {          if (lstInstruments) {

Legend:
Removed from v.2  
changed lines
  Added in v.21

  ViewVC Help
Powered by ViewVC