/[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 1301 by persson, Sat Aug 25 09:59:53 2007 UTC revision 1358 by schoenebeck, Sun Sep 30 18:13:33 2007 UTC
# Line 1262  namespace { Line 1262  namespace {
1262      uint                               DimensionRegion::Instances       = 0;      uint                               DimensionRegion::Instances       = 0;
1263      DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;      DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1264    
1265      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1266          Instances++;          Instances++;
1267    
1268          pSample = NULL;          pSample = NULL;
1269            pRegion = pParent;
1270    
1271          if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);          if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1272          else memset(&Crossfade, 0, 4);          else memset(&Crossfade, 0, 4);
# Line 1511  namespace { Line 1512  namespace {
1512                                                       VelocityResponseDepth,                                                       VelocityResponseDepth,
1513                                                       VelocityResponseCurveScaling);                                                       VelocityResponseCurveScaling);
1514    
1515          curve_type_t curveType = ReleaseVelocityResponseCurve;          pVelocityReleaseTable = GetReleaseVelocityTable(
1516          uint8_t depth = ReleaseVelocityResponseDepth;                                      ReleaseVelocityResponseCurve,
1517                                        ReleaseVelocityResponseDepth
1518          // this models a strange behaviour or bug in GSt: two of the                                  );
1519          // velocity response curves for release time are not used even  
1520          // if specified, instead another curve is chosen.          pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1521          if ((curveType == curve_type_nonlinear && depth == 0) ||                                                        VCFVelocityDynamicRange,
1522              (curveType == curve_type_special   && depth == 4)) {                                                        VCFVelocityScale,
1523              curveType = curve_type_nonlinear;                                                        VCFCutoffController);
             depth = 3;  
         }  
         pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);  
   
         curveType = VCFVelocityCurve;  
         depth = VCFVelocityDynamicRange;  
   
         // even stranger GSt: two of the velocity response curves for  
         // filter cutoff are not used, instead another special curve  
         // is chosen. This curve is not used anywhere else.  
         if ((curveType == curve_type_nonlinear && depth == 0) ||  
             (curveType == curve_type_special   && depth == 4)) {  
             curveType = curve_type_special;  
             depth = 5;  
         }  
         pVelocityCutoffTable = GetVelocityTable(curveType, depth,  
                                                 VCFCutoffController <= vcf_cutoff_ctrl_none2 ? VCFVelocityScale : 0);  
1524    
1525          SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));          SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1526          VelocityTable = 0;          VelocityTable = 0;
# Line 1565  namespace { Line 1549  namespace {
1549      }      }
1550    
1551      /**      /**
1552         * Updates the respective member variable and updates @c SampleAttenuation
1553         * which depends on this value.
1554         */
1555        void DimensionRegion::SetGain(int32_t gain) {
1556            DLS::Sampler::SetGain(gain);
1557            SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1558        }
1559    
1560        /**
1561       * Apply dimension region settings to the respective RIFF chunks. You       * Apply dimension region settings to the respective RIFF chunks. You
1562       * have to call File::Save() to make changes persistent.       * have to call File::Save() to make changes persistent.
1563       *       *
# Line 1572  namespace { Line 1565  namespace {
1565       * It will be called automatically when File::Save() was called.       * It will be called automatically when File::Save() was called.
1566       */       */
1567      void DimensionRegion::UpdateChunks() {      void DimensionRegion::UpdateChunks() {
         // check if wsmp is going to be created by  
         // DLS::Sampler::UpdateChunks  
         bool wsmp_created = !pParentList->GetSubChunk(CHUNK_ID_WSMP);  
   
1568          // first update base class's chunk          // first update base class's chunk
1569          DLS::Sampler::UpdateChunks();          DLS::Sampler::UpdateChunks();
1570    
# Line 1588  namespace { Line 1577  namespace {
1577    
1578          // make sure '3ewa' chunk exists          // make sure '3ewa' chunk exists
1579          RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);          RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1580          if (!_3ewa)  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, 140);          if (!_3ewa) {
1581          else if (wsmp_created) {              File* pFile = (File*) GetParent()->GetParent()->GetParent();
1582              // make sure the chunk order is: wsmp, 3ewa              bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1583              pParentList->MoveSubChunk(_3ewa, 0);              _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1584          }          }
1585          pData = (uint8_t*) _3ewa->LoadChunkData();          pData = (uint8_t*) _3ewa->LoadChunkData();
1586    
# Line 1859  namespace { Line 1848  namespace {
1848          }          }
1849      }      }
1850    
1851        double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
1852            curve_type_t curveType = releaseVelocityResponseCurve;
1853            uint8_t depth = releaseVelocityResponseDepth;
1854            // this models a strange behaviour or bug in GSt: two of the
1855            // velocity response curves for release time are not used even
1856            // if specified, instead another curve is chosen.
1857            if ((curveType == curve_type_nonlinear && depth == 0) ||
1858                (curveType == curve_type_special   && depth == 4)) {
1859                curveType = curve_type_nonlinear;
1860                depth = 3;
1861            }
1862            return GetVelocityTable(curveType, depth, 0);
1863        }
1864    
1865        double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
1866                                                        uint8_t vcfVelocityDynamicRange,
1867                                                        uint8_t vcfVelocityScale,
1868                                                        vcf_cutoff_ctrl_t vcfCutoffController)
1869        {
1870            curve_type_t curveType = vcfVelocityCurve;
1871            uint8_t depth = vcfVelocityDynamicRange;
1872            // even stranger GSt: two of the velocity response curves for
1873            // filter cutoff are not used, instead another special curve
1874            // is chosen. This curve is not used anywhere else.
1875            if ((curveType == curve_type_nonlinear && depth == 0) ||
1876                (curveType == curve_type_special   && depth == 4)) {
1877                curveType = curve_type_special;
1878                depth = 5;
1879            }
1880            return GetVelocityTable(curveType, depth,
1881                                    (vcfCutoffController <= vcf_cutoff_ctrl_none2)
1882                                        ? vcfVelocityScale : 0);
1883        }
1884    
1885      // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet      // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
1886      double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)      double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
1887      {      {
# Line 1874  namespace { Line 1897  namespace {
1897          return table;          return table;
1898      }      }
1899    
1900        Region* DimensionRegion::GetParent() const {
1901            return pRegion;
1902        }
1903    
1904      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
1905          leverage_ctrl_t decodedcontroller;          leverage_ctrl_t decodedcontroller;
1906          switch (EncodedController) {          switch (EncodedController) {
# Line 2127  namespace { Line 2154  namespace {
2154          return pVelocityCutoffTable[MIDIKeyVelocity];          return pVelocityCutoffTable[MIDIKeyVelocity];
2155      }      }
2156    
2157        /**
2158         * Updates the respective member variable and the lookup table / cache
2159         * that depends on this value.
2160         */
2161        void DimensionRegion::SetVelocityResponseCurve(curve_type_t curve) {
2162            pVelocityAttenuationTable =
2163                GetVelocityTable(
2164                    curve, VelocityResponseDepth, VelocityResponseCurveScaling
2165                );
2166            VelocityResponseCurve = curve;
2167        }
2168    
2169        /**
2170         * Updates the respective member variable and the lookup table / cache
2171         * that depends on this value.
2172         */
2173        void DimensionRegion::SetVelocityResponseDepth(uint8_t depth) {
2174            pVelocityAttenuationTable =
2175                GetVelocityTable(
2176                    VelocityResponseCurve, depth, VelocityResponseCurveScaling
2177                );
2178            VelocityResponseDepth = depth;
2179        }
2180    
2181        /**
2182         * Updates the respective member variable and the lookup table / cache
2183         * that depends on this value.
2184         */
2185        void DimensionRegion::SetVelocityResponseCurveScaling(uint8_t scaling) {
2186            pVelocityAttenuationTable =
2187                GetVelocityTable(
2188                    VelocityResponseCurve, VelocityResponseDepth, scaling
2189                );
2190            VelocityResponseCurveScaling = scaling;
2191        }
2192    
2193        /**
2194         * Updates the respective member variable and the lookup table / cache
2195         * that depends on this value.
2196         */
2197        void DimensionRegion::SetReleaseVelocityResponseCurve(curve_type_t curve) {
2198            pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
2199            ReleaseVelocityResponseCurve = curve;
2200        }
2201    
2202        /**
2203         * Updates the respective member variable and the lookup table / cache
2204         * that depends on this value.
2205         */
2206        void DimensionRegion::SetReleaseVelocityResponseDepth(uint8_t depth) {
2207            pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
2208            ReleaseVelocityResponseDepth = depth;
2209        }
2210    
2211        /**
2212         * Updates the respective member variable and the lookup table / cache
2213         * that depends on this value.
2214         */
2215        void DimensionRegion::SetVCFCutoffController(vcf_cutoff_ctrl_t controller) {
2216            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
2217            VCFCutoffController = controller;
2218        }
2219    
2220        /**
2221         * Updates the respective member variable and the lookup table / cache
2222         * that depends on this value.
2223         */
2224        void DimensionRegion::SetVCFVelocityCurve(curve_type_t curve) {
2225            pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
2226            VCFVelocityCurve = curve;
2227        }
2228    
2229        /**
2230         * Updates the respective member variable and the lookup table / cache
2231         * that depends on this value.
2232         */
2233        void DimensionRegion::SetVCFVelocityDynamicRange(uint8_t range) {
2234            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
2235            VCFVelocityDynamicRange = range;
2236        }
2237    
2238        /**
2239         * Updates the respective member variable and the lookup table / cache
2240         * that depends on this value.
2241         */
2242        void DimensionRegion::SetVCFVelocityScale(uint8_t scaling) {
2243            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
2244            VCFVelocityScale = scaling;
2245        }
2246    
2247      double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {      double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
2248    
2249          // line-segment approximations of the 15 velocity curves          // line-segment approximations of the 15 velocity curves
# Line 2273  namespace { Line 2390  namespace {
2390              RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);              RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
2391              if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);              if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
2392              RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);              RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
2393              pDimensionRegions[0] = new DimensionRegion(_3ewl);              pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
2394              DimensionRegions = 1;              DimensionRegions = 1;
2395          }          }
2396      }      }
# Line 2297  namespace { Line 2414  namespace {
2414          // first update base class's chunks          // first update base class's chunks
2415          DLS::Region::UpdateChunks();          DLS::Region::UpdateChunks();
2416    
         File* pFile = (File*) GetParent()->GetParent();  
         bool version3 = pFile->pVersion && pFile->pVersion->major == 3;  
   
2417          // update dimension region's chunks          // update dimension region's chunks
2418          for (int i = 0; i < DimensionRegions; i++) {          for (int i = 0; i < DimensionRegions; i++) {
2419              DimensionRegion* d = pDimensionRegions[i];              pDimensionRegions[i]->UpdateChunks();
   
             // make sure '3ewa' chunk exists (we need to this before  
             // calling DimensionRegion::UpdateChunks, as  
             // DimensionRegion doesn't know which file version it is)  
             RIFF::Chunk* _3ewa = d->pParentList->GetSubChunk(CHUNK_ID_3EWA);  
             if (!_3ewa) d->pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);  
   
             d->UpdateChunks();  
2420          }          }
2421    
2422            File* pFile = (File*) GetParent()->GetParent();
2423            bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
2424          const int iMaxDimensions =  version3 ? 8 : 5;          const int iMaxDimensions =  version3 ? 8 : 5;
2425          const int iMaxDimensionRegions = version3 ? 256 : 32;          const int iMaxDimensionRegions = version3 ? 256 : 32;
2426    
# Line 2368  namespace { Line 2476  namespace {
2476              RIFF::List* _3ewl = _3prg->GetFirstSubList();              RIFF::List* _3ewl = _3prg->GetFirstSubList();
2477              while (_3ewl) {              while (_3ewl) {
2478                  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {                  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
2479                      pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);                      pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
2480                      dimensionRegionNr++;                      dimensionRegionNr++;
2481                  }                  }
2482                  _3ewl = _3prg->GetNextSubList();                  _3ewl = _3prg->GetNextSubList();
# Line 2377  namespace { Line 2485  namespace {
2485          }          }
2486      }      }
2487    
2488        void Region::SetKeyRange(uint16_t Low, uint16_t High) {
2489            // update KeyRange struct and make sure regions are in correct order
2490            DLS::Region::SetKeyRange(Low, High);
2491            // update Region key table for fast lookup
2492            ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
2493        }
2494    
2495      void Region::UpdateVelocityTable() {      void Region::UpdateVelocityTable() {
2496          // get velocity dimension's index          // get velocity dimension's index
2497          int veldim = -1;          int veldim = -1;
# Line 2816  namespace { Line 2931  namespace {
2931      }      }
2932    
2933      void Instrument::UpdateRegionKeyTable() {      void Instrument::UpdateRegionKeyTable() {
2934            for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
2935          RegionList::iterator iter = pRegions->begin();          RegionList::iterator iter = pRegions->begin();
2936          RegionList::iterator end  = pRegions->end();          RegionList::iterator end  = pRegions->end();
2937          for (; iter != end; ++iter) {          for (; iter != end; ++iter) {
# Line 2883  namespace { Line 2999  namespace {
2999       *             there is no Region defined for the given \a Key       *             there is no Region defined for the given \a Key
3000       */       */
3001      Region* Instrument::GetRegion(unsigned int Key) {      Region* Instrument::GetRegion(unsigned int Key) {
3002          if (!pRegions || !pRegions->size() || Key > 127) return NULL;          if (!pRegions || pRegions->empty() || Key > 127) return NULL;
3003          return RegionKeyTable[Key];          return RegionKeyTable[Key];
3004    
3005          /*for (int i = 0; i < Regions; i++) {          /*for (int i = 0; i < Regions; i++) {

Legend:
Removed from v.1301  
changed lines
  Added in v.1358

  ViewVC Help
Powered by ViewVC