/[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 1384 by schoenebeck, Fri Oct 5 11:26:53 2007 UTC revision 2394 by schoenebeck, Mon Jan 7 23:23:58 2013 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-2013 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 366  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          static const DLS::Info::FixedStringLength fixedStringLengths[] = {          static const DLS::Info::string_length_t fixedStringLengths[] = {
371              { CHUNK_ID_INAM, 64 },              { CHUNK_ID_INAM, 64 },
372              { 0, 0 }              { 0, 0 }
373          };          };
374          pInfo->FixedStringLengths = fixedStringLengths;          pInfo->SetFixedStringLengths(fixedStringLengths);
375          Instances++;          Instances++;
376          FileNo = fileNo;          FileNo = fileNo;
377    
# Line 676  namespace { Line 677  namespace {
677          if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;          if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
678          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
679          unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;          unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
680            SetPos(0); // reset read position to begin of sample
681          RAMCache.pStart            = new int8_t[allocationsize];          RAMCache.pStart            = new int8_t[allocationsize];
682          RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;          RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
683          RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;          RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
# Line 713  namespace { Line 715  namespace {
715          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
716          RAMCache.pStart = NULL;          RAMCache.pStart = NULL;
717          RAMCache.Size   = 0;          RAMCache.Size   = 0;
718            RAMCache.NullExtensionSize = 0;
719      }      }
720    
721      /** @brief Resize sample.      /** @brief Resize sample.
# Line 907  namespace { Line 910  namespace {
910                                  }                                  }
911    
912                                  // reverse the sample frames for backward playback                                  // reverse the sample frames for backward playback
913                                  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!
914                                        SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
915                              }                              }
916                          } while (samplestoread && readsamples);                          } while (samplestoread && readsamples);
917                          break;                          break;
# Line 1577  namespace { Line 1581  namespace {
1581       */       */
1582      DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1583          Instances++;          Instances++;
1584            //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1585          *this = src; // default memberwise shallow copy of all parameters          *this = src; // default memberwise shallow copy of all parameters
1586          pParentList = _3ewl; // restore the chunk pointer          pParentList = _3ewl; // restore the chunk pointer
1587    
# Line 1592  namespace { Line 1597  namespace {
1597                  pSampleLoops[k] = src.pSampleLoops[k];                  pSampleLoops[k] = src.pSampleLoops[k];
1598          }          }
1599      }      }
1600        
1601        /**
1602         * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1603         * and assign it to this object.
1604         *
1605         * Note that all sample pointers referenced by @a orig are simply copied as
1606         * memory address. Thus the respective samples are shared, not duplicated!
1607         *
1608         * @param orig - original DimensionRegion object to be copied from
1609         */
1610        void DimensionRegion::CopyAssign(const DimensionRegion* orig) {
1611            // delete all allocated data first
1612            if (VelocityTable) delete [] VelocityTable;
1613            if (pSampleLoops) delete [] pSampleLoops;
1614            
1615            // backup parent list pointer
1616            RIFF::List* p = pParentList;
1617            
1618            //NOTE: copy code copied from assignment constructor above, see comment there as well
1619            
1620            *this = *orig; // default memberwise shallow copy of all parameters
1621            pParentList = p; // restore the chunk pointer
1622    
1623            // deep copy of owned structures
1624            if (orig->VelocityTable) {
1625                VelocityTable = new uint8_t[128];
1626                for (int k = 0 ; k < 128 ; k++)
1627                    VelocityTable[k] = orig->VelocityTable[k];
1628            }
1629            if (orig->pSampleLoops) {
1630                pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops];
1631                for (int k = 0 ; k < orig->SampleLoops ; k++)
1632                    pSampleLoops[k] = orig->pSampleLoops[k];
1633            }
1634        }
1635    
1636      /**      /**
1637       * Updates the respective member variable and updates @c SampleAttenuation       * Updates the respective member variable and updates @c SampleAttenuation
# Line 1834  namespace { Line 1874  namespace {
1874    
1875          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1876                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
1877          pData[116] = eg3depth;          store16(&pData[116], eg3depth);
1878    
1879          // next 2 bytes unknown          // next 2 bytes unknown
1880    
# Line 1881  namespace { Line 1921  namespace {
1921                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
1922          pData[137] = vcfbreakpoint;          pData[137] = vcfbreakpoint;
1923    
1924          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
1925                                      VCFVelocityCurve * 5;                                      VCFVelocityCurve * 5;
1926          pData[138] = vcfvelocity;          pData[138] = vcfvelocity;
1927    
# Line 2372  namespace { Line 2412  namespace {
2412    
2413          // Actual Loading          // Actual Loading
2414    
2415            if (!file->GetAutoLoad()) return;
2416    
2417          LoadDimensionRegions(rgnList);          LoadDimensionRegions(rgnList);
2418    
2419          RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);          RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
# Line 2415  namespace { Line 2457  namespace {
2457              else              else
2458                  _3lnk->SetPos(44);                  _3lnk->SetPos(44);
2459    
2460              // load sample references              // load sample references (if auto loading is enabled)
2461              for (uint i = 0; i < DimensionRegions; i++) {              if (file->GetAutoLoad()) {
2462                  uint32_t wavepoolindex = _3lnk->ReadUint32();                  for (uint i = 0; i < DimensionRegions; i++) {
2463                  if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);                      uint32_t wavepoolindex = _3lnk->ReadUint32();
2464                        if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
2465                    }
2466                    GetSample(); // load global region sample reference
2467              }              }
             GetSample(); // load global region sample reference  
2468          } else {          } else {
2469              DimensionRegions = 0;              DimensionRegions = 0;
2470              for (int i = 0 ; i < 8 ; i++) {              for (int i = 0 ; i < 8 ; i++) {
# Line 2917  namespace { Line 2961  namespace {
2961          }          }
2962          return NULL;          return NULL;
2963      }      }
2964        
2965        /**
2966         * Make a (semi) deep copy of the Region object given by @a orig
2967         * and assign it to this object.
2968         *
2969         * Note that all sample pointers referenced by @a orig are simply copied as
2970         * memory address. Thus the respective samples are shared, not duplicated!
2971         *
2972         * @param orig - original Region object to be copied from
2973         */
2974        void Region::CopyAssign(const Region* orig) {
2975            // handle base classes
2976            DLS::Region::CopyAssign(orig);
2977            
2978            // handle own member variables
2979            for (int i = Dimensions - 1; i >= 0; --i) {
2980                DeleteDimension(&pDimensionDefinitions[i]);
2981            }
2982            Layers = 0; // just to be sure
2983            for (int i = 0; i < orig->Dimensions; i++) {
2984                // we need to copy the dim definition here, to avoid the compiler
2985                // complaining about const-ness issue
2986                dimension_def_t def = orig->pDimensionDefinitions[i];
2987                AddDimension(&def);
2988            }
2989            for (int i = 0; i < 256; i++) {
2990                if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
2991                    pDimensionRegions[i]->CopyAssign(
2992                        orig->pDimensionRegions[i]
2993                    );
2994                }
2995            }
2996            Layers = orig->Layers;
2997        }
2998    
2999    
3000    // *************** MidiRule ***************
3001    // *
3002    
3003    MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
3004        _3ewg->SetPos(36);
3005        Triggers = _3ewg->ReadUint8();
3006        _3ewg->SetPos(40);
3007        ControllerNumber = _3ewg->ReadUint8();
3008        _3ewg->SetPos(46);
3009        for (int i = 0 ; i < Triggers ; i++) {
3010            pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
3011            pTriggers[i].Descending = _3ewg->ReadUint8();
3012            pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
3013            pTriggers[i].Key = _3ewg->ReadUint8();
3014            pTriggers[i].NoteOff = _3ewg->ReadUint8();
3015            pTriggers[i].Velocity = _3ewg->ReadUint8();
3016            pTriggers[i].OverridePedal = _3ewg->ReadUint8();
3017            _3ewg->ReadUint8();
3018        }
3019    }
3020    
3021    
3022  // *************** Instrument ***************  // *************** Instrument ***************
3023  // *  // *
3024    
3025      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) {
3026          static const DLS::Info::FixedStringLength fixedStringLengths[] = {          static const DLS::Info::string_length_t fixedStringLengths[] = {
3027              { CHUNK_ID_INAM, 64 },              { CHUNK_ID_INAM, 64 },
3028              { CHUNK_ID_ISFT, 12 },              { CHUNK_ID_ISFT, 12 },
3029              { 0, 0 }              { 0, 0 }
3030          };          };
3031          pInfo->FixedStringLengths = fixedStringLengths;          pInfo->SetFixedStringLengths(fixedStringLengths);
3032    
3033          // Initialization          // Initialization
3034          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
# Line 2940  namespace { Line 3039  namespace {
3039          PianoReleaseMode = false;          PianoReleaseMode = false;
3040          DimensionKeyRange.low = 0;          DimensionKeyRange.low = 0;
3041          DimensionKeyRange.high = 0;          DimensionKeyRange.high = 0;
3042            pMidiRules = new MidiRule*[3];
3043            pMidiRules[0] = NULL;
3044    
3045          // Loading          // Loading
3046          RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);          RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
# Line 2954  namespace { Line 3055  namespace {
3055                  PianoReleaseMode       = dimkeystart & 0x01;                  PianoReleaseMode       = dimkeystart & 0x01;
3056                  DimensionKeyRange.low  = dimkeystart >> 1;                  DimensionKeyRange.low  = dimkeystart >> 1;
3057                  DimensionKeyRange.high = _3ewg->ReadUint8();                  DimensionKeyRange.high = _3ewg->ReadUint8();
3058    
3059                    if (_3ewg->GetSize() > 32) {
3060                        // read MIDI rules
3061                        int i = 0;
3062                        _3ewg->SetPos(32);
3063                        uint8_t id1 = _3ewg->ReadUint8();
3064                        uint8_t id2 = _3ewg->ReadUint8();
3065    
3066                        if (id1 == 4 && id2 == 16) {
3067                            pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
3068                        }
3069                        //TODO: all the other types of rules
3070    
3071                        pMidiRules[i] = NULL;
3072                    }
3073              }              }
3074          }          }
3075    
3076          if (!pRegions) pRegions = new RegionList;          if (pFile->GetAutoLoad()) {
3077          RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);              if (!pRegions) pRegions = new RegionList;
3078          if (lrgn) {              RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
3079              RIFF::List* rgn = lrgn->GetFirstSubList();              if (lrgn) {
3080              while (rgn) {                  RIFF::List* rgn = lrgn->GetFirstSubList();
3081                  if (rgn->GetListType() == LIST_TYPE_RGN) {                  while (rgn) {
3082                      __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);                      if (rgn->GetListType() == LIST_TYPE_RGN) {
3083                      pRegions->push_back(new Region(this, rgn));                          __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
3084                            pRegions->push_back(new Region(this, rgn));
3085                        }
3086                        rgn = lrgn->GetNextSubList();
3087                  }                  }
3088                  rgn = lrgn->GetNextSubList();                  // Creating Region Key Table for fast lookup
3089                    UpdateRegionKeyTable();
3090              }              }
             // Creating Region Key Table for fast lookup  
             UpdateRegionKeyTable();  
3091          }          }
3092    
3093          __notify_progress(pProgress, 1.0f); // notify done          __notify_progress(pProgress, 1.0f); // notify done
# Line 2988  namespace { Line 3106  namespace {
3106      }      }
3107    
3108      Instrument::~Instrument() {      Instrument::~Instrument() {
3109            for (int i = 0 ; pMidiRules[i] ; i++) {
3110                delete pMidiRules[i];
3111            }
3112            delete[] pMidiRules;
3113      }      }
3114    
3115      /**      /**
# Line 3102  namespace { Line 3224  namespace {
3224          UpdateRegionKeyTable();          UpdateRegionKeyTable();
3225      }      }
3226    
3227        /**
3228         * Returns a MIDI rule of the instrument.
3229         *
3230         * The list of MIDI rules, at least in gig v3, always contains at
3231         * most two rules. The second rule can only be the DEF filter
3232         * (which currently isn't supported by libgig).
3233         *
3234         * @param i - MIDI rule number
3235         * @returns   pointer address to MIDI rule number i or NULL if there is none
3236         */
3237        MidiRule* Instrument::GetMidiRule(int i) {
3238            return pMidiRules[i];
3239        }
3240        
3241        /**
3242         * Make a (semi) deep copy of the Instrument object given by @a orig
3243         * and assign it to this object.
3244         *
3245         * Note that all sample pointers referenced by @a orig are simply copied as
3246         * memory address. Thus the respective samples are shared, not duplicated!
3247         *
3248         * @param orig - original Instrument object to be copied from
3249         */
3250        void Instrument::CopyAssign(const Instrument* orig) {
3251            // handle base class
3252            // (without copying DLS region stuff)
3253            DLS::Instrument::CopyAssignCore(orig);
3254            
3255            // handle own member variables
3256            Attenuation = orig->Attenuation;
3257            EffectSend = orig->EffectSend;
3258            FineTune = orig->FineTune;
3259            PitchbendRange = orig->PitchbendRange;
3260            PianoReleaseMode = orig->PianoReleaseMode;
3261            DimensionKeyRange = orig->DimensionKeyRange;
3262            
3263            // free old midi rules
3264            for (int i = 0 ; pMidiRules[i] ; i++) {
3265                delete pMidiRules[i];
3266            }
3267            //TODO: MIDI rule copying
3268            pMidiRules[0] = NULL;
3269            
3270            // delete all old regions
3271            while (Regions) DeleteRegion(GetFirstRegion());
3272            // create new regions and copy them from original
3273            {
3274                RegionList::const_iterator it = orig->pRegions->begin();
3275                for (int i = 0; i < orig->Regions; ++i, ++it) {
3276                    Region* dstRgn = AddRegion();
3277                    //NOTE: Region does semi-deep copy !
3278                    dstRgn->CopyAssign(
3279                        static_cast<gig::Region*>(*it)
3280                    );
3281                }
3282            }
3283    
3284            UpdateRegionKeyTable();
3285        }
3286    
3287    
3288  // *************** Group ***************  // *************** Group ***************
# Line 3237  namespace { Line 3418  namespace {
3418          0, 3, 20030331 & 0xffff, 20030331 >> 16          0, 3, 20030331 & 0xffff, 20030331 >> 16
3419      };      };
3420    
3421      const DLS::Info::FixedStringLength File::FixedStringLengths[] = {      static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
3422          { CHUNK_ID_IARL, 256 },          { CHUNK_ID_IARL, 256 },
3423          { CHUNK_ID_IART, 128 },          { CHUNK_ID_IART, 128 },
3424          { CHUNK_ID_ICMS, 128 },          { CHUNK_ID_ICMS, 128 },
# Line 3259  namespace { Line 3440  namespace {
3440      };      };
3441    
3442      File::File() : DLS::File() {      File::File() : DLS::File() {
3443            bAutoLoad = true;
3444          *pVersion = VERSION_3;          *pVersion = VERSION_3;
3445          pGroups = NULL;          pGroups = NULL;
3446          pInfo->FixedStringLengths = FixedStringLengths;          pInfo->SetFixedStringLengths(_FileFixedStringLengths);
3447          pInfo->ArchivalLocation = String(256, ' ');          pInfo->ArchivalLocation = String(256, ' ');
3448    
3449          // add some mandatory chunks to get the file chunks in right          // add some mandatory chunks to get the file chunks in right
# Line 3274  namespace { Line 3456  namespace {
3456      }      }
3457    
3458      File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {      File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
3459            bAutoLoad = true;
3460          pGroups = NULL;          pGroups = NULL;
3461          pInfo->FixedStringLengths = FixedStringLengths;          pInfo->SetFixedStringLengths(_FileFixedStringLengths);
3462      }      }
3463    
3464      File::~File() {      File::~File() {
# Line 3343  namespace { Line 3526  namespace {
3526          pSamples->erase(iter);          pSamples->erase(iter);
3527          delete pSample;          delete pSample;
3528    
3529            SampleList::iterator tmp = SamplesIterator;
3530          // remove all references to the sample          // remove all references to the sample
3531          for (Instrument* instrument = GetFirstInstrument() ; instrument ;          for (Instrument* instrument = GetFirstInstrument() ; instrument ;
3532               instrument = GetNextInstrument()) {               instrument = GetNextInstrument()) {
# Line 3357  namespace { Line 3541  namespace {
3541                  }                  }
3542              }              }
3543          }          }
3544            SamplesIterator = tmp; // restore iterator
3545      }      }
3546    
3547      void File::LoadSamples() {      void File::LoadSamples() {
# Line 3447  namespace { Line 3632  namespace {
3632              progress_t subprogress;              progress_t subprogress;
3633              __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
3634              __notify_progress(&subprogress, 0.0f);              __notify_progress(&subprogress, 0.0f);
3635              GetFirstSample(&subprogress); // now force all samples to be loaded              if (GetAutoLoad())
3636                    GetFirstSample(&subprogress); // now force all samples to be loaded
3637              __notify_progress(&subprogress, 1.0f);              __notify_progress(&subprogress, 1.0f);
3638    
3639              // instrument loading subtask              // instrument loading subtask
# Line 3496  namespace { Line 3682  namespace {
3682         pInstruments->push_back(pInstrument);         pInstruments->push_back(pInstrument);
3683         return pInstrument;         return pInstrument;
3684      }      }
3685        
3686        /** @brief Add a duplicate of an existing instrument.
3687         *
3688         * Duplicates the instrument definition given by @a orig and adds it
3689         * to this file. This allows in an instrument editor application to
3690         * easily create variations of an instrument, which will be stored in
3691         * the same .gig file, sharing i.e. the same samples.
3692         *
3693         * Note that all sample pointers referenced by @a orig are simply copied as
3694         * memory address. Thus the respective samples are shared, not duplicated!
3695         *
3696         * You have to call Save() to make this persistent to the file.
3697         *
3698         * @param orig - original instrument to be copied
3699         * @returns duplicated copy of the given instrument
3700         */
3701        Instrument* File::AddDuplicateInstrument(const Instrument* orig) {
3702            Instrument* instr = AddInstrument();
3703            instr->CopyAssign(orig);
3704            return instr;
3705        }
3706    
3707      /** @brief Delete an instrument.      /** @brief Delete an instrument.
3708       *       *
# Line 3854  namespace { Line 4061  namespace {
4061          }          }
4062      }      }
4063    
4064        /**
4065         * Enable / disable automatic loading. By default this properyt is
4066         * enabled and all informations are loaded automatically. However
4067         * loading all Regions, DimensionRegions and especially samples might
4068         * take a long time for large .gig files, and sometimes one might only
4069         * be interested in retrieving very superficial informations like the
4070         * amount of instruments and their names. In this case one might disable
4071         * automatic loading to avoid very slow response times.
4072         *
4073         * @e CAUTION: by disabling this property many pointers (i.e. sample
4074         * references) and informations will have invalid or even undefined
4075         * data! This feature is currently only intended for retrieving very
4076         * superficial informations in a very fast way. Don't use it to retrieve
4077         * details like synthesis informations or even to modify .gig files!
4078         */
4079        void File::SetAutoLoad(bool b) {
4080            bAutoLoad = b;
4081        }
4082    
4083        /**
4084         * Returns whether automatic loading is enabled.
4085         * @see SetAutoLoad()
4086         */
4087        bool File::GetAutoLoad() {
4088            return bAutoLoad;
4089        }
4090    
4091    
4092    
4093  // *************** Exception ***************  // *************** Exception ***************

Legend:
Removed from v.1384  
changed lines
  Added in v.2394

  ViewVC Help
Powered by ViewVC