/[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 1113 by schoenebeck, Fri Mar 23 20:05:02 2007 UTC revision 2547 by schoenebeck, Tue May 13 11:17:24 2014 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file access library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2007 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2014 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
# Line 25  Line 25 
25    
26  #include "helper.h"  #include "helper.h"
27    
28    #include <algorithm>
29  #include <math.h>  #include <math.h>
30  #include <iostream>  #include <iostream>
31    
# Line 255  namespace { Line 256  namespace {
256    
257    
258    
259    // *************** Internal CRC-32 (Cyclic Redundancy Check) functions  ***************
260    // *
261    
262        static uint32_t* __initCRCTable() {
263            static uint32_t res[256];
264    
265            for (int i = 0 ; i < 256 ; i++) {
266                uint32_t c = i;
267                for (int j = 0 ; j < 8 ; j++) {
268                    c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
269                }
270                res[i] = c;
271            }
272            return res;
273        }
274    
275        static const uint32_t* __CRCTable = __initCRCTable();
276    
277        /**
278         * Initialize a CRC variable.
279         *
280         * @param crc - variable to be initialized
281         */
282        inline static void __resetCRC(uint32_t& crc) {
283            crc = 0xffffffff;
284        }
285    
286        /**
287         * Used to calculate checksums of the sample data in a gig file. The
288         * checksums are stored in the 3crc chunk of the gig file and
289         * automatically updated when a sample is written with Sample::Write().
290         *
291         * One should call __resetCRC() to initialize the CRC variable to be
292         * used before calling this function the first time.
293         *
294         * After initializing the CRC variable one can call this function
295         * arbitrary times, i.e. to split the overall CRC calculation into
296         * steps.
297         *
298         * Once the whole data was processed by __calculateCRC(), one should
299         * call __encodeCRC() to get the final CRC result.
300         *
301         * @param buf     - pointer to data the CRC shall be calculated of
302         * @param bufSize - size of the data to be processed
303         * @param crc     - variable the CRC sum shall be stored to
304         */
305        static void __calculateCRC(unsigned char* buf, int bufSize, uint32_t& crc) {
306            for (int i = 0 ; i < bufSize ; i++) {
307                crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
308            }
309        }
310    
311        /**
312         * Returns the final CRC result.
313         *
314         * @param crc - variable previously passed to __calculateCRC()
315         */
316        inline static uint32_t __encodeCRC(const uint32_t& crc) {
317            return crc ^ 0xffffffff;
318        }
319    
320    
321    
322  // *************** Other Internal functions  ***************  // *************** Other Internal functions  ***************
323  // *  // *
324    
# Line 303  namespace { Line 367  namespace {
367       *                         is located, 0 otherwise       *                         is located, 0 otherwise
368       */       */
369      Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {      Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
370          pInfo->UseFixedLengthStrings = true;          static const DLS::Info::string_length_t fixedStringLengths[] = {
371                { CHUNK_ID_INAM, 64 },
372                { 0, 0 }
373            };
374            pInfo->SetFixedStringLengths(fixedStringLengths);
375          Instances++;          Instances++;
376          FileNo = fileNo;          FileNo = fileNo;
377    
378            __resetCRC(crc);
379    
380          pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);          pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
381          if (pCk3gix) {          if (pCk3gix) {
382              uint16_t iSampleGroup = pCk3gix->ReadInt16();              uint16_t iSampleGroup = pCk3gix->ReadInt16();
# Line 338  namespace { Line 408  namespace {
408              Manufacturer  = 0;              Manufacturer  = 0;
409              Product       = 0;              Product       = 0;
410              SamplePeriod  = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);              SamplePeriod  = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
411              MIDIUnityNote = 64;              MIDIUnityNote = 60;
412              FineTune      = 0;              FineTune      = 0;
413                SMPTEFormat   = smpte_format_no_offset;
414              SMPTEOffset   = 0;              SMPTEOffset   = 0;
415              Loops         = 0;              Loops         = 0;
416              LoopID        = 0;              LoopID        = 0;
417                LoopType      = loop_type_normal;
418              LoopStart     = 0;              LoopStart     = 0;
419              LoopEnd       = 0;              LoopEnd       = 0;
420              LoopFraction  = 0;              LoopFraction  = 0;
# Line 382  namespace { Line 454  namespace {
454      }      }
455    
456      /**      /**
457         * Make a (semi) deep copy of the Sample object given by @a orig (without
458         * the actual waveform data) and assign it to this object.
459         *
460         * Discussion: copying .gig samples is a bit tricky. It requires three
461         * steps:
462         * 1. Copy sample's meta informations (done by CopyAssignMeta()) including
463         *    its new sample waveform data size.
464         * 2. Saving the file (done by File::Save()) so that it gains correct size
465         *    and layout for writing the actual wave form data directly to disc
466         *    in next step.
467         * 3. Copy the waveform data with disk streaming (done by CopyAssignWave()).
468         *
469         * @param orig - original Sample object to be copied from
470         */
471        void Sample::CopyAssignMeta(const Sample* orig) {
472            // handle base classes
473            DLS::Sample::CopyAssignCore(orig);
474            
475            // handle actual own attributes of this class
476            Manufacturer = orig->Manufacturer;
477            Product = orig->Product;
478            SamplePeriod = orig->SamplePeriod;
479            MIDIUnityNote = orig->MIDIUnityNote;
480            FineTune = orig->FineTune;
481            SMPTEFormat = orig->SMPTEFormat;
482            SMPTEOffset = orig->SMPTEOffset;
483            Loops = orig->Loops;
484            LoopID = orig->LoopID;
485            LoopType = orig->LoopType;
486            LoopStart = orig->LoopStart;
487            LoopEnd = orig->LoopEnd;
488            LoopSize = orig->LoopSize;
489            LoopFraction = orig->LoopFraction;
490            LoopPlayCount = orig->LoopPlayCount;
491            
492            // schedule resizing this sample to the given sample's size
493            Resize(orig->GetSize());
494        }
495    
496        /**
497         * Should be called after CopyAssignMeta() and File::Save() sequence.
498         * Read more about it in the discussion of CopyAssignMeta(). This method
499         * copies the actual waveform data by disk streaming.
500         *
501         * @e CAUTION: this method is currently not thread safe! During this
502         * operation the sample must not be used for other purposes by other
503         * threads!
504         *
505         * @param orig - original Sample object to be copied from
506         */
507        void Sample::CopyAssignWave(const Sample* orig) {
508            const int iReadAtOnce = 32*1024;
509            char* buf = new char[iReadAtOnce * orig->FrameSize];
510            Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
511            unsigned long restorePos = pOrig->GetPos();
512            pOrig->SetPos(0);
513            SetPos(0);
514            for (unsigned long n = pOrig->Read(buf, iReadAtOnce); n;
515                               n = pOrig->Read(buf, iReadAtOnce))
516            {
517                Write(buf, n);
518            }
519            pOrig->SetPos(restorePos);
520            delete [] buf;
521        }
522    
523        /**
524       * Apply sample and its settings to the respective RIFF chunks. You have       * Apply sample and its settings to the respective RIFF chunks. You have
525       * to call File::Save() to make changes persistent.       * to call File::Save() to make changes persistent.
526       *       *
# Line 398  namespace { Line 537  namespace {
537    
538          // make sure 'smpl' chunk exists          // make sure 'smpl' chunk exists
539          pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);          pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
540          if (!pCkSmpl) pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);          if (!pCkSmpl) {
541                pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
542                memset(pCkSmpl->LoadChunkData(), 0, 60);
543            }
544          // update 'smpl' chunk          // update 'smpl' chunk
545          uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();          uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
546          SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);          SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
547          memcpy(&pData[0], &Manufacturer, 4);          store32(&pData[0], Manufacturer);
548          memcpy(&pData[4], &Product, 4);          store32(&pData[4], Product);
549          memcpy(&pData[8], &SamplePeriod, 4);          store32(&pData[8], SamplePeriod);
550          memcpy(&pData[12], &MIDIUnityNote, 4);          store32(&pData[12], MIDIUnityNote);
551          memcpy(&pData[16], &FineTune, 4);          store32(&pData[16], FineTune);
552          memcpy(&pData[20], &SMPTEFormat, 4);          store32(&pData[20], SMPTEFormat);
553          memcpy(&pData[24], &SMPTEOffset, 4);          store32(&pData[24], SMPTEOffset);
554          memcpy(&pData[28], &Loops, 4);          store32(&pData[28], Loops);
555    
556          // we skip 'manufByt' for now (4 bytes)          // we skip 'manufByt' for now (4 bytes)
557    
558          memcpy(&pData[36], &LoopID, 4);          store32(&pData[36], LoopID);
559          memcpy(&pData[40], &LoopType, 4);          store32(&pData[40], LoopType);
560          memcpy(&pData[44], &LoopStart, 4);          store32(&pData[44], LoopStart);
561          memcpy(&pData[48], &LoopEnd, 4);          store32(&pData[48], LoopEnd);
562          memcpy(&pData[52], &LoopFraction, 4);          store32(&pData[52], LoopFraction);
563          memcpy(&pData[56], &LoopPlayCount, 4);          store32(&pData[56], LoopPlayCount);
564    
565          // make sure '3gix' chunk exists          // make sure '3gix' chunk exists
566          pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);          pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
# Line 438  namespace { Line 580  namespace {
580          }          }
581          // update '3gix' chunk          // update '3gix' chunk
582          pData = (uint8_t*) pCk3gix->LoadChunkData();          pData = (uint8_t*) pCk3gix->LoadChunkData();
583          memcpy(&pData[0], &iSampleGroup, 2);          store16(&pData[0], iSampleGroup);
584    
585            // if the library user toggled the "Compressed" attribute from true to
586            // false, then the EWAV chunk associated with compressed samples needs
587            // to be deleted
588            RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
589            if (ewav && !Compressed) {
590                pWaveList->DeleteSubChunk(ewav);
591            }
592      }      }
593    
594      /// 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 602  namespace { Line 752  namespace {
752          if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;          if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
753          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
754          unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;          unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
755            SetPos(0); // reset read position to begin of sample
756          RAMCache.pStart            = new int8_t[allocationsize];          RAMCache.pStart            = new int8_t[allocationsize];
757          RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;          RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
758          RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;          RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
# Line 639  namespace { Line 790  namespace {
790          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
791          RAMCache.pStart = NULL;          RAMCache.pStart = NULL;
792          RAMCache.Size   = 0;          RAMCache.Size   = 0;
793            RAMCache.NullExtensionSize = 0;
794      }      }
795    
796      /** @brief Resize sample.      /** @brief Resize sample.
# Line 731  namespace { Line 883  namespace {
883      /**      /**
884       * Returns the current position in the sample (in sample points).       * Returns the current position in the sample (in sample points).
885       */       */
886      unsigned long Sample::GetPos() {      unsigned long Sample::GetPos() const {
887          if (Compressed) return SamplePos;          if (Compressed) return SamplePos;
888          else            return pCkData->GetPos() / FrameSize;          else            return pCkData->GetPos() / FrameSize;
889      }      }
# Line 833  namespace { Line 985  namespace {
985                                  }                                  }
986    
987                                  // reverse the sample frames for backward playback                                  // reverse the sample frames for backward playback
988                                  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);                                  if (totalreadsamples > swapareastart) //FIXME: this if() is just a crash workaround for now (#102), but totalreadsamples <= swapareastart should never be the case, so there's probably still a bug above!
989                                        SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
990                              }                              }
991                          } while (samplestoread && readsamples);                          } while (samplestoread && readsamples);
992                          break;                          break;
# Line 1123  namespace { Line 1276  namespace {
1276       *       *
1277       * Note: there is currently no support for writing compressed samples.       * Note: there is currently no support for writing compressed samples.
1278       *       *
1279         * For 16 bit samples, the data in the source buffer should be
1280         * int16_t (using native endianness). For 24 bit, the buffer
1281         * should contain three bytes per sample, little-endian.
1282         *
1283       * @param pBuffer     - source buffer       * @param pBuffer     - source buffer
1284       * @param SampleCount - number of sample points to write       * @param SampleCount - number of sample points to write
1285       * @throws DLS::Exception if current sample size is too small       * @throws DLS::Exception if current sample size is too small
# Line 1131  namespace { Line 1288  namespace {
1288       */       */
1289      unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {      unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
1290          if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");          if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1291          return DLS::Sample::Write(pBuffer, SampleCount);  
1292            // if this is the first write in this sample, reset the
1293            // checksum calculator
1294            if (pCkData->GetPos() == 0) {
1295                __resetCRC(crc);
1296            }
1297            if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1298            unsigned long res;
1299            if (BitDepth == 24) {
1300                res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1301            } else { // 16 bit
1302                res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1303                                    : pCkData->Write(pBuffer, SampleCount, 2);
1304            }
1305            __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1306    
1307            // if this is the last write, update the checksum chunk in the
1308            // file
1309            if (pCkData->GetPos() == pCkData->GetSize()) {
1310                File* pFile = static_cast<File*>(GetParent());
1311                pFile->SetSampleChecksum(this, __encodeCRC(crc));
1312            }
1313            return res;
1314      }      }
1315    
1316      /**      /**
# Line 1207  namespace { Line 1386  namespace {
1386      uint                               DimensionRegion::Instances       = 0;      uint                               DimensionRegion::Instances       = 0;
1387      DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;      DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1388    
1389      DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1390          Instances++;          Instances++;
1391    
1392          pSample = NULL;          pSample = NULL;
1393            pRegion = pParent;
1394    
1395            if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1396            else memset(&Crossfade, 0, 4);
1397    
         memcpy(&Crossfade, &SamplerOptions, 4);  
1398          if (!pVelocityTables) pVelocityTables = new VelocityTableMap;          if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1399    
1400          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);          RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
# Line 1326  namespace { Line 1508  namespace {
1508                                                          : vcf_res_ctrl_none;                                                          : vcf_res_ctrl_none;
1509              uint16_t eg3depth = _3ewa->ReadUint16();              uint16_t eg3depth = _3ewa->ReadUint16();
1510              EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */              EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1511                                          : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */                                          : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1512              _3ewa->ReadInt16(); // unknown              _3ewa->ReadInt16(); // unknown
1513              ChannelOffset = _3ewa->ReadUint8() / 4;              ChannelOffset = _3ewa->ReadUint8() / 4;
1514              uint8_t regoptions = _3ewa->ReadUint8();              uint8_t regoptions = _3ewa->ReadUint8();
# Line 1376  namespace { Line 1558  namespace {
1558              LFO1ControlDepth                = 0;              LFO1ControlDepth                = 0;
1559              LFO3ControlDepth                = 0;              LFO3ControlDepth                = 0;
1560              EG1Attack                       = 0.0;              EG1Attack                       = 0.0;
1561              EG1Decay1                       = 0.0;              EG1Decay1                       = 0.005;
1562              EG1Sustain                      = 0;              EG1Sustain                      = 1000;
1563              EG1Release                      = 0.0;              EG1Release                      = 0.3;
1564              EG1Controller.type              = eg1_ctrl_t::type_none;              EG1Controller.type              = eg1_ctrl_t::type_none;
1565              EG1Controller.controller_number = 0;              EG1Controller.controller_number = 0;
1566              EG1ControllerInvert             = false;              EG1ControllerInvert             = false;
# Line 1393  namespace { Line 1575  namespace {
1575              EG2ControllerReleaseInfluence   = 0;              EG2ControllerReleaseInfluence   = 0;
1576              LFO1Frequency                   = 1.0;              LFO1Frequency                   = 1.0;
1577              EG2Attack                       = 0.0;              EG2Attack                       = 0.0;
1578              EG2Decay1                       = 0.0;              EG2Decay1                       = 0.005;
1579              EG2Sustain                      = 0;              EG2Sustain                      = 1000;
1580              EG2Release                      = 0.0;              EG2Release                      = 0.3;
1581              LFO2ControlDepth                = 0;              LFO2ControlDepth                = 0;
1582              LFO2Frequency                   = 1.0;              LFO2Frequency                   = 1.0;
1583              LFO2InternalDepth               = 0;              LFO2InternalDepth               = 0;
1584              EG1Decay2                       = 0.0;              EG1Decay2                       = 0.0;
1585              EG1InfiniteSustain              = false;              EG1InfiniteSustain              = true;
1586              EG1PreAttack                    = 1000;              EG1PreAttack                    = 0;
1587              EG2Decay2                       = 0.0;              EG2Decay2                       = 0.0;
1588              EG2InfiniteSustain              = false;              EG2InfiniteSustain              = true;
1589              EG2PreAttack                    = 1000;              EG2PreAttack                    = 0;
1590              VelocityResponseCurve           = curve_type_nonlinear;              VelocityResponseCurve           = curve_type_nonlinear;
1591              VelocityResponseDepth           = 3;              VelocityResponseDepth           = 3;
1592              ReleaseVelocityResponseCurve    = curve_type_nonlinear;              ReleaseVelocityResponseCurve    = curve_type_nonlinear;
# Line 1447  namespace { Line 1629  namespace {
1629              VCFVelocityDynamicRange         = 0x04;              VCFVelocityDynamicRange         = 0x04;
1630              VCFVelocityCurve                = curve_type_linear;              VCFVelocityCurve                = curve_type_linear;
1631              VCFType                         = vcf_type_lowpass;              VCFType                         = vcf_type_lowpass;
1632              memset(DimensionUpperLimits, 0, 8);              memset(DimensionUpperLimits, 127, 8);
1633          }          }
1634    
1635          pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,          pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1636                                                       VelocityResponseDepth,                                                       VelocityResponseDepth,
1637                                                       VelocityResponseCurveScaling);                                                       VelocityResponseCurveScaling);
1638    
1639          curve_type_t curveType = ReleaseVelocityResponseCurve;          pVelocityReleaseTable = GetReleaseVelocityTable(
1640          uint8_t depth = ReleaseVelocityResponseDepth;                                      ReleaseVelocityResponseCurve,
1641                                        ReleaseVelocityResponseDepth
1642                                    );
1643    
1644            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1645                                                          VCFVelocityDynamicRange,
1646                                                          VCFVelocityScale,
1647                                                          VCFCutoffController);
1648    
1649          // this models a strange behaviour or bug in GSt: two of the          SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1650          // velocity response curves for release time are not used even          VelocityTable = 0;
1651          // if specified, instead another curve is chosen.      }
         if ((curveType == curve_type_nonlinear && depth == 0) ||  
             (curveType == curve_type_special   && depth == 4)) {  
             curveType = curve_type_nonlinear;  
             depth = 3;  
         }  
         pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);  
1652    
1653          curveType = VCFVelocityCurve;      /*
1654          depth = VCFVelocityDynamicRange;       * Constructs a DimensionRegion by copying all parameters from
1655         * another DimensionRegion
1656         */
1657        DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1658            Instances++;
1659            //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1660            *this = src; // default memberwise shallow copy of all parameters
1661            pParentList = _3ewl; // restore the chunk pointer
1662    
1663            // deep copy of owned structures
1664            if (src.VelocityTable) {
1665                VelocityTable = new uint8_t[128];
1666                for (int k = 0 ; k < 128 ; k++)
1667                    VelocityTable[k] = src.VelocityTable[k];
1668            }
1669            if (src.pSampleLoops) {
1670                pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1671                for (int k = 0 ; k < src.SampleLoops ; k++)
1672                    pSampleLoops[k] = src.pSampleLoops[k];
1673            }
1674        }
1675        
1676        /**
1677         * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1678         * and assign it to this object.
1679         *
1680         * Note that all sample pointers referenced by @a orig are simply copied as
1681         * memory address. Thus the respective samples are shared, not duplicated!
1682         *
1683         * @param orig - original DimensionRegion object to be copied from
1684         */
1685        void DimensionRegion::CopyAssign(const DimensionRegion* orig) {
1686            CopyAssign(orig, NULL);
1687        }
1688    
1689          // even stranger GSt: two of the velocity response curves for      /**
1690          // filter cutoff are not used, instead another special curve       * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1691          // is chosen. This curve is not used anywhere else.       * and assign it to this object.
1692          if ((curveType == curve_type_nonlinear && depth == 0) ||       *
1693              (curveType == curve_type_special   && depth == 4)) {       * @param orig - original DimensionRegion object to be copied from
1694              curveType = curve_type_special;       * @param mSamples - crosslink map between the foreign file's samples and
1695              depth = 5;       *                   this file's samples
1696         */
1697        void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1698            // delete all allocated data first
1699            if (VelocityTable) delete [] VelocityTable;
1700            if (pSampleLoops) delete [] pSampleLoops;
1701            
1702            // backup parent list pointer
1703            RIFF::List* p = pParentList;
1704            
1705            gig::Sample* pOriginalSample = pSample;
1706            gig::Region* pOriginalRegion = pRegion;
1707            
1708            //NOTE: copy code copied from assignment constructor above, see comment there as well
1709            
1710            *this = *orig; // default memberwise shallow copy of all parameters
1711            
1712            // restore members that shall not be altered
1713            pParentList = p; // restore the chunk pointer
1714            pRegion = pOriginalRegion;
1715            
1716            // only take the raw sample reference reference if the
1717            // two DimensionRegion objects are part of the same file
1718            if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1719                pSample = pOriginalSample;
1720            }
1721            
1722            if (mSamples && mSamples->count(orig->pSample)) {
1723                pSample = mSamples->find(orig->pSample)->second;
1724            }
1725    
1726            // deep copy of owned structures
1727            if (orig->VelocityTable) {
1728                VelocityTable = new uint8_t[128];
1729                for (int k = 0 ; k < 128 ; k++)
1730                    VelocityTable[k] = orig->VelocityTable[k];
1731            }
1732            if (orig->pSampleLoops) {
1733                pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops];
1734                for (int k = 0 ; k < orig->SampleLoops ; k++)
1735                    pSampleLoops[k] = orig->pSampleLoops[k];
1736          }          }
1737          pVelocityCutoffTable = GetVelocityTable(curveType, depth,      }
                                                 VCFCutoffController <= vcf_cutoff_ctrl_none2 ? VCFVelocityScale : 0);  
1738    
1739        /**
1740         * Updates the respective member variable and updates @c SampleAttenuation
1741         * which depends on this value.
1742         */
1743        void DimensionRegion::SetGain(int32_t gain) {
1744            DLS::Sampler::SetGain(gain);
1745          SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));          SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
         VelocityTable = 0;  
1746      }      }
1747    
1748      /**      /**
# Line 1496  namespace { Line 1756  namespace {
1756          // first update base class's chunk          // first update base class's chunk
1757          DLS::Sampler::UpdateChunks();          DLS::Sampler::UpdateChunks();
1758    
1759            RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1760            uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1761            pData[12] = Crossfade.in_start;
1762            pData[13] = Crossfade.in_end;
1763            pData[14] = Crossfade.out_start;
1764            pData[15] = Crossfade.out_end;
1765    
1766          // make sure '3ewa' chunk exists          // make sure '3ewa' chunk exists
1767          RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);          RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1768          if (!_3ewa)  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, 140);          if (!_3ewa) {
1769          uint8_t* pData = (uint8_t*) _3ewa->LoadChunkData();              File* pFile = (File*) GetParent()->GetParent()->GetParent();
1770                bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1771                _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1772            }
1773            pData = (uint8_t*) _3ewa->LoadChunkData();
1774    
1775          // update '3ewa' chunk with DimensionRegion's current settings          // update '3ewa' chunk with DimensionRegion's current settings
1776    
1777          const uint32_t chunksize = _3ewa->GetSize();          const uint32_t chunksize = _3ewa->GetNewSize();
1778          memcpy(&pData[0], &chunksize, 4); // unknown, always chunk size?          store32(&pData[0], chunksize); // unknown, always chunk size?
1779    
1780          const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);          const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1781          memcpy(&pData[4], &lfo3freq, 4);          store32(&pData[4], lfo3freq);
1782    
1783          const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);          const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1784          memcpy(&pData[8], &eg3attack, 4);          store32(&pData[8], eg3attack);
1785    
1786          // next 2 bytes unknown          // next 2 bytes unknown
1787    
1788          memcpy(&pData[14], &LFO1InternalDepth, 2);          store16(&pData[14], LFO1InternalDepth);
1789    
1790          // next 2 bytes unknown          // next 2 bytes unknown
1791    
1792          memcpy(&pData[18], &LFO3InternalDepth, 2);          store16(&pData[18], LFO3InternalDepth);
1793    
1794          // next 2 bytes unknown          // next 2 bytes unknown
1795    
1796          memcpy(&pData[22], &LFO1ControlDepth, 2);          store16(&pData[22], LFO1ControlDepth);
1797    
1798          // next 2 bytes unknown          // next 2 bytes unknown
1799    
1800          memcpy(&pData[26], &LFO3ControlDepth, 2);          store16(&pData[26], LFO3ControlDepth);
1801    
1802          const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);          const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
1803          memcpy(&pData[28], &eg1attack, 4);          store32(&pData[28], eg1attack);
1804    
1805          const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);          const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
1806          memcpy(&pData[32], &eg1decay1, 4);          store32(&pData[32], eg1decay1);
1807    
1808          // next 2 bytes unknown          // next 2 bytes unknown
1809    
1810          memcpy(&pData[38], &EG1Sustain, 2);          store16(&pData[38], EG1Sustain);
1811    
1812          const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);          const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
1813          memcpy(&pData[40], &eg1release, 4);          store32(&pData[40], eg1release);
1814    
1815          const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);          const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
1816          memcpy(&pData[44], &eg1ctl, 1);          pData[44] = eg1ctl;
1817    
1818          const uint8_t eg1ctrloptions =          const uint8_t eg1ctrloptions =
1819              (EG1ControllerInvert) ? 0x01 : 0x00 |              (EG1ControllerInvert ? 0x01 : 0x00) |
1820              GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |              GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
1821              GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |              GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
1822              GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);              GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
1823          memcpy(&pData[45], &eg1ctrloptions, 1);          pData[45] = eg1ctrloptions;
1824    
1825          const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);          const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
1826          memcpy(&pData[46], &eg2ctl, 1);          pData[46] = eg2ctl;
1827    
1828          const uint8_t eg2ctrloptions =          const uint8_t eg2ctrloptions =
1829              (EG2ControllerInvert) ? 0x01 : 0x00 |              (EG2ControllerInvert ? 0x01 : 0x00) |
1830              GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |              GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
1831              GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |              GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
1832              GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);              GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
1833          memcpy(&pData[47], &eg2ctrloptions, 1);          pData[47] = eg2ctrloptions;
1834    
1835          const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);          const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
1836          memcpy(&pData[48], &lfo1freq, 4);          store32(&pData[48], lfo1freq);
1837    
1838          const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);          const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
1839          memcpy(&pData[52], &eg2attack, 4);          store32(&pData[52], eg2attack);
1840    
1841          const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);          const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
1842          memcpy(&pData[56], &eg2decay1, 4);          store32(&pData[56], eg2decay1);
1843    
1844          // next 2 bytes unknown          // next 2 bytes unknown
1845    
1846          memcpy(&pData[62], &EG2Sustain, 2);          store16(&pData[62], EG2Sustain);
1847    
1848          const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);          const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
1849          memcpy(&pData[64], &eg2release, 4);          store32(&pData[64], eg2release);
1850    
1851          // next 2 bytes unknown          // next 2 bytes unknown
1852    
1853          memcpy(&pData[70], &LFO2ControlDepth, 2);          store16(&pData[70], LFO2ControlDepth);
1854    
1855          const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);          const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
1856          memcpy(&pData[72], &lfo2freq, 4);          store32(&pData[72], lfo2freq);
1857    
1858          // next 2 bytes unknown          // next 2 bytes unknown
1859    
1860          memcpy(&pData[78], &LFO2InternalDepth, 2);          store16(&pData[78], LFO2InternalDepth);
1861    
1862          const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);          const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
1863          memcpy(&pData[80], &eg1decay2, 4);          store32(&pData[80], eg1decay2);
1864    
1865          // next 2 bytes unknown          // next 2 bytes unknown
1866    
1867          memcpy(&pData[86], &EG1PreAttack, 2);          store16(&pData[86], EG1PreAttack);
1868    
1869          const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);          const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
1870          memcpy(&pData[88], &eg2decay2, 4);          store32(&pData[88], eg2decay2);
1871    
1872          // next 2 bytes unknown          // next 2 bytes unknown
1873    
1874          memcpy(&pData[94], &EG2PreAttack, 2);          store16(&pData[94], EG2PreAttack);
1875    
1876          {          {
1877              if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");              if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
# Line 1618  namespace { Line 1889  namespace {
1889                  default:                  default:
1890                      throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");                      throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
1891              }              }
1892              memcpy(&pData[96], &velocityresponse, 1);              pData[96] = velocityresponse;
1893          }          }
1894    
1895          {          {
# Line 1637  namespace { Line 1908  namespace {
1908                  default:                  default:
1909                      throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");                      throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
1910              }              }
1911              memcpy(&pData[97], &releasevelocityresponse, 1);              pData[97] = releasevelocityresponse;
1912          }          }
1913    
1914          memcpy(&pData[98], &VelocityResponseCurveScaling, 1);          pData[98] = VelocityResponseCurveScaling;
1915    
1916          memcpy(&pData[99], &AttenuationControllerThreshold, 1);          pData[99] = AttenuationControllerThreshold;
1917    
1918          // next 4 bytes unknown          // next 4 bytes unknown
1919    
1920          memcpy(&pData[104], &SampleStartOffset, 2);          store16(&pData[104], SampleStartOffset);
1921    
1922          // next 2 bytes unknown          // next 2 bytes unknown
1923    
# Line 1665  namespace { Line 1936  namespace {
1936                  default:                  default:
1937                      throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");                      throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
1938              }              }
1939              memcpy(&pData[108], &pitchTrackDimensionBypass, 1);              pData[108] = pitchTrackDimensionBypass;
1940          }          }
1941    
1942          const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit          const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
1943          memcpy(&pData[109], &pan, 1);          pData[109] = pan;
1944    
1945          const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;          const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
1946          memcpy(&pData[110], &selfmask, 1);          pData[110] = selfmask;
1947    
1948          // next byte unknown          // next byte unknown
1949    
# Line 1681  namespace { Line 1952  namespace {
1952              if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5              if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
1953              if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7              if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
1954              if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6              if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
1955              memcpy(&pData[112], &lfo3ctrl, 1);              pData[112] = lfo3ctrl;
1956          }          }
1957    
1958          const uint8_t attenctl = EncodeLeverageController(AttenuationController);          const uint8_t attenctl = EncodeLeverageController(AttenuationController);
1959          memcpy(&pData[113], &attenctl, 1);          pData[113] = attenctl;
1960    
1961          {          {
1962              uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits              uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
1963              if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7              if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
1964              if (LFO2Sync)      lfo2ctrl |= 0x20; // bit 5              if (LFO2Sync)      lfo2ctrl |= 0x20; // bit 5
1965              if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6              if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
1966              memcpy(&pData[114], &lfo2ctrl, 1);              pData[114] = lfo2ctrl;
1967          }          }
1968    
1969          {          {
# Line 1701  namespace { Line 1972  namespace {
1972              if (LFO1Sync)      lfo1ctrl |= 0x40; // bit 6              if (LFO1Sync)      lfo1ctrl |= 0x40; // bit 6
1973              if (VCFResonanceController != vcf_res_ctrl_none)              if (VCFResonanceController != vcf_res_ctrl_none)
1974                  lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);                  lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
1975              memcpy(&pData[115], &lfo1ctrl, 1);              pData[115] = lfo1ctrl;
1976          }          }
1977    
1978          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1979                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
1980          memcpy(&pData[116], &eg3depth, 1);          store16(&pData[116], eg3depth);
1981    
1982          // next 2 bytes unknown          // next 2 bytes unknown
1983    
1984          const uint8_t channeloffset = ChannelOffset * 4;          const uint8_t channeloffset = ChannelOffset * 4;
1985          memcpy(&pData[120], &channeloffset, 1);          pData[120] = channeloffset;
1986    
1987          {          {
1988              uint8_t regoptions = 0;              uint8_t regoptions = 0;
1989              if (MSDecode)      regoptions |= 0x01; // bit 0              if (MSDecode)      regoptions |= 0x01; // bit 0
1990              if (SustainDefeat) regoptions |= 0x02; // bit 1              if (SustainDefeat) regoptions |= 0x02; // bit 1
1991              memcpy(&pData[121], &regoptions, 1);              pData[121] = regoptions;
1992          }          }
1993    
1994          // next 2 bytes unknown          // next 2 bytes unknown
1995    
1996          memcpy(&pData[124], &VelocityUpperLimit, 1);          pData[124] = VelocityUpperLimit;
1997    
1998          // next 3 bytes unknown          // next 3 bytes unknown
1999    
2000          memcpy(&pData[128], &ReleaseTriggerDecay, 1);          pData[128] = ReleaseTriggerDecay;
2001    
2002          // next 2 bytes unknown          // next 2 bytes unknown
2003    
2004          const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7          const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
2005          memcpy(&pData[131], &eg1hold, 1);          pData[131] = eg1hold;
2006    
2007          const uint8_t vcfcutoff = (VCFEnabled) ? 0x80 : 0x00 |  /* bit 7 */          const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) |  /* bit 7 */
2008                                    (VCFCutoff & 0x7f);   /* lower 7 bits */                                    (VCFCutoff & 0x7f);   /* lower 7 bits */
2009          memcpy(&pData[132], &vcfcutoff, 1);          pData[132] = vcfcutoff;
2010    
2011          memcpy(&pData[133], &VCFCutoffController, 1);          pData[133] = VCFCutoffController;
2012    
2013          const uint8_t vcfvelscale = (VCFCutoffControllerInvert) ? 0x80 : 0x00 | /* bit 7 */          const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
2014                                      (VCFVelocityScale & 0x7f); /* lower 7 bits */                                      (VCFVelocityScale & 0x7f); /* lower 7 bits */
2015          memcpy(&pData[134], &vcfvelscale, 1);          pData[134] = vcfvelscale;
2016    
2017          // next byte unknown          // next byte unknown
2018    
2019          const uint8_t vcfresonance = (VCFResonanceDynamic) ? 0x00 : 0x80 | /* bit 7 */          const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
2020                                       (VCFResonance & 0x7f); /* lower 7 bits */                                       (VCFResonance & 0x7f); /* lower 7 bits */
2021          memcpy(&pData[136], &vcfresonance, 1);          pData[136] = vcfresonance;
2022    
2023          const uint8_t vcfbreakpoint = (VCFKeyboardTracking) ? 0x80 : 0x00 | /* bit 7 */          const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2024                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2025          memcpy(&pData[137], &vcfbreakpoint, 1);          pData[137] = vcfbreakpoint;
2026    
2027          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2028                                      VCFVelocityCurve * 5;                                      VCFVelocityCurve * 5;
2029          memcpy(&pData[138], &vcfvelocity, 1);          pData[138] = vcfvelocity;
2030    
2031          const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;          const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2032          memcpy(&pData[139], &vcftype, 1);          pData[139] = vcftype;
2033    
2034          if (chunksize >= 148) {          if (chunksize >= 148) {
2035              memcpy(&pData[140], DimensionUpperLimits, 8);              memcpy(&pData[140], DimensionUpperLimits, 8);
2036          }          }
2037      }      }
2038    
2039        double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2040            curve_type_t curveType = releaseVelocityResponseCurve;
2041            uint8_t depth = releaseVelocityResponseDepth;
2042            // this models a strange behaviour or bug in GSt: two of the
2043            // velocity response curves for release time are not used even
2044            // if specified, instead another curve is chosen.
2045            if ((curveType == curve_type_nonlinear && depth == 0) ||
2046                (curveType == curve_type_special   && depth == 4)) {
2047                curveType = curve_type_nonlinear;
2048                depth = 3;
2049            }
2050            return GetVelocityTable(curveType, depth, 0);
2051        }
2052    
2053        double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2054                                                        uint8_t vcfVelocityDynamicRange,
2055                                                        uint8_t vcfVelocityScale,
2056                                                        vcf_cutoff_ctrl_t vcfCutoffController)
2057        {
2058            curve_type_t curveType = vcfVelocityCurve;
2059            uint8_t depth = vcfVelocityDynamicRange;
2060            // even stranger GSt: two of the velocity response curves for
2061            // filter cutoff are not used, instead another special curve
2062            // is chosen. This curve is not used anywhere else.
2063            if ((curveType == curve_type_nonlinear && depth == 0) ||
2064                (curveType == curve_type_special   && depth == 4)) {
2065                curveType = curve_type_special;
2066                depth = 5;
2067            }
2068            return GetVelocityTable(curveType, depth,
2069                                    (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2070                                        ? vcfVelocityScale : 0);
2071        }
2072    
2073      // 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
2074      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)
2075      {      {
# Line 1780  namespace { Line 2085  namespace {
2085          return table;          return table;
2086      }      }
2087    
2088        Region* DimensionRegion::GetParent() const {
2089            return pRegion;
2090        }
2091    
2092    // show error if some _lev_ctrl_* enum entry is not listed in the following function
2093    // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2094    // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2095    //#pragma GCC diagnostic push
2096    //#pragma GCC diagnostic error "-Wswitch"
2097    
2098      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2099          leverage_ctrl_t decodedcontroller;          leverage_ctrl_t decodedcontroller;
2100          switch (EncodedController) {          switch (EncodedController) {
# Line 1891  namespace { Line 2206  namespace {
2206                  decodedcontroller.controller_number = 95;                  decodedcontroller.controller_number = 95;
2207                  break;                  break;
2208    
2209                // format extension (these controllers are so far only supported by
2210                // LinuxSampler & gigedit) they will *NOT* work with
2211                // Gigasampler/GigaStudio !
2212                case _lev_ctrl_CC3_EXT:
2213                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2214                    decodedcontroller.controller_number = 3;
2215                    break;
2216                case _lev_ctrl_CC6_EXT:
2217                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2218                    decodedcontroller.controller_number = 6;
2219                    break;
2220                case _lev_ctrl_CC7_EXT:
2221                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2222                    decodedcontroller.controller_number = 7;
2223                    break;
2224                case _lev_ctrl_CC8_EXT:
2225                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2226                    decodedcontroller.controller_number = 8;
2227                    break;
2228                case _lev_ctrl_CC9_EXT:
2229                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2230                    decodedcontroller.controller_number = 9;
2231                    break;
2232                case _lev_ctrl_CC10_EXT:
2233                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2234                    decodedcontroller.controller_number = 10;
2235                    break;
2236                case _lev_ctrl_CC11_EXT:
2237                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2238                    decodedcontroller.controller_number = 11;
2239                    break;
2240                case _lev_ctrl_CC14_EXT:
2241                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2242                    decodedcontroller.controller_number = 14;
2243                    break;
2244                case _lev_ctrl_CC15_EXT:
2245                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2246                    decodedcontroller.controller_number = 15;
2247                    break;
2248                case _lev_ctrl_CC20_EXT:
2249                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2250                    decodedcontroller.controller_number = 20;
2251                    break;
2252                case _lev_ctrl_CC21_EXT:
2253                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2254                    decodedcontroller.controller_number = 21;
2255                    break;
2256                case _lev_ctrl_CC22_EXT:
2257                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2258                    decodedcontroller.controller_number = 22;
2259                    break;
2260                case _lev_ctrl_CC23_EXT:
2261                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2262                    decodedcontroller.controller_number = 23;
2263                    break;
2264                case _lev_ctrl_CC24_EXT:
2265                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2266                    decodedcontroller.controller_number = 24;
2267                    break;
2268                case _lev_ctrl_CC25_EXT:
2269                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2270                    decodedcontroller.controller_number = 25;
2271                    break;
2272                case _lev_ctrl_CC26_EXT:
2273                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2274                    decodedcontroller.controller_number = 26;
2275                    break;
2276                case _lev_ctrl_CC27_EXT:
2277                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2278                    decodedcontroller.controller_number = 27;
2279                    break;
2280                case _lev_ctrl_CC28_EXT:
2281                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2282                    decodedcontroller.controller_number = 28;
2283                    break;
2284                case _lev_ctrl_CC29_EXT:
2285                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2286                    decodedcontroller.controller_number = 29;
2287                    break;
2288                case _lev_ctrl_CC30_EXT:
2289                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2290                    decodedcontroller.controller_number = 30;
2291                    break;
2292                case _lev_ctrl_CC31_EXT:
2293                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2294                    decodedcontroller.controller_number = 31;
2295                    break;
2296                case _lev_ctrl_CC68_EXT:
2297                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2298                    decodedcontroller.controller_number = 68;
2299                    break;
2300                case _lev_ctrl_CC69_EXT:
2301                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2302                    decodedcontroller.controller_number = 69;
2303                    break;
2304                case _lev_ctrl_CC70_EXT:
2305                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2306                    decodedcontroller.controller_number = 70;
2307                    break;
2308                case _lev_ctrl_CC71_EXT:
2309                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2310                    decodedcontroller.controller_number = 71;
2311                    break;
2312                case _lev_ctrl_CC72_EXT:
2313                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2314                    decodedcontroller.controller_number = 72;
2315                    break;
2316                case _lev_ctrl_CC73_EXT:
2317                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2318                    decodedcontroller.controller_number = 73;
2319                    break;
2320                case _lev_ctrl_CC74_EXT:
2321                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2322                    decodedcontroller.controller_number = 74;
2323                    break;
2324                case _lev_ctrl_CC75_EXT:
2325                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2326                    decodedcontroller.controller_number = 75;
2327                    break;
2328                case _lev_ctrl_CC76_EXT:
2329                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2330                    decodedcontroller.controller_number = 76;
2331                    break;
2332                case _lev_ctrl_CC77_EXT:
2333                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2334                    decodedcontroller.controller_number = 77;
2335                    break;
2336                case _lev_ctrl_CC78_EXT:
2337                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2338                    decodedcontroller.controller_number = 78;
2339                    break;
2340                case _lev_ctrl_CC79_EXT:
2341                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2342                    decodedcontroller.controller_number = 79;
2343                    break;
2344                case _lev_ctrl_CC84_EXT:
2345                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2346                    decodedcontroller.controller_number = 84;
2347                    break;
2348                case _lev_ctrl_CC85_EXT:
2349                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2350                    decodedcontroller.controller_number = 85;
2351                    break;
2352                case _lev_ctrl_CC86_EXT:
2353                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2354                    decodedcontroller.controller_number = 86;
2355                    break;
2356                case _lev_ctrl_CC87_EXT:
2357                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2358                    decodedcontroller.controller_number = 87;
2359                    break;
2360                case _lev_ctrl_CC89_EXT:
2361                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2362                    decodedcontroller.controller_number = 89;
2363                    break;
2364                case _lev_ctrl_CC90_EXT:
2365                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2366                    decodedcontroller.controller_number = 90;
2367                    break;
2368                case _lev_ctrl_CC96_EXT:
2369                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2370                    decodedcontroller.controller_number = 96;
2371                    break;
2372                case _lev_ctrl_CC97_EXT:
2373                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2374                    decodedcontroller.controller_number = 97;
2375                    break;
2376                case _lev_ctrl_CC102_EXT:
2377                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2378                    decodedcontroller.controller_number = 102;
2379                    break;
2380                case _lev_ctrl_CC103_EXT:
2381                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2382                    decodedcontroller.controller_number = 103;
2383                    break;
2384                case _lev_ctrl_CC104_EXT:
2385                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2386                    decodedcontroller.controller_number = 104;
2387                    break;
2388                case _lev_ctrl_CC105_EXT:
2389                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2390                    decodedcontroller.controller_number = 105;
2391                    break;
2392                case _lev_ctrl_CC106_EXT:
2393                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2394                    decodedcontroller.controller_number = 106;
2395                    break;
2396                case _lev_ctrl_CC107_EXT:
2397                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2398                    decodedcontroller.controller_number = 107;
2399                    break;
2400                case _lev_ctrl_CC108_EXT:
2401                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2402                    decodedcontroller.controller_number = 108;
2403                    break;
2404                case _lev_ctrl_CC109_EXT:
2405                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2406                    decodedcontroller.controller_number = 109;
2407                    break;
2408                case _lev_ctrl_CC110_EXT:
2409                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2410                    decodedcontroller.controller_number = 110;
2411                    break;
2412                case _lev_ctrl_CC111_EXT:
2413                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2414                    decodedcontroller.controller_number = 111;
2415                    break;
2416                case _lev_ctrl_CC112_EXT:
2417                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2418                    decodedcontroller.controller_number = 112;
2419                    break;
2420                case _lev_ctrl_CC113_EXT:
2421                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2422                    decodedcontroller.controller_number = 113;
2423                    break;
2424                case _lev_ctrl_CC114_EXT:
2425                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2426                    decodedcontroller.controller_number = 114;
2427                    break;
2428                case _lev_ctrl_CC115_EXT:
2429                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2430                    decodedcontroller.controller_number = 115;
2431                    break;
2432                case _lev_ctrl_CC116_EXT:
2433                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2434                    decodedcontroller.controller_number = 116;
2435                    break;
2436                case _lev_ctrl_CC117_EXT:
2437                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2438                    decodedcontroller.controller_number = 117;
2439                    break;
2440                case _lev_ctrl_CC118_EXT:
2441                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2442                    decodedcontroller.controller_number = 118;
2443                    break;
2444                case _lev_ctrl_CC119_EXT:
2445                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2446                    decodedcontroller.controller_number = 119;
2447                    break;
2448    
2449              // unknown controller type              // unknown controller type
2450              default:              default:
2451                  throw gig::Exception("Unknown leverage controller type.");                  throw gig::Exception("Unknown leverage controller type.");
2452          }          }
2453          return decodedcontroller;          return decodedcontroller;
2454      }      }
2455        
2456    // see above (diagnostic push not supported prior GCC 4.6)
2457    //#pragma GCC diagnostic pop
2458    
2459      DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {      DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2460          _lev_ctrl_t encodedcontroller;          _lev_ctrl_t encodedcontroller;
# Line 1984  namespace { Line 2542  namespace {
2542                      case 95:                      case 95:
2543                          encodedcontroller = _lev_ctrl_effect5depth;                          encodedcontroller = _lev_ctrl_effect5depth;
2544                          break;                          break;
2545    
2546                        // format extension (these controllers are so far only
2547                        // supported by LinuxSampler & gigedit) they will *NOT*
2548                        // work with Gigasampler/GigaStudio !
2549                        case 3:
2550                            encodedcontroller = _lev_ctrl_CC3_EXT;
2551                            break;
2552                        case 6:
2553                            encodedcontroller = _lev_ctrl_CC6_EXT;
2554                            break;
2555                        case 7:
2556                            encodedcontroller = _lev_ctrl_CC7_EXT;
2557                            break;
2558                        case 8:
2559                            encodedcontroller = _lev_ctrl_CC8_EXT;
2560                            break;
2561                        case 9:
2562                            encodedcontroller = _lev_ctrl_CC9_EXT;
2563                            break;
2564                        case 10:
2565                            encodedcontroller = _lev_ctrl_CC10_EXT;
2566                            break;
2567                        case 11:
2568                            encodedcontroller = _lev_ctrl_CC11_EXT;
2569                            break;
2570                        case 14:
2571                            encodedcontroller = _lev_ctrl_CC14_EXT;
2572                            break;
2573                        case 15:
2574                            encodedcontroller = _lev_ctrl_CC15_EXT;
2575                            break;
2576                        case 20:
2577                            encodedcontroller = _lev_ctrl_CC20_EXT;
2578                            break;
2579                        case 21:
2580                            encodedcontroller = _lev_ctrl_CC21_EXT;
2581                            break;
2582                        case 22:
2583                            encodedcontroller = _lev_ctrl_CC22_EXT;
2584                            break;
2585                        case 23:
2586                            encodedcontroller = _lev_ctrl_CC23_EXT;
2587                            break;
2588                        case 24:
2589                            encodedcontroller = _lev_ctrl_CC24_EXT;
2590                            break;
2591                        case 25:
2592                            encodedcontroller = _lev_ctrl_CC25_EXT;
2593                            break;
2594                        case 26:
2595                            encodedcontroller = _lev_ctrl_CC26_EXT;
2596                            break;
2597                        case 27:
2598                            encodedcontroller = _lev_ctrl_CC27_EXT;
2599                            break;
2600                        case 28:
2601                            encodedcontroller = _lev_ctrl_CC28_EXT;
2602                            break;
2603                        case 29:
2604                            encodedcontroller = _lev_ctrl_CC29_EXT;
2605                            break;
2606                        case 30:
2607                            encodedcontroller = _lev_ctrl_CC30_EXT;
2608                            break;
2609                        case 31:
2610                            encodedcontroller = _lev_ctrl_CC31_EXT;
2611                            break;
2612                        case 68:
2613                            encodedcontroller = _lev_ctrl_CC68_EXT;
2614                            break;
2615                        case 69:
2616                            encodedcontroller = _lev_ctrl_CC69_EXT;
2617                            break;
2618                        case 70:
2619                            encodedcontroller = _lev_ctrl_CC70_EXT;
2620                            break;
2621                        case 71:
2622                            encodedcontroller = _lev_ctrl_CC71_EXT;
2623                            break;
2624                        case 72:
2625                            encodedcontroller = _lev_ctrl_CC72_EXT;
2626                            break;
2627                        case 73:
2628                            encodedcontroller = _lev_ctrl_CC73_EXT;
2629                            break;
2630                        case 74:
2631                            encodedcontroller = _lev_ctrl_CC74_EXT;
2632                            break;
2633                        case 75:
2634                            encodedcontroller = _lev_ctrl_CC75_EXT;
2635                            break;
2636                        case 76:
2637                            encodedcontroller = _lev_ctrl_CC76_EXT;
2638                            break;
2639                        case 77:
2640                            encodedcontroller = _lev_ctrl_CC77_EXT;
2641                            break;
2642                        case 78:
2643                            encodedcontroller = _lev_ctrl_CC78_EXT;
2644                            break;
2645                        case 79:
2646                            encodedcontroller = _lev_ctrl_CC79_EXT;
2647                            break;
2648                        case 84:
2649                            encodedcontroller = _lev_ctrl_CC84_EXT;
2650                            break;
2651                        case 85:
2652                            encodedcontroller = _lev_ctrl_CC85_EXT;
2653                            break;
2654                        case 86:
2655                            encodedcontroller = _lev_ctrl_CC86_EXT;
2656                            break;
2657                        case 87:
2658                            encodedcontroller = _lev_ctrl_CC87_EXT;
2659                            break;
2660                        case 89:
2661                            encodedcontroller = _lev_ctrl_CC89_EXT;
2662                            break;
2663                        case 90:
2664                            encodedcontroller = _lev_ctrl_CC90_EXT;
2665                            break;
2666                        case 96:
2667                            encodedcontroller = _lev_ctrl_CC96_EXT;
2668                            break;
2669                        case 97:
2670                            encodedcontroller = _lev_ctrl_CC97_EXT;
2671                            break;
2672                        case 102:
2673                            encodedcontroller = _lev_ctrl_CC102_EXT;
2674                            break;
2675                        case 103:
2676                            encodedcontroller = _lev_ctrl_CC103_EXT;
2677                            break;
2678                        case 104:
2679                            encodedcontroller = _lev_ctrl_CC104_EXT;
2680                            break;
2681                        case 105:
2682                            encodedcontroller = _lev_ctrl_CC105_EXT;
2683                            break;
2684                        case 106:
2685                            encodedcontroller = _lev_ctrl_CC106_EXT;
2686                            break;
2687                        case 107:
2688                            encodedcontroller = _lev_ctrl_CC107_EXT;
2689                            break;
2690                        case 108:
2691                            encodedcontroller = _lev_ctrl_CC108_EXT;
2692                            break;
2693                        case 109:
2694                            encodedcontroller = _lev_ctrl_CC109_EXT;
2695                            break;
2696                        case 110:
2697                            encodedcontroller = _lev_ctrl_CC110_EXT;
2698                            break;
2699                        case 111:
2700                            encodedcontroller = _lev_ctrl_CC111_EXT;
2701                            break;
2702                        case 112:
2703                            encodedcontroller = _lev_ctrl_CC112_EXT;
2704                            break;
2705                        case 113:
2706                            encodedcontroller = _lev_ctrl_CC113_EXT;
2707                            break;
2708                        case 114:
2709                            encodedcontroller = _lev_ctrl_CC114_EXT;
2710                            break;
2711                        case 115:
2712                            encodedcontroller = _lev_ctrl_CC115_EXT;
2713                            break;
2714                        case 116:
2715                            encodedcontroller = _lev_ctrl_CC116_EXT;
2716                            break;
2717                        case 117:
2718                            encodedcontroller = _lev_ctrl_CC117_EXT;
2719                            break;
2720                        case 118:
2721                            encodedcontroller = _lev_ctrl_CC118_EXT;
2722                            break;
2723                        case 119:
2724                            encodedcontroller = _lev_ctrl_CC119_EXT;
2725                            break;
2726    
2727                      default:                      default:
2728                          throw gig::Exception("leverage controller number is not supported by the gig format");                          throw gig::Exception("leverage controller number is not supported by the gig format");
2729                  }                  }
2730                    break;
2731              default:              default:
2732                  throw gig::Exception("Unknown leverage controller type.");                  throw gig::Exception("Unknown leverage controller type.");
2733          }          }
# Line 2032  namespace { Line 2773  namespace {
2773          return pVelocityCutoffTable[MIDIKeyVelocity];          return pVelocityCutoffTable[MIDIKeyVelocity];
2774      }      }
2775    
2776        /**
2777         * Updates the respective member variable and the lookup table / cache
2778         * that depends on this value.
2779         */
2780        void DimensionRegion::SetVelocityResponseCurve(curve_type_t curve) {
2781            pVelocityAttenuationTable =
2782                GetVelocityTable(
2783                    curve, VelocityResponseDepth, VelocityResponseCurveScaling
2784                );
2785            VelocityResponseCurve = curve;
2786        }
2787    
2788        /**
2789         * Updates the respective member variable and the lookup table / cache
2790         * that depends on this value.
2791         */
2792        void DimensionRegion::SetVelocityResponseDepth(uint8_t depth) {
2793            pVelocityAttenuationTable =
2794                GetVelocityTable(
2795                    VelocityResponseCurve, depth, VelocityResponseCurveScaling
2796                );
2797            VelocityResponseDepth = depth;
2798        }
2799    
2800        /**
2801         * Updates the respective member variable and the lookup table / cache
2802         * that depends on this value.
2803         */
2804        void DimensionRegion::SetVelocityResponseCurveScaling(uint8_t scaling) {
2805            pVelocityAttenuationTable =
2806                GetVelocityTable(
2807                    VelocityResponseCurve, VelocityResponseDepth, scaling
2808                );
2809            VelocityResponseCurveScaling = scaling;
2810        }
2811    
2812        /**
2813         * Updates the respective member variable and the lookup table / cache
2814         * that depends on this value.
2815         */
2816        void DimensionRegion::SetReleaseVelocityResponseCurve(curve_type_t curve) {
2817            pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
2818            ReleaseVelocityResponseCurve = curve;
2819        }
2820    
2821        /**
2822         * Updates the respective member variable and the lookup table / cache
2823         * that depends on this value.
2824         */
2825        void DimensionRegion::SetReleaseVelocityResponseDepth(uint8_t depth) {
2826            pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
2827            ReleaseVelocityResponseDepth = depth;
2828        }
2829    
2830        /**
2831         * Updates the respective member variable and the lookup table / cache
2832         * that depends on this value.
2833         */
2834        void DimensionRegion::SetVCFCutoffController(vcf_cutoff_ctrl_t controller) {
2835            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
2836            VCFCutoffController = controller;
2837        }
2838    
2839        /**
2840         * Updates the respective member variable and the lookup table / cache
2841         * that depends on this value.
2842         */
2843        void DimensionRegion::SetVCFVelocityCurve(curve_type_t curve) {
2844            pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
2845            VCFVelocityCurve = curve;
2846        }
2847    
2848        /**
2849         * Updates the respective member variable and the lookup table / cache
2850         * that depends on this value.
2851         */
2852        void DimensionRegion::SetVCFVelocityDynamicRange(uint8_t range) {
2853            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
2854            VCFVelocityDynamicRange = range;
2855        }
2856    
2857        /**
2858         * Updates the respective member variable and the lookup table / cache
2859         * that depends on this value.
2860         */
2861        void DimensionRegion::SetVCFVelocityScale(uint8_t scaling) {
2862            pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
2863            VCFVelocityScale = scaling;
2864        }
2865    
2866      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) {
2867    
2868          // line-segment approximations of the 15 velocity curves          // line-segment approximations of the 15 velocity curves
# Line 2104  namespace { Line 2935  namespace {
2935  // *  // *
2936    
2937      Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {      Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
         pInfo->UseFixedLengthStrings = true;  
   
2938          // Initialization          // Initialization
2939          Dimensions = 0;          Dimensions = 0;
2940          for (int i = 0; i < 256; i++) {          for (int i = 0; i < 256; i++) {
# Line 2117  namespace { Line 2946  namespace {
2946    
2947          // Actual Loading          // Actual Loading
2948    
2949            if (!file->GetAutoLoad()) return;
2950    
2951          LoadDimensionRegions(rgnList);          LoadDimensionRegions(rgnList);
2952    
2953          RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);          RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
# Line 2125  namespace { Line 2956  namespace {
2956              for (int i = 0; i < dimensionBits; i++) {              for (int i = 0; i < dimensionBits; i++) {
2957                  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());                  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
2958                  uint8_t     bits      = _3lnk->ReadUint8();                  uint8_t     bits      = _3lnk->ReadUint8();
2959                  _3lnk->ReadUint8(); // probably the position of the dimension                  _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
2960                  _3lnk->ReadUint8(); // unknown                  _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
2961                  uint8_t     zones     = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)                  uint8_t     zones     = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
2962                  if (dimension == dimension_none) { // inactive dimension                  if (dimension == dimension_none) { // inactive dimension
2963                      pDimensionDefinitions[i].dimension  = dimension_none;                      pDimensionDefinitions[i].dimension  = dimension_none;
# Line 2160  namespace { Line 2991  namespace {
2991              else              else
2992                  _3lnk->SetPos(44);                  _3lnk->SetPos(44);
2993    
2994              // load sample references              // load sample references (if auto loading is enabled)
2995              for (uint i = 0; i < DimensionRegions; i++) {              if (file->GetAutoLoad()) {
2996                  uint32_t wavepoolindex = _3lnk->ReadUint32();                  for (uint i = 0; i < DimensionRegions; i++) {
2997                  if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);                      uint32_t wavepoolindex = _3lnk->ReadUint32();
2998                        if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
2999                    }
3000                    GetSample(); // load global region sample reference
3001              }              }
             GetSample(); // load global region sample reference  
3002          } else {          } else {
3003              DimensionRegions = 0;              DimensionRegions = 0;
3004                for (int i = 0 ; i < 8 ; i++) {
3005                    pDimensionDefinitions[i].dimension  = dimension_none;
3006                    pDimensionDefinitions[i].bits       = 0;
3007                    pDimensionDefinitions[i].zones      = 0;
3008                }
3009          }          }
3010    
3011          // make sure there is at least one dimension region          // make sure there is at least one dimension region
# Line 2175  namespace { Line 3013  namespace {
3013              RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);              RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
3014              if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);              if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
3015              RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);              RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
3016              pDimensionRegions[0] = new DimensionRegion(_3ewl);              pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
3017              DimensionRegions = 1;              DimensionRegions = 1;
3018          }          }
3019      }      }
# Line 2205  namespace { Line 3043  namespace {
3043          }          }
3044    
3045          File* pFile = (File*) GetParent()->GetParent();          File* pFile = (File*) GetParent()->GetParent();
3046          const int iMaxDimensions = (pFile->pVersion && pFile->pVersion->major == 3) ? 8 : 5;          bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
3047          const int iMaxDimensionRegions = (pFile->pVersion && pFile->pVersion->major == 3) ? 256 : 32;          const int iMaxDimensions =  version3 ? 8 : 5;
3048            const int iMaxDimensionRegions = version3 ? 256 : 32;
3049    
3050          // make sure '3lnk' chunk exists          // make sure '3lnk' chunk exists
3051          RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);          RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3052          if (!_3lnk) {          if (!_3lnk) {
3053              const int _3lnkChunkSize = (pFile->pVersion && pFile->pVersion->major == 3) ? 1092 : 172;              const int _3lnkChunkSize = version3 ? 1092 : 172;
3054              _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);              _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3055                memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3056    
3057                // move 3prg to last position
3058                pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), 0);
3059          }          }
3060    
3061          // update dimension definitions in '3lnk' chunk          // update dimension definitions in '3lnk' chunk
3062          uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();          uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3063          memcpy(&pData[0], &DimensionRegions, 4);          store32(&pData[0], DimensionRegions);
3064            int shift = 0;
3065          for (int i = 0; i < iMaxDimensions; i++) {          for (int i = 0; i < iMaxDimensions; i++) {
3066              pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;              pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3067              pData[5 + i * 8] = pDimensionDefinitions[i].bits;              pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3068              // next 2 bytes unknown              pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3069                pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3070              pData[8 + i * 8] = pDimensionDefinitions[i].zones;              pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3071              // next 3 bytes unknown              // next 3 bytes unknown, always zero?
3072    
3073                shift += pDimensionDefinitions[i].bits;
3074          }          }
3075    
3076          // update wave pool table in '3lnk' chunk          // update wave pool table in '3lnk' chunk
3077          const int iWavePoolOffset = (pFile->pVersion && pFile->pVersion->major == 3) ? 68 : 44;          const int iWavePoolOffset = version3 ? 68 : 44;
3078          for (uint i = 0; i < iMaxDimensionRegions; i++) {          for (uint i = 0; i < iMaxDimensionRegions; i++) {
3079              int iWaveIndex = -1;              int iWaveIndex = -1;
3080              if (i < DimensionRegions) {              if (i < DimensionRegions) {
# Line 2240  namespace { Line 3087  namespace {
3087                          break;                          break;
3088                      }                      }
3089                  }                  }
                 if (iWaveIndex < 0) throw gig::Exception("Could not update gig::Region, could not find DimensionRegion's sample");  
3090              }              }
3091              memcpy(&pData[iWavePoolOffset + i * 4], &iWaveIndex, 4);              store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3092          }          }
3093      }      }
3094    
# Line 2253  namespace { Line 3099  namespace {
3099              RIFF::List* _3ewl = _3prg->GetFirstSubList();              RIFF::List* _3ewl = _3prg->GetFirstSubList();
3100              while (_3ewl) {              while (_3ewl) {
3101                  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {                  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3102                      pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);                      pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3103                      dimensionRegionNr++;                      dimensionRegionNr++;
3104                  }                  }
3105                  _3ewl = _3prg->GetNextSubList();                  _3ewl = _3prg->GetNextSubList();
# Line 2262  namespace { Line 3108  namespace {
3108          }          }
3109      }      }
3110    
3111        void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3112            // update KeyRange struct and make sure regions are in correct order
3113            DLS::Region::SetKeyRange(Low, High);
3114            // update Region key table for fast lookup
3115            ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3116        }
3117    
3118      void Region::UpdateVelocityTable() {      void Region::UpdateVelocityTable() {
3119          // get velocity dimension's index          // get velocity dimension's index
3120          int veldim = -1;          int veldim = -1;
# Line 2348  namespace { Line 3201  namespace {
3201       *                        dimension bits limit is violated       *                        dimension bits limit is violated
3202       */       */
3203      void Region::AddDimension(dimension_def_t* pDimDef) {      void Region::AddDimension(dimension_def_t* pDimDef) {
3204            // some initial sanity checks of the given dimension definition
3205            if (pDimDef->zones < 2)
3206                throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3207            if (pDimDef->bits < 1)
3208                throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3209            if (pDimDef->dimension == dimension_samplechannel) {
3210                if (pDimDef->zones != 2)
3211                    throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3212                if (pDimDef->bits != 1)
3213                    throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3214            }
3215    
3216          // check if max. amount of dimensions reached          // check if max. amount of dimensions reached
3217          File* file = (File*) GetParent()->GetParent();          File* file = (File*) GetParent()->GetParent();
3218          const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;          const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
# Line 2367  namespace { Line 3232  namespace {
3232              if (pDimensionDefinitions[i].dimension == pDimDef->dimension)              if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3233                  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");                  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3234    
3235            // pos is where the new dimension should be placed, normally
3236            // last in list, except for the samplechannel dimension which
3237            // has to be first in list
3238            int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3239            int bitpos = 0;
3240            for (int i = 0 ; i < pos ; i++)
3241                bitpos += pDimensionDefinitions[i].bits;
3242    
3243            // make room for the new dimension
3244            for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3245            for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3246                for (int j = Dimensions ; j > pos ; j--) {
3247                    pDimensionRegions[i]->DimensionUpperLimits[j] =
3248                        pDimensionRegions[i]->DimensionUpperLimits[j - 1];
3249                }
3250            }
3251    
3252          // assign definition of new dimension          // assign definition of new dimension
3253          pDimensionDefinitions[Dimensions] = *pDimDef;          pDimensionDefinitions[pos] = *pDimDef;
3254    
3255          // auto correct certain dimension definition fields (where possible)          // auto correct certain dimension definition fields (where possible)
3256          pDimensionDefinitions[Dimensions].split_type  =          pDimensionDefinitions[pos].split_type  =
3257              __resolveSplitType(pDimensionDefinitions[Dimensions].dimension);              __resolveSplitType(pDimensionDefinitions[pos].dimension);
3258          pDimensionDefinitions[Dimensions].zone_size =          pDimensionDefinitions[pos].zone_size =
3259              __resolveZoneSize(pDimensionDefinitions[Dimensions]);              __resolveZoneSize(pDimensionDefinitions[pos]);
3260    
3261          // create new dimension region(s) for this new dimension          // create new dimension region(s) for this new dimension, and make
3262          for (int i = 1 << iCurrentBits; i < 1 << iNewBits; i++) {          // sure that the dimension regions are placed correctly in both the
3263              //TODO: maybe we should copy existing dimension regions if possible instead of simply creating new ones with default values          // RIFF list and the pDimensionRegions array
3264              RIFF::List* pNewDimRgnListChunk = pCkRegion->AddSubList(LIST_TYPE_3EWL);          RIFF::Chunk* moveTo = NULL;
3265              pDimensionRegions[i] = new DimensionRegion(pNewDimRgnListChunk);          RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3266              DimensionRegions++;          for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3267                for (int k = 0 ; k < (1 << bitpos) ; k++) {
3268                    pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3269                }
3270                for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3271                    for (int k = 0 ; k < (1 << bitpos) ; k++) {
3272                        RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3273                        if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3274                        // create a new dimension region and copy all parameter values from
3275                        // an existing dimension region
3276                        pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3277                            new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3278    
3279                        DimensionRegions++;
3280                    }
3281                }
3282                moveTo = pDimensionRegions[i]->pParentList;
3283            }
3284    
3285            // initialize the upper limits for this dimension
3286            int mask = (1 << bitpos) - 1;
3287            for (int z = 0 ; z < pDimDef->zones ; z++) {
3288                uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3289                for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3290                    pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3291                                      (z << bitpos) |
3292                                      (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3293                }
3294          }          }
3295    
3296          Dimensions++;          Dimensions++;
# Line 2424  namespace { Line 3333  namespace {
3333          for (int i = iDimensionNr + 1; i < Dimensions; i++)          for (int i = iDimensionNr + 1; i < Dimensions; i++)
3334              iUpperBits += pDimensionDefinitions[i].bits;              iUpperBits += pDimensionDefinitions[i].bits;
3335    
3336            RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3337    
3338          // delete dimension regions which belong to the given dimension          // delete dimension regions which belong to the given dimension
3339          // (that is where the dimension's bit > 0)          // (that is where the dimension's bit > 0)
3340          for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {          for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
# Line 2432  namespace { Line 3343  namespace {
3343                      int iToDelete = iUpperBit    << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |                      int iToDelete = iUpperBit    << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3344                                      iObsoleteBit << iLowerBits |                                      iObsoleteBit << iLowerBits |
3345                                      iLowerBit;                                      iLowerBit;
3346    
3347                        _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3348                      delete pDimensionRegions[iToDelete];                      delete pDimensionRegions[iToDelete];
3349                      pDimensionRegions[iToDelete] = NULL;                      pDimensionRegions[iToDelete] = NULL;
3350                      DimensionRegions--;                      DimensionRegions--;
# Line 2452  namespace { Line 3365  namespace {
3365              }              }
3366          }          }
3367    
3368            // remove the this dimension from the upper limits arrays
3369            for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3370                DimensionRegion* d = pDimensionRegions[j];
3371                for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3372                    d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3373                }
3374                d->DimensionUpperLimits[Dimensions - 1] = 127;
3375            }
3376    
3377          // 'remove' dimension definition          // 'remove' dimension definition
3378          for (int i = iDimensionNr + 1; i < Dimensions; i++) {          for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3379              pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];              pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
# Line 2466  namespace { Line 3388  namespace {
3388          if (pDimDef->dimension == dimension_layer) Layers = 1;          if (pDimDef->dimension == dimension_layer) Layers = 1;
3389      }      }
3390    
3391        /**
3392         * Searches in the current Region for a dimension of the given dimension
3393         * type and returns the precise configuration of that dimension in this
3394         * Region.
3395         *
3396         * @param type - dimension type of the sought dimension
3397         * @returns dimension definition or NULL if there is no dimension with
3398         *          sought type in this Region.
3399         */
3400        dimension_def_t* Region::GetDimensionDefinition(dimension_t type) {
3401            for (int i = 0; i < Dimensions; ++i)
3402                if (pDimensionDefinitions[i].dimension == type)
3403                    return &pDimensionDefinitions[i];
3404            return NULL;
3405        }
3406    
3407      Region::~Region() {      Region::~Region() {
3408          for (int i = 0; i < 256; i++) {          for (int i = 0; i < 256; i++) {
3409              if (pDimensionRegions[i]) delete pDimensionRegions[i];              if (pDimensionRegions[i]) delete pDimensionRegions[i];
# Line 2585  namespace { Line 3523  namespace {
3523          }          }
3524          return NULL;          return NULL;
3525      }      }
3526        
3527        /**
3528         * Make a (semi) deep copy of the Region object given by @a orig
3529         * and assign it to this object.
3530         *
3531         * Note that all sample pointers referenced by @a orig are simply copied as
3532         * memory address. Thus the respective samples are shared, not duplicated!
3533         *
3534         * @param orig - original Region object to be copied from
3535         */
3536        void Region::CopyAssign(const Region* orig) {
3537            CopyAssign(orig, NULL);
3538        }
3539        
3540        /**
3541         * Make a (semi) deep copy of the Region object given by @a orig and
3542         * assign it to this object
3543         *
3544         * @param mSamples - crosslink map between the foreign file's samples and
3545         *                   this file's samples
3546         */
3547        void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
3548            // handle base classes
3549            DLS::Region::CopyAssign(orig);
3550            
3551            if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
3552                pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
3553            }
3554            
3555            // handle own member variables
3556            for (int i = Dimensions - 1; i >= 0; --i) {
3557                DeleteDimension(&pDimensionDefinitions[i]);
3558            }
3559            Layers = 0; // just to be sure
3560            for (int i = 0; i < orig->Dimensions; i++) {
3561                // we need to copy the dim definition here, to avoid the compiler
3562                // complaining about const-ness issue
3563                dimension_def_t def = orig->pDimensionDefinitions[i];
3564                AddDimension(&def);
3565            }
3566            for (int i = 0; i < 256; i++) {
3567                if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
3568                    pDimensionRegions[i]->CopyAssign(
3569                        orig->pDimensionRegions[i],
3570                        mSamples
3571                    );
3572                }
3573            }
3574            Layers = orig->Layers;
3575        }
3576    
3577    
3578    // *************** MidiRule ***************
3579    // *
3580    
3581        MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
3582            _3ewg->SetPos(36);
3583            Triggers = _3ewg->ReadUint8();
3584            _3ewg->SetPos(40);
3585            ControllerNumber = _3ewg->ReadUint8();
3586            _3ewg->SetPos(46);
3587            for (int i = 0 ; i < Triggers ; i++) {
3588                pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
3589                pTriggers[i].Descending = _3ewg->ReadUint8();
3590                pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
3591                pTriggers[i].Key = _3ewg->ReadUint8();
3592                pTriggers[i].NoteOff = _3ewg->ReadUint8();
3593                pTriggers[i].Velocity = _3ewg->ReadUint8();
3594                pTriggers[i].OverridePedal = _3ewg->ReadUint8();
3595                _3ewg->ReadUint8();
3596            }
3597        }
3598    
3599        MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
3600            ControllerNumber(0),
3601            Triggers(0) {
3602        }
3603    
3604        void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
3605            pData[32] = 4;
3606            pData[33] = 16;
3607            pData[36] = Triggers;
3608            pData[40] = ControllerNumber;
3609            for (int i = 0 ; i < Triggers ; i++) {
3610                pData[46 + i * 8] = pTriggers[i].TriggerPoint;
3611                pData[47 + i * 8] = pTriggers[i].Descending;
3612                pData[48 + i * 8] = pTriggers[i].VelSensitivity;
3613                pData[49 + i * 8] = pTriggers[i].Key;
3614                pData[50 + i * 8] = pTriggers[i].NoteOff;
3615                pData[51 + i * 8] = pTriggers[i].Velocity;
3616                pData[52 + i * 8] = pTriggers[i].OverridePedal;
3617            }
3618        }
3619    
3620        MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
3621            _3ewg->SetPos(36);
3622            LegatoSamples = _3ewg->ReadUint8(); // always 12
3623            _3ewg->SetPos(40);
3624            BypassUseController = _3ewg->ReadUint8();
3625            BypassKey = _3ewg->ReadUint8();
3626            BypassController = _3ewg->ReadUint8();
3627            ThresholdTime = _3ewg->ReadUint16();
3628            _3ewg->ReadInt16();
3629            ReleaseTime = _3ewg->ReadUint16();
3630            _3ewg->ReadInt16();
3631            KeyRange.low = _3ewg->ReadUint8();
3632            KeyRange.high = _3ewg->ReadUint8();
3633            _3ewg->SetPos(64);
3634            ReleaseTriggerKey = _3ewg->ReadUint8();
3635            AltSustain1Key = _3ewg->ReadUint8();
3636            AltSustain2Key = _3ewg->ReadUint8();
3637        }
3638    
3639        MidiRuleLegato::MidiRuleLegato() :
3640            LegatoSamples(12),
3641            BypassUseController(false),
3642            BypassKey(0),
3643            BypassController(1),
3644            ThresholdTime(20),
3645            ReleaseTime(20),
3646            ReleaseTriggerKey(0),
3647            AltSustain1Key(0),
3648            AltSustain2Key(0)
3649        {
3650            KeyRange.low = KeyRange.high = 0;
3651        }
3652    
3653        void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
3654            pData[32] = 0;
3655            pData[33] = 16;
3656            pData[36] = LegatoSamples;
3657            pData[40] = BypassUseController;
3658            pData[41] = BypassKey;
3659            pData[42] = BypassController;
3660            store16(&pData[43], ThresholdTime);
3661            store16(&pData[47], ReleaseTime);
3662            pData[51] = KeyRange.low;
3663            pData[52] = KeyRange.high;
3664            pData[64] = ReleaseTriggerKey;
3665            pData[65] = AltSustain1Key;
3666            pData[66] = AltSustain2Key;
3667        }
3668    
3669        MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
3670            _3ewg->SetPos(36);
3671            Articulations = _3ewg->ReadUint8();
3672            int flags = _3ewg->ReadUint8();
3673            Polyphonic = flags & 8;
3674            Chained = flags & 4;
3675            Selector = (flags & 2) ? selector_controller :
3676                (flags & 1) ? selector_key_switch : selector_none;
3677            Patterns = _3ewg->ReadUint8();
3678            _3ewg->ReadUint8(); // chosen row
3679            _3ewg->ReadUint8(); // unknown
3680            _3ewg->ReadUint8(); // unknown
3681            _3ewg->ReadUint8(); // unknown
3682            KeySwitchRange.low = _3ewg->ReadUint8();
3683            KeySwitchRange.high = _3ewg->ReadUint8();
3684            Controller = _3ewg->ReadUint8();
3685            PlayRange.low = _3ewg->ReadUint8();
3686            PlayRange.high = _3ewg->ReadUint8();
3687    
3688            int n = std::min(int(Articulations), 32);
3689            for (int i = 0 ; i < n ; i++) {
3690                _3ewg->ReadString(pArticulations[i], 32);
3691            }
3692            _3ewg->SetPos(1072);
3693            n = std::min(int(Patterns), 32);
3694            for (int i = 0 ; i < n ; i++) {
3695                _3ewg->ReadString(pPatterns[i].Name, 16);
3696                pPatterns[i].Size = _3ewg->ReadUint8();
3697                _3ewg->Read(&pPatterns[i][0], 1, 32);
3698            }
3699        }
3700    
3701        MidiRuleAlternator::MidiRuleAlternator() :
3702            Articulations(0),
3703            Patterns(0),
3704            Selector(selector_none),
3705            Controller(0),
3706            Polyphonic(false),
3707            Chained(false)
3708        {
3709            PlayRange.low = PlayRange.high = 0;
3710            KeySwitchRange.low = KeySwitchRange.high = 0;
3711        }
3712    
3713        void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
3714            pData[32] = 3;
3715            pData[33] = 16;
3716            pData[36] = Articulations;
3717            pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
3718                (Selector == selector_controller ? 2 :
3719                 (Selector == selector_key_switch ? 1 : 0));
3720            pData[38] = Patterns;
3721    
3722            pData[43] = KeySwitchRange.low;
3723            pData[44] = KeySwitchRange.high;
3724            pData[45] = Controller;
3725            pData[46] = PlayRange.low;
3726            pData[47] = PlayRange.high;
3727    
3728            char* str = reinterpret_cast<char*>(pData);
3729            int pos = 48;
3730            int n = std::min(int(Articulations), 32);
3731            for (int i = 0 ; i < n ; i++, pos += 32) {
3732                strncpy(&str[pos], pArticulations[i].c_str(), 32);
3733            }
3734    
3735            pos = 1072;
3736            n = std::min(int(Patterns), 32);
3737            for (int i = 0 ; i < n ; i++, pos += 49) {
3738                strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
3739                pData[pos + 16] = pPatterns[i].Size;
3740                memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
3741            }
3742        }
3743    
3744  // *************** Instrument ***************  // *************** Instrument ***************
3745  // *  // *
3746    
3747      Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {      Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
3748          pInfo->UseFixedLengthStrings = true;          static const DLS::Info::string_length_t fixedStringLengths[] = {
3749                { CHUNK_ID_INAM, 64 },
3750                { CHUNK_ID_ISFT, 12 },
3751                { 0, 0 }
3752            };
3753            pInfo->SetFixedStringLengths(fixedStringLengths);
3754    
3755          // Initialization          // Initialization
3756          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
3757            EffectSend = 0;
3758            Attenuation = 0;
3759            FineTune = 0;
3760            PitchbendRange = 0;
3761            PianoReleaseMode = false;
3762            DimensionKeyRange.low = 0;
3763            DimensionKeyRange.high = 0;
3764            pMidiRules = new MidiRule*[3];
3765            pMidiRules[0] = NULL;
3766    
3767          // Loading          // Loading
3768          RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);          RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
# Line 2610  namespace { Line 3777  namespace {
3777                  PianoReleaseMode       = dimkeystart & 0x01;                  PianoReleaseMode       = dimkeystart & 0x01;
3778                  DimensionKeyRange.low  = dimkeystart >> 1;                  DimensionKeyRange.low  = dimkeystart >> 1;
3779                  DimensionKeyRange.high = _3ewg->ReadUint8();                  DimensionKeyRange.high = _3ewg->ReadUint8();
3780    
3781                    if (_3ewg->GetSize() > 32) {
3782                        // read MIDI rules
3783                        int i = 0;
3784                        _3ewg->SetPos(32);
3785                        uint8_t id1 = _3ewg->ReadUint8();
3786                        uint8_t id2 = _3ewg->ReadUint8();
3787    
3788                        if (id2 == 16) {
3789                            if (id1 == 4) {
3790                                pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
3791                            } else if (id1 == 0) {
3792                                pMidiRules[i++] = new MidiRuleLegato(_3ewg);
3793                            } else if (id1 == 3) {
3794                                pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
3795                            } else {
3796                                pMidiRules[i++] = new MidiRuleUnknown;
3797                            }
3798                        }
3799                        else if (id1 != 0 || id2 != 0) {
3800                            pMidiRules[i++] = new MidiRuleUnknown;
3801                        }
3802                        //TODO: all the other types of rules
3803    
3804                        pMidiRules[i] = NULL;
3805                    }
3806              }              }
3807          }          }
3808    
3809          if (!pRegions) pRegions = new RegionList;          if (pFile->GetAutoLoad()) {
3810          RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);              if (!pRegions) pRegions = new RegionList;
3811          if (lrgn) {              RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
3812              RIFF::List* rgn = lrgn->GetFirstSubList();              if (lrgn) {
3813              while (rgn) {                  RIFF::List* rgn = lrgn->GetFirstSubList();
3814                  if (rgn->GetListType() == LIST_TYPE_RGN) {                  while (rgn) {
3815                      __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);                      if (rgn->GetListType() == LIST_TYPE_RGN) {
3816                      pRegions->push_back(new Region(this, rgn));                          __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
3817                            pRegions->push_back(new Region(this, rgn));
3818                        }
3819                        rgn = lrgn->GetNextSubList();
3820                  }                  }
3821                  rgn = lrgn->GetNextSubList();                  // Creating Region Key Table for fast lookup
3822                    UpdateRegionKeyTable();
3823              }              }
             // Creating Region Key Table for fast lookup  
             UpdateRegionKeyTable();  
3824          }          }
3825    
3826          __notify_progress(pProgress, 1.0f); // notify done          __notify_progress(pProgress, 1.0f); // notify done
3827      }      }
3828    
3829      void Instrument::UpdateRegionKeyTable() {      void Instrument::UpdateRegionKeyTable() {
3830            for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
3831          RegionList::iterator iter = pRegions->begin();          RegionList::iterator iter = pRegions->begin();
3832          RegionList::iterator end  = pRegions->end();          RegionList::iterator end  = pRegions->end();
3833          for (; iter != end; ++iter) {          for (; iter != end; ++iter) {
# Line 2643  namespace { Line 3839  namespace {
3839      }      }
3840    
3841      Instrument::~Instrument() {      Instrument::~Instrument() {
3842            for (int i = 0 ; pMidiRules[i] ; i++) {
3843                delete pMidiRules[i];
3844            }
3845            delete[] pMidiRules;
3846      }      }
3847    
3848      /**      /**
# Line 2671  namespace { Line 3871  namespace {
3871          if (!lart)  lart = pCkInstrument->AddSubList(LIST_TYPE_LART);          if (!lart)  lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
3872          // make sure '3ewg' RIFF chunk exists          // make sure '3ewg' RIFF chunk exists
3873          RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);          RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
3874          if (!_3ewg)  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, 12);          if (!_3ewg)  {
3875                File* pFile = (File*) GetParent();
3876    
3877                // 3ewg is bigger in gig3, as it includes the iMIDI rules
3878                int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
3879                _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
3880                memset(_3ewg->LoadChunkData(), 0, size);
3881            }
3882          // update '3ewg' RIFF chunk          // update '3ewg' RIFF chunk
3883          uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();          uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
3884          memcpy(&pData[0], &EffectSend, 2);          store16(&pData[0], EffectSend);
3885          memcpy(&pData[2], &Attenuation, 4);          store32(&pData[2], Attenuation);
3886          memcpy(&pData[6], &FineTune, 2);          store16(&pData[6], FineTune);
3887          memcpy(&pData[8], &PitchbendRange, 2);          store16(&pData[8], PitchbendRange);
3888          const uint8_t dimkeystart = (PianoReleaseMode) ? 0x01 : 0x00 |          const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
3889                                      DimensionKeyRange.low << 1;                                      DimensionKeyRange.low << 1;
3890          memcpy(&pData[10], &dimkeystart, 1);          pData[10] = dimkeystart;
3891          memcpy(&pData[11], &DimensionKeyRange.high, 1);          pData[11] = DimensionKeyRange.high;
3892    
3893            if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
3894                pData[32] = 0;
3895                pData[33] = 0;
3896            } else {
3897                for (int i = 0 ; pMidiRules[i] ; i++) {
3898                    pMidiRules[i]->UpdateChunks(pData);
3899                }
3900            }
3901      }      }
3902    
3903      /**      /**
# Line 2692  namespace { Line 3908  namespace {
3908       *             there is no Region defined for the given \a Key       *             there is no Region defined for the given \a Key
3909       */       */
3910      Region* Instrument::GetRegion(unsigned int Key) {      Region* Instrument::GetRegion(unsigned int Key) {
3911          if (!pRegions || !pRegions->size() || Key > 127) return NULL;          if (!pRegions || pRegions->empty() || Key > 127) return NULL;
3912          return RegionKeyTable[Key];          return RegionKeyTable[Key];
3913    
3914          /*for (int i = 0; i < Regions; i++) {          /*for (int i = 0; i < Regions; i++) {
# Line 2750  namespace { Line 3966  namespace {
3966          UpdateRegionKeyTable();          UpdateRegionKeyTable();
3967      }      }
3968    
3969        /**
3970         * Returns a MIDI rule of the instrument.
3971         *
3972         * The list of MIDI rules, at least in gig v3, always contains at
3973         * most two rules. The second rule can only be the DEF filter
3974         * (which currently isn't supported by libgig).
3975         *
3976         * @param i - MIDI rule number
3977         * @returns   pointer address to MIDI rule number i or NULL if there is none
3978         */
3979        MidiRule* Instrument::GetMidiRule(int i) {
3980            return pMidiRules[i];
3981        }
3982    
3983        /**
3984         * Adds the "controller trigger" MIDI rule to the instrument.
3985         *
3986         * @returns the new MIDI rule
3987         */
3988        MidiRuleCtrlTrigger* Instrument::AddMidiRuleCtrlTrigger() {
3989            delete pMidiRules[0];
3990            MidiRuleCtrlTrigger* r = new MidiRuleCtrlTrigger;
3991            pMidiRules[0] = r;
3992            pMidiRules[1] = 0;
3993            return r;
3994        }
3995    
3996        /**
3997         * Adds the legato MIDI rule to the instrument.
3998         *
3999         * @returns the new MIDI rule
4000         */
4001        MidiRuleLegato* Instrument::AddMidiRuleLegato() {
4002            delete pMidiRules[0];
4003            MidiRuleLegato* r = new MidiRuleLegato;
4004            pMidiRules[0] = r;
4005            pMidiRules[1] = 0;
4006            return r;
4007        }
4008    
4009        /**
4010         * Adds the alternator MIDI rule to the instrument.
4011         *
4012         * @returns the new MIDI rule
4013         */
4014        MidiRuleAlternator* Instrument::AddMidiRuleAlternator() {
4015            delete pMidiRules[0];
4016            MidiRuleAlternator* r = new MidiRuleAlternator;
4017            pMidiRules[0] = r;
4018            pMidiRules[1] = 0;
4019            return r;
4020        }
4021    
4022        /**
4023         * Deletes a MIDI rule from the instrument.
4024         *
4025         * @param i - MIDI rule number
4026         */
4027        void Instrument::DeleteMidiRule(int i) {
4028            delete pMidiRules[i];
4029            pMidiRules[i] = 0;
4030        }
4031    
4032        /**
4033         * Make a (semi) deep copy of the Instrument object given by @a orig
4034         * and assign it to this object.
4035         *
4036         * Note that all sample pointers referenced by @a orig are simply copied as
4037         * memory address. Thus the respective samples are shared, not duplicated!
4038         *
4039         * @param orig - original Instrument object to be copied from
4040         */
4041        void Instrument::CopyAssign(const Instrument* orig) {
4042            CopyAssign(orig, NULL);
4043        }
4044            
4045        /**
4046         * Make a (semi) deep copy of the Instrument object given by @a orig
4047         * and assign it to this object.
4048         *
4049         * @param orig - original Instrument object to be copied from
4050         * @param mSamples - crosslink map between the foreign file's samples and
4051         *                   this file's samples
4052         */
4053        void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
4054            // handle base class
4055            // (without copying DLS region stuff)
4056            DLS::Instrument::CopyAssignCore(orig);
4057            
4058            // handle own member variables
4059            Attenuation = orig->Attenuation;
4060            EffectSend = orig->EffectSend;
4061            FineTune = orig->FineTune;
4062            PitchbendRange = orig->PitchbendRange;
4063            PianoReleaseMode = orig->PianoReleaseMode;
4064            DimensionKeyRange = orig->DimensionKeyRange;
4065            
4066            // free old midi rules
4067            for (int i = 0 ; pMidiRules[i] ; i++) {
4068                delete pMidiRules[i];
4069            }
4070            //TODO: MIDI rule copying
4071            pMidiRules[0] = NULL;
4072            
4073            // delete all old regions
4074            while (Regions) DeleteRegion(GetFirstRegion());
4075            // create new regions and copy them from original
4076            {
4077                RegionList::const_iterator it = orig->pRegions->begin();
4078                for (int i = 0; i < orig->Regions; ++i, ++it) {
4079                    Region* dstRgn = AddRegion();
4080                    //NOTE: Region does semi-deep copy !
4081                    dstRgn->CopyAssign(
4082                        static_cast<gig::Region*>(*it),
4083                        mSamples
4084                    );
4085                }
4086            }
4087    
4088            UpdateRegionKeyTable();
4089        }
4090    
4091    
4092  // *************** Group ***************  // *************** Group ***************
# Line 2783  namespace { Line 4120  namespace {
4120      void Group::UpdateChunks() {      void Group::UpdateChunks() {
4121          // make sure <3gri> and <3gnl> list chunks exist          // make sure <3gri> and <3gnl> list chunks exist
4122          RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);          RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
4123          if (!_3gri) _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);          if (!_3gri) {
4124                _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
4125                pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
4126            }
4127          RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);          RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
4128          if (!_3gnl) _3gnl = pFile->pRIFF->AddSubList(LIST_TYPE_3GNL);          if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
4129    
4130            if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
4131                // v3 has a fixed list of 128 strings, find a free one
4132                for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
4133                    if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
4134                        pNameChunk = ck;
4135                        break;
4136                    }
4137                }
4138            }
4139    
4140          // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk          // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
4141          ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);          ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
4142      }      }
# Line 2861  namespace { Line 4212  namespace {
4212  // *************** File ***************  // *************** File ***************
4213  // *  // *
4214    
4215        /// Reflects Gigasampler file format version 2.0 (1998-06-28).
4216        const DLS::version_t File::VERSION_2 = {
4217            0, 2, 19980628 & 0xffff, 19980628 >> 16
4218        };
4219    
4220        /// Reflects Gigasampler file format version 3.0 (2003-03-31).
4221        const DLS::version_t File::VERSION_3 = {
4222            0, 3, 20030331 & 0xffff, 20030331 >> 16
4223        };
4224    
4225        static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
4226            { CHUNK_ID_IARL, 256 },
4227            { CHUNK_ID_IART, 128 },
4228            { CHUNK_ID_ICMS, 128 },
4229            { CHUNK_ID_ICMT, 1024 },
4230            { CHUNK_ID_ICOP, 128 },
4231            { CHUNK_ID_ICRD, 128 },
4232            { CHUNK_ID_IENG, 128 },
4233            { CHUNK_ID_IGNR, 128 },
4234            { CHUNK_ID_IKEY, 128 },
4235            { CHUNK_ID_IMED, 128 },
4236            { CHUNK_ID_INAM, 128 },
4237            { CHUNK_ID_IPRD, 128 },
4238            { CHUNK_ID_ISBJ, 128 },
4239            { CHUNK_ID_ISFT, 128 },
4240            { CHUNK_ID_ISRC, 128 },
4241            { CHUNK_ID_ISRF, 128 },
4242            { CHUNK_ID_ITCH, 128 },
4243            { 0, 0 }
4244        };
4245    
4246      File::File() : DLS::File() {      File::File() : DLS::File() {
4247            bAutoLoad = true;
4248            *pVersion = VERSION_3;
4249          pGroups = NULL;          pGroups = NULL;
4250          pInfo->UseFixedLengthStrings = true;          pInfo->SetFixedStringLengths(_FileFixedStringLengths);
4251            pInfo->ArchivalLocation = String(256, ' ');
4252    
4253            // add some mandatory chunks to get the file chunks in right
4254            // order (INFO chunk will be moved to first position later)
4255            pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
4256            pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
4257            pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
4258    
4259            GenerateDLSID();
4260      }      }
4261    
4262      File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {      File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
4263            bAutoLoad = true;
4264          pGroups = NULL;          pGroups = NULL;
4265          pInfo->UseFixedLengthStrings = true;          pInfo->SetFixedStringLengths(_FileFixedStringLengths);
4266      }      }
4267    
4268      File::~File() {      File::~File() {
# Line 2895  namespace { Line 4289  namespace {
4289          SamplesIterator++;          SamplesIterator++;
4290          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
4291      }      }
4292        
4293        /**
4294         * Returns Sample object of @a index.
4295         *
4296         * @returns sample object or NULL if index is out of bounds
4297         */
4298        Sample* File::GetSample(uint index) {
4299            if (!pSamples) LoadSamples();
4300            if (!pSamples) return NULL;
4301            DLS::File::SampleList::iterator it = pSamples->begin();
4302            for (int i = 0; i < index; ++i) {
4303                ++it;
4304                if (it == pSamples->end()) return NULL;
4305            }
4306            if (it == pSamples->end()) return NULL;
4307            return static_cast<gig::Sample*>( *it );
4308        }
4309    
4310      /** @brief Add a new sample.      /** @brief Add a new sample.
4311       *       *
# Line 2910  namespace { Line 4321  namespace {
4321         // create new Sample object and its respective 'wave' list chunk         // create new Sample object and its respective 'wave' list chunk
4322         RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);         RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
4323         Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);         Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
4324    
4325           // add mandatory chunks to get the chunks in right order
4326           wave->AddSubChunk(CHUNK_ID_FMT, 16);
4327           wave->AddSubList(LIST_TYPE_INFO);
4328    
4329         pSamples->push_back(pSample);         pSamples->push_back(pSample);
4330         return pSample;         return pSample;
4331      }      }
4332    
4333      /** @brief Delete a sample.      /** @brief Delete a sample.
4334       *       *
4335       * This will delete the given Sample object from the gig file. You have       * This will delete the given Sample object from the gig file. Any
4336       * to call Save() to make this persistent to the file.       * references to this sample from Regions and DimensionRegions will be
4337         * removed. You have to call Save() to make this persistent to the file.
4338       *       *
4339       * @param pSample - sample to delete       * @param pSample - sample to delete
4340       * @throws gig::Exception if given sample could not be found       * @throws gig::Exception if given sample could not be found
# Line 2929  namespace { Line 4346  namespace {
4346          if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation          if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
4347          pSamples->erase(iter);          pSamples->erase(iter);
4348          delete pSample;          delete pSample;
4349    
4350            SampleList::iterator tmp = SamplesIterator;
4351            // remove all references to the sample
4352            for (Instrument* instrument = GetFirstInstrument() ; instrument ;
4353                 instrument = GetNextInstrument()) {
4354                for (Region* region = instrument->GetFirstRegion() ; region ;
4355                     region = instrument->GetNextRegion()) {
4356    
4357                    if (region->GetSample() == pSample) region->SetSample(NULL);
4358    
4359                    for (int i = 0 ; i < region->DimensionRegions ; i++) {
4360                        gig::DimensionRegion *d = region->pDimensionRegions[i];
4361                        if (d->pSample == pSample) d->pSample = NULL;
4362                    }
4363                }
4364            }
4365            SamplesIterator = tmp; // restore iterator
4366      }      }
4367    
4368      void File::LoadSamples() {      void File::LoadSamples() {
# Line 2938  namespace { Line 4372  namespace {
4372      void File::LoadSamples(progress_t* pProgress) {      void File::LoadSamples(progress_t* pProgress) {
4373          // Groups must be loaded before samples, because samples will try          // Groups must be loaded before samples, because samples will try
4374          // to resolve the group they belong to          // to resolve the group they belong to
4375          LoadGroups();          if (!pGroups) LoadGroups();
4376    
4377          if (!pSamples) pSamples = new SampleList;          if (!pSamples) pSamples = new SampleList;
4378    
# Line 3019  namespace { Line 4453  namespace {
4453              progress_t subprogress;              progress_t subprogress;
4454              __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask              __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
4455              __notify_progress(&subprogress, 0.0f);              __notify_progress(&subprogress, 0.0f);
4456              GetFirstSample(&subprogress); // now force all samples to be loaded              if (GetAutoLoad())
4457                    GetFirstSample(&subprogress); // now force all samples to be loaded
4458              __notify_progress(&subprogress, 1.0f);              __notify_progress(&subprogress, 1.0f);
4459    
4460              // instrument loading subtask              // instrument loading subtask
# Line 3052  namespace { Line 4487  namespace {
4487         __ensureMandatoryChunksExist();         __ensureMandatoryChunksExist();
4488         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
4489         RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);         RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
4490    
4491           // add mandatory chunks to get the chunks in right order
4492           lstInstr->AddSubList(LIST_TYPE_INFO);
4493           lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
4494    
4495         Instrument* pInstrument = new Instrument(this, lstInstr);         Instrument* pInstrument = new Instrument(this, lstInstr);
4496           pInstrument->GenerateDLSID();
4497    
4498           lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
4499    
4500           // this string is needed for the gig to be loadable in GSt:
4501           pInstrument->pInfo->Software = "Endless Wave";
4502    
4503         pInstruments->push_back(pInstrument);         pInstruments->push_back(pInstrument);
4504         return pInstrument;         return pInstrument;
4505      }      }
4506        
4507        /** @brief Add a duplicate of an existing instrument.
4508         *
4509         * Duplicates the instrument definition given by @a orig and adds it
4510         * to this file. This allows in an instrument editor application to
4511         * easily create variations of an instrument, which will be stored in
4512         * the same .gig file, sharing i.e. the same samples.
4513         *
4514         * Note that all sample pointers referenced by @a orig are simply copied as
4515         * memory address. Thus the respective samples are shared, not duplicated!
4516         *
4517         * You have to call Save() to make this persistent to the file.
4518         *
4519         * @param orig - original instrument to be copied
4520         * @returns duplicated copy of the given instrument
4521         */
4522        Instrument* File::AddDuplicateInstrument(const Instrument* orig) {
4523            Instrument* instr = AddInstrument();
4524            instr->CopyAssign(orig);
4525            return instr;
4526        }
4527        
4528        /** @brief Add content of another existing file.
4529         *
4530         * Duplicates the samples, groups and instruments of the original file
4531         * given by @a pFile and adds them to @c this File. In case @c this File is
4532         * a new one that you haven't saved before, then you have to call
4533         * SetFileName() before calling AddContentOf(), because this method will
4534         * automatically save this file during operation, which is required for
4535         * writing the sample waveform data by disk streaming.
4536         *
4537         * @param pFile - original file whose's content shall be copied from
4538         */
4539        void File::AddContentOf(File* pFile) {
4540            static int iCallCount = -1;
4541            iCallCount++;
4542            std::map<Group*,Group*> mGroups;
4543            std::map<Sample*,Sample*> mSamples;
4544            
4545            // clone sample groups
4546            for (int i = 0; pFile->GetGroup(i); ++i) {
4547                Group* g = AddGroup();
4548                g->Name =
4549                    "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
4550                mGroups[pFile->GetGroup(i)] = g;
4551            }
4552            
4553            // clone samples (not waveform data here yet)
4554            for (int i = 0; pFile->GetSample(i); ++i) {
4555                Sample* s = AddSample();
4556                s->CopyAssignMeta(pFile->GetSample(i));
4557                mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
4558                mSamples[pFile->GetSample(i)] = s;
4559            }
4560            
4561            //BUG: For some reason this method only works with this additional
4562            //     Save() call in between here.
4563            //
4564            // Important: The correct one of the 2 Save() methods has to be called
4565            // here, depending on whether the file is completely new or has been
4566            // saved to disk already, otherwise it will result in data corruption.
4567            if (pRIFF->IsNew())
4568                Save(GetFileName());
4569            else
4570                Save();
4571            
4572            // clone instruments
4573            // (passing the crosslink table here for the cloned samples)
4574            for (int i = 0; pFile->GetInstrument(i); ++i) {
4575                Instrument* instr = AddInstrument();
4576                instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
4577            }
4578            
4579            // Mandatory: file needs to be saved to disk at this point, so this
4580            // file has the correct size and data layout for writing the samples'
4581            // waveform data to disk.
4582            Save();
4583            
4584            // clone samples' waveform data
4585            // (using direct read & write disk streaming)
4586            for (int i = 0; pFile->GetSample(i); ++i) {
4587                mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
4588            }
4589        }
4590    
4591      /** @brief Delete an instrument.      /** @brief Delete an instrument.
4592       *       *
# Line 3103  namespace { Line 4634  namespace {
4634          }          }
4635      }      }
4636    
4637        /// Updates the 3crc chunk with the checksum of a sample. The
4638        /// update is done directly to disk, as this method is called
4639        /// after File::Save()
4640        void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
4641            RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
4642            if (!_3crc) return;
4643    
4644            // get the index of the sample
4645            int iWaveIndex = -1;
4646            File::SampleList::iterator iter = pSamples->begin();
4647            File::SampleList::iterator end  = pSamples->end();
4648            for (int index = 0; iter != end; ++iter, ++index) {
4649                if (*iter == pSample) {
4650                    iWaveIndex = index;
4651                    break;
4652                }
4653            }
4654            if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
4655    
4656            // write the CRC-32 checksum to disk
4657            _3crc->SetPos(iWaveIndex * 8);
4658            uint32_t tmp = 1;
4659            _3crc->WriteUint32(&tmp); // unknown, always 1?
4660            _3crc->WriteUint32(&crc);
4661        }
4662    
4663      Group* File::GetFirstGroup() {      Group* File::GetFirstGroup() {
4664          if (!pGroups) LoadGroups();          if (!pGroups) LoadGroups();
4665          // there must always be at least one group          // there must always be at least one group
# Line 3132  namespace { Line 4689  namespace {
4689          return NULL;          return NULL;
4690      }      }
4691    
4692        /**
4693         * Returns the group with the given group name.
4694         *
4695         * Note: group names don't have to be unique in the gig format! So there
4696         * can be multiple groups with the same name. This method will simply
4697         * return the first group found with the given name.
4698         *
4699         * @param name - name of the sought group
4700         * @returns sought group or NULL if there's no group with that name
4701         */
4702        Group* File::GetGroup(String name) {
4703            if (!pGroups) LoadGroups();
4704            GroupsIterator = pGroups->begin();
4705            for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
4706                if ((*GroupsIterator)->Name == name) return *GroupsIterator;
4707            return NULL;
4708        }
4709    
4710      Group* File::AddGroup() {      Group* File::AddGroup() {
4711          if (!pGroups) LoadGroups();          if (!pGroups) LoadGroups();
4712          // there must always be at least one group          // there must always be at least one group
# Line 3195  namespace { Line 4770  namespace {
4770                  RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();                  RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
4771                  while (ck) {                  while (ck) {
4772                      if (ck->GetChunkID() == CHUNK_ID_3GNM) {                      if (ck->GetChunkID() == CHUNK_ID_3GNM) {
4773                            if (pVersion && pVersion->major == 3 &&
4774                                strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
4775    
4776                          pGroups->push_back(new Group(this, ck));                          pGroups->push_back(new Group(this, ck));
4777                      }                      }
4778                      ck = lst3gnl->GetNextSubChunk();                      ck = lst3gnl->GetNextSubChunk();
# Line 3220  namespace { Line 4798  namespace {
4798       * @throws Exception - on errors       * @throws Exception - on errors
4799       */       */
4800      void File::UpdateChunks() {      void File::UpdateChunks() {
4801            bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
4802    
4803            b64BitWavePoolOffsets = pVersion && pVersion->major == 3;
4804    
4805          // first update base class's chunks          // first update base class's chunks
4806          DLS::File::UpdateChunks();          DLS::File::UpdateChunks();
4807    
4808            if (newFile) {
4809                // INFO was added by Resource::UpdateChunks - make sure it
4810                // is placed first in file
4811                RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
4812                RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
4813                if (first != info) {
4814                    pRIFF->MoveSubChunk(info, first);
4815                }
4816            }
4817    
4818          // update group's chunks          // update group's chunks
4819          if (pGroups) {          if (pGroups) {
4820                // make sure '3gri' and '3gnl' list chunks exist
4821                // (before updating the Group chunks)
4822                RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
4823                if (!_3gri) {
4824                    _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
4825                    pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
4826                }
4827                RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
4828                if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
4829    
4830                // v3: make sure the file has 128 3gnm chunks
4831                // (before updating the Group chunks)
4832                if (pVersion && pVersion->major == 3) {
4833                    RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
4834                    for (int i = 0 ; i < 128 ; i++) {
4835                        if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
4836                        if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
4837                    }
4838                }
4839    
4840              std::list<Group*>::iterator iter = pGroups->begin();              std::list<Group*>::iterator iter = pGroups->begin();
4841              std::list<Group*>::iterator end  = pGroups->end();              std::list<Group*>::iterator end  = pGroups->end();
4842              for (; iter != end; ++iter) {              for (; iter != end; ++iter) {
4843                  (*iter)->UpdateChunks();                  (*iter)->UpdateChunks();
4844              }              }
4845          }          }
4846    
4847            // update einf chunk
4848    
4849            // The einf chunk contains statistics about the gig file, such
4850            // as the number of regions and samples used by each
4851            // instrument. It is divided in equally sized parts, where the
4852            // first part contains information about the whole gig file,
4853            // and the rest of the parts map to each instrument in the
4854            // file.
4855            //
4856            // At the end of each part there is a bit map of each sample
4857            // in the file, where a set bit means that the sample is used
4858            // by the file/instrument.
4859            //
4860            // Note that there are several fields with unknown use. These
4861            // are set to zero.
4862    
4863            int sublen = pSamples->size() / 8 + 49;
4864            int einfSize = (Instruments + 1) * sublen;
4865    
4866            RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
4867            if (einf) {
4868                if (einf->GetSize() != einfSize) {
4869                    einf->Resize(einfSize);
4870                    memset(einf->LoadChunkData(), 0, einfSize);
4871                }
4872            } else if (newFile) {
4873                einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
4874            }
4875            if (einf) {
4876                uint8_t* pData = (uint8_t*) einf->LoadChunkData();
4877    
4878                std::map<gig::Sample*,int> sampleMap;
4879                int sampleIdx = 0;
4880                for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
4881                    sampleMap[pSample] = sampleIdx++;
4882                }
4883    
4884                int totnbusedsamples = 0;
4885                int totnbusedchannels = 0;
4886                int totnbregions = 0;
4887                int totnbdimregions = 0;
4888                int totnbloops = 0;
4889                int instrumentIdx = 0;
4890    
4891                memset(&pData[48], 0, sublen - 48);
4892    
4893                for (Instrument* instrument = GetFirstInstrument() ; instrument ;
4894                     instrument = GetNextInstrument()) {
4895                    int nbusedsamples = 0;
4896                    int nbusedchannels = 0;
4897                    int nbdimregions = 0;
4898                    int nbloops = 0;
4899    
4900                    memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
4901    
4902                    for (Region* region = instrument->GetFirstRegion() ; region ;
4903                         region = instrument->GetNextRegion()) {
4904                        for (int i = 0 ; i < region->DimensionRegions ; i++) {
4905                            gig::DimensionRegion *d = region->pDimensionRegions[i];
4906                            if (d->pSample) {
4907                                int sampleIdx = sampleMap[d->pSample];
4908                                int byte = 48 + sampleIdx / 8;
4909                                int bit = 1 << (sampleIdx & 7);
4910                                if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
4911                                    pData[(instrumentIdx + 1) * sublen + byte] |= bit;
4912                                    nbusedsamples++;
4913                                    nbusedchannels += d->pSample->Channels;
4914    
4915                                    if ((pData[byte] & bit) == 0) {
4916                                        pData[byte] |= bit;
4917                                        totnbusedsamples++;
4918                                        totnbusedchannels += d->pSample->Channels;
4919                                    }
4920                                }
4921                            }
4922                            if (d->SampleLoops) nbloops++;
4923                        }
4924                        nbdimregions += region->DimensionRegions;
4925                    }
4926                    // first 4 bytes unknown - sometimes 0, sometimes length of einf part
4927                    // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
4928                    store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
4929                    store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
4930                    store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
4931                    store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
4932                    store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
4933                    store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
4934                    // next 8 bytes unknown
4935                    store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
4936                    store32(&pData[(instrumentIdx + 1) * sublen + 40], pSamples->size());
4937                    // next 4 bytes unknown
4938    
4939                    totnbregions += instrument->Regions;
4940                    totnbdimregions += nbdimregions;
4941                    totnbloops += nbloops;
4942                    instrumentIdx++;
4943                }
4944                // first 4 bytes unknown - sometimes 0, sometimes length of einf part
4945                // store32(&pData[0], sublen);
4946                store32(&pData[4], totnbusedchannels);
4947                store32(&pData[8], totnbusedsamples);
4948                store32(&pData[12], Instruments);
4949                store32(&pData[16], totnbregions);
4950                store32(&pData[20], totnbdimregions);
4951                store32(&pData[24], totnbloops);
4952                // next 8 bytes unknown
4953                // next 4 bytes unknown, not always 0
4954                store32(&pData[40], pSamples->size());
4955                // next 4 bytes unknown
4956            }
4957    
4958            // update 3crc chunk
4959    
4960            // The 3crc chunk contains CRC-32 checksums for the
4961            // samples. The actual checksum values will be filled in
4962            // later, by Sample::Write.
4963    
4964            RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
4965            if (_3crc) {
4966                _3crc->Resize(pSamples->size() * 8);
4967            } else if (newFile) {
4968                _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
4969                _3crc->LoadChunkData();
4970    
4971                // the order of einf and 3crc is not the same in v2 and v3
4972                if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
4973            }
4974        }
4975    
4976        /**
4977         * Enable / disable automatic loading. By default this properyt is
4978         * enabled and all informations are loaded automatically. However
4979         * loading all Regions, DimensionRegions and especially samples might
4980         * take a long time for large .gig files, and sometimes one might only
4981         * be interested in retrieving very superficial informations like the
4982         * amount of instruments and their names. In this case one might disable
4983         * automatic loading to avoid very slow response times.
4984         *
4985         * @e CAUTION: by disabling this property many pointers (i.e. sample
4986         * references) and informations will have invalid or even undefined
4987         * data! This feature is currently only intended for retrieving very
4988         * superficial informations in a very fast way. Don't use it to retrieve
4989         * details like synthesis informations or even to modify .gig files!
4990         */
4991        void File::SetAutoLoad(bool b) {
4992            bAutoLoad = b;
4993        }
4994    
4995        /**
4996         * Returns whether automatic loading is enabled.
4997         * @see SetAutoLoad()
4998         */
4999        bool File::GetAutoLoad() {
5000            return bAutoLoad;
5001      }      }
5002    
5003    

Legend:
Removed from v.1113  
changed lines
  Added in v.2547

  ViewVC Help
Powered by ViewVC