/[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 1875 by schoenebeck, Thu Mar 26 13:32:59 2009 UTC revision 2555 by schoenebeck, Fri May 16 23:08:42 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-2009 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 28  Line 28 
28  #include <algorithm>  #include <algorithm>
29  #include <math.h>  #include <math.h>
30  #include <iostream>  #include <iostream>
31    #include <assert.h>
32    
33  /// Initial size of the sample buffer which is used for decompression of  /// Initial size of the sample buffer which is used for decompression of
34  /// compressed sample wave streams - this value should always be bigger than  /// compressed sample wave streams - this value should always be bigger than
# Line 454  namespace { Line 455  namespace {
455      }      }
456    
457      /**      /**
458         * Make a (semi) deep copy of the Sample object given by @a orig (without
459         * the actual waveform data) and assign it to this object.
460         *
461         * Discussion: copying .gig samples is a bit tricky. It requires three
462         * steps:
463         * 1. Copy sample's meta informations (done by CopyAssignMeta()) including
464         *    its new sample waveform data size.
465         * 2. Saving the file (done by File::Save()) so that it gains correct size
466         *    and layout for writing the actual wave form data directly to disc
467         *    in next step.
468         * 3. Copy the waveform data with disk streaming (done by CopyAssignWave()).
469         *
470         * @param orig - original Sample object to be copied from
471         */
472        void Sample::CopyAssignMeta(const Sample* orig) {
473            // handle base classes
474            DLS::Sample::CopyAssignCore(orig);
475            
476            // handle actual own attributes of this class
477            Manufacturer = orig->Manufacturer;
478            Product = orig->Product;
479            SamplePeriod = orig->SamplePeriod;
480            MIDIUnityNote = orig->MIDIUnityNote;
481            FineTune = orig->FineTune;
482            SMPTEFormat = orig->SMPTEFormat;
483            SMPTEOffset = orig->SMPTEOffset;
484            Loops = orig->Loops;
485            LoopID = orig->LoopID;
486            LoopType = orig->LoopType;
487            LoopStart = orig->LoopStart;
488            LoopEnd = orig->LoopEnd;
489            LoopSize = orig->LoopSize;
490            LoopFraction = orig->LoopFraction;
491            LoopPlayCount = orig->LoopPlayCount;
492            
493            // schedule resizing this sample to the given sample's size
494            Resize(orig->GetSize());
495        }
496    
497        /**
498         * Should be called after CopyAssignMeta() and File::Save() sequence.
499         * Read more about it in the discussion of CopyAssignMeta(). This method
500         * copies the actual waveform data by disk streaming.
501         *
502         * @e CAUTION: this method is currently not thread safe! During this
503         * operation the sample must not be used for other purposes by other
504         * threads!
505         *
506         * @param orig - original Sample object to be copied from
507         */
508        void Sample::CopyAssignWave(const Sample* orig) {
509            const int iReadAtOnce = 32*1024;
510            char* buf = new char[iReadAtOnce * orig->FrameSize];
511            Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
512            unsigned long restorePos = pOrig->GetPos();
513            pOrig->SetPos(0);
514            SetPos(0);
515            for (unsigned long n = pOrig->Read(buf, iReadAtOnce); n;
516                               n = pOrig->Read(buf, iReadAtOnce))
517            {
518                Write(buf, n);
519            }
520            pOrig->SetPos(restorePos);
521            delete [] buf;
522        }
523    
524        /**
525       * Apply sample and its settings to the respective RIFF chunks. You have       * Apply sample and its settings to the respective RIFF chunks. You have
526       * to call File::Save() to make changes persistent.       * to call File::Save() to make changes persistent.
527       *       *
# Line 514  namespace { Line 582  namespace {
582          // update '3gix' chunk          // update '3gix' chunk
583          pData = (uint8_t*) pCk3gix->LoadChunkData();          pData = (uint8_t*) pCk3gix->LoadChunkData();
584          store16(&pData[0], iSampleGroup);          store16(&pData[0], iSampleGroup);
585    
586            // if the library user toggled the "Compressed" attribute from true to
587            // false, then the EWAV chunk associated with compressed samples needs
588            // to be deleted
589            RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
590            if (ewav && !Compressed) {
591                pWaveList->DeleteSubChunk(ewav);
592            }
593      }      }
594    
595      /// 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 808  namespace { Line 884  namespace {
884      /**      /**
885       * Returns the current position in the sample (in sample points).       * Returns the current position in the sample (in sample points).
886       */       */
887      unsigned long Sample::GetPos() {      unsigned long Sample::GetPos() const {
888          if (Compressed) return SamplePos;          if (Compressed) return SamplePos;
889          else            return pCkData->GetPos() / FrameSize;          else            return pCkData->GetPos() / FrameSize;
890      }      }
# Line 1433  namespace { Line 1509  namespace {
1509                                                          : vcf_res_ctrl_none;                                                          : vcf_res_ctrl_none;
1510              uint16_t eg3depth = _3ewa->ReadUint16();              uint16_t eg3depth = _3ewa->ReadUint16();
1511              EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */              EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1512                                          : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */                                          : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1513              _3ewa->ReadInt16(); // unknown              _3ewa->ReadInt16(); // unknown
1514              ChannelOffset = _3ewa->ReadUint8() / 4;              ChannelOffset = _3ewa->ReadUint8() / 4;
1515              uint8_t regoptions = _3ewa->ReadUint8();              uint8_t regoptions = _3ewa->ReadUint8();
# Line 1581  namespace { Line 1657  namespace {
1657       */       */
1658      DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {      DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1659          Instances++;          Instances++;
1660            //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1661          *this = src; // default memberwise shallow copy of all parameters          *this = src; // default memberwise shallow copy of all parameters
1662          pParentList = _3ewl; // restore the chunk pointer          pParentList = _3ewl; // restore the chunk pointer
1663    
# Line 1596  namespace { Line 1673  namespace {
1673                  pSampleLoops[k] = src.pSampleLoops[k];                  pSampleLoops[k] = src.pSampleLoops[k];
1674          }          }
1675      }      }
1676        
1677        /**
1678         * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1679         * and assign it to this object.
1680         *
1681         * Note that all sample pointers referenced by @a orig are simply copied as
1682         * memory address. Thus the respective samples are shared, not duplicated!
1683         *
1684         * @param orig - original DimensionRegion object to be copied from
1685         */
1686        void DimensionRegion::CopyAssign(const DimensionRegion* orig) {
1687            CopyAssign(orig, NULL);
1688        }
1689    
1690        /**
1691         * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1692         * and assign it to this object.
1693         *
1694         * @param orig - original DimensionRegion object to be copied from
1695         * @param mSamples - crosslink map between the foreign file's samples and
1696         *                   this file's samples
1697         */
1698        void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1699            // delete all allocated data first
1700            if (VelocityTable) delete [] VelocityTable;
1701            if (pSampleLoops) delete [] pSampleLoops;
1702            
1703            // backup parent list pointer
1704            RIFF::List* p = pParentList;
1705            
1706            gig::Sample* pOriginalSample = pSample;
1707            gig::Region* pOriginalRegion = pRegion;
1708            
1709            //NOTE: copy code copied from assignment constructor above, see comment there as well
1710            
1711            *this = *orig; // default memberwise shallow copy of all parameters
1712            
1713            // restore members that shall not be altered
1714            pParentList = p; // restore the chunk pointer
1715            pRegion = pOriginalRegion;
1716            
1717            // only take the raw sample reference reference if the
1718            // two DimensionRegion objects are part of the same file
1719            if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1720                pSample = pOriginalSample;
1721            }
1722            
1723            if (mSamples && mSamples->count(orig->pSample)) {
1724                pSample = mSamples->find(orig->pSample)->second;
1725            }
1726    
1727            // deep copy of owned structures
1728            if (orig->VelocityTable) {
1729                VelocityTable = new uint8_t[128];
1730                for (int k = 0 ; k < 128 ; k++)
1731                    VelocityTable[k] = orig->VelocityTable[k];
1732            }
1733            if (orig->pSampleLoops) {
1734                pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops];
1735                for (int k = 0 ; k < orig->SampleLoops ; k++)
1736                    pSampleLoops[k] = orig->pSampleLoops[k];
1737            }
1738        }
1739    
1740      /**      /**
1741       * Updates the respective member variable and updates @c SampleAttenuation       * Updates the respective member variable and updates @c SampleAttenuation
# Line 1837  namespace { Line 1977  namespace {
1977          }          }
1978    
1979          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth          const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1980                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */                                                    : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
1981          store16(&pData[116], eg3depth);          store16(&pData[116], eg3depth);
1982    
1983          // next 2 bytes unknown          // next 2 bytes unknown
# Line 1885  namespace { Line 2025  namespace {
2025                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */                                        (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2026          pData[137] = vcfbreakpoint;          pData[137] = vcfbreakpoint;
2027    
2028          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |          const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2029                                      VCFVelocityCurve * 5;                                      VCFVelocityCurve * 5;
2030          pData[138] = vcfvelocity;          pData[138] = vcfvelocity;
2031    
# Line 1950  namespace { Line 2090  namespace {
2090          return pRegion;          return pRegion;
2091      }      }
2092    
2093    // show error if some _lev_ctrl_* enum entry is not listed in the following function
2094    // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2095    // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2096    //#pragma GCC diagnostic push
2097    //#pragma GCC diagnostic error "-Wswitch"
2098    
2099      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {      leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2100          leverage_ctrl_t decodedcontroller;          leverage_ctrl_t decodedcontroller;
2101          switch (EncodedController) {          switch (EncodedController) {
# Line 2061  namespace { Line 2207  namespace {
2207                  decodedcontroller.controller_number = 95;                  decodedcontroller.controller_number = 95;
2208                  break;                  break;
2209    
2210                // format extension (these controllers are so far only supported by
2211                // LinuxSampler & gigedit) they will *NOT* work with
2212                // Gigasampler/GigaStudio !
2213                case _lev_ctrl_CC3_EXT:
2214                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2215                    decodedcontroller.controller_number = 3;
2216                    break;
2217                case _lev_ctrl_CC6_EXT:
2218                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2219                    decodedcontroller.controller_number = 6;
2220                    break;
2221                case _lev_ctrl_CC7_EXT:
2222                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2223                    decodedcontroller.controller_number = 7;
2224                    break;
2225                case _lev_ctrl_CC8_EXT:
2226                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2227                    decodedcontroller.controller_number = 8;
2228                    break;
2229                case _lev_ctrl_CC9_EXT:
2230                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2231                    decodedcontroller.controller_number = 9;
2232                    break;
2233                case _lev_ctrl_CC10_EXT:
2234                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2235                    decodedcontroller.controller_number = 10;
2236                    break;
2237                case _lev_ctrl_CC11_EXT:
2238                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2239                    decodedcontroller.controller_number = 11;
2240                    break;
2241                case _lev_ctrl_CC14_EXT:
2242                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2243                    decodedcontroller.controller_number = 14;
2244                    break;
2245                case _lev_ctrl_CC15_EXT:
2246                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2247                    decodedcontroller.controller_number = 15;
2248                    break;
2249                case _lev_ctrl_CC20_EXT:
2250                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2251                    decodedcontroller.controller_number = 20;
2252                    break;
2253                case _lev_ctrl_CC21_EXT:
2254                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2255                    decodedcontroller.controller_number = 21;
2256                    break;
2257                case _lev_ctrl_CC22_EXT:
2258                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2259                    decodedcontroller.controller_number = 22;
2260                    break;
2261                case _lev_ctrl_CC23_EXT:
2262                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2263                    decodedcontroller.controller_number = 23;
2264                    break;
2265                case _lev_ctrl_CC24_EXT:
2266                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2267                    decodedcontroller.controller_number = 24;
2268                    break;
2269                case _lev_ctrl_CC25_EXT:
2270                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2271                    decodedcontroller.controller_number = 25;
2272                    break;
2273                case _lev_ctrl_CC26_EXT:
2274                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2275                    decodedcontroller.controller_number = 26;
2276                    break;
2277                case _lev_ctrl_CC27_EXT:
2278                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2279                    decodedcontroller.controller_number = 27;
2280                    break;
2281                case _lev_ctrl_CC28_EXT:
2282                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2283                    decodedcontroller.controller_number = 28;
2284                    break;
2285                case _lev_ctrl_CC29_EXT:
2286                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2287                    decodedcontroller.controller_number = 29;
2288                    break;
2289                case _lev_ctrl_CC30_EXT:
2290                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2291                    decodedcontroller.controller_number = 30;
2292                    break;
2293                case _lev_ctrl_CC31_EXT:
2294                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2295                    decodedcontroller.controller_number = 31;
2296                    break;
2297                case _lev_ctrl_CC68_EXT:
2298                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2299                    decodedcontroller.controller_number = 68;
2300                    break;
2301                case _lev_ctrl_CC69_EXT:
2302                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2303                    decodedcontroller.controller_number = 69;
2304                    break;
2305                case _lev_ctrl_CC70_EXT:
2306                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2307                    decodedcontroller.controller_number = 70;
2308                    break;
2309                case _lev_ctrl_CC71_EXT:
2310                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2311                    decodedcontroller.controller_number = 71;
2312                    break;
2313                case _lev_ctrl_CC72_EXT:
2314                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2315                    decodedcontroller.controller_number = 72;
2316                    break;
2317                case _lev_ctrl_CC73_EXT:
2318                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2319                    decodedcontroller.controller_number = 73;
2320                    break;
2321                case _lev_ctrl_CC74_EXT:
2322                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2323                    decodedcontroller.controller_number = 74;
2324                    break;
2325                case _lev_ctrl_CC75_EXT:
2326                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2327                    decodedcontroller.controller_number = 75;
2328                    break;
2329                case _lev_ctrl_CC76_EXT:
2330                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2331                    decodedcontroller.controller_number = 76;
2332                    break;
2333                case _lev_ctrl_CC77_EXT:
2334                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2335                    decodedcontroller.controller_number = 77;
2336                    break;
2337                case _lev_ctrl_CC78_EXT:
2338                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2339                    decodedcontroller.controller_number = 78;
2340                    break;
2341                case _lev_ctrl_CC79_EXT:
2342                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2343                    decodedcontroller.controller_number = 79;
2344                    break;
2345                case _lev_ctrl_CC84_EXT:
2346                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2347                    decodedcontroller.controller_number = 84;
2348                    break;
2349                case _lev_ctrl_CC85_EXT:
2350                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2351                    decodedcontroller.controller_number = 85;
2352                    break;
2353                case _lev_ctrl_CC86_EXT:
2354                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2355                    decodedcontroller.controller_number = 86;
2356                    break;
2357                case _lev_ctrl_CC87_EXT:
2358                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2359                    decodedcontroller.controller_number = 87;
2360                    break;
2361                case _lev_ctrl_CC89_EXT:
2362                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2363                    decodedcontroller.controller_number = 89;
2364                    break;
2365                case _lev_ctrl_CC90_EXT:
2366                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2367                    decodedcontroller.controller_number = 90;
2368                    break;
2369                case _lev_ctrl_CC96_EXT:
2370                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2371                    decodedcontroller.controller_number = 96;
2372                    break;
2373                case _lev_ctrl_CC97_EXT:
2374                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2375                    decodedcontroller.controller_number = 97;
2376                    break;
2377                case _lev_ctrl_CC102_EXT:
2378                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2379                    decodedcontroller.controller_number = 102;
2380                    break;
2381                case _lev_ctrl_CC103_EXT:
2382                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2383                    decodedcontroller.controller_number = 103;
2384                    break;
2385                case _lev_ctrl_CC104_EXT:
2386                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2387                    decodedcontroller.controller_number = 104;
2388                    break;
2389                case _lev_ctrl_CC105_EXT:
2390                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2391                    decodedcontroller.controller_number = 105;
2392                    break;
2393                case _lev_ctrl_CC106_EXT:
2394                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2395                    decodedcontroller.controller_number = 106;
2396                    break;
2397                case _lev_ctrl_CC107_EXT:
2398                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2399                    decodedcontroller.controller_number = 107;
2400                    break;
2401                case _lev_ctrl_CC108_EXT:
2402                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2403                    decodedcontroller.controller_number = 108;
2404                    break;
2405                case _lev_ctrl_CC109_EXT:
2406                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2407                    decodedcontroller.controller_number = 109;
2408                    break;
2409                case _lev_ctrl_CC110_EXT:
2410                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2411                    decodedcontroller.controller_number = 110;
2412                    break;
2413                case _lev_ctrl_CC111_EXT:
2414                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2415                    decodedcontroller.controller_number = 111;
2416                    break;
2417                case _lev_ctrl_CC112_EXT:
2418                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2419                    decodedcontroller.controller_number = 112;
2420                    break;
2421                case _lev_ctrl_CC113_EXT:
2422                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2423                    decodedcontroller.controller_number = 113;
2424                    break;
2425                case _lev_ctrl_CC114_EXT:
2426                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2427                    decodedcontroller.controller_number = 114;
2428                    break;
2429                case _lev_ctrl_CC115_EXT:
2430                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2431                    decodedcontroller.controller_number = 115;
2432                    break;
2433                case _lev_ctrl_CC116_EXT:
2434                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2435                    decodedcontroller.controller_number = 116;
2436                    break;
2437                case _lev_ctrl_CC117_EXT:
2438                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2439                    decodedcontroller.controller_number = 117;
2440                    break;
2441                case _lev_ctrl_CC118_EXT:
2442                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2443                    decodedcontroller.controller_number = 118;
2444                    break;
2445                case _lev_ctrl_CC119_EXT:
2446                    decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2447                    decodedcontroller.controller_number = 119;
2448                    break;
2449    
2450              // unknown controller type              // unknown controller type
2451              default:              default:
2452                  throw gig::Exception("Unknown leverage controller type.");                  throw gig::Exception("Unknown leverage controller type.");
2453          }          }
2454          return decodedcontroller;          return decodedcontroller;
2455      }      }
2456        
2457    // see above (diagnostic push not supported prior GCC 4.6)
2458    //#pragma GCC diagnostic pop
2459    
2460      DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {      DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2461          _lev_ctrl_t encodedcontroller;          _lev_ctrl_t encodedcontroller;
# Line 2154  namespace { Line 2543  namespace {
2543                      case 95:                      case 95:
2544                          encodedcontroller = _lev_ctrl_effect5depth;                          encodedcontroller = _lev_ctrl_effect5depth;
2545                          break;                          break;
2546    
2547                        // format extension (these controllers are so far only
2548                        // supported by LinuxSampler & gigedit) they will *NOT*
2549                        // work with Gigasampler/GigaStudio !
2550                        case 3:
2551                            encodedcontroller = _lev_ctrl_CC3_EXT;
2552                            break;
2553                        case 6:
2554                            encodedcontroller = _lev_ctrl_CC6_EXT;
2555                            break;
2556                        case 7:
2557                            encodedcontroller = _lev_ctrl_CC7_EXT;
2558                            break;
2559                        case 8:
2560                            encodedcontroller = _lev_ctrl_CC8_EXT;
2561                            break;
2562                        case 9:
2563                            encodedcontroller = _lev_ctrl_CC9_EXT;
2564                            break;
2565                        case 10:
2566                            encodedcontroller = _lev_ctrl_CC10_EXT;
2567                            break;
2568                        case 11:
2569                            encodedcontroller = _lev_ctrl_CC11_EXT;
2570                            break;
2571                        case 14:
2572                            encodedcontroller = _lev_ctrl_CC14_EXT;
2573                            break;
2574                        case 15:
2575                            encodedcontroller = _lev_ctrl_CC15_EXT;
2576                            break;
2577                        case 20:
2578                            encodedcontroller = _lev_ctrl_CC20_EXT;
2579                            break;
2580                        case 21:
2581                            encodedcontroller = _lev_ctrl_CC21_EXT;
2582                            break;
2583                        case 22:
2584                            encodedcontroller = _lev_ctrl_CC22_EXT;
2585                            break;
2586                        case 23:
2587                            encodedcontroller = _lev_ctrl_CC23_EXT;
2588                            break;
2589                        case 24:
2590                            encodedcontroller = _lev_ctrl_CC24_EXT;
2591                            break;
2592                        case 25:
2593                            encodedcontroller = _lev_ctrl_CC25_EXT;
2594                            break;
2595                        case 26:
2596                            encodedcontroller = _lev_ctrl_CC26_EXT;
2597                            break;
2598                        case 27:
2599                            encodedcontroller = _lev_ctrl_CC27_EXT;
2600                            break;
2601                        case 28:
2602                            encodedcontroller = _lev_ctrl_CC28_EXT;
2603                            break;
2604                        case 29:
2605                            encodedcontroller = _lev_ctrl_CC29_EXT;
2606                            break;
2607                        case 30:
2608                            encodedcontroller = _lev_ctrl_CC30_EXT;
2609                            break;
2610                        case 31:
2611                            encodedcontroller = _lev_ctrl_CC31_EXT;
2612                            break;
2613                        case 68:
2614                            encodedcontroller = _lev_ctrl_CC68_EXT;
2615                            break;
2616                        case 69:
2617                            encodedcontroller = _lev_ctrl_CC69_EXT;
2618                            break;
2619                        case 70:
2620                            encodedcontroller = _lev_ctrl_CC70_EXT;
2621                            break;
2622                        case 71:
2623                            encodedcontroller = _lev_ctrl_CC71_EXT;
2624                            break;
2625                        case 72:
2626                            encodedcontroller = _lev_ctrl_CC72_EXT;
2627                            break;
2628                        case 73:
2629                            encodedcontroller = _lev_ctrl_CC73_EXT;
2630                            break;
2631                        case 74:
2632                            encodedcontroller = _lev_ctrl_CC74_EXT;
2633                            break;
2634                        case 75:
2635                            encodedcontroller = _lev_ctrl_CC75_EXT;
2636                            break;
2637                        case 76:
2638                            encodedcontroller = _lev_ctrl_CC76_EXT;
2639                            break;
2640                        case 77:
2641                            encodedcontroller = _lev_ctrl_CC77_EXT;
2642                            break;
2643                        case 78:
2644                            encodedcontroller = _lev_ctrl_CC78_EXT;
2645                            break;
2646                        case 79:
2647                            encodedcontroller = _lev_ctrl_CC79_EXT;
2648                            break;
2649                        case 84:
2650                            encodedcontroller = _lev_ctrl_CC84_EXT;
2651                            break;
2652                        case 85:
2653                            encodedcontroller = _lev_ctrl_CC85_EXT;
2654                            break;
2655                        case 86:
2656                            encodedcontroller = _lev_ctrl_CC86_EXT;
2657                            break;
2658                        case 87:
2659                            encodedcontroller = _lev_ctrl_CC87_EXT;
2660                            break;
2661                        case 89:
2662                            encodedcontroller = _lev_ctrl_CC89_EXT;
2663                            break;
2664                        case 90:
2665                            encodedcontroller = _lev_ctrl_CC90_EXT;
2666                            break;
2667                        case 96:
2668                            encodedcontroller = _lev_ctrl_CC96_EXT;
2669                            break;
2670                        case 97:
2671                            encodedcontroller = _lev_ctrl_CC97_EXT;
2672                            break;
2673                        case 102:
2674                            encodedcontroller = _lev_ctrl_CC102_EXT;
2675                            break;
2676                        case 103:
2677                            encodedcontroller = _lev_ctrl_CC103_EXT;
2678                            break;
2679                        case 104:
2680                            encodedcontroller = _lev_ctrl_CC104_EXT;
2681                            break;
2682                        case 105:
2683                            encodedcontroller = _lev_ctrl_CC105_EXT;
2684                            break;
2685                        case 106:
2686                            encodedcontroller = _lev_ctrl_CC106_EXT;
2687                            break;
2688                        case 107:
2689                            encodedcontroller = _lev_ctrl_CC107_EXT;
2690                            break;
2691                        case 108:
2692                            encodedcontroller = _lev_ctrl_CC108_EXT;
2693                            break;
2694                        case 109:
2695                            encodedcontroller = _lev_ctrl_CC109_EXT;
2696                            break;
2697                        case 110:
2698                            encodedcontroller = _lev_ctrl_CC110_EXT;
2699                            break;
2700                        case 111:
2701                            encodedcontroller = _lev_ctrl_CC111_EXT;
2702                            break;
2703                        case 112:
2704                            encodedcontroller = _lev_ctrl_CC112_EXT;
2705                            break;
2706                        case 113:
2707                            encodedcontroller = _lev_ctrl_CC113_EXT;
2708                            break;
2709                        case 114:
2710                            encodedcontroller = _lev_ctrl_CC114_EXT;
2711                            break;
2712                        case 115:
2713                            encodedcontroller = _lev_ctrl_CC115_EXT;
2714                            break;
2715                        case 116:
2716                            encodedcontroller = _lev_ctrl_CC116_EXT;
2717                            break;
2718                        case 117:
2719                            encodedcontroller = _lev_ctrl_CC117_EXT;
2720                            break;
2721                        case 118:
2722                            encodedcontroller = _lev_ctrl_CC118_EXT;
2723                            break;
2724                        case 119:
2725                            encodedcontroller = _lev_ctrl_CC119_EXT;
2726                            break;
2727    
2728                      default:                      default:
2729                          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");
2730                  }                  }
# Line 2631  namespace { Line 3202  namespace {
3202       *                        dimension bits limit is violated       *                        dimension bits limit is violated
3203       */       */
3204      void Region::AddDimension(dimension_def_t* pDimDef) {      void Region::AddDimension(dimension_def_t* pDimDef) {
3205            // some initial sanity checks of the given dimension definition
3206            if (pDimDef->zones < 2)
3207                throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3208            if (pDimDef->bits < 1)
3209                throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3210            if (pDimDef->dimension == dimension_samplechannel) {
3211                if (pDimDef->zones != 2)
3212                    throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3213                if (pDimDef->bits != 1)
3214                    throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3215            }
3216    
3217          // check if max. amount of dimensions reached          // check if max. amount of dimensions reached
3218          File* file = (File*) GetParent()->GetParent();          File* file = (File*) GetParent()->GetParent();
3219          const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;          const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
# Line 2806  namespace { Line 3389  namespace {
3389          if (pDimDef->dimension == dimension_layer) Layers = 1;          if (pDimDef->dimension == dimension_layer) Layers = 1;
3390      }      }
3391    
3392        /** @brief Delete one split zone of a dimension (decrement zone amount).
3393         *
3394         * Instead of deleting an entire dimensions, this method will only delete
3395         * one particular split zone given by @a zone of the Region's dimension
3396         * given by @a type. So this method will simply decrement the amount of
3397         * zones by one of the dimension in question. To be able to do that, the
3398         * respective dimension must exist on this Region and it must have at least
3399         * 3 zones. All DimensionRegion objects associated with the zone will be
3400         * deleted.
3401         *
3402         * @param type - identifies the dimension where a zone shall be deleted
3403         * @param zone - index of the dimension split zone that shall be deleted
3404         * @throws gig::Exception if requested zone could not be deleted
3405         */
3406        void Region::DeleteDimensionZone(dimension_t type, int zone) {
3407            dimension_def_t* oldDef = GetDimensionDefinition(type);
3408            if (!oldDef)
3409                throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3410            if (oldDef->zones <= 2)
3411                throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3412            if (zone < 0 || zone >= oldDef->zones)
3413                throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3414    
3415            const int newZoneSize = oldDef->zones - 1;
3416    
3417            // create a temporary Region which just acts as a temporary copy
3418            // container and will be deleted at the end of this function and will
3419            // also not be visible through the API during this process
3420            gig::Region* tempRgn = NULL;
3421            {
3422                // adding these temporary chunks is probably not even necessary
3423                Instrument* instr = static_cast<Instrument*>(GetParent());
3424                RIFF::List* pCkInstrument = instr->pCkInstrument;
3425                RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3426                if (!lrgn)  lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3427                RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3428                tempRgn = new Region(instr, rgn);
3429            }
3430    
3431            // copy this region's dimensions (with already the dimension split size
3432            // requested by the arguments of this method call) to the temporary
3433            // region, and don't use Region::CopyAssign() here for this task, since
3434            // it would also alter fast lookup helper variables here and there
3435            dimension_def_t newDef;
3436            for (int i = 0; i < Dimensions; ++i) {
3437                dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3438                // is this the dimension requested by the method arguments? ...
3439                if (def.dimension == type) { // ... if yes, decrement zone amount by one
3440                    def.zones = newZoneSize;
3441                    if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3442                    newDef = def;
3443                }
3444                tempRgn->AddDimension(&def);
3445            }
3446    
3447            // find the dimension index in the tempRegion which is the dimension
3448            // type passed to this method (paranoidly expecting different order)
3449            int tempReducedDimensionIndex = -1;
3450            for (int d = 0; d < tempRgn->Dimensions; ++d) {
3451                if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3452                    tempReducedDimensionIndex = d;
3453                    break;
3454                }
3455            }
3456    
3457            // copy dimension regions from this region to the temporary region
3458            for (int iDst = 0; iDst < 256; ++iDst) {
3459                DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3460                if (!dstDimRgn) continue;
3461                std::map<dimension_t,int> dimCase;
3462                bool isValidZone = true;
3463                for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3464                    const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3465                    dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3466                        (iDst >> baseBits) & ((1 << dstBits) - 1);
3467                    baseBits += dstBits;
3468                    // there are also DimensionRegion objects of unused zones, skip them
3469                    if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3470                        isValidZone = false;
3471                        break;
3472                    }
3473                }
3474                if (!isValidZone) continue;
3475                // a bit paranoid: cope with the chance that the dimensions would
3476                // have different order in source and destination regions
3477                const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3478                if (dimCase[type] >= zone) dimCase[type]++;
3479                DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3480                dstDimRgn->CopyAssign(srcDimRgn);
3481                // if this is the upper most zone of the dimension passed to this
3482                // method, then correct (raise) its upper limit to 127
3483                if (newDef.split_type == split_type_normal && isLastZone)
3484                    dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3485            }
3486    
3487            // now tempRegion's dimensions and DimensionRegions basically reflect
3488            // what we wanted to get for this actual Region here, so we now just
3489            // delete and recreate the dimension in question with the new amount
3490            // zones and then copy back from tempRegion      
3491            DeleteDimension(oldDef);
3492            AddDimension(&newDef);
3493            for (int iSrc = 0; iSrc < 256; ++iSrc) {
3494                DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3495                if (!srcDimRgn) continue;
3496                std::map<dimension_t,int> dimCase;
3497                for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3498                    const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3499                    dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3500                        (iSrc >> baseBits) & ((1 << srcBits) - 1);
3501                    baseBits += srcBits;
3502                }
3503                // a bit paranoid: cope with the chance that the dimensions would
3504                // have different order in source and destination regions
3505                DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3506                if (!dstDimRgn) continue;
3507                dstDimRgn->CopyAssign(srcDimRgn);
3508            }
3509    
3510            // delete temporary region
3511            delete tempRgn;
3512        }
3513    
3514        /** @brief Divide split zone of a dimension in two (increment zone amount).
3515         *
3516         * This will increment the amount of zones for the dimension (given by
3517         * @a type) by one. It will do so by dividing the zone (given by @a zone)
3518         * in the middle of its zone range in two. So the two zones resulting from
3519         * the zone being splitted, will be an equivalent copy regarding all their
3520         * articulation informations and sample reference. The two zones will only
3521         * differ in their zone's upper limit
3522         * (DimensionRegion::DimensionUpperLimits).
3523         *
3524         * @param type - identifies the dimension where a zone shall be splitted
3525         * @param zone - index of the dimension split zone that shall be splitted
3526         * @throws gig::Exception if requested zone could not be splitted
3527         */
3528        void Region::SplitDimensionZone(dimension_t type, int zone) {
3529            dimension_def_t* oldDef = GetDimensionDefinition(type);
3530            if (!oldDef)
3531                throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3532            if (zone < 0 || zone >= oldDef->zones)
3533                throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3534    
3535            const int newZoneSize = oldDef->zones + 1;
3536    
3537            // create a temporary Region which just acts as a temporary copy
3538            // container and will be deleted at the end of this function and will
3539            // also not be visible through the API during this process
3540            gig::Region* tempRgn = NULL;
3541            {
3542                // adding these temporary chunks is probably not even necessary
3543                Instrument* instr = static_cast<Instrument*>(GetParent());
3544                RIFF::List* pCkInstrument = instr->pCkInstrument;
3545                RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3546                if (!lrgn)  lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3547                RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3548                tempRgn = new Region(instr, rgn);
3549            }
3550    
3551            // copy this region's dimensions (with already the dimension split size
3552            // requested by the arguments of this method call) to the temporary
3553            // region, and don't use Region::CopyAssign() here for this task, since
3554            // it would also alter fast lookup helper variables here and there
3555            dimension_def_t newDef;
3556            for (int i = 0; i < Dimensions; ++i) {
3557                dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3558                // is this the dimension requested by the method arguments? ...
3559                if (def.dimension == type) { // ... if yes, increment zone amount by one
3560                    def.zones = newZoneSize;
3561                    if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3562                    newDef = def;
3563                }
3564                tempRgn->AddDimension(&def);
3565            }
3566    
3567            // find the dimension index in the tempRegion which is the dimension
3568            // type passed to this method (paranoidly expecting different order)
3569            int tempIncreasedDimensionIndex = -1;
3570            for (int d = 0; d < tempRgn->Dimensions; ++d) {
3571                if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3572                    tempIncreasedDimensionIndex = d;
3573                    break;
3574                }
3575            }
3576    
3577            // copy dimension regions from this region to the temporary region
3578            for (int iSrc = 0; iSrc < 256; ++iSrc) {
3579                DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
3580                if (!srcDimRgn) continue;
3581                std::map<dimension_t,int> dimCase;
3582                bool isValidZone = true;
3583                for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
3584                    const int srcBits = pDimensionDefinitions[d].bits;
3585                    dimCase[pDimensionDefinitions[d].dimension] =
3586                        (iSrc >> baseBits) & ((1 << srcBits) - 1);
3587                    // there are also DimensionRegion objects for unused zones, skip them
3588                    if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
3589                        isValidZone = false;
3590                        break;
3591                    }
3592                    baseBits += srcBits;
3593                }
3594                if (!isValidZone) continue;
3595                // a bit paranoid: cope with the chance that the dimensions would
3596                // have different order in source and destination regions            
3597                if (dimCase[type] > zone) dimCase[type]++;
3598                DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3599                dstDimRgn->CopyAssign(srcDimRgn);
3600                // if this is the requested zone to be splitted, then also copy
3601                // the source DimensionRegion to the newly created target zone
3602                // and set the old zones upper limit lower
3603                if (dimCase[type] == zone) {
3604                    // lower old zones upper limit
3605                    if (newDef.split_type == split_type_normal) {
3606                        const int high =
3607                            dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
3608                        int low = 0;
3609                        if (zone > 0) {
3610                            std::map<dimension_t,int> lowerCase = dimCase;
3611                            lowerCase[type]--;
3612                            DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
3613                            low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
3614                        }
3615                        dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
3616                    }
3617                    // fill the newly created zone of the divided zone as well
3618                    dimCase[type]++;
3619                    dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3620                    dstDimRgn->CopyAssign(srcDimRgn);
3621                }
3622            }
3623    
3624            // now tempRegion's dimensions and DimensionRegions basically reflect
3625            // what we wanted to get for this actual Region here, so we now just
3626            // delete and recreate the dimension in question with the new amount
3627            // zones and then copy back from tempRegion      
3628            DeleteDimension(oldDef);
3629            AddDimension(&newDef);
3630            for (int iSrc = 0; iSrc < 256; ++iSrc) {
3631                DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3632                if (!srcDimRgn) continue;
3633                std::map<dimension_t,int> dimCase;
3634                for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3635                    const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3636                    dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3637                        (iSrc >> baseBits) & ((1 << srcBits) - 1);
3638                    baseBits += srcBits;
3639                }
3640                // a bit paranoid: cope with the chance that the dimensions would
3641                // have different order in source and destination regions
3642                DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3643                if (!dstDimRgn) continue;
3644                dstDimRgn->CopyAssign(srcDimRgn);
3645            }
3646    
3647            // delete temporary region
3648            delete tempRgn;
3649        }
3650    
3651        DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
3652            uint8_t bits[8] = {};
3653            for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3654                 it != DimCase.end(); ++it)
3655            {
3656                for (int d = 0; d < Dimensions; ++d) {
3657                    if (pDimensionDefinitions[d].dimension == it->first) {
3658                        bits[d] = it->second;
3659                        goto nextDimCaseSlice;
3660                    }
3661                }
3662                assert(false); // do crash ... too harsh maybe ? ignore it instead ?
3663                nextDimCaseSlice:
3664                ; // noop
3665            }
3666            return GetDimensionRegionByBit(bits);
3667        }
3668    
3669        /**
3670         * Searches in the current Region for a dimension of the given dimension
3671         * type and returns the precise configuration of that dimension in this
3672         * Region.
3673         *
3674         * @param type - dimension type of the sought dimension
3675         * @returns dimension definition or NULL if there is no dimension with
3676         *          sought type in this Region.
3677         */
3678        dimension_def_t* Region::GetDimensionDefinition(dimension_t type) {
3679            for (int i = 0; i < Dimensions; ++i)
3680                if (pDimensionDefinitions[i].dimension == type)
3681                    return &pDimensionDefinitions[i];
3682            return NULL;
3683        }
3684    
3685      Region::~Region() {      Region::~Region() {
3686          for (int i = 0; i < 256; i++) {          for (int i = 0; i < 256; i++) {
3687              if (pDimensionRegions[i]) delete pDimensionRegions[i];              if (pDimensionRegions[i]) delete pDimensionRegions[i];
# Line 2925  namespace { Line 3801  namespace {
3801          }          }
3802          return NULL;          return NULL;
3803      }      }
3804        
3805        /**
3806         * Make a (semi) deep copy of the Region object given by @a orig
3807         * and assign it to this object.
3808         *
3809         * Note that all sample pointers referenced by @a orig are simply copied as
3810         * memory address. Thus the respective samples are shared, not duplicated!
3811         *
3812         * @param orig - original Region object to be copied from
3813         */
3814        void Region::CopyAssign(const Region* orig) {
3815            CopyAssign(orig, NULL);
3816        }
3817        
3818        /**
3819         * Make a (semi) deep copy of the Region object given by @a orig and
3820         * assign it to this object
3821         *
3822         * @param mSamples - crosslink map between the foreign file's samples and
3823         *                   this file's samples
3824         */
3825        void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
3826            // handle base classes
3827            DLS::Region::CopyAssign(orig);
3828            
3829            if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
3830                pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
3831            }
3832            
3833            // handle own member variables
3834            for (int i = Dimensions - 1; i >= 0; --i) {
3835                DeleteDimension(&pDimensionDefinitions[i]);
3836            }
3837            Layers = 0; // just to be sure
3838            for (int i = 0; i < orig->Dimensions; i++) {
3839                // we need to copy the dim definition here, to avoid the compiler
3840                // complaining about const-ness issue
3841                dimension_def_t def = orig->pDimensionDefinitions[i];
3842                AddDimension(&def);
3843            }
3844            for (int i = 0; i < 256; i++) {
3845                if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
3846                    pDimensionRegions[i]->CopyAssign(
3847                        orig->pDimensionRegions[i],
3848                        mSamples
3849                    );
3850                }
3851            }
3852            Layers = orig->Layers;
3853        }
3854    
3855    
3856  // *************** MidiRule ***************  // *************** MidiRule ***************
3857  // *  // *
3858    
3859  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {      MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
3860      _3ewg->SetPos(36);          _3ewg->SetPos(36);
3861      Triggers = _3ewg->ReadUint8();          Triggers = _3ewg->ReadUint8();
3862      _3ewg->SetPos(40);          _3ewg->SetPos(40);
3863      ControllerNumber = _3ewg->ReadUint8();          ControllerNumber = _3ewg->ReadUint8();
3864      _3ewg->SetPos(46);          _3ewg->SetPos(46);
3865      for (int i = 0 ; i < Triggers ; i++) {          for (int i = 0 ; i < Triggers ; i++) {
3866          pTriggers[i].TriggerPoint = _3ewg->ReadUint8();              pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
3867          pTriggers[i].Descending = _3ewg->ReadUint8();              pTriggers[i].Descending = _3ewg->ReadUint8();
3868          pTriggers[i].VelSensitivity = _3ewg->ReadUint8();              pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
3869          pTriggers[i].Key = _3ewg->ReadUint8();              pTriggers[i].Key = _3ewg->ReadUint8();
3870          pTriggers[i].NoteOff = _3ewg->ReadUint8();              pTriggers[i].NoteOff = _3ewg->ReadUint8();
3871          pTriggers[i].Velocity = _3ewg->ReadUint8();              pTriggers[i].Velocity = _3ewg->ReadUint8();
3872          pTriggers[i].OverridePedal = _3ewg->ReadUint8();              pTriggers[i].OverridePedal = _3ewg->ReadUint8();
3873          _3ewg->ReadUint8();              _3ewg->ReadUint8();
3874            }
3875        }
3876    
3877        MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
3878            ControllerNumber(0),
3879            Triggers(0) {
3880        }
3881    
3882        void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
3883            pData[32] = 4;
3884            pData[33] = 16;
3885            pData[36] = Triggers;
3886            pData[40] = ControllerNumber;
3887            for (int i = 0 ; i < Triggers ; i++) {
3888                pData[46 + i * 8] = pTriggers[i].TriggerPoint;
3889                pData[47 + i * 8] = pTriggers[i].Descending;
3890                pData[48 + i * 8] = pTriggers[i].VelSensitivity;
3891                pData[49 + i * 8] = pTriggers[i].Key;
3892                pData[50 + i * 8] = pTriggers[i].NoteOff;
3893                pData[51 + i * 8] = pTriggers[i].Velocity;
3894                pData[52 + i * 8] = pTriggers[i].OverridePedal;
3895            }
3896        }
3897    
3898        MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
3899            _3ewg->SetPos(36);
3900            LegatoSamples = _3ewg->ReadUint8(); // always 12
3901            _3ewg->SetPos(40);
3902            BypassUseController = _3ewg->ReadUint8();
3903            BypassKey = _3ewg->ReadUint8();
3904            BypassController = _3ewg->ReadUint8();
3905            ThresholdTime = _3ewg->ReadUint16();
3906            _3ewg->ReadInt16();
3907            ReleaseTime = _3ewg->ReadUint16();
3908            _3ewg->ReadInt16();
3909            KeyRange.low = _3ewg->ReadUint8();
3910            KeyRange.high = _3ewg->ReadUint8();
3911            _3ewg->SetPos(64);
3912            ReleaseTriggerKey = _3ewg->ReadUint8();
3913            AltSustain1Key = _3ewg->ReadUint8();
3914            AltSustain2Key = _3ewg->ReadUint8();
3915        }
3916    
3917        MidiRuleLegato::MidiRuleLegato() :
3918            LegatoSamples(12),
3919            BypassUseController(false),
3920            BypassKey(0),
3921            BypassController(1),
3922            ThresholdTime(20),
3923            ReleaseTime(20),
3924            ReleaseTriggerKey(0),
3925            AltSustain1Key(0),
3926            AltSustain2Key(0)
3927        {
3928            KeyRange.low = KeyRange.high = 0;
3929      }      }
 }  
3930    
3931        void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
3932            pData[32] = 0;
3933            pData[33] = 16;
3934            pData[36] = LegatoSamples;
3935            pData[40] = BypassUseController;
3936            pData[41] = BypassKey;
3937            pData[42] = BypassController;
3938            store16(&pData[43], ThresholdTime);
3939            store16(&pData[47], ReleaseTime);
3940            pData[51] = KeyRange.low;
3941            pData[52] = KeyRange.high;
3942            pData[64] = ReleaseTriggerKey;
3943            pData[65] = AltSustain1Key;
3944            pData[66] = AltSustain2Key;
3945        }
3946    
3947        MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
3948            _3ewg->SetPos(36);
3949            Articulations = _3ewg->ReadUint8();
3950            int flags = _3ewg->ReadUint8();
3951            Polyphonic = flags & 8;
3952            Chained = flags & 4;
3953            Selector = (flags & 2) ? selector_controller :
3954                (flags & 1) ? selector_key_switch : selector_none;
3955            Patterns = _3ewg->ReadUint8();
3956            _3ewg->ReadUint8(); // chosen row
3957            _3ewg->ReadUint8(); // unknown
3958            _3ewg->ReadUint8(); // unknown
3959            _3ewg->ReadUint8(); // unknown
3960            KeySwitchRange.low = _3ewg->ReadUint8();
3961            KeySwitchRange.high = _3ewg->ReadUint8();
3962            Controller = _3ewg->ReadUint8();
3963            PlayRange.low = _3ewg->ReadUint8();
3964            PlayRange.high = _3ewg->ReadUint8();
3965    
3966            int n = std::min(int(Articulations), 32);
3967            for (int i = 0 ; i < n ; i++) {
3968                _3ewg->ReadString(pArticulations[i], 32);
3969            }
3970            _3ewg->SetPos(1072);
3971            n = std::min(int(Patterns), 32);
3972            for (int i = 0 ; i < n ; i++) {
3973                _3ewg->ReadString(pPatterns[i].Name, 16);
3974                pPatterns[i].Size = _3ewg->ReadUint8();
3975                _3ewg->Read(&pPatterns[i][0], 1, 32);
3976            }
3977        }
3978    
3979        MidiRuleAlternator::MidiRuleAlternator() :
3980            Articulations(0),
3981            Patterns(0),
3982            Selector(selector_none),
3983            Controller(0),
3984            Polyphonic(false),
3985            Chained(false)
3986        {
3987            PlayRange.low = PlayRange.high = 0;
3988            KeySwitchRange.low = KeySwitchRange.high = 0;
3989        }
3990    
3991        void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
3992            pData[32] = 3;
3993            pData[33] = 16;
3994            pData[36] = Articulations;
3995            pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
3996                (Selector == selector_controller ? 2 :
3997                 (Selector == selector_key_switch ? 1 : 0));
3998            pData[38] = Patterns;
3999    
4000            pData[43] = KeySwitchRange.low;
4001            pData[44] = KeySwitchRange.high;
4002            pData[45] = Controller;
4003            pData[46] = PlayRange.low;
4004            pData[47] = PlayRange.high;
4005    
4006            char* str = reinterpret_cast<char*>(pData);
4007            int pos = 48;
4008            int n = std::min(int(Articulations), 32);
4009            for (int i = 0 ; i < n ; i++, pos += 32) {
4010                strncpy(&str[pos], pArticulations[i].c_str(), 32);
4011            }
4012    
4013            pos = 1072;
4014            n = std::min(int(Patterns), 32);
4015            for (int i = 0 ; i < n ; i++, pos += 49) {
4016                strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4017                pData[pos + 16] = pPatterns[i].Size;
4018                memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4019            }
4020        }
4021    
4022  // *************** Instrument ***************  // *************** Instrument ***************
4023  // *  // *
# Line 2993  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4063  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4063                      uint8_t id1 = _3ewg->ReadUint8();                      uint8_t id1 = _3ewg->ReadUint8();
4064                      uint8_t id2 = _3ewg->ReadUint8();                      uint8_t id2 = _3ewg->ReadUint8();
4065    
4066                      if (id1 == 4 && id2 == 16) {                      if (id2 == 16) {
4067                          pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);                          if (id1 == 4) {
4068                                pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4069                            } else if (id1 == 0) {
4070                                pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4071                            } else if (id1 == 3) {
4072                                pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4073                            } else {
4074                                pMidiRules[i++] = new MidiRuleUnknown;
4075                            }
4076                        }
4077                        else if (id1 != 0 || id2 != 0) {
4078                            pMidiRules[i++] = new MidiRuleUnknown;
4079                      }                      }
4080                      //TODO: all the other types of rules                      //TODO: all the other types of rules
4081    
# Line 3036  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4117  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4117      }      }
4118    
4119      Instrument::~Instrument() {      Instrument::~Instrument() {
4120            for (int i = 0 ; pMidiRules[i] ; i++) {
4121                delete pMidiRules[i];
4122            }
4123          delete[] pMidiRules;          delete[] pMidiRules;
4124      }      }
4125    
# Line 3083  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4167  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4167                                      DimensionKeyRange.low << 1;                                      DimensionKeyRange.low << 1;
4168          pData[10] = dimkeystart;          pData[10] = dimkeystart;
4169          pData[11] = DimensionKeyRange.high;          pData[11] = DimensionKeyRange.high;
4170    
4171            if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
4172                pData[32] = 0;
4173                pData[33] = 0;
4174            } else {
4175                for (int i = 0 ; pMidiRules[i] ; i++) {
4176                    pMidiRules[i]->UpdateChunks(pData);
4177                }
4178            }
4179      }      }
4180    
4181      /**      /**
# Line 3165  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4258  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4258          return pMidiRules[i];          return pMidiRules[i];
4259      }      }
4260    
4261        /**
4262         * Adds the "controller trigger" MIDI rule to the instrument.
4263         *
4264         * @returns the new MIDI rule
4265         */
4266        MidiRuleCtrlTrigger* Instrument::AddMidiRuleCtrlTrigger() {
4267            delete pMidiRules[0];
4268            MidiRuleCtrlTrigger* r = new MidiRuleCtrlTrigger;
4269            pMidiRules[0] = r;
4270            pMidiRules[1] = 0;
4271            return r;
4272        }
4273    
4274        /**
4275         * Adds the legato MIDI rule to the instrument.
4276         *
4277         * @returns the new MIDI rule
4278         */
4279        MidiRuleLegato* Instrument::AddMidiRuleLegato() {
4280            delete pMidiRules[0];
4281            MidiRuleLegato* r = new MidiRuleLegato;
4282            pMidiRules[0] = r;
4283            pMidiRules[1] = 0;
4284            return r;
4285        }
4286    
4287        /**
4288         * Adds the alternator MIDI rule to the instrument.
4289         *
4290         * @returns the new MIDI rule
4291         */
4292        MidiRuleAlternator* Instrument::AddMidiRuleAlternator() {
4293            delete pMidiRules[0];
4294            MidiRuleAlternator* r = new MidiRuleAlternator;
4295            pMidiRules[0] = r;
4296            pMidiRules[1] = 0;
4297            return r;
4298        }
4299    
4300        /**
4301         * Deletes a MIDI rule from the instrument.
4302         *
4303         * @param i - MIDI rule number
4304         */
4305        void Instrument::DeleteMidiRule(int i) {
4306            delete pMidiRules[i];
4307            pMidiRules[i] = 0;
4308        }
4309    
4310        /**
4311         * Make a (semi) deep copy of the Instrument object given by @a orig
4312         * and assign it to this object.
4313         *
4314         * Note that all sample pointers referenced by @a orig are simply copied as
4315         * memory address. Thus the respective samples are shared, not duplicated!
4316         *
4317         * @param orig - original Instrument object to be copied from
4318         */
4319        void Instrument::CopyAssign(const Instrument* orig) {
4320            CopyAssign(orig, NULL);
4321        }
4322            
4323        /**
4324         * Make a (semi) deep copy of the Instrument object given by @a orig
4325         * and assign it to this object.
4326         *
4327         * @param orig - original Instrument object to be copied from
4328         * @param mSamples - crosslink map between the foreign file's samples and
4329         *                   this file's samples
4330         */
4331        void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
4332            // handle base class
4333            // (without copying DLS region stuff)
4334            DLS::Instrument::CopyAssignCore(orig);
4335            
4336            // handle own member variables
4337            Attenuation = orig->Attenuation;
4338            EffectSend = orig->EffectSend;
4339            FineTune = orig->FineTune;
4340            PitchbendRange = orig->PitchbendRange;
4341            PianoReleaseMode = orig->PianoReleaseMode;
4342            DimensionKeyRange = orig->DimensionKeyRange;
4343            
4344            // free old midi rules
4345            for (int i = 0 ; pMidiRules[i] ; i++) {
4346                delete pMidiRules[i];
4347            }
4348            //TODO: MIDI rule copying
4349            pMidiRules[0] = NULL;
4350            
4351            // delete all old regions
4352            while (Regions) DeleteRegion(GetFirstRegion());
4353            // create new regions and copy them from original
4354            {
4355                RegionList::const_iterator it = orig->pRegions->begin();
4356                for (int i = 0; i < orig->Regions; ++i, ++it) {
4357                    Region* dstRgn = AddRegion();
4358                    //NOTE: Region does semi-deep copy !
4359                    dstRgn->CopyAssign(
4360                        static_cast<gig::Region*>(*it),
4361                        mSamples
4362                    );
4363                }
4364            }
4365    
4366            UpdateRegionKeyTable();
4367        }
4368    
4369    
4370  // *************** Group ***************  // *************** Group ***************
4371  // *  // *
# Line 3366  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4567  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4567          SamplesIterator++;          SamplesIterator++;
4568          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
4569      }      }
4570        
4571        /**
4572         * Returns Sample object of @a index.
4573         *
4574         * @returns sample object or NULL if index is out of bounds
4575         */
4576        Sample* File::GetSample(uint index) {
4577            if (!pSamples) LoadSamples();
4578            if (!pSamples) return NULL;
4579            DLS::File::SampleList::iterator it = pSamples->begin();
4580            for (int i = 0; i < index; ++i) {
4581                ++it;
4582                if (it == pSamples->end()) return NULL;
4583            }
4584            if (it == pSamples->end()) return NULL;
4585            return static_cast<gig::Sample*>( *it );
4586        }
4587    
4588      /** @brief Add a new sample.      /** @brief Add a new sample.
4589       *       *
# Line 3563  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4781  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4781         pInstruments->push_back(pInstrument);         pInstruments->push_back(pInstrument);
4782         return pInstrument;         return pInstrument;
4783      }      }
4784        
4785        /** @brief Add a duplicate of an existing instrument.
4786         *
4787         * Duplicates the instrument definition given by @a orig and adds it
4788         * to this file. This allows in an instrument editor application to
4789         * easily create variations of an instrument, which will be stored in
4790         * the same .gig file, sharing i.e. the same samples.
4791         *
4792         * Note that all sample pointers referenced by @a orig are simply copied as
4793         * memory address. Thus the respective samples are shared, not duplicated!
4794         *
4795         * You have to call Save() to make this persistent to the file.
4796         *
4797         * @param orig - original instrument to be copied
4798         * @returns duplicated copy of the given instrument
4799         */
4800        Instrument* File::AddDuplicateInstrument(const Instrument* orig) {
4801            Instrument* instr = AddInstrument();
4802            instr->CopyAssign(orig);
4803            return instr;
4804        }
4805        
4806        /** @brief Add content of another existing file.
4807         *
4808         * Duplicates the samples, groups and instruments of the original file
4809         * given by @a pFile and adds them to @c this File. In case @c this File is
4810         * a new one that you haven't saved before, then you have to call
4811         * SetFileName() before calling AddContentOf(), because this method will
4812         * automatically save this file during operation, which is required for
4813         * writing the sample waveform data by disk streaming.
4814         *
4815         * @param pFile - original file whose's content shall be copied from
4816         */
4817        void File::AddContentOf(File* pFile) {
4818            static int iCallCount = -1;
4819            iCallCount++;
4820            std::map<Group*,Group*> mGroups;
4821            std::map<Sample*,Sample*> mSamples;
4822            
4823            // clone sample groups
4824            for (int i = 0; pFile->GetGroup(i); ++i) {
4825                Group* g = AddGroup();
4826                g->Name =
4827                    "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
4828                mGroups[pFile->GetGroup(i)] = g;
4829            }
4830            
4831            // clone samples (not waveform data here yet)
4832            for (int i = 0; pFile->GetSample(i); ++i) {
4833                Sample* s = AddSample();
4834                s->CopyAssignMeta(pFile->GetSample(i));
4835                mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
4836                mSamples[pFile->GetSample(i)] = s;
4837            }
4838            
4839            //BUG: For some reason this method only works with this additional
4840            //     Save() call in between here.
4841            //
4842            // Important: The correct one of the 2 Save() methods has to be called
4843            // here, depending on whether the file is completely new or has been
4844            // saved to disk already, otherwise it will result in data corruption.
4845            if (pRIFF->IsNew())
4846                Save(GetFileName());
4847            else
4848                Save();
4849            
4850            // clone instruments
4851            // (passing the crosslink table here for the cloned samples)
4852            for (int i = 0; pFile->GetInstrument(i); ++i) {
4853                Instrument* instr = AddInstrument();
4854                instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
4855            }
4856            
4857            // Mandatory: file needs to be saved to disk at this point, so this
4858            // file has the correct size and data layout for writing the samples'
4859            // waveform data to disk.
4860            Save();
4861            
4862            // clone samples' waveform data
4863            // (using direct read & write disk streaming)
4864            for (int i = 0; pFile->GetSample(i); ++i) {
4865                mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
4866            }
4867        }
4868    
4869      /** @brief Delete an instrument.      /** @brief Delete an instrument.
4870       *       *
# Line 3665  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 4967  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
4967          return NULL;          return NULL;
4968      }      }
4969    
4970        /**
4971         * Returns the group with the given group name.
4972         *
4973         * Note: group names don't have to be unique in the gig format! So there
4974         * can be multiple groups with the same name. This method will simply
4975         * return the first group found with the given name.
4976         *
4977         * @param name - name of the sought group
4978         * @returns sought group or NULL if there's no group with that name
4979         */
4980        Group* File::GetGroup(String name) {
4981            if (!pGroups) LoadGroups();
4982            GroupsIterator = pGroups->begin();
4983            for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
4984                if ((*GroupsIterator)->Name == name) return *GroupsIterator;
4985            return NULL;
4986        }
4987    
4988      Group* File::AddGroup() {      Group* File::AddGroup() {
4989          if (!pGroups) LoadGroups();          if (!pGroups) LoadGroups();
4990          // there must always be at least one group          // there must always be at least one group
# Line 3775  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger Line 5095  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger
5095    
5096          // update group's chunks          // update group's chunks
5097          if (pGroups) {          if (pGroups) {
5098              std::list<Group*>::iterator iter = pGroups->begin();              // make sure '3gri' and '3gnl' list chunks exist
5099              std::list<Group*>::iterator end  = pGroups->end();              // (before updating the Group chunks)
5100              for (; iter != end; ++iter) {              RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
5101                  (*iter)->UpdateChunks();              if (!_3gri) {
5102                    _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
5103                    pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
5104              }              }
5105                RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
5106                if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
5107    
5108              // v3: make sure the file has 128 3gnm chunks              // v3: make sure the file has 128 3gnm chunks
5109                // (before updating the Group chunks)
5110              if (pVersion && pVersion->major == 3) {              if (pVersion && pVersion->major == 3) {
                 RIFF::List* _3gnl = pRIFF->GetSubList(LIST_TYPE_3GRI)->GetSubList(LIST_TYPE_3GNL);  
5111                  RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();                  RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
5112                  for (int i = 0 ; i < 128 ; i++) {                  for (int i = 0 ; i < 128 ; i++) {
5113                      if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);                      if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
5114                      if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();                      if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
5115                  }                  }
5116              }              }
5117    
5118                std::list<Group*>::iterator iter = pGroups->begin();
5119                std::list<Group*>::iterator end  = pGroups->end();
5120                for (; iter != end; ++iter) {
5121                    (*iter)->UpdateChunks();
5122                }
5123          }          }
5124    
5125          // update einf chunk          // update einf chunk

Legend:
Removed from v.1875  
changed lines
  Added in v.2555

  ViewVC Help
Powered by ViewVC