gig.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libgig - C++ cross-platform Gigasampler format file access library    *
00004  *                                                                         *
00005  *   Copyright (C) 2003-2009 by Christian Schoenebeck                      *
00006  *                              <cuse@users.sourceforge.net>               *
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this library; if not, write to the Free Software           *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
00022  ***************************************************************************/
00023 
00024 #include "gig.h"
00025 
00026 #include "helper.h"
00027 
00028 #include <algorithm>
00029 #include <math.h>
00030 #include <iostream>
00031 
00037 #define INITIAL_SAMPLE_BUFFER_SIZE              512000 // 512 kB
00038 
00040 #define GIG_EXP_DECODE(x)                       (pow(1.000000008813822, x))
00041 #define GIG_EXP_ENCODE(x)                       (log(x) / log(1.000000008813822))
00042 #define GIG_PITCH_TRACK_EXTRACT(x)              (!(x & 0x01))
00043 #define GIG_PITCH_TRACK_ENCODE(x)               ((x) ? 0x00 : 0x01)
00044 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x)       ((x >> 4) & 0x03)
00045 #define GIG_VCF_RESONANCE_CTRL_ENCODE(x)        ((x & 0x03) << 4)
00046 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x)  ((x >> 1) & 0x03)
00047 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x)   ((x >> 3) & 0x03)
00048 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
00049 #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x)   ((x & 0x03) << 1)
00050 #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x)    ((x & 0x03) << 3)
00051 #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x)  ((x & 0x03) << 5)
00052 
00053 namespace gig {
00054 
00055 // *************** progress_t ***************
00056 // *
00057 
00058     progress_t::progress_t() {
00059         callback    = NULL;
00060         custom      = NULL;
00061         __range_min = 0.0f;
00062         __range_max = 1.0f;
00063     }
00064 
00065     // private helper function to convert progress of a subprocess into the global progress
00066     static void __notify_progress(progress_t* pProgress, float subprogress) {
00067         if (pProgress && pProgress->callback) {
00068             const float totalrange    = pProgress->__range_max - pProgress->__range_min;
00069             const float totalprogress = pProgress->__range_min + subprogress * totalrange;
00070             pProgress->factor         = totalprogress;
00071             pProgress->callback(pProgress); // now actually notify about the progress
00072         }
00073     }
00074 
00075     // private helper function to divide a progress into subprogresses
00076     static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) {
00077         if (pParentProgress && pParentProgress->callback) {
00078             const float totalrange    = pParentProgress->__range_max - pParentProgress->__range_min;
00079             pSubProgress->callback    = pParentProgress->callback;
00080             pSubProgress->custom      = pParentProgress->custom;
00081             pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks;
00082             pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks;
00083         }
00084     }
00085 
00086 
00087 // *************** Internal functions for sample decompression ***************
00088 // *
00089 
00090 namespace {
00091 
00092     inline int get12lo(const unsigned char* pSrc)
00093     {
00094         const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
00095         return x & 0x800 ? x - 0x1000 : x;
00096     }
00097 
00098     inline int get12hi(const unsigned char* pSrc)
00099     {
00100         const int x = pSrc[1] >> 4 | pSrc[2] << 4;
00101         return x & 0x800 ? x - 0x1000 : x;
00102     }
00103 
00104     inline int16_t get16(const unsigned char* pSrc)
00105     {
00106         return int16_t(pSrc[0] | pSrc[1] << 8);
00107     }
00108 
00109     inline int get24(const unsigned char* pSrc)
00110     {
00111         const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
00112         return x & 0x800000 ? x - 0x1000000 : x;
00113     }
00114 
00115     inline void store24(unsigned char* pDst, int x)
00116     {
00117         pDst[0] = x;
00118         pDst[1] = x >> 8;
00119         pDst[2] = x >> 16;
00120     }
00121 
00122     void Decompress16(int compressionmode, const unsigned char* params,
00123                       int srcStep, int dstStep,
00124                       const unsigned char* pSrc, int16_t* pDst,
00125                       unsigned long currentframeoffset,
00126                       unsigned long copysamples)
00127     {
00128         switch (compressionmode) {
00129             case 0: // 16 bit uncompressed
00130                 pSrc += currentframeoffset * srcStep;
00131                 while (copysamples) {
00132                     *pDst = get16(pSrc);
00133                     pDst += dstStep;
00134                     pSrc += srcStep;
00135                     copysamples--;
00136                 }
00137                 break;
00138 
00139             case 1: // 16 bit compressed to 8 bit
00140                 int y  = get16(params);
00141                 int dy = get16(params + 2);
00142                 while (currentframeoffset) {
00143                     dy -= int8_t(*pSrc);
00144                     y  -= dy;
00145                     pSrc += srcStep;
00146                     currentframeoffset--;
00147                 }
00148                 while (copysamples) {
00149                     dy -= int8_t(*pSrc);
00150                     y  -= dy;
00151                     *pDst = y;
00152                     pDst += dstStep;
00153                     pSrc += srcStep;
00154                     copysamples--;
00155                 }
00156                 break;
00157         }
00158     }
00159 
00160     void Decompress24(int compressionmode, const unsigned char* params,
00161                       int dstStep, const unsigned char* pSrc, uint8_t* pDst,
00162                       unsigned long currentframeoffset,
00163                       unsigned long copysamples, int truncatedBits)
00164     {
00165         int y, dy, ddy, dddy;
00166 
00167 #define GET_PARAMS(params)                      \
00168         y    = get24(params);                   \
00169         dy   = y - get24((params) + 3);         \
00170         ddy  = get24((params) + 6);             \
00171         dddy = get24((params) + 9)
00172 
00173 #define SKIP_ONE(x)                             \
00174         dddy -= (x);                            \
00175         ddy  -= dddy;                           \
00176         dy   =  -dy - ddy;                      \
00177         y    += dy
00178 
00179 #define COPY_ONE(x)                             \
00180         SKIP_ONE(x);                            \
00181         store24(pDst, y << truncatedBits);      \
00182         pDst += dstStep
00183 
00184         switch (compressionmode) {
00185             case 2: // 24 bit uncompressed
00186                 pSrc += currentframeoffset * 3;
00187                 while (copysamples) {
00188                     store24(pDst, get24(pSrc) << truncatedBits);
00189                     pDst += dstStep;
00190                     pSrc += 3;
00191                     copysamples--;
00192                 }
00193                 break;
00194 
00195             case 3: // 24 bit compressed to 16 bit
00196                 GET_PARAMS(params);
00197                 while (currentframeoffset) {
00198                     SKIP_ONE(get16(pSrc));
00199                     pSrc += 2;
00200                     currentframeoffset--;
00201                 }
00202                 while (copysamples) {
00203                     COPY_ONE(get16(pSrc));
00204                     pSrc += 2;
00205                     copysamples--;
00206                 }
00207                 break;
00208 
00209             case 4: // 24 bit compressed to 12 bit
00210                 GET_PARAMS(params);
00211                 while (currentframeoffset > 1) {
00212                     SKIP_ONE(get12lo(pSrc));
00213                     SKIP_ONE(get12hi(pSrc));
00214                     pSrc += 3;
00215                     currentframeoffset -= 2;
00216                 }
00217                 if (currentframeoffset) {
00218                     SKIP_ONE(get12lo(pSrc));
00219                     currentframeoffset--;
00220                     if (copysamples) {
00221                         COPY_ONE(get12hi(pSrc));
00222                         pSrc += 3;
00223                         copysamples--;
00224                     }
00225                 }
00226                 while (copysamples > 1) {
00227                     COPY_ONE(get12lo(pSrc));
00228                     COPY_ONE(get12hi(pSrc));
00229                     pSrc += 3;
00230                     copysamples -= 2;
00231                 }
00232                 if (copysamples) {
00233                     COPY_ONE(get12lo(pSrc));
00234                 }
00235                 break;
00236 
00237             case 5: // 24 bit compressed to 8 bit
00238                 GET_PARAMS(params);
00239                 while (currentframeoffset) {
00240                     SKIP_ONE(int8_t(*pSrc++));
00241                     currentframeoffset--;
00242                 }
00243                 while (copysamples) {
00244                     COPY_ONE(int8_t(*pSrc++));
00245                     copysamples--;
00246                 }
00247                 break;
00248         }
00249     }
00250 
00251     const int bytesPerFrame[] =      { 4096, 2052, 768, 524, 396, 268 };
00252     const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
00253     const int headerSize[] =         { 0, 4, 0, 12, 12, 12 };
00254     const int bitsPerSample[] =      { 16, 8, 24, 16, 12, 8 };
00255 }
00256 
00257 
00258 
00259 // *************** Internal CRC-32 (Cyclic Redundancy Check) functions  ***************
00260 // *
00261 
00262     static uint32_t* __initCRCTable() {
00263         static uint32_t res[256];
00264 
00265         for (int i = 0 ; i < 256 ; i++) {
00266             uint32_t c = i;
00267             for (int j = 0 ; j < 8 ; j++) {
00268                 c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
00269             }
00270             res[i] = c;
00271         }
00272         return res;
00273     }
00274 
00275     static const uint32_t* __CRCTable = __initCRCTable();
00276 
00282     inline static void __resetCRC(uint32_t& crc) {
00283         crc = 0xffffffff;
00284     }
00285 
00305     static void __calculateCRC(unsigned char* buf, int bufSize, uint32_t& crc) {
00306         for (int i = 0 ; i < bufSize ; i++) {
00307             crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
00308         }
00309     }
00310 
00316     inline static uint32_t __encodeCRC(const uint32_t& crc) {
00317         return crc ^ 0xffffffff;
00318     }
00319 
00320 
00321 
00322 // *************** Other Internal functions  ***************
00323 // *
00324 
00325     static split_type_t __resolveSplitType(dimension_t dimension) {
00326         return (
00327             dimension == dimension_layer ||
00328             dimension == dimension_samplechannel ||
00329             dimension == dimension_releasetrigger ||
00330             dimension == dimension_keyboard ||
00331             dimension == dimension_roundrobin ||
00332             dimension == dimension_random ||
00333             dimension == dimension_smartmidi ||
00334             dimension == dimension_roundrobinkeyboard
00335         ) ? split_type_bit : split_type_normal;
00336     }
00337 
00338     static int __resolveZoneSize(dimension_def_t& dimension_definition) {
00339         return (dimension_definition.split_type == split_type_normal)
00340         ? int(128.0 / dimension_definition.zones) : 0;
00341     }
00342 
00343 
00344 
00345 // *************** Sample ***************
00346 // *
00347 
00348     unsigned int Sample::Instances = 0;
00349     buffer_t     Sample::InternalDecompressionBuffer;
00350 
00369     Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
00370         static const DLS::Info::string_length_t fixedStringLengths[] = {
00371             { CHUNK_ID_INAM, 64 },
00372             { 0, 0 }
00373         };
00374         pInfo->SetFixedStringLengths(fixedStringLengths);
00375         Instances++;
00376         FileNo = fileNo;
00377 
00378         __resetCRC(crc);
00379 
00380         pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
00381         if (pCk3gix) {
00382             uint16_t iSampleGroup = pCk3gix->ReadInt16();
00383             pGroup = pFile->GetGroup(iSampleGroup);
00384         } else { // '3gix' chunk missing
00385             // by default assigned to that mandatory "Default Group"
00386             pGroup = pFile->GetGroup(0);
00387         }
00388 
00389         pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
00390         if (pCkSmpl) {
00391             Manufacturer  = pCkSmpl->ReadInt32();
00392             Product       = pCkSmpl->ReadInt32();
00393             SamplePeriod  = pCkSmpl->ReadInt32();
00394             MIDIUnityNote = pCkSmpl->ReadInt32();
00395             FineTune      = pCkSmpl->ReadInt32();
00396             pCkSmpl->Read(&SMPTEFormat, 1, 4);
00397             SMPTEOffset   = pCkSmpl->ReadInt32();
00398             Loops         = pCkSmpl->ReadInt32();
00399             pCkSmpl->ReadInt32(); // manufByt
00400             LoopID        = pCkSmpl->ReadInt32();
00401             pCkSmpl->Read(&LoopType, 1, 4);
00402             LoopStart     = pCkSmpl->ReadInt32();
00403             LoopEnd       = pCkSmpl->ReadInt32();
00404             LoopFraction  = pCkSmpl->ReadInt32();
00405             LoopPlayCount = pCkSmpl->ReadInt32();
00406         } else { // 'smpl' chunk missing
00407             // use default values
00408             Manufacturer  = 0;
00409             Product       = 0;
00410             SamplePeriod  = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
00411             MIDIUnityNote = 60;
00412             FineTune      = 0;
00413             SMPTEFormat   = smpte_format_no_offset;
00414             SMPTEOffset   = 0;
00415             Loops         = 0;
00416             LoopID        = 0;
00417             LoopType      = loop_type_normal;
00418             LoopStart     = 0;
00419             LoopEnd       = 0;
00420             LoopFraction  = 0;
00421             LoopPlayCount = 0;
00422         }
00423 
00424         FrameTable                 = NULL;
00425         SamplePos                  = 0;
00426         RAMCache.Size              = 0;
00427         RAMCache.pStart            = NULL;
00428         RAMCache.NullExtensionSize = 0;
00429 
00430         if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
00431 
00432         RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
00433         Compressed        = ewav;
00434         Dithered          = false;
00435         TruncatedBits     = 0;
00436         if (Compressed) {
00437             uint32_t version = ewav->ReadInt32();
00438             if (version == 3 && BitDepth == 24) {
00439                 Dithered = ewav->ReadInt32();
00440                 ewav->SetPos(Channels == 2 ? 84 : 64);
00441                 TruncatedBits = ewav->ReadInt32();
00442             }
00443             ScanCompressedSample();
00444         }
00445 
00446         // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
00447         if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
00448             InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
00449             InternalDecompressionBuffer.Size   = INITIAL_SAMPLE_BUFFER_SIZE;
00450         }
00451         FrameOffset = 0; // just for streaming compressed samples
00452 
00453         LoopSize = LoopEnd - LoopStart + 1;
00454     }
00455 
00467     void Sample::UpdateChunks() {
00468         // first update base class's chunks
00469         DLS::Sample::UpdateChunks();
00470 
00471         // make sure 'smpl' chunk exists
00472         pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
00473         if (!pCkSmpl) {
00474             pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
00475             memset(pCkSmpl->LoadChunkData(), 0, 60);
00476         }
00477         // update 'smpl' chunk
00478         uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
00479         SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
00480         store32(&pData[0], Manufacturer);
00481         store32(&pData[4], Product);
00482         store32(&pData[8], SamplePeriod);
00483         store32(&pData[12], MIDIUnityNote);
00484         store32(&pData[16], FineTune);
00485         store32(&pData[20], SMPTEFormat);
00486         store32(&pData[24], SMPTEOffset);
00487         store32(&pData[28], Loops);
00488 
00489         // we skip 'manufByt' for now (4 bytes)
00490 
00491         store32(&pData[36], LoopID);
00492         store32(&pData[40], LoopType);
00493         store32(&pData[44], LoopStart);
00494         store32(&pData[48], LoopEnd);
00495         store32(&pData[52], LoopFraction);
00496         store32(&pData[56], LoopPlayCount);
00497 
00498         // make sure '3gix' chunk exists
00499         pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
00500         if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
00501         // determine appropriate sample group index (to be stored in chunk)
00502         uint16_t iSampleGroup = 0; // 0 refers to default sample group
00503         File* pFile = static_cast<File*>(pParent);
00504         if (pFile->pGroups) {
00505             std::list<Group*>::iterator iter = pFile->pGroups->begin();
00506             std::list<Group*>::iterator end  = pFile->pGroups->end();
00507             for (int i = 0; iter != end; i++, iter++) {
00508                 if (*iter == pGroup) {
00509                     iSampleGroup = i;
00510                     break; // found
00511                 }
00512             }
00513         }
00514         // update '3gix' chunk
00515         pData = (uint8_t*) pCk3gix->LoadChunkData();
00516         store16(&pData[0], iSampleGroup);
00517     }
00518 
00520     void Sample::ScanCompressedSample() {
00521         //TODO: we have to add some more scans here (e.g. determine compression rate)
00522         this->SamplesTotal = 0;
00523         std::list<unsigned long> frameOffsets;
00524 
00525         SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
00526         WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
00527 
00528         // Scanning
00529         pCkData->SetPos(0);
00530         if (Channels == 2) { // Stereo
00531             for (int i = 0 ; ; i++) {
00532                 // for 24 bit samples every 8:th frame offset is
00533                 // stored, to save some memory
00534                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00535 
00536                 const int mode_l = pCkData->ReadUint8();
00537                 const int mode_r = pCkData->ReadUint8();
00538                 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
00539                 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
00540 
00541                 if (pCkData->RemainingBytes() <= frameSize) {
00542                     SamplesInLastFrame =
00543                         ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
00544                         (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
00545                     SamplesTotal += SamplesInLastFrame;
00546                     break;
00547                 }
00548                 SamplesTotal += SamplesPerFrame;
00549                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00550             }
00551         }
00552         else { // Mono
00553             for (int i = 0 ; ; i++) {
00554                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00555 
00556                 const int mode = pCkData->ReadUint8();
00557                 if (mode > 5) throw gig::Exception("Unknown compression mode");
00558                 const unsigned long frameSize = bytesPerFrame[mode];
00559 
00560                 if (pCkData->RemainingBytes() <= frameSize) {
00561                     SamplesInLastFrame =
00562                         ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
00563                     SamplesTotal += SamplesInLastFrame;
00564                     break;
00565                 }
00566                 SamplesTotal += SamplesPerFrame;
00567                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00568             }
00569         }
00570         pCkData->SetPos(0);
00571 
00572         // Build the frames table (which is used for fast resolving of a frame's chunk offset)
00573         if (FrameTable) delete[] FrameTable;
00574         FrameTable = new unsigned long[frameOffsets.size()];
00575         std::list<unsigned long>::iterator end  = frameOffsets.end();
00576         std::list<unsigned long>::iterator iter = frameOffsets.begin();
00577         for (int i = 0; iter != end; i++, iter++) {
00578             FrameTable[i] = *iter;
00579         }
00580     }
00581 
00591     buffer_t Sample::LoadSampleData() {
00592         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
00593     }
00594 
00617     buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
00618         return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
00619     }
00620 
00640     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
00641         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
00642     }
00643 
00676     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
00677         if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
00678         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00679         unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
00680         SetPos(0); // reset read position to begin of sample
00681         RAMCache.pStart            = new int8_t[allocationsize];
00682         RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
00683         RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
00684         // fill the remaining buffer space with silence samples
00685         memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
00686         return GetCache();
00687     }
00688 
00699     buffer_t Sample::GetCache() {
00700         // return a copy of the buffer_t structure
00701         buffer_t result;
00702         result.Size              = this->RAMCache.Size;
00703         result.pStart            = this->RAMCache.pStart;
00704         result.NullExtensionSize = this->RAMCache.NullExtensionSize;
00705         return result;
00706     }
00707 
00714     void Sample::ReleaseSampleData() {
00715         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00716         RAMCache.pStart = NULL;
00717         RAMCache.Size   = 0;
00718         RAMCache.NullExtensionSize = 0;
00719     }
00720 
00751     void Sample::Resize(int iNewSize) {
00752         if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
00753         DLS::Sample::Resize(iNewSize);
00754     }
00755 
00777     unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
00778         if (Compressed) {
00779             switch (Whence) {
00780                 case RIFF::stream_curpos:
00781                     this->SamplePos += SampleCount;
00782                     break;
00783                 case RIFF::stream_end:
00784                     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
00785                     break;
00786                 case RIFF::stream_backward:
00787                     this->SamplePos -= SampleCount;
00788                     break;
00789                 case RIFF::stream_start: default:
00790                     this->SamplePos = SampleCount;
00791                     break;
00792             }
00793             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00794 
00795             unsigned long frame = this->SamplePos / 2048; // to which frame to jump
00796             this->FrameOffset   = this->SamplePos % 2048; // offset (in sample points) within that frame
00797             pCkData->SetPos(FrameTable[frame]);           // set chunk pointer to the start of sought frame
00798             return this->SamplePos;
00799         }
00800         else { // not compressed
00801             unsigned long orderedBytes = SampleCount * this->FrameSize;
00802             unsigned long result = pCkData->SetPos(orderedBytes, Whence);
00803             return (result == orderedBytes) ? SampleCount
00804                                             : result / this->FrameSize;
00805         }
00806     }
00807 
00811     unsigned long Sample::GetPos() {
00812         if (Compressed) return SamplePos;
00813         else            return pCkData->GetPos() / FrameSize;
00814     }
00815 
00850     unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState,
00851                                       DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
00852         unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
00853         uint8_t* pDst = (uint8_t*) pBuffer;
00854 
00855         SetPos(pPlaybackState->position); // recover position from the last time
00856 
00857         if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
00858 
00859             const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
00860             const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
00861 
00862             if (GetPos() <= loopEnd) {
00863                 switch (loop.LoopType) {
00864 
00865                     case loop_type_bidirectional: { //TODO: not tested yet!
00866                         do {
00867                             // if not endless loop check if max. number of loop cycles have been passed
00868                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00869 
00870                             if (!pPlaybackState->reverse) { // forward playback
00871                                 do {
00872                                     samplestoloopend  = loopEnd - GetPos();
00873                                     readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00874                                     samplestoread    -= readsamples;
00875                                     totalreadsamples += readsamples;
00876                                     if (readsamples == samplestoloopend) {
00877                                         pPlaybackState->reverse = true;
00878                                         break;
00879                                     }
00880                                 } while (samplestoread && readsamples);
00881                             }
00882                             else { // backward playback
00883 
00884                                 // as we can only read forward from disk, we have to
00885                                 // determine the end position within the loop first,
00886                                 // read forward from that 'end' and finally after
00887                                 // reading, swap all sample frames so it reflects
00888                                 // backward playback
00889 
00890                                 unsigned long swapareastart       = totalreadsamples;
00891                                 unsigned long loopoffset          = GetPos() - loop.LoopStart;
00892                                 unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
00893                                 unsigned long reverseplaybackend  = GetPos() - samplestoreadinloop;
00894 
00895                                 SetPos(reverseplaybackend);
00896 
00897                                 // read samples for backward playback
00898                                 do {
00899                                     readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
00900                                     samplestoreadinloop -= readsamples;
00901                                     samplestoread       -= readsamples;
00902                                     totalreadsamples    += readsamples;
00903                                 } while (samplestoreadinloop && readsamples);
00904 
00905                                 SetPos(reverseplaybackend); // pretend we really read backwards
00906 
00907                                 if (reverseplaybackend == loop.LoopStart) {
00908                                     pPlaybackState->loop_cycles_left--;
00909                                     pPlaybackState->reverse = false;
00910                                 }
00911 
00912                                 // reverse the sample frames for backward playback
00913                                 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!
00914                                     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00915                             }
00916                         } while (samplestoread && readsamples);
00917                         break;
00918                     }
00919 
00920                     case loop_type_backward: { // TODO: not tested yet!
00921                         // forward playback (not entered the loop yet)
00922                         if (!pPlaybackState->reverse) do {
00923                             samplestoloopend  = loopEnd - GetPos();
00924                             readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00925                             samplestoread    -= readsamples;
00926                             totalreadsamples += readsamples;
00927                             if (readsamples == samplestoloopend) {
00928                                 pPlaybackState->reverse = true;
00929                                 break;
00930                             }
00931                         } while (samplestoread && readsamples);
00932 
00933                         if (!samplestoread) break;
00934 
00935                         // as we can only read forward from disk, we have to
00936                         // determine the end position within the loop first,
00937                         // read forward from that 'end' and finally after
00938                         // reading, swap all sample frames so it reflects
00939                         // backward playback
00940 
00941                         unsigned long swapareastart       = totalreadsamples;
00942                         unsigned long loopoffset          = GetPos() - loop.LoopStart;
00943                         unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
00944                                                                                   : samplestoread;
00945                         unsigned long reverseplaybackend  = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
00946 
00947                         SetPos(reverseplaybackend);
00948 
00949                         // read samples for backward playback
00950                         do {
00951                             // if not endless loop check if max. number of loop cycles have been passed
00952                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00953                             samplestoloopend     = loopEnd - GetPos();
00954                             readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
00955                             samplestoreadinloop -= readsamples;
00956                             samplestoread       -= readsamples;
00957                             totalreadsamples    += readsamples;
00958                             if (readsamples == samplestoloopend) {
00959                                 pPlaybackState->loop_cycles_left--;
00960                                 SetPos(loop.LoopStart);
00961                             }
00962                         } while (samplestoreadinloop && readsamples);
00963 
00964                         SetPos(reverseplaybackend); // pretend we really read backwards
00965 
00966                         // reverse the sample frames for backward playback
00967                         SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00968                         break;
00969                     }
00970 
00971                     default: case loop_type_normal: {
00972                         do {
00973                             // if not endless loop check if max. number of loop cycles have been passed
00974                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00975                             samplestoloopend  = loopEnd - GetPos();
00976                             readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00977                             samplestoread    -= readsamples;
00978                             totalreadsamples += readsamples;
00979                             if (readsamples == samplestoloopend) {
00980                                 pPlaybackState->loop_cycles_left--;
00981                                 SetPos(loop.LoopStart);
00982                             }
00983                         } while (samplestoread && readsamples);
00984                         break;
00985                     }
00986                 }
00987             }
00988         }
00989 
00990         // read on without looping
00991         if (samplestoread) do {
00992             readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
00993             samplestoread    -= readsamples;
00994             totalreadsamples += readsamples;
00995         } while (readsamples && samplestoread);
00996 
00997         // store current position
00998         pPlaybackState->position = GetPos();
00999 
01000         return totalreadsamples;
01001     }
01002 
01025     unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
01026         if (SampleCount == 0) return 0;
01027         if (!Compressed) {
01028             if (BitDepth == 24) {
01029                 return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
01030             }
01031             else { // 16 bit
01032                 // (pCkData->Read does endian correction)
01033                 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
01034                                      : pCkData->Read(pBuffer, SampleCount, 2);
01035             }
01036         }
01037         else {
01038             if (this->SamplePos >= this->SamplesTotal) return 0;
01039             //TODO: efficiency: maybe we should test for an average compression rate
01040             unsigned long assumedsize      = GuessSize(SampleCount),
01041                           remainingbytes   = 0,           // remaining bytes in the local buffer
01042                           remainingsamples = SampleCount,
01043                           copysamples, skipsamples,
01044                           currentframeoffset = this->FrameOffset;  // offset in current sample frame since last Read()
01045             this->FrameOffset = 0;
01046 
01047             buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
01048 
01049             // if decompression buffer too small, then reduce amount of samples to read
01050             if (pDecompressionBuffer->Size < assumedsize) {
01051                 std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
01052                 SampleCount      = WorstCaseMaxSamples(pDecompressionBuffer);
01053                 remainingsamples = SampleCount;
01054                 assumedsize      = GuessSize(SampleCount);
01055             }
01056 
01057             unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
01058             int16_t* pDst = static_cast<int16_t*>(pBuffer);
01059             uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
01060             remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
01061 
01062             while (remainingsamples && remainingbytes) {
01063                 unsigned long framesamples = SamplesPerFrame;
01064                 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
01065 
01066                 int mode_l = *pSrc++, mode_r = 0;
01067 
01068                 if (Channels == 2) {
01069                     mode_r = *pSrc++;
01070                     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
01071                     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
01072                     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
01073                     if (remainingbytes < framebytes) { // last frame in sample
01074                         framesamples = SamplesInLastFrame;
01075                         if (mode_l == 4 && (framesamples & 1)) {
01076                             rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
01077                         }
01078                         else {
01079                             rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
01080                         }
01081                     }
01082                 }
01083                 else {
01084                     framebytes = bytesPerFrame[mode_l] + 1;
01085                     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
01086                     if (remainingbytes < framebytes) {
01087                         framesamples = SamplesInLastFrame;
01088                     }
01089                 }
01090 
01091                 // determine how many samples in this frame to skip and read
01092                 if (currentframeoffset + remainingsamples >= framesamples) {
01093                     if (currentframeoffset <= framesamples) {
01094                         copysamples = framesamples - currentframeoffset;
01095                         skipsamples = currentframeoffset;
01096                     }
01097                     else {
01098                         copysamples = 0;
01099                         skipsamples = framesamples;
01100                     }
01101                 }
01102                 else {
01103                     // This frame has enough data for pBuffer, but not
01104                     // all of the frame is needed. Set file position
01105                     // to start of this frame for next call to Read.
01106                     copysamples = remainingsamples;
01107                     skipsamples = currentframeoffset;
01108                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01109                     this->FrameOffset = currentframeoffset + copysamples;
01110                 }
01111                 remainingsamples -= copysamples;
01112 
01113                 if (remainingbytes > framebytes) {
01114                     remainingbytes -= framebytes;
01115                     if (remainingsamples == 0 &&
01116                         currentframeoffset + copysamples == framesamples) {
01117                         // This frame has enough data for pBuffer, and
01118                         // all of the frame is needed. Set file
01119                         // position to start of next frame for next
01120                         // call to Read. FrameOffset is 0.
01121                         pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01122                     }
01123                 }
01124                 else remainingbytes = 0;
01125 
01126                 currentframeoffset -= skipsamples;
01127 
01128                 if (copysamples == 0) {
01129                     // skip this frame
01130                     pSrc += framebytes - Channels;
01131                 }
01132                 else {
01133                     const unsigned char* const param_l = pSrc;
01134                     if (BitDepth == 24) {
01135                         if (mode_l != 2) pSrc += 12;
01136 
01137                         if (Channels == 2) { // Stereo
01138                             const unsigned char* const param_r = pSrc;
01139                             if (mode_r != 2) pSrc += 12;
01140 
01141                             Decompress24(mode_l, param_l, 6, pSrc, pDst24,
01142                                          skipsamples, copysamples, TruncatedBits);
01143                             Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
01144                                          skipsamples, copysamples, TruncatedBits);
01145                             pDst24 += copysamples * 6;
01146                         }
01147                         else { // Mono
01148                             Decompress24(mode_l, param_l, 3, pSrc, pDst24,
01149                                          skipsamples, copysamples, TruncatedBits);
01150                             pDst24 += copysamples * 3;
01151                         }
01152                     }
01153                     else { // 16 bit
01154                         if (mode_l) pSrc += 4;
01155 
01156                         int step;
01157                         if (Channels == 2) { // Stereo
01158                             const unsigned char* const param_r = pSrc;
01159                             if (mode_r) pSrc += 4;
01160 
01161                             step = (2 - mode_l) + (2 - mode_r);
01162                             Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
01163                             Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
01164                                          skipsamples, copysamples);
01165                             pDst += copysamples << 1;
01166                         }
01167                         else { // Mono
01168                             step = 2 - mode_l;
01169                             Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
01170                             pDst += copysamples;
01171                         }
01172                     }
01173                     pSrc += nextFrameOffset;
01174                 }
01175 
01176                 // reload from disk to local buffer if needed
01177                 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
01178                     assumedsize    = GuessSize(remainingsamples);
01179                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01180                     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
01181                     remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
01182                     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
01183                 }
01184             } // while
01185 
01186             this->SamplePos += (SampleCount - remainingsamples);
01187             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
01188             return (SampleCount - remainingsamples);
01189         }
01190     }
01191 
01214     unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
01215         if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
01216 
01217         // if this is the first write in this sample, reset the
01218         // checksum calculator
01219         if (pCkData->GetPos() == 0) {
01220             __resetCRC(crc);
01221         }
01222         if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
01223         unsigned long res;
01224         if (BitDepth == 24) {
01225             res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
01226         } else { // 16 bit
01227             res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
01228                                 : pCkData->Write(pBuffer, SampleCount, 2);
01229         }
01230         __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
01231 
01232         // if this is the last write, update the checksum chunk in the
01233         // file
01234         if (pCkData->GetPos() == pCkData->GetSize()) {
01235             File* pFile = static_cast<File*>(GetParent());
01236             pFile->SetSampleChecksum(this, __encodeCRC(crc));
01237         }
01238         return res;
01239     }
01240 
01257     buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
01258         buffer_t result;
01259         const double worstCaseHeaderOverhead =
01260                 (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
01261         result.Size              = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
01262         result.pStart            = new int8_t[result.Size];
01263         result.NullExtensionSize = 0;
01264         return result;
01265     }
01266 
01274     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
01275         if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
01276             delete[] (int8_t*) DecompressionBuffer.pStart;
01277             DecompressionBuffer.pStart = NULL;
01278             DecompressionBuffer.Size   = 0;
01279             DecompressionBuffer.NullExtensionSize = 0;
01280         }
01281     }
01282 
01291     Group* Sample::GetGroup() const {
01292         return pGroup;
01293     }
01294 
01295     Sample::~Sample() {
01296         Instances--;
01297         if (!Instances && InternalDecompressionBuffer.Size) {
01298             delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
01299             InternalDecompressionBuffer.pStart = NULL;
01300             InternalDecompressionBuffer.Size   = 0;
01301         }
01302         if (FrameTable) delete[] FrameTable;
01303         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
01304     }
01305 
01306 
01307 
01308 // *************** DimensionRegion ***************
01309 // *
01310 
01311     uint                               DimensionRegion::Instances       = 0;
01312     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
01313 
01314     DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
01315         Instances++;
01316 
01317         pSample = NULL;
01318         pRegion = pParent;
01319 
01320         if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
01321         else memset(&Crossfade, 0, 4);
01322 
01323         if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
01324 
01325         RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
01326         if (_3ewa) { // if '3ewa' chunk exists
01327             _3ewa->ReadInt32(); // unknown, always == chunk size ?
01328             LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01329             EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01330             _3ewa->ReadInt16(); // unknown
01331             LFO1InternalDepth = _3ewa->ReadUint16();
01332             _3ewa->ReadInt16(); // unknown
01333             LFO3InternalDepth = _3ewa->ReadInt16();
01334             _3ewa->ReadInt16(); // unknown
01335             LFO1ControlDepth = _3ewa->ReadUint16();
01336             _3ewa->ReadInt16(); // unknown
01337             LFO3ControlDepth = _3ewa->ReadInt16();
01338             EG1Attack           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01339             EG1Decay1           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01340             _3ewa->ReadInt16(); // unknown
01341             EG1Sustain          = _3ewa->ReadUint16();
01342             EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01343             EG1Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01344             uint8_t eg1ctrloptions        = _3ewa->ReadUint8();
01345             EG1ControllerInvert           = eg1ctrloptions & 0x01;
01346             EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
01347             EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
01348             EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
01349             EG2Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01350             uint8_t eg2ctrloptions        = _3ewa->ReadUint8();
01351             EG2ControllerInvert           = eg2ctrloptions & 0x01;
01352             EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
01353             EG2ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
01354             EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
01355             LFO1Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01356             EG2Attack        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01357             EG2Decay1        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01358             _3ewa->ReadInt16(); // unknown
01359             EG2Sustain       = _3ewa->ReadUint16();
01360             EG2Release       = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01361             _3ewa->ReadInt16(); // unknown
01362             LFO2ControlDepth = _3ewa->ReadUint16();
01363             LFO2Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01364             _3ewa->ReadInt16(); // unknown
01365             LFO2InternalDepth = _3ewa->ReadUint16();
01366             int32_t eg1decay2 = _3ewa->ReadInt32();
01367             EG1Decay2          = (double) GIG_EXP_DECODE(eg1decay2);
01368             EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
01369             _3ewa->ReadInt16(); // unknown
01370             EG1PreAttack      = _3ewa->ReadUint16();
01371             int32_t eg2decay2 = _3ewa->ReadInt32();
01372             EG2Decay2         = (double) GIG_EXP_DECODE(eg2decay2);
01373             EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
01374             _3ewa->ReadInt16(); // unknown
01375             EG2PreAttack      = _3ewa->ReadUint16();
01376             uint8_t velocityresponse = _3ewa->ReadUint8();
01377             if (velocityresponse < 5) {
01378                 VelocityResponseCurve = curve_type_nonlinear;
01379                 VelocityResponseDepth = velocityresponse;
01380             } else if (velocityresponse < 10) {
01381                 VelocityResponseCurve = curve_type_linear;
01382                 VelocityResponseDepth = velocityresponse - 5;
01383             } else if (velocityresponse < 15) {
01384                 VelocityResponseCurve = curve_type_special;
01385                 VelocityResponseDepth = velocityresponse - 10;
01386             } else {
01387                 VelocityResponseCurve = curve_type_unknown;
01388                 VelocityResponseDepth = 0;
01389             }
01390             uint8_t releasevelocityresponse = _3ewa->ReadUint8();
01391             if (releasevelocityresponse < 5) {
01392                 ReleaseVelocityResponseCurve = curve_type_nonlinear;
01393                 ReleaseVelocityResponseDepth = releasevelocityresponse;
01394             } else if (releasevelocityresponse < 10) {
01395                 ReleaseVelocityResponseCurve = curve_type_linear;
01396                 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
01397             } else if (releasevelocityresponse < 15) {
01398                 ReleaseVelocityResponseCurve = curve_type_special;
01399                 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
01400             } else {
01401                 ReleaseVelocityResponseCurve = curve_type_unknown;
01402                 ReleaseVelocityResponseDepth = 0;
01403             }
01404             VelocityResponseCurveScaling = _3ewa->ReadUint8();
01405             AttenuationControllerThreshold = _3ewa->ReadInt8();
01406             _3ewa->ReadInt32(); // unknown
01407             SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
01408             _3ewa->ReadInt16(); // unknown
01409             uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
01410             PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
01411             if      (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
01412             else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
01413             else                                       DimensionBypass = dim_bypass_ctrl_none;
01414             uint8_t pan = _3ewa->ReadUint8();
01415             Pan         = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
01416             SelfMask = _3ewa->ReadInt8() & 0x01;
01417             _3ewa->ReadInt8(); // unknown
01418             uint8_t lfo3ctrl = _3ewa->ReadUint8();
01419             LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
01420             LFO3Sync                 = lfo3ctrl & 0x20; // bit 5
01421             InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
01422             AttenuationController  = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01423             uint8_t lfo2ctrl       = _3ewa->ReadUint8();
01424             LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
01425             LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7
01426             LFO2Sync               = lfo2ctrl & 0x20; // bit 5
01427             bool extResonanceCtrl  = lfo2ctrl & 0x40; // bit 6
01428             uint8_t lfo1ctrl       = _3ewa->ReadUint8();
01429             LFO1Controller         = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
01430             LFO1FlipPhase          = lfo1ctrl & 0x80; // bit 7
01431             LFO1Sync               = lfo1ctrl & 0x40; // bit 6
01432             VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
01433                                                         : vcf_res_ctrl_none;
01434             uint16_t eg3depth = _3ewa->ReadUint16();
01435             EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
01436                                         : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
01437             _3ewa->ReadInt16(); // unknown
01438             ChannelOffset = _3ewa->ReadUint8() / 4;
01439             uint8_t regoptions = _3ewa->ReadUint8();
01440             MSDecode           = regoptions & 0x01; // bit 0
01441             SustainDefeat      = regoptions & 0x02; // bit 1
01442             _3ewa->ReadInt16(); // unknown
01443             VelocityUpperLimit = _3ewa->ReadInt8();
01444             _3ewa->ReadInt8(); // unknown
01445             _3ewa->ReadInt16(); // unknown
01446             ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
01447             _3ewa->ReadInt8(); // unknown
01448             _3ewa->ReadInt8(); // unknown
01449             EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
01450             uint8_t vcfcutoff = _3ewa->ReadUint8();
01451             VCFEnabled = vcfcutoff & 0x80; // bit 7
01452             VCFCutoff  = vcfcutoff & 0x7f; // lower 7 bits
01453             VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
01454             uint8_t vcfvelscale = _3ewa->ReadUint8();
01455             VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
01456             VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
01457             _3ewa->ReadInt8(); // unknown
01458             uint8_t vcfresonance = _3ewa->ReadUint8();
01459             VCFResonance = vcfresonance & 0x7f; // lower 7 bits
01460             VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
01461             uint8_t vcfbreakpoint         = _3ewa->ReadUint8();
01462             VCFKeyboardTracking           = vcfbreakpoint & 0x80; // bit 7
01463             VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
01464             uint8_t vcfvelocity = _3ewa->ReadUint8();
01465             VCFVelocityDynamicRange = vcfvelocity % 5;
01466             VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
01467             VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
01468             if (VCFType == vcf_type_lowpass) {
01469                 if (lfo3ctrl & 0x40) // bit 6
01470                     VCFType = vcf_type_lowpassturbo;
01471             }
01472             if (_3ewa->RemainingBytes() >= 8) {
01473                 _3ewa->Read(DimensionUpperLimits, 1, 8);
01474             } else {
01475                 memset(DimensionUpperLimits, 0, 8);
01476             }
01477         } else { // '3ewa' chunk does not exist yet
01478             // use default values
01479             LFO3Frequency                   = 1.0;
01480             EG3Attack                       = 0.0;
01481             LFO1InternalDepth               = 0;
01482             LFO3InternalDepth               = 0;
01483             LFO1ControlDepth                = 0;
01484             LFO3ControlDepth                = 0;
01485             EG1Attack                       = 0.0;
01486             EG1Decay1                       = 0.005;
01487             EG1Sustain                      = 1000;
01488             EG1Release                      = 0.3;
01489             EG1Controller.type              = eg1_ctrl_t::type_none;
01490             EG1Controller.controller_number = 0;
01491             EG1ControllerInvert             = false;
01492             EG1ControllerAttackInfluence    = 0;
01493             EG1ControllerDecayInfluence     = 0;
01494             EG1ControllerReleaseInfluence   = 0;
01495             EG2Controller.type              = eg2_ctrl_t::type_none;
01496             EG2Controller.controller_number = 0;
01497             EG2ControllerInvert             = false;
01498             EG2ControllerAttackInfluence    = 0;
01499             EG2ControllerDecayInfluence     = 0;
01500             EG2ControllerReleaseInfluence   = 0;
01501             LFO1Frequency                   = 1.0;
01502             EG2Attack                       = 0.0;
01503             EG2Decay1                       = 0.005;
01504             EG2Sustain                      = 1000;
01505             EG2Release                      = 0.3;
01506             LFO2ControlDepth                = 0;
01507             LFO2Frequency                   = 1.0;
01508             LFO2InternalDepth               = 0;
01509             EG1Decay2                       = 0.0;
01510             EG1InfiniteSustain              = true;
01511             EG1PreAttack                    = 0;
01512             EG2Decay2                       = 0.0;
01513             EG2InfiniteSustain              = true;
01514             EG2PreAttack                    = 0;
01515             VelocityResponseCurve           = curve_type_nonlinear;
01516             VelocityResponseDepth           = 3;
01517             ReleaseVelocityResponseCurve    = curve_type_nonlinear;
01518             ReleaseVelocityResponseDepth    = 3;
01519             VelocityResponseCurveScaling    = 32;
01520             AttenuationControllerThreshold  = 0;
01521             SampleStartOffset               = 0;
01522             PitchTrack                      = true;
01523             DimensionBypass                 = dim_bypass_ctrl_none;
01524             Pan                             = 0;
01525             SelfMask                        = true;
01526             LFO3Controller                  = lfo3_ctrl_modwheel;
01527             LFO3Sync                        = false;
01528             InvertAttenuationController     = false;
01529             AttenuationController.type      = attenuation_ctrl_t::type_none;
01530             AttenuationController.controller_number = 0;
01531             LFO2Controller                  = lfo2_ctrl_internal;
01532             LFO2FlipPhase                   = false;
01533             LFO2Sync                        = false;
01534             LFO1Controller                  = lfo1_ctrl_internal;
01535             LFO1FlipPhase                   = false;
01536             LFO1Sync                        = false;
01537             VCFResonanceController          = vcf_res_ctrl_none;
01538             EG3Depth                        = 0;
01539             ChannelOffset                   = 0;
01540             MSDecode                        = false;
01541             SustainDefeat                   = false;
01542             VelocityUpperLimit              = 0;
01543             ReleaseTriggerDecay             = 0;
01544             EG1Hold                         = false;
01545             VCFEnabled                      = false;
01546             VCFCutoff                       = 0;
01547             VCFCutoffController             = vcf_cutoff_ctrl_none;
01548             VCFCutoffControllerInvert       = false;
01549             VCFVelocityScale                = 0;
01550             VCFResonance                    = 0;
01551             VCFResonanceDynamic             = false;
01552             VCFKeyboardTracking             = false;
01553             VCFKeyboardTrackingBreakpoint   = 0;
01554             VCFVelocityDynamicRange         = 0x04;
01555             VCFVelocityCurve                = curve_type_linear;
01556             VCFType                         = vcf_type_lowpass;
01557             memset(DimensionUpperLimits, 127, 8);
01558         }
01559 
01560         pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
01561                                                      VelocityResponseDepth,
01562                                                      VelocityResponseCurveScaling);
01563 
01564         pVelocityReleaseTable = GetReleaseVelocityTable(
01565                                     ReleaseVelocityResponseCurve,
01566                                     ReleaseVelocityResponseDepth
01567                                 );
01568 
01569         pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
01570                                                       VCFVelocityDynamicRange,
01571                                                       VCFVelocityScale,
01572                                                       VCFCutoffController);
01573 
01574         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01575         VelocityTable = 0;
01576     }
01577 
01578     /*
01579      * Constructs a DimensionRegion by copying all parameters from
01580      * another DimensionRegion
01581      */
01582     DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
01583         Instances++;
01584         *this = src; // default memberwise shallow copy of all parameters
01585         pParentList = _3ewl; // restore the chunk pointer
01586 
01587         // deep copy of owned structures
01588         if (src.VelocityTable) {
01589             VelocityTable = new uint8_t[128];
01590             for (int k = 0 ; k < 128 ; k++)
01591                 VelocityTable[k] = src.VelocityTable[k];
01592         }
01593         if (src.pSampleLoops) {
01594             pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
01595             for (int k = 0 ; k < src.SampleLoops ; k++)
01596                 pSampleLoops[k] = src.pSampleLoops[k];
01597         }
01598     }
01599 
01604     void DimensionRegion::SetGain(int32_t gain) {
01605         DLS::Sampler::SetGain(gain);
01606         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01607     }
01608 
01616     void DimensionRegion::UpdateChunks() {
01617         // first update base class's chunk
01618         DLS::Sampler::UpdateChunks();
01619 
01620         RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
01621         uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
01622         pData[12] = Crossfade.in_start;
01623         pData[13] = Crossfade.in_end;
01624         pData[14] = Crossfade.out_start;
01625         pData[15] = Crossfade.out_end;
01626 
01627         // make sure '3ewa' chunk exists
01628         RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
01629         if (!_3ewa) {
01630             File* pFile = (File*) GetParent()->GetParent()->GetParent();
01631             bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
01632             _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
01633         }
01634         pData = (uint8_t*) _3ewa->LoadChunkData();
01635 
01636         // update '3ewa' chunk with DimensionRegion's current settings
01637 
01638         const uint32_t chunksize = _3ewa->GetNewSize();
01639         store32(&pData[0], chunksize); // unknown, always chunk size?
01640 
01641         const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
01642         store32(&pData[4], lfo3freq);
01643 
01644         const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
01645         store32(&pData[8], eg3attack);
01646 
01647         // next 2 bytes unknown
01648 
01649         store16(&pData[14], LFO1InternalDepth);
01650 
01651         // next 2 bytes unknown
01652 
01653         store16(&pData[18], LFO3InternalDepth);
01654 
01655         // next 2 bytes unknown
01656 
01657         store16(&pData[22], LFO1ControlDepth);
01658 
01659         // next 2 bytes unknown
01660 
01661         store16(&pData[26], LFO3ControlDepth);
01662 
01663         const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
01664         store32(&pData[28], eg1attack);
01665 
01666         const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
01667         store32(&pData[32], eg1decay1);
01668 
01669         // next 2 bytes unknown
01670 
01671         store16(&pData[38], EG1Sustain);
01672 
01673         const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
01674         store32(&pData[40], eg1release);
01675 
01676         const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
01677         pData[44] = eg1ctl;
01678 
01679         const uint8_t eg1ctrloptions =
01680             (EG1ControllerInvert ? 0x01 : 0x00) |
01681             GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
01682             GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
01683             GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
01684         pData[45] = eg1ctrloptions;
01685 
01686         const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
01687         pData[46] = eg2ctl;
01688 
01689         const uint8_t eg2ctrloptions =
01690             (EG2ControllerInvert ? 0x01 : 0x00) |
01691             GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
01692             GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
01693             GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
01694         pData[47] = eg2ctrloptions;
01695 
01696         const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
01697         store32(&pData[48], lfo1freq);
01698 
01699         const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
01700         store32(&pData[52], eg2attack);
01701 
01702         const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
01703         store32(&pData[56], eg2decay1);
01704 
01705         // next 2 bytes unknown
01706 
01707         store16(&pData[62], EG2Sustain);
01708 
01709         const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
01710         store32(&pData[64], eg2release);
01711 
01712         // next 2 bytes unknown
01713 
01714         store16(&pData[70], LFO2ControlDepth);
01715 
01716         const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
01717         store32(&pData[72], lfo2freq);
01718 
01719         // next 2 bytes unknown
01720 
01721         store16(&pData[78], LFO2InternalDepth);
01722 
01723         const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
01724         store32(&pData[80], eg1decay2);
01725 
01726         // next 2 bytes unknown
01727 
01728         store16(&pData[86], EG1PreAttack);
01729 
01730         const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
01731         store32(&pData[88], eg2decay2);
01732 
01733         // next 2 bytes unknown
01734 
01735         store16(&pData[94], EG2PreAttack);
01736 
01737         {
01738             if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
01739             uint8_t velocityresponse = VelocityResponseDepth;
01740             switch (VelocityResponseCurve) {
01741                 case curve_type_nonlinear:
01742                     break;
01743                 case curve_type_linear:
01744                     velocityresponse += 5;
01745                     break;
01746                 case curve_type_special:
01747                     velocityresponse += 10;
01748                     break;
01749                 case curve_type_unknown:
01750                 default:
01751                     throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
01752             }
01753             pData[96] = velocityresponse;
01754         }
01755 
01756         {
01757             if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
01758             uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
01759             switch (ReleaseVelocityResponseCurve) {
01760                 case curve_type_nonlinear:
01761                     break;
01762                 case curve_type_linear:
01763                     releasevelocityresponse += 5;
01764                     break;
01765                 case curve_type_special:
01766                     releasevelocityresponse += 10;
01767                     break;
01768                 case curve_type_unknown:
01769                 default:
01770                     throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
01771             }
01772             pData[97] = releasevelocityresponse;
01773         }
01774 
01775         pData[98] = VelocityResponseCurveScaling;
01776 
01777         pData[99] = AttenuationControllerThreshold;
01778 
01779         // next 4 bytes unknown
01780 
01781         store16(&pData[104], SampleStartOffset);
01782 
01783         // next 2 bytes unknown
01784 
01785         {
01786             uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
01787             switch (DimensionBypass) {
01788                 case dim_bypass_ctrl_94:
01789                     pitchTrackDimensionBypass |= 0x10;
01790                     break;
01791                 case dim_bypass_ctrl_95:
01792                     pitchTrackDimensionBypass |= 0x20;
01793                     break;
01794                 case dim_bypass_ctrl_none:
01795                     //FIXME: should we set anything here?
01796                     break;
01797                 default:
01798                     throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
01799             }
01800             pData[108] = pitchTrackDimensionBypass;
01801         }
01802 
01803         const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
01804         pData[109] = pan;
01805 
01806         const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
01807         pData[110] = selfmask;
01808 
01809         // next byte unknown
01810 
01811         {
01812             uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
01813             if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
01814             if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
01815             if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
01816             pData[112] = lfo3ctrl;
01817         }
01818 
01819         const uint8_t attenctl = EncodeLeverageController(AttenuationController);
01820         pData[113] = attenctl;
01821 
01822         {
01823             uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
01824             if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
01825             if (LFO2Sync)      lfo2ctrl |= 0x20; // bit 5
01826             if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
01827             pData[114] = lfo2ctrl;
01828         }
01829 
01830         {
01831             uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
01832             if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
01833             if (LFO1Sync)      lfo1ctrl |= 0x40; // bit 6
01834             if (VCFResonanceController != vcf_res_ctrl_none)
01835                 lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
01836             pData[115] = lfo1ctrl;
01837         }
01838 
01839         const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
01840                                                   : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
01841         store16(&pData[116], eg3depth);
01842 
01843         // next 2 bytes unknown
01844 
01845         const uint8_t channeloffset = ChannelOffset * 4;
01846         pData[120] = channeloffset;
01847 
01848         {
01849             uint8_t regoptions = 0;
01850             if (MSDecode)      regoptions |= 0x01; // bit 0
01851             if (SustainDefeat) regoptions |= 0x02; // bit 1
01852             pData[121] = regoptions;
01853         }
01854 
01855         // next 2 bytes unknown
01856 
01857         pData[124] = VelocityUpperLimit;
01858 
01859         // next 3 bytes unknown
01860 
01861         pData[128] = ReleaseTriggerDecay;
01862 
01863         // next 2 bytes unknown
01864 
01865         const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
01866         pData[131] = eg1hold;
01867 
01868         const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) |  /* bit 7 */
01869                                   (VCFCutoff & 0x7f);   /* lower 7 bits */
01870         pData[132] = vcfcutoff;
01871 
01872         pData[133] = VCFCutoffController;
01873 
01874         const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
01875                                     (VCFVelocityScale & 0x7f); /* lower 7 bits */
01876         pData[134] = vcfvelscale;
01877 
01878         // next byte unknown
01879 
01880         const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
01881                                      (VCFResonance & 0x7f); /* lower 7 bits */
01882         pData[136] = vcfresonance;
01883 
01884         const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
01885                                       (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
01886         pData[137] = vcfbreakpoint;
01887 
01888         const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
01889                                     VCFVelocityCurve * 5;
01890         pData[138] = vcfvelocity;
01891 
01892         const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
01893         pData[139] = vcftype;
01894 
01895         if (chunksize >= 148) {
01896             memcpy(&pData[140], DimensionUpperLimits, 8);
01897         }
01898     }
01899 
01900     double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
01901         curve_type_t curveType = releaseVelocityResponseCurve;
01902         uint8_t depth = releaseVelocityResponseDepth;
01903         // this models a strange behaviour or bug in GSt: two of the
01904         // velocity response curves for release time are not used even
01905         // if specified, instead another curve is chosen.
01906         if ((curveType == curve_type_nonlinear && depth == 0) ||
01907             (curveType == curve_type_special   && depth == 4)) {
01908             curveType = curve_type_nonlinear;
01909             depth = 3;
01910         }
01911         return GetVelocityTable(curveType, depth, 0);
01912     }
01913 
01914     double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
01915                                                     uint8_t vcfVelocityDynamicRange,
01916                                                     uint8_t vcfVelocityScale,
01917                                                     vcf_cutoff_ctrl_t vcfCutoffController)
01918     {
01919         curve_type_t curveType = vcfVelocityCurve;
01920         uint8_t depth = vcfVelocityDynamicRange;
01921         // even stranger GSt: two of the velocity response curves for
01922         // filter cutoff are not used, instead another special curve
01923         // is chosen. This curve is not used anywhere else.
01924         if ((curveType == curve_type_nonlinear && depth == 0) ||
01925             (curveType == curve_type_special   && depth == 4)) {
01926             curveType = curve_type_special;
01927             depth = 5;
01928         }
01929         return GetVelocityTable(curveType, depth,
01930                                 (vcfCutoffController <= vcf_cutoff_ctrl_none2)
01931                                     ? vcfVelocityScale : 0);
01932     }
01933 
01934     // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
01935     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
01936     {
01937         double* table;
01938         uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
01939         if (pVelocityTables->count(tableKey)) { // if key exists
01940             table = (*pVelocityTables)[tableKey];
01941         }
01942         else {
01943             table = CreateVelocityTable(curveType, depth, scaling);
01944             (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
01945         }
01946         return table;
01947     }
01948 
01949     Region* DimensionRegion::GetParent() const {
01950         return pRegion;
01951     }
01952 
01953     leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
01954         leverage_ctrl_t decodedcontroller;
01955         switch (EncodedController) {
01956             // special controller
01957             case _lev_ctrl_none:
01958                 decodedcontroller.type = leverage_ctrl_t::type_none;
01959                 decodedcontroller.controller_number = 0;
01960                 break;
01961             case _lev_ctrl_velocity:
01962                 decodedcontroller.type = leverage_ctrl_t::type_velocity;
01963                 decodedcontroller.controller_number = 0;
01964                 break;
01965             case _lev_ctrl_channelaftertouch:
01966                 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
01967                 decodedcontroller.controller_number = 0;
01968                 break;
01969 
01970             // ordinary MIDI control change controller
01971             case _lev_ctrl_modwheel:
01972                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01973                 decodedcontroller.controller_number = 1;
01974                 break;
01975             case _lev_ctrl_breath:
01976                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01977                 decodedcontroller.controller_number = 2;
01978                 break;
01979             case _lev_ctrl_foot:
01980                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01981                 decodedcontroller.controller_number = 4;
01982                 break;
01983             case _lev_ctrl_effect1:
01984                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01985                 decodedcontroller.controller_number = 12;
01986                 break;
01987             case _lev_ctrl_effect2:
01988                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01989                 decodedcontroller.controller_number = 13;
01990                 break;
01991             case _lev_ctrl_genpurpose1:
01992                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01993                 decodedcontroller.controller_number = 16;
01994                 break;
01995             case _lev_ctrl_genpurpose2:
01996                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01997                 decodedcontroller.controller_number = 17;
01998                 break;
01999             case _lev_ctrl_genpurpose3:
02000                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02001                 decodedcontroller.controller_number = 18;
02002                 break;
02003             case _lev_ctrl_genpurpose4:
02004                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02005                 decodedcontroller.controller_number = 19;
02006                 break;
02007             case _lev_ctrl_portamentotime:
02008                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02009                 decodedcontroller.controller_number = 5;
02010                 break;
02011             case _lev_ctrl_sustainpedal:
02012                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02013                 decodedcontroller.controller_number = 64;
02014                 break;
02015             case _lev_ctrl_portamento:
02016                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02017                 decodedcontroller.controller_number = 65;
02018                 break;
02019             case _lev_ctrl_sostenutopedal:
02020                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02021                 decodedcontroller.controller_number = 66;
02022                 break;
02023             case _lev_ctrl_softpedal:
02024                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02025                 decodedcontroller.controller_number = 67;
02026                 break;
02027             case _lev_ctrl_genpurpose5:
02028                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02029                 decodedcontroller.controller_number = 80;
02030                 break;
02031             case _lev_ctrl_genpurpose6:
02032                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02033                 decodedcontroller.controller_number = 81;
02034                 break;
02035             case _lev_ctrl_genpurpose7:
02036                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02037                 decodedcontroller.controller_number = 82;
02038                 break;
02039             case _lev_ctrl_genpurpose8:
02040                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02041                 decodedcontroller.controller_number = 83;
02042                 break;
02043             case _lev_ctrl_effect1depth:
02044                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02045                 decodedcontroller.controller_number = 91;
02046                 break;
02047             case _lev_ctrl_effect2depth:
02048                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02049                 decodedcontroller.controller_number = 92;
02050                 break;
02051             case _lev_ctrl_effect3depth:
02052                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02053                 decodedcontroller.controller_number = 93;
02054                 break;
02055             case _lev_ctrl_effect4depth:
02056                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02057                 decodedcontroller.controller_number = 94;
02058                 break;
02059             case _lev_ctrl_effect5depth:
02060                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
02061                 decodedcontroller.controller_number = 95;
02062                 break;
02063 
02064             // unknown controller type
02065             default:
02066                 throw gig::Exception("Unknown leverage controller type.");
02067         }
02068         return decodedcontroller;
02069     }
02070 
02071     DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
02072         _lev_ctrl_t encodedcontroller;
02073         switch (DecodedController.type) {
02074             // special controller
02075             case leverage_ctrl_t::type_none:
02076                 encodedcontroller = _lev_ctrl_none;
02077                 break;
02078             case leverage_ctrl_t::type_velocity:
02079                 encodedcontroller = _lev_ctrl_velocity;
02080                 break;
02081             case leverage_ctrl_t::type_channelaftertouch:
02082                 encodedcontroller = _lev_ctrl_channelaftertouch;
02083                 break;
02084 
02085             // ordinary MIDI control change controller
02086             case leverage_ctrl_t::type_controlchange:
02087                 switch (DecodedController.controller_number) {
02088                     case 1:
02089                         encodedcontroller = _lev_ctrl_modwheel;
02090                         break;
02091                     case 2:
02092                         encodedcontroller = _lev_ctrl_breath;
02093                         break;
02094                     case 4:
02095                         encodedcontroller = _lev_ctrl_foot;
02096                         break;
02097                     case 12:
02098                         encodedcontroller = _lev_ctrl_effect1;
02099                         break;
02100                     case 13:
02101                         encodedcontroller = _lev_ctrl_effect2;
02102                         break;
02103                     case 16:
02104                         encodedcontroller = _lev_ctrl_genpurpose1;
02105                         break;
02106                     case 17:
02107                         encodedcontroller = _lev_ctrl_genpurpose2;
02108                         break;
02109                     case 18:
02110                         encodedcontroller = _lev_ctrl_genpurpose3;
02111                         break;
02112                     case 19:
02113                         encodedcontroller = _lev_ctrl_genpurpose4;
02114                         break;
02115                     case 5:
02116                         encodedcontroller = _lev_ctrl_portamentotime;
02117                         break;
02118                     case 64:
02119                         encodedcontroller = _lev_ctrl_sustainpedal;
02120                         break;
02121                     case 65:
02122                         encodedcontroller = _lev_ctrl_portamento;
02123                         break;
02124                     case 66:
02125                         encodedcontroller = _lev_ctrl_sostenutopedal;
02126                         break;
02127                     case 67:
02128                         encodedcontroller = _lev_ctrl_softpedal;
02129                         break;
02130                     case 80:
02131                         encodedcontroller = _lev_ctrl_genpurpose5;
02132                         break;
02133                     case 81:
02134                         encodedcontroller = _lev_ctrl_genpurpose6;
02135                         break;
02136                     case 82:
02137                         encodedcontroller = _lev_ctrl_genpurpose7;
02138                         break;
02139                     case 83:
02140                         encodedcontroller = _lev_ctrl_genpurpose8;
02141                         break;
02142                     case 91:
02143                         encodedcontroller = _lev_ctrl_effect1depth;
02144                         break;
02145                     case 92:
02146                         encodedcontroller = _lev_ctrl_effect2depth;
02147                         break;
02148                     case 93:
02149                         encodedcontroller = _lev_ctrl_effect3depth;
02150                         break;
02151                     case 94:
02152                         encodedcontroller = _lev_ctrl_effect4depth;
02153                         break;
02154                     case 95:
02155                         encodedcontroller = _lev_ctrl_effect5depth;
02156                         break;
02157                     default:
02158                         throw gig::Exception("leverage controller number is not supported by the gig format");
02159                 }
02160                 break;
02161             default:
02162                 throw gig::Exception("Unknown leverage controller type.");
02163         }
02164         return encodedcontroller;
02165     }
02166 
02167     DimensionRegion::~DimensionRegion() {
02168         Instances--;
02169         if (!Instances) {
02170             // delete the velocity->volume tables
02171             VelocityTableMap::iterator iter;
02172             for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
02173                 double* pTable = iter->second;
02174                 if (pTable) delete[] pTable;
02175             }
02176             pVelocityTables->clear();
02177             delete pVelocityTables;
02178             pVelocityTables = NULL;
02179         }
02180         if (VelocityTable) delete[] VelocityTable;
02181     }
02182 
02194     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
02195         return pVelocityAttenuationTable[MIDIKeyVelocity];
02196     }
02197 
02198     double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
02199         return pVelocityReleaseTable[MIDIKeyVelocity];
02200     }
02201 
02202     double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
02203         return pVelocityCutoffTable[MIDIKeyVelocity];
02204     }
02205 
02210     void DimensionRegion::SetVelocityResponseCurve(curve_type_t curve) {
02211         pVelocityAttenuationTable =
02212             GetVelocityTable(
02213                 curve, VelocityResponseDepth, VelocityResponseCurveScaling
02214             );
02215         VelocityResponseCurve = curve;
02216     }
02217 
02222     void DimensionRegion::SetVelocityResponseDepth(uint8_t depth) {
02223         pVelocityAttenuationTable =
02224             GetVelocityTable(
02225                 VelocityResponseCurve, depth, VelocityResponseCurveScaling
02226             );
02227         VelocityResponseDepth = depth;
02228     }
02229 
02234     void DimensionRegion::SetVelocityResponseCurveScaling(uint8_t scaling) {
02235         pVelocityAttenuationTable =
02236             GetVelocityTable(
02237                 VelocityResponseCurve, VelocityResponseDepth, scaling
02238             );
02239         VelocityResponseCurveScaling = scaling;
02240     }
02241 
02246     void DimensionRegion::SetReleaseVelocityResponseCurve(curve_type_t curve) {
02247         pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
02248         ReleaseVelocityResponseCurve = curve;
02249     }
02250 
02255     void DimensionRegion::SetReleaseVelocityResponseDepth(uint8_t depth) {
02256         pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
02257         ReleaseVelocityResponseDepth = depth;
02258     }
02259 
02264     void DimensionRegion::SetVCFCutoffController(vcf_cutoff_ctrl_t controller) {
02265         pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
02266         VCFCutoffController = controller;
02267     }
02268 
02273     void DimensionRegion::SetVCFVelocityCurve(curve_type_t curve) {
02274         pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
02275         VCFVelocityCurve = curve;
02276     }
02277 
02282     void DimensionRegion::SetVCFVelocityDynamicRange(uint8_t range) {
02283         pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
02284         VCFVelocityDynamicRange = range;
02285     }
02286 
02291     void DimensionRegion::SetVCFVelocityScale(uint8_t scaling) {
02292         pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
02293         VCFVelocityScale = scaling;
02294     }
02295 
02296     double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
02297 
02298         // line-segment approximations of the 15 velocity curves
02299 
02300         // linear
02301         const int lin0[] = { 1, 1, 127, 127 };
02302         const int lin1[] = { 1, 21, 127, 127 };
02303         const int lin2[] = { 1, 45, 127, 127 };
02304         const int lin3[] = { 1, 74, 127, 127 };
02305         const int lin4[] = { 1, 127, 127, 127 };
02306 
02307         // non-linear
02308         const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
02309         const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
02310                              127, 127 };
02311         const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
02312                              127, 127 };
02313         const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
02314                              127, 127 };
02315         const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
02316 
02317         // special
02318         const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
02319                              113, 127, 127, 127 };
02320         const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
02321                              118, 127, 127, 127 };
02322         const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
02323                              85, 90, 91, 127, 127, 127 };
02324         const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
02325                              117, 127, 127, 127 };
02326         const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
02327                              127, 127 };
02328 
02329         // this is only used by the VCF velocity curve
02330         const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
02331                              91, 127, 127, 127 };
02332 
02333         const int* const curves[] = { non0, non1, non2, non3, non4,
02334                                       lin0, lin1, lin2, lin3, lin4,
02335                                       spe0, spe1, spe2, spe3, spe4, spe5 };
02336 
02337         double* const table = new double[128];
02338 
02339         const int* curve = curves[curveType * 5 + depth];
02340         const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
02341 
02342         table[0] = 0;
02343         for (int x = 1 ; x < 128 ; x++) {
02344 
02345             if (x > curve[2]) curve += 2;
02346             double y = curve[1] + (x - curve[0]) *
02347                 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
02348             y = y / 127;
02349 
02350             // Scale up for s > 20, down for s < 20. When
02351             // down-scaling, the curve still ends at 1.0.
02352             if (s < 20 && y >= 0.5)
02353                 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
02354             else
02355                 y = y * (s / 20.0);
02356             if (y > 1) y = 1;
02357 
02358             table[x] = y;
02359         }
02360         return table;
02361     }
02362 
02363 
02364 // *************** Region ***************
02365 // *
02366 
02367     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
02368         // Initialization
02369         Dimensions = 0;
02370         for (int i = 0; i < 256; i++) {
02371             pDimensionRegions[i] = NULL;
02372         }
02373         Layers = 1;
02374         File* file = (File*) GetParent()->GetParent();
02375         int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
02376 
02377         // Actual Loading
02378 
02379         if (!file->GetAutoLoad()) return;
02380 
02381         LoadDimensionRegions(rgnList);
02382 
02383         RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
02384         if (_3lnk) {
02385             DimensionRegions = _3lnk->ReadUint32();
02386             for (int i = 0; i < dimensionBits; i++) {
02387                 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
02388                 uint8_t     bits      = _3lnk->ReadUint8();
02389                 _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
02390                 _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
02391                 uint8_t     zones     = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
02392                 if (dimension == dimension_none) { // inactive dimension
02393                     pDimensionDefinitions[i].dimension  = dimension_none;
02394                     pDimensionDefinitions[i].bits       = 0;
02395                     pDimensionDefinitions[i].zones      = 0;
02396                     pDimensionDefinitions[i].split_type = split_type_bit;
02397                     pDimensionDefinitions[i].zone_size  = 0;
02398                 }
02399                 else { // active dimension
02400                     pDimensionDefinitions[i].dimension = dimension;
02401                     pDimensionDefinitions[i].bits      = bits;
02402                     pDimensionDefinitions[i].zones     = zones ? zones : 0x01 << bits; // = pow(2,bits)
02403                     pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
02404                     pDimensionDefinitions[i].zone_size  = __resolveZoneSize(pDimensionDefinitions[i]);
02405                     Dimensions++;
02406 
02407                     // if this is a layer dimension, remember the amount of layers
02408                     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
02409                 }
02410                 _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
02411             }
02412             for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
02413 
02414             // if there's a velocity dimension and custom velocity zone splits are used,
02415             // update the VelocityTables in the dimension regions
02416             UpdateVelocityTable();
02417 
02418             // jump to start of the wave pool indices (if not already there)
02419             if (file->pVersion && file->pVersion->major == 3)
02420                 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
02421             else
02422                 _3lnk->SetPos(44);
02423 
02424             // load sample references (if auto loading is enabled)
02425             if (file->GetAutoLoad()) {
02426                 for (uint i = 0; i < DimensionRegions; i++) {
02427                     uint32_t wavepoolindex = _3lnk->ReadUint32();
02428                     if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
02429                 }
02430                 GetSample(); // load global region sample reference
02431             }
02432         } else {
02433             DimensionRegions = 0;
02434             for (int i = 0 ; i < 8 ; i++) {
02435                 pDimensionDefinitions[i].dimension  = dimension_none;
02436                 pDimensionDefinitions[i].bits       = 0;
02437                 pDimensionDefinitions[i].zones      = 0;
02438             }
02439         }
02440 
02441         // make sure there is at least one dimension region
02442         if (!DimensionRegions) {
02443             RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
02444             if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
02445             RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
02446             pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
02447             DimensionRegions = 1;
02448         }
02449     }
02450 
02460     void Region::UpdateChunks() {
02461         // in the gig format we don't care about the Region's sample reference
02462         // but we still have to provide some existing one to not corrupt the
02463         // file, so to avoid the latter we simply always assign the sample of
02464         // the first dimension region of this region
02465         pSample = pDimensionRegions[0]->pSample;
02466 
02467         // first update base class's chunks
02468         DLS::Region::UpdateChunks();
02469 
02470         // update dimension region's chunks
02471         for (int i = 0; i < DimensionRegions; i++) {
02472             pDimensionRegions[i]->UpdateChunks();
02473         }
02474 
02475         File* pFile = (File*) GetParent()->GetParent();
02476         bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
02477         const int iMaxDimensions =  version3 ? 8 : 5;
02478         const int iMaxDimensionRegions = version3 ? 256 : 32;
02479 
02480         // make sure '3lnk' chunk exists
02481         RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
02482         if (!_3lnk) {
02483             const int _3lnkChunkSize = version3 ? 1092 : 172;
02484             _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
02485             memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
02486 
02487             // move 3prg to last position
02488             pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), 0);
02489         }
02490 
02491         // update dimension definitions in '3lnk' chunk
02492         uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
02493         store32(&pData[0], DimensionRegions);
02494         int shift = 0;
02495         for (int i = 0; i < iMaxDimensions; i++) {
02496             pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
02497             pData[5 + i * 8] = pDimensionDefinitions[i].bits;
02498             pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
02499             pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
02500             pData[8 + i * 8] = pDimensionDefinitions[i].zones;
02501             // next 3 bytes unknown, always zero?
02502 
02503             shift += pDimensionDefinitions[i].bits;
02504         }
02505 
02506         // update wave pool table in '3lnk' chunk
02507         const int iWavePoolOffset = version3 ? 68 : 44;
02508         for (uint i = 0; i < iMaxDimensionRegions; i++) {
02509             int iWaveIndex = -1;
02510             if (i < DimensionRegions) {
02511                 if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
02512                 File::SampleList::iterator iter = pFile->pSamples->begin();
02513                 File::SampleList::iterator end  = pFile->pSamples->end();
02514                 for (int index = 0; iter != end; ++iter, ++index) {
02515                     if (*iter == pDimensionRegions[i]->pSample) {
02516                         iWaveIndex = index;
02517                         break;
02518                     }
02519                 }
02520             }
02521             store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
02522         }
02523     }
02524 
02525     void Region::LoadDimensionRegions(RIFF::List* rgn) {
02526         RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
02527         if (_3prg) {
02528             int dimensionRegionNr = 0;
02529             RIFF::List* _3ewl = _3prg->GetFirstSubList();
02530             while (_3ewl) {
02531                 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
02532                     pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
02533                     dimensionRegionNr++;
02534                 }
02535                 _3ewl = _3prg->GetNextSubList();
02536             }
02537             if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
02538         }
02539     }
02540 
02541     void Region::SetKeyRange(uint16_t Low, uint16_t High) {
02542         // update KeyRange struct and make sure regions are in correct order
02543         DLS::Region::SetKeyRange(Low, High);
02544         // update Region key table for fast lookup
02545         ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
02546     }
02547 
02548     void Region::UpdateVelocityTable() {
02549         // get velocity dimension's index
02550         int veldim = -1;
02551         for (int i = 0 ; i < Dimensions ; i++) {
02552             if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
02553                 veldim = i;
02554                 break;
02555             }
02556         }
02557         if (veldim == -1) return;
02558 
02559         int step = 1;
02560         for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
02561         int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
02562         int end = step * pDimensionDefinitions[veldim].zones;
02563 
02564         // loop through all dimension regions for all dimensions except the velocity dimension
02565         int dim[8] = { 0 };
02566         for (int i = 0 ; i < DimensionRegions ; i++) {
02567 
02568             if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
02569                 pDimensionRegions[i]->VelocityUpperLimit) {
02570                 // create the velocity table
02571                 uint8_t* table = pDimensionRegions[i]->VelocityTable;
02572                 if (!table) {
02573                     table = new uint8_t[128];
02574                     pDimensionRegions[i]->VelocityTable = table;
02575                 }
02576                 int tableidx = 0;
02577                 int velocityZone = 0;
02578                 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
02579                     for (int k = i ; k < end ; k += step) {
02580                         DimensionRegion *d = pDimensionRegions[k];
02581                         for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
02582                         velocityZone++;
02583                     }
02584                 } else { // gig2
02585                     for (int k = i ; k < end ; k += step) {
02586                         DimensionRegion *d = pDimensionRegions[k];
02587                         for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
02588                         velocityZone++;
02589                     }
02590                 }
02591             } else {
02592                 if (pDimensionRegions[i]->VelocityTable) {
02593                     delete[] pDimensionRegions[i]->VelocityTable;
02594                     pDimensionRegions[i]->VelocityTable = 0;
02595                 }
02596             }
02597 
02598             int j;
02599             int shift = 0;
02600             for (j = 0 ; j < Dimensions ; j++) {
02601                 if (j == veldim) i += skipveldim; // skip velocity dimension
02602                 else {
02603                     dim[j]++;
02604                     if (dim[j] < pDimensionDefinitions[j].zones) break;
02605                     else {
02606                         // skip unused dimension regions
02607                         dim[j] = 0;
02608                         i += ((1 << pDimensionDefinitions[j].bits) -
02609                               pDimensionDefinitions[j].zones) << shift;
02610                     }
02611                 }
02612                 shift += pDimensionDefinitions[j].bits;
02613             }
02614             if (j == Dimensions) break;
02615         }
02616     }
02617 
02633     void Region::AddDimension(dimension_def_t* pDimDef) {
02634         // check if max. amount of dimensions reached
02635         File* file = (File*) GetParent()->GetParent();
02636         const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
02637         if (Dimensions >= iMaxDimensions)
02638             throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
02639         // check if max. amount of dimension bits reached
02640         int iCurrentBits = 0;
02641         for (int i = 0; i < Dimensions; i++)
02642             iCurrentBits += pDimensionDefinitions[i].bits;
02643         if (iCurrentBits >= iMaxDimensions)
02644             throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
02645         const int iNewBits = iCurrentBits + pDimDef->bits;
02646         if (iNewBits > iMaxDimensions)
02647             throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
02648         // check if there's already a dimensions of the same type
02649         for (int i = 0; i < Dimensions; i++)
02650             if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
02651                 throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
02652 
02653         // pos is where the new dimension should be placed, normally
02654         // last in list, except for the samplechannel dimension which
02655         // has to be first in list
02656         int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
02657         int bitpos = 0;
02658         for (int i = 0 ; i < pos ; i++)
02659             bitpos += pDimensionDefinitions[i].bits;
02660 
02661         // make room for the new dimension
02662         for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
02663         for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
02664             for (int j = Dimensions ; j > pos ; j--) {
02665                 pDimensionRegions[i]->DimensionUpperLimits[j] =
02666                     pDimensionRegions[i]->DimensionUpperLimits[j - 1];
02667             }
02668         }
02669 
02670         // assign definition of new dimension
02671         pDimensionDefinitions[pos] = *pDimDef;
02672 
02673         // auto correct certain dimension definition fields (where possible)
02674         pDimensionDefinitions[pos].split_type  =
02675             __resolveSplitType(pDimensionDefinitions[pos].dimension);
02676         pDimensionDefinitions[pos].zone_size =
02677             __resolveZoneSize(pDimensionDefinitions[pos]);
02678 
02679         // create new dimension region(s) for this new dimension, and make
02680         // sure that the dimension regions are placed correctly in both the
02681         // RIFF list and the pDimensionRegions array
02682         RIFF::Chunk* moveTo = NULL;
02683         RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
02684         for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
02685             for (int k = 0 ; k < (1 << bitpos) ; k++) {
02686                 pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
02687             }
02688             for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
02689                 for (int k = 0 ; k < (1 << bitpos) ; k++) {
02690                     RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
02691                     if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
02692                     // create a new dimension region and copy all parameter values from
02693                     // an existing dimension region
02694                     pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
02695                         new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
02696 
02697                     DimensionRegions++;
02698                 }
02699             }
02700             moveTo = pDimensionRegions[i]->pParentList;
02701         }
02702 
02703         // initialize the upper limits for this dimension
02704         int mask = (1 << bitpos) - 1;
02705         for (int z = 0 ; z < pDimDef->zones ; z++) {
02706             uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
02707             for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
02708                 pDimensionRegions[((i & ~mask) << pDimDef->bits) |
02709                                   (z << bitpos) |
02710                                   (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
02711             }
02712         }
02713 
02714         Dimensions++;
02715 
02716         // if this is a layer dimension, update 'Layers' attribute
02717         if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
02718 
02719         UpdateVelocityTable();
02720     }
02721 
02733     void Region::DeleteDimension(dimension_def_t* pDimDef) {
02734         // get dimension's index
02735         int iDimensionNr = -1;
02736         for (int i = 0; i < Dimensions; i++) {
02737             if (&pDimensionDefinitions[i] == pDimDef) {
02738                 iDimensionNr = i;
02739                 break;
02740             }
02741         }
02742         if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
02743 
02744         // get amount of bits below the dimension to delete
02745         int iLowerBits = 0;
02746         for (int i = 0; i < iDimensionNr; i++)
02747             iLowerBits += pDimensionDefinitions[i].bits;
02748 
02749         // get amount ot bits above the dimension to delete
02750         int iUpperBits = 0;
02751         for (int i = iDimensionNr + 1; i < Dimensions; i++)
02752             iUpperBits += pDimensionDefinitions[i].bits;
02753 
02754         RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
02755 
02756         // delete dimension regions which belong to the given dimension
02757         // (that is where the dimension's bit > 0)
02758         for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
02759             for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
02760                 for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
02761                     int iToDelete = iUpperBit    << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
02762                                     iObsoleteBit << iLowerBits |
02763                                     iLowerBit;
02764 
02765                     _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
02766                     delete pDimensionRegions[iToDelete];
02767                     pDimensionRegions[iToDelete] = NULL;
02768                     DimensionRegions--;
02769                 }
02770             }
02771         }
02772 
02773         // defrag pDimensionRegions array
02774         // (that is remove the NULL spaces within the pDimensionRegions array)
02775         for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
02776             if (!pDimensionRegions[iTo]) {
02777                 if (iFrom <= iTo) iFrom = iTo + 1;
02778                 while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
02779                 if (iFrom < 256 && pDimensionRegions[iFrom]) {
02780                     pDimensionRegions[iTo]   = pDimensionRegions[iFrom];
02781                     pDimensionRegions[iFrom] = NULL;
02782                 }
02783             }
02784         }
02785 
02786         // remove the this dimension from the upper limits arrays
02787         for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
02788             DimensionRegion* d = pDimensionRegions[j];
02789             for (int i = iDimensionNr + 1; i < Dimensions; i++) {
02790                 d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
02791             }
02792             d->DimensionUpperLimits[Dimensions - 1] = 127;
02793         }
02794 
02795         // 'remove' dimension definition
02796         for (int i = iDimensionNr + 1; i < Dimensions; i++) {
02797             pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
02798         }
02799         pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
02800         pDimensionDefinitions[Dimensions - 1].bits      = 0;
02801         pDimensionDefinitions[Dimensions - 1].zones     = 0;
02802 
02803         Dimensions--;
02804 
02805         // if this was a layer dimension, update 'Layers' attribute
02806         if (pDimDef->dimension == dimension_layer) Layers = 1;
02807     }
02808 
02809     Region::~Region() {
02810         for (int i = 0; i < 256; i++) {
02811             if (pDimensionRegions[i]) delete pDimensionRegions[i];
02812         }
02813     }
02814 
02833     DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
02834         uint8_t bits;
02835         int veldim = -1;
02836         int velbitpos;
02837         int bitpos = 0;
02838         int dimregidx = 0;
02839         for (uint i = 0; i < Dimensions; i++) {
02840             if (pDimensionDefinitions[i].dimension == dimension_velocity) {
02841                 // the velocity dimension must be handled after the other dimensions
02842                 veldim = i;
02843                 velbitpos = bitpos;
02844             } else {
02845                 switch (pDimensionDefinitions[i].split_type) {
02846                     case split_type_normal:
02847                         if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
02848                             // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
02849                             for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
02850                                 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
02851                             }
02852                         } else {
02853                             // gig2: evenly sized zones
02854                             bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
02855                         }
02856                         break;
02857                     case split_type_bit: // the value is already the sought dimension bit number
02858                         const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
02859                         bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
02860                         break;
02861                 }
02862                 dimregidx |= bits << bitpos;
02863             }
02864             bitpos += pDimensionDefinitions[i].bits;
02865         }
02866         DimensionRegion* dimreg = pDimensionRegions[dimregidx];
02867         if (veldim != -1) {
02868             // (dimreg is now the dimension region for the lowest velocity)
02869             if (dimreg->VelocityTable) // custom defined zone ranges
02870                 bits = dimreg->VelocityTable[DimValues[veldim]];
02871             else // normal split type
02872                 bits = uint8_t(DimValues[veldim] / pDimensionDefinitions[veldim].zone_size);
02873 
02874             dimregidx |= bits << velbitpos;
02875             dimreg = pDimensionRegions[dimregidx];
02876         }
02877         return dimreg;
02878     }
02879 
02890     DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
02891         return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
02892                                                   << pDimensionDefinitions[5].bits | DimBits[5])
02893                                                   << pDimensionDefinitions[4].bits | DimBits[4])
02894                                                   << pDimensionDefinitions[3].bits | DimBits[3])
02895                                                   << pDimensionDefinitions[2].bits | DimBits[2])
02896                                                   << pDimensionDefinitions[1].bits | DimBits[1])
02897                                                   << pDimensionDefinitions[0].bits | DimBits[0]];
02898     }
02899 
02909     Sample* Region::GetSample() {
02910         if (pSample) return static_cast<gig::Sample*>(pSample);
02911         else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
02912     }
02913 
02914     Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
02915         if ((int32_t)WavePoolTableIndex == -1) return NULL;
02916         File* file = (File*) GetParent()->GetParent();
02917         if (!file->pWavePoolTable) return NULL;
02918         unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
02919         unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
02920         Sample* sample = file->GetFirstSample(pProgress);
02921         while (sample) {
02922             if (sample->ulWavePoolOffset == soughtoffset &&
02923                 sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
02924             sample = file->GetNextSample();
02925         }
02926         return NULL;
02927     }
02928 
02929 
02930 // *************** MidiRule ***************
02931 // *
02932 
02933 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
02934     _3ewg->SetPos(36);
02935     Triggers = _3ewg->ReadUint8();
02936     _3ewg->SetPos(40);
02937     ControllerNumber = _3ewg->ReadUint8();
02938     _3ewg->SetPos(46);
02939     for (int i = 0 ; i < Triggers ; i++) {
02940         pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
02941         pTriggers[i].Descending = _3ewg->ReadUint8();
02942         pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
02943         pTriggers[i].Key = _3ewg->ReadUint8();
02944         pTriggers[i].NoteOff = _3ewg->ReadUint8();
02945         pTriggers[i].Velocity = _3ewg->ReadUint8();
02946         pTriggers[i].OverridePedal = _3ewg->ReadUint8();
02947         _3ewg->ReadUint8();
02948     }
02949 }
02950 
02951 
02952 // *************** Instrument ***************
02953 // *
02954 
02955     Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
02956         static const DLS::Info::string_length_t fixedStringLengths[] = {
02957             { CHUNK_ID_INAM, 64 },
02958             { CHUNK_ID_ISFT, 12 },
02959             { 0, 0 }
02960         };
02961         pInfo->SetFixedStringLengths(fixedStringLengths);
02962 
02963         // Initialization
02964         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
02965         EffectSend = 0;
02966         Attenuation = 0;
02967         FineTune = 0;
02968         PitchbendRange = 0;
02969         PianoReleaseMode = false;
02970         DimensionKeyRange.low = 0;
02971         DimensionKeyRange.high = 0;
02972         pMidiRules = new MidiRule*[3];
02973         pMidiRules[0] = NULL;
02974 
02975         // Loading
02976         RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
02977         if (lart) {
02978             RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
02979             if (_3ewg) {
02980                 EffectSend             = _3ewg->ReadUint16();
02981                 Attenuation            = _3ewg->ReadInt32();
02982                 FineTune               = _3ewg->ReadInt16();
02983                 PitchbendRange         = _3ewg->ReadInt16();
02984                 uint8_t dimkeystart    = _3ewg->ReadUint8();
02985                 PianoReleaseMode       = dimkeystart & 0x01;
02986                 DimensionKeyRange.low  = dimkeystart >> 1;
02987                 DimensionKeyRange.high = _3ewg->ReadUint8();
02988 
02989                 if (_3ewg->GetSize() > 32) {
02990                     // read MIDI rules
02991                     int i = 0;
02992                     _3ewg->SetPos(32);
02993                     uint8_t id1 = _3ewg->ReadUint8();
02994                     uint8_t id2 = _3ewg->ReadUint8();
02995 
02996                     if (id1 == 4 && id2 == 16) {
02997                         pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
02998                     }
02999                     //TODO: all the other types of rules
03000 
03001                     pMidiRules[i] = NULL;
03002                 }
03003             }
03004         }
03005 
03006         if (pFile->GetAutoLoad()) {
03007             if (!pRegions) pRegions = new RegionList;
03008             RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
03009             if (lrgn) {
03010                 RIFF::List* rgn = lrgn->GetFirstSubList();
03011                 while (rgn) {
03012                     if (rgn->GetListType() == LIST_TYPE_RGN) {
03013                         __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
03014                         pRegions->push_back(new Region(this, rgn));
03015                     }
03016                     rgn = lrgn->GetNextSubList();
03017                 }
03018                 // Creating Region Key Table for fast lookup
03019                 UpdateRegionKeyTable();
03020             }
03021         }
03022 
03023         __notify_progress(pProgress, 1.0f); // notify done
03024     }
03025 
03026     void Instrument::UpdateRegionKeyTable() {
03027         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
03028         RegionList::iterator iter = pRegions->begin();
03029         RegionList::iterator end  = pRegions->end();
03030         for (; iter != end; ++iter) {
03031             gig::Region* pRegion = static_cast<gig::Region*>(*iter);
03032             for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
03033                 RegionKeyTable[iKey] = pRegion;
03034             }
03035         }
03036     }
03037 
03038     Instrument::~Instrument() {
03039         for (int i = 0 ; pMidiRules[i] ; i++) {
03040             delete pMidiRules[i];
03041         }
03042         delete[] pMidiRules;
03043     }
03044 
03054     void Instrument::UpdateChunks() {
03055         // first update base classes' chunks
03056         DLS::Instrument::UpdateChunks();
03057 
03058         // update Regions' chunks
03059         {
03060             RegionList::iterator iter = pRegions->begin();
03061             RegionList::iterator end  = pRegions->end();
03062             for (; iter != end; ++iter)
03063                 (*iter)->UpdateChunks();
03064         }
03065 
03066         // make sure 'lart' RIFF list chunk exists
03067         RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
03068         if (!lart)  lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
03069         // make sure '3ewg' RIFF chunk exists
03070         RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
03071         if (!_3ewg)  {
03072             File* pFile = (File*) GetParent();
03073 
03074             // 3ewg is bigger in gig3, as it includes the iMIDI rules
03075             int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
03076             _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
03077             memset(_3ewg->LoadChunkData(), 0, size);
03078         }
03079         // update '3ewg' RIFF chunk
03080         uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
03081         store16(&pData[0], EffectSend);
03082         store32(&pData[2], Attenuation);
03083         store16(&pData[6], FineTune);
03084         store16(&pData[8], PitchbendRange);
03085         const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
03086                                     DimensionKeyRange.low << 1;
03087         pData[10] = dimkeystart;
03088         pData[11] = DimensionKeyRange.high;
03089     }
03090 
03098     Region* Instrument::GetRegion(unsigned int Key) {
03099         if (!pRegions || pRegions->empty() || Key > 127) return NULL;
03100         return RegionKeyTable[Key];
03101 
03102         /*for (int i = 0; i < Regions; i++) {
03103             if (Key <= pRegions[i]->KeyRange.high &&
03104                 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
03105         }
03106         return NULL;*/
03107     }
03108 
03116     Region* Instrument::GetFirstRegion() {
03117         if (!pRegions) return NULL;
03118         RegionsIterator = pRegions->begin();
03119         return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
03120     }
03121 
03130     Region* Instrument::GetNextRegion() {
03131         if (!pRegions) return NULL;
03132         RegionsIterator++;
03133         return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
03134     }
03135 
03136     Region* Instrument::AddRegion() {
03137         // create new Region object (and its RIFF chunks)
03138         RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
03139         if (!lrgn)  lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
03140         RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
03141         Region* pNewRegion = new Region(this, rgn);
03142         pRegions->push_back(pNewRegion);
03143         Regions = pRegions->size();
03144         // update Region key table for fast lookup
03145         UpdateRegionKeyTable();
03146         // done
03147         return pNewRegion;
03148     }
03149 
03150     void Instrument::DeleteRegion(Region* pRegion) {
03151         if (!pRegions) return;
03152         DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
03153         // update Region key table for fast lookup
03154         UpdateRegionKeyTable();
03155     }
03156 
03167     MidiRule* Instrument::GetMidiRule(int i) {
03168         return pMidiRules[i];
03169     }
03170 
03171 
03172 // *************** Group ***************
03173 // *
03174 
03181     Group::Group(File* file, RIFF::Chunk* ck3gnm) {
03182         pFile      = file;
03183         pNameChunk = ck3gnm;
03184         ::LoadString(pNameChunk, Name);
03185     }
03186 
03187     Group::~Group() {
03188         // remove the chunk associated with this group (if any)
03189         if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
03190     }
03191 
03200     void Group::UpdateChunks() {
03201         // make sure <3gri> and <3gnl> list chunks exist
03202         RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
03203         if (!_3gri) {
03204             _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
03205             pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
03206         }
03207         RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
03208         if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
03209 
03210         if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
03211             // v3 has a fixed list of 128 strings, find a free one
03212             for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
03213                 if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
03214                     pNameChunk = ck;
03215                     break;
03216                 }
03217             }
03218         }
03219 
03220         // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
03221         ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
03222     }
03223 
03235     Sample* Group::GetFirstSample() {
03236         // FIXME: lazy und unsafe implementation, should be an autonomous iterator
03237         for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
03238             if (pSample->GetGroup() == this) return pSample;
03239         }
03240         return NULL;
03241     }
03242 
03253     Sample* Group::GetNextSample() {
03254         // FIXME: lazy und unsafe implementation, should be an autonomous iterator
03255         for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
03256             if (pSample->GetGroup() == this) return pSample;
03257         }
03258         return NULL;
03259     }
03260 
03264     void Group::AddSample(Sample* pSample) {
03265         pSample->pGroup = this;
03266     }
03267 
03274     void Group::MoveAll() {
03275         // get "that" other group first
03276         Group* pOtherGroup = NULL;
03277         for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
03278             if (pOtherGroup != this) break;
03279         }
03280         if (!pOtherGroup) throw Exception(
03281             "Could not move samples to another group, since there is no "
03282             "other Group. This is a bug, report it!"
03283         );
03284         // now move all samples of this group to the other group
03285         for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
03286             pOtherGroup->AddSample(pSample);
03287         }
03288     }
03289 
03290 
03291 
03292 // *************** File ***************
03293 // *
03294 
03296     const DLS::version_t File::VERSION_2 = {
03297         0, 2, 19980628 & 0xffff, 19980628 >> 16
03298     };
03299 
03301     const DLS::version_t File::VERSION_3 = {
03302         0, 3, 20030331 & 0xffff, 20030331 >> 16
03303     };
03304 
03305     static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
03306         { CHUNK_ID_IARL, 256 },
03307         { CHUNK_ID_IART, 128 },
03308         { CHUNK_ID_ICMS, 128 },
03309         { CHUNK_ID_ICMT, 1024 },
03310         { CHUNK_ID_ICOP, 128 },
03311         { CHUNK_ID_ICRD, 128 },
03312         { CHUNK_ID_IENG, 128 },
03313         { CHUNK_ID_IGNR, 128 },
03314         { CHUNK_ID_IKEY, 128 },
03315         { CHUNK_ID_IMED, 128 },
03316         { CHUNK_ID_INAM, 128 },
03317         { CHUNK_ID_IPRD, 128 },
03318         { CHUNK_ID_ISBJ, 128 },
03319         { CHUNK_ID_ISFT, 128 },
03320         { CHUNK_ID_ISRC, 128 },
03321         { CHUNK_ID_ISRF, 128 },
03322         { CHUNK_ID_ITCH, 128 },
03323         { 0, 0 }
03324     };
03325 
03326     File::File() : DLS::File() {
03327         bAutoLoad = true;
03328         *pVersion = VERSION_3;
03329         pGroups = NULL;
03330         pInfo->SetFixedStringLengths(_FileFixedStringLengths);
03331         pInfo->ArchivalLocation = String(256, ' ');
03332 
03333         // add some mandatory chunks to get the file chunks in right
03334         // order (INFO chunk will be moved to first position later)
03335         pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
03336         pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
03337         pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
03338 
03339         GenerateDLSID();
03340     }
03341 
03342     File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
03343         bAutoLoad = true;
03344         pGroups = NULL;
03345         pInfo->SetFixedStringLengths(_FileFixedStringLengths);
03346     }
03347 
03348     File::~File() {
03349         if (pGroups) {
03350             std::list<Group*>::iterator iter = pGroups->begin();
03351             std::list<Group*>::iterator end  = pGroups->end();
03352             while (iter != end) {
03353                 delete *iter;
03354                 ++iter;
03355             }
03356             delete pGroups;
03357         }
03358     }
03359 
03360     Sample* File::GetFirstSample(progress_t* pProgress) {
03361         if (!pSamples) LoadSamples(pProgress);
03362         if (!pSamples) return NULL;
03363         SamplesIterator = pSamples->begin();
03364         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
03365     }
03366 
03367     Sample* File::GetNextSample() {
03368         if (!pSamples) return NULL;
03369         SamplesIterator++;
03370         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
03371     }
03372 
03380     Sample* File::AddSample() {
03381        if (!pSamples) LoadSamples();
03382        __ensureMandatoryChunksExist();
03383        RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
03384        // create new Sample object and its respective 'wave' list chunk
03385        RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
03386        Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
03387 
03388        // add mandatory chunks to get the chunks in right order
03389        wave->AddSubChunk(CHUNK_ID_FMT, 16);
03390        wave->AddSubList(LIST_TYPE_INFO);
03391 
03392        pSamples->push_back(pSample);
03393        return pSample;
03394     }
03395 
03405     void File::DeleteSample(Sample* pSample) {
03406         if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
03407         SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
03408         if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
03409         if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
03410         pSamples->erase(iter);
03411         delete pSample;
03412 
03413         SampleList::iterator tmp = SamplesIterator;
03414         // remove all references to the sample
03415         for (Instrument* instrument = GetFirstInstrument() ; instrument ;
03416              instrument = GetNextInstrument()) {
03417             for (Region* region = instrument->GetFirstRegion() ; region ;
03418                  region = instrument->GetNextRegion()) {
03419 
03420                 if (region->GetSample() == pSample) region->SetSample(NULL);
03421 
03422                 for (int i = 0 ; i < region->DimensionRegions ; i++) {
03423                     gig::DimensionRegion *d = region->pDimensionRegions[i];
03424                     if (d->pSample == pSample) d->pSample = NULL;
03425                 }
03426             }
03427         }
03428         SamplesIterator = tmp; // restore iterator
03429     }
03430 
03431     void File::LoadSamples() {
03432         LoadSamples(NULL);
03433     }
03434 
03435     void File::LoadSamples(progress_t* pProgress) {
03436         // Groups must be loaded before samples, because samples will try
03437         // to resolve the group they belong to
03438         if (!pGroups) LoadGroups();
03439 
03440         if (!pSamples) pSamples = new SampleList;
03441 
03442         RIFF::File* file = pRIFF;
03443 
03444         // just for progress calculation
03445         int iSampleIndex  = 0;
03446         int iTotalSamples = WavePoolCount;
03447 
03448         // check if samples should be loaded from extension files
03449         int lastFileNo = 0;
03450         for (int i = 0 ; i < WavePoolCount ; i++) {
03451             if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
03452         }
03453         String name(pRIFF->GetFileName());
03454         int nameLen = name.length();
03455         char suffix[6];
03456         if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
03457 
03458         for (int fileNo = 0 ; ; ) {
03459             RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
03460             if (wvpl) {
03461                 unsigned long wvplFileOffset = wvpl->GetFilePos();
03462                 RIFF::List* wave = wvpl->GetFirstSubList();
03463                 while (wave) {
03464                     if (wave->GetListType() == LIST_TYPE_WAVE) {
03465                         // notify current progress
03466                         const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
03467                         __notify_progress(pProgress, subprogress);
03468 
03469                         unsigned long waveFileOffset = wave->GetFilePos();
03470                         pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
03471 
03472                         iSampleIndex++;
03473                     }
03474                     wave = wvpl->GetNextSubList();
03475                 }
03476 
03477                 if (fileNo == lastFileNo) break;
03478 
03479                 // open extension file (*.gx01, *.gx02, ...)
03480                 fileNo++;
03481                 sprintf(suffix, ".gx%02d", fileNo);
03482                 name.replace(nameLen, 5, suffix);
03483                 file = new RIFF::File(name);
03484                 ExtensionFiles.push_back(file);
03485             } else break;
03486         }
03487 
03488         __notify_progress(pProgress, 1.0); // notify done
03489     }
03490 
03491     Instrument* File::GetFirstInstrument() {
03492         if (!pInstruments) LoadInstruments();
03493         if (!pInstruments) return NULL;
03494         InstrumentsIterator = pInstruments->begin();
03495         return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
03496     }
03497 
03498     Instrument* File::GetNextInstrument() {
03499         if (!pInstruments) return NULL;
03500         InstrumentsIterator++;
03501         return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
03502     }
03503 
03511     Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
03512         if (!pInstruments) {
03513             // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
03514 
03515             // sample loading subtask
03516             progress_t subprogress;
03517             __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
03518             __notify_progress(&subprogress, 0.0f);
03519             if (GetAutoLoad())
03520                 GetFirstSample(&subprogress); // now force all samples to be loaded
03521             __notify_progress(&subprogress, 1.0f);
03522 
03523             // instrument loading subtask
03524             if (pProgress && pProgress->callback) {
03525                 subprogress.__range_min = subprogress.__range_max;
03526                 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
03527             }
03528             __notify_progress(&subprogress, 0.0f);
03529             LoadInstruments(&subprogress);
03530             __notify_progress(&subprogress, 1.0f);
03531         }
03532         if (!pInstruments) return NULL;
03533         InstrumentsIterator = pInstruments->begin();
03534         for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
03535             if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
03536             InstrumentsIterator++;
03537         }
03538         return NULL;
03539     }
03540 
03548     Instrument* File::AddInstrument() {
03549        if (!pInstruments) LoadInstruments();
03550        __ensureMandatoryChunksExist();
03551        RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
03552        RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
03553 
03554        // add mandatory chunks to get the chunks in right order
03555        lstInstr->AddSubList(LIST_TYPE_INFO);
03556        lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
03557 
03558        Instrument* pInstrument = new Instrument(this, lstInstr);
03559        pInstrument->GenerateDLSID();
03560 
03561        lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
03562 
03563        // this string is needed for the gig to be loadable in GSt:
03564        pInstrument->pInfo->Software = "Endless Wave";
03565 
03566        pInstruments->push_back(pInstrument);
03567        return pInstrument;
03568     }
03569 
03578     void File::DeleteInstrument(Instrument* pInstrument) {
03579         if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
03580         InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
03581         if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
03582         pInstruments->erase(iter);
03583         delete pInstrument;
03584     }
03585 
03586     void File::LoadInstruments() {
03587         LoadInstruments(NULL);
03588     }
03589 
03590     void File::LoadInstruments(progress_t* pProgress) {
03591         if (!pInstruments) pInstruments = new InstrumentList;
03592         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
03593         if (lstInstruments) {
03594             int iInstrumentIndex = 0;
03595             RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
03596             while (lstInstr) {
03597                 if (lstInstr->GetListType() == LIST_TYPE_INS) {
03598                     // notify current progress
03599                     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
03600                     __notify_progress(pProgress, localProgress);
03601 
03602                     // divide local progress into subprogress for loading current Instrument
03603                     progress_t subprogress;
03604                     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
03605 
03606                     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
03607 
03608                     iInstrumentIndex++;
03609                 }
03610                 lstInstr = lstInstruments->GetNextSubList();
03611             }
03612             __notify_progress(pProgress, 1.0); // notify done
03613         }
03614     }
03615 
03619     void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
03620         RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
03621         if (!_3crc) return;
03622 
03623         // get the index of the sample
03624         int iWaveIndex = -1;
03625         File::SampleList::iterator iter = pSamples->begin();
03626         File::SampleList::iterator end  = pSamples->end();
03627         for (int index = 0; iter != end; ++iter, ++index) {
03628             if (*iter == pSample) {
03629                 iWaveIndex = index;
03630                 break;
03631             }
03632         }
03633         if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
03634 
03635         // write the CRC-32 checksum to disk
03636         _3crc->SetPos(iWaveIndex * 8);
03637         uint32_t tmp = 1;
03638         _3crc->WriteUint32(&tmp); // unknown, always 1?
03639         _3crc->WriteUint32(&crc);
03640     }
03641 
03642     Group* File::GetFirstGroup() {
03643         if (!pGroups) LoadGroups();
03644         // there must always be at least one group
03645         GroupsIterator = pGroups->begin();
03646         return *GroupsIterator;
03647     }
03648 
03649     Group* File::GetNextGroup() {
03650         if (!pGroups) return NULL;
03651         ++GroupsIterator;
03652         return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
03653     }
03654 
03661     Group* File::GetGroup(uint index) {
03662         if (!pGroups) LoadGroups();
03663         GroupsIterator = pGroups->begin();
03664         for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
03665             if (i == index) return *GroupsIterator;
03666             ++GroupsIterator;
03667         }
03668         return NULL;
03669     }
03670 
03671     Group* File::AddGroup() {
03672         if (!pGroups) LoadGroups();
03673         // there must always be at least one group
03674         __ensureMandatoryChunksExist();
03675         Group* pGroup = new Group(this, NULL);
03676         pGroups->push_back(pGroup);
03677         return pGroup;
03678     }
03679 
03689     void File::DeleteGroup(Group* pGroup) {
03690         if (!pGroups) LoadGroups();
03691         std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
03692         if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
03693         if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
03694         // delete all members of this group
03695         for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
03696             DeleteSample(pSample);
03697         }
03698         // now delete this group object
03699         pGroups->erase(iter);
03700         delete pGroup;
03701     }
03702 
03713     void File::DeleteGroupOnly(Group* pGroup) {
03714         if (!pGroups) LoadGroups();
03715         std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
03716         if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
03717         if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
03718         // move all members of this group to another group
03719         pGroup->MoveAll();
03720         pGroups->erase(iter);
03721         delete pGroup;
03722     }
03723 
03724     void File::LoadGroups() {
03725         if (!pGroups) pGroups = new std::list<Group*>;
03726         // try to read defined groups from file
03727         RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
03728         if (lst3gri) {
03729             RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
03730             if (lst3gnl) {
03731                 RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
03732                 while (ck) {
03733                     if (ck->GetChunkID() == CHUNK_ID_3GNM) {
03734                         if (pVersion && pVersion->major == 3 &&
03735                             strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
03736 
03737                         pGroups->push_back(new Group(this, ck));
03738                     }
03739                     ck = lst3gnl->GetNextSubChunk();
03740                 }
03741             }
03742         }
03743         // if there were no group(s), create at least the mandatory default group
03744         if (!pGroups->size()) {
03745             Group* pGroup = new Group(this, NULL);
03746             pGroup->Name = "Default Group";
03747             pGroups->push_back(pGroup);
03748         }
03749     }
03750 
03761     void File::UpdateChunks() {
03762         bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
03763 
03764         b64BitWavePoolOffsets = pVersion && pVersion->major == 3;
03765 
03766         // first update base class's chunks
03767         DLS::File::UpdateChunks();
03768 
03769         if (newFile) {
03770             // INFO was added by Resource::UpdateChunks - make sure it
03771             // is placed first in file
03772             RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
03773             RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
03774             if (first != info) {
03775                 pRIFF->MoveSubChunk(info, first);
03776             }
03777         }
03778 
03779         // update group's chunks
03780         if (pGroups) {
03781             std::list<Group*>::iterator iter = pGroups->begin();
03782             std::list<Group*>::iterator end  = pGroups->end();
03783             for (; iter != end; ++iter) {
03784                 (*iter)->UpdateChunks();
03785             }
03786 
03787             // v3: make sure the file has 128 3gnm chunks
03788             if (pVersion && pVersion->major == 3) {
03789                 RIFF::List* _3gnl = pRIFF->GetSubList(LIST_TYPE_3GRI)->GetSubList(LIST_TYPE_3GNL);
03790                 RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
03791                 for (int i = 0 ; i < 128 ; i++) {
03792                     if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
03793                     if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
03794                 }
03795             }
03796         }
03797 
03798         // update einf chunk
03799 
03800         // The einf chunk contains statistics about the gig file, such
03801         // as the number of regions and samples used by each
03802         // instrument. It is divided in equally sized parts, where the
03803         // first part contains information about the whole gig file,
03804         // and the rest of the parts map to each instrument in the
03805         // file.
03806         //
03807         // At the end of each part there is a bit map of each sample
03808         // in the file, where a set bit means that the sample is used
03809         // by the file/instrument.
03810         //
03811         // Note that there are several fields with unknown use. These
03812         // are set to zero.
03813 
03814         int sublen = pSamples->size() / 8 + 49;
03815         int einfSize = (Instruments + 1) * sublen;
03816 
03817         RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
03818         if (einf) {
03819             if (einf->GetSize() != einfSize) {
03820                 einf->Resize(einfSize);
03821                 memset(einf->LoadChunkData(), 0, einfSize);
03822             }
03823         } else if (newFile) {
03824             einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
03825         }
03826         if (einf) {
03827             uint8_t* pData = (uint8_t*) einf->LoadChunkData();
03828 
03829             std::map<gig::Sample*,int> sampleMap;
03830             int sampleIdx = 0;
03831             for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
03832                 sampleMap[pSample] = sampleIdx++;
03833             }
03834 
03835             int totnbusedsamples = 0;
03836             int totnbusedchannels = 0;
03837             int totnbregions = 0;
03838             int totnbdimregions = 0;
03839             int totnbloops = 0;
03840             int instrumentIdx = 0;
03841 
03842             memset(&pData[48], 0, sublen - 48);
03843 
03844             for (Instrument* instrument = GetFirstInstrument() ; instrument ;
03845                  instrument = GetNextInstrument()) {
03846                 int nbusedsamples = 0;
03847                 int nbusedchannels = 0;
03848                 int nbdimregions = 0;
03849                 int nbloops = 0;
03850 
03851                 memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
03852 
03853                 for (Region* region = instrument->GetFirstRegion() ; region ;
03854                      region = instrument->GetNextRegion()) {
03855                     for (int i = 0 ; i < region->DimensionRegions ; i++) {
03856                         gig::DimensionRegion *d = region->pDimensionRegions[i];
03857                         if (d->pSample) {
03858                             int sampleIdx = sampleMap[d->pSample];
03859                             int byte = 48 + sampleIdx / 8;
03860                             int bit = 1 << (sampleIdx & 7);
03861                             if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
03862                                 pData[(instrumentIdx + 1) * sublen + byte] |= bit;
03863                                 nbusedsamples++;
03864                                 nbusedchannels += d->pSample->Channels;
03865 
03866                                 if ((pData[byte] & bit) == 0) {
03867                                     pData[byte] |= bit;
03868                                     totnbusedsamples++;
03869                                     totnbusedchannels += d->pSample->Channels;
03870                                 }
03871                             }
03872                         }
03873                         if (d->SampleLoops) nbloops++;
03874                     }
03875                     nbdimregions += region->DimensionRegions;
03876                 }
03877                 // first 4 bytes unknown - sometimes 0, sometimes length of einf part
03878                 // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
03879                 store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
03880                 store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
03881                 store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
03882                 store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
03883                 store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
03884                 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
03885                 // next 8 bytes unknown
03886                 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
03887                 store32(&pData[(instrumentIdx + 1) * sublen + 40], pSamples->size());
03888                 // next 4 bytes unknown
03889 
03890                 totnbregions += instrument->Regions;
03891                 totnbdimregions += nbdimregions;
03892                 totnbloops += nbloops;
03893                 instrumentIdx++;
03894             }
03895             // first 4 bytes unknown - sometimes 0, sometimes length of einf part
03896             // store32(&pData[0], sublen);
03897             store32(&pData[4], totnbusedchannels);
03898             store32(&pData[8], totnbusedsamples);
03899             store32(&pData[12], Instruments);
03900             store32(&pData[16], totnbregions);
03901             store32(&pData[20], totnbdimregions);
03902             store32(&pData[24], totnbloops);
03903             // next 8 bytes unknown
03904             // next 4 bytes unknown, not always 0
03905             store32(&pData[40], pSamples->size());
03906             // next 4 bytes unknown
03907         }
03908 
03909         // update 3crc chunk
03910 
03911         // The 3crc chunk contains CRC-32 checksums for the
03912         // samples. The actual checksum values will be filled in
03913         // later, by Sample::Write.
03914 
03915         RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
03916         if (_3crc) {
03917             _3crc->Resize(pSamples->size() * 8);
03918         } else if (newFile) {
03919             _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
03920             _3crc->LoadChunkData();
03921 
03922             // the order of einf and 3crc is not the same in v2 and v3
03923             if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
03924         }
03925     }
03926 
03942     void File::SetAutoLoad(bool b) {
03943         bAutoLoad = b;
03944     }
03945 
03950     bool File::GetAutoLoad() {
03951         return bAutoLoad;
03952     }
03953 
03954 
03955 
03956 // *************** Exception ***************
03957 // *
03958 
03959     Exception::Exception(String Message) : DLS::Exception(Message) {
03960     }
03961 
03962     void Exception::PrintMessage() {
03963         std::cout << "gig::Exception: " << Message << std::endl;
03964     }
03965 
03966 
03967 // *************** functions ***************
03968 // *
03969 
03975     String libraryName() {
03976         return PACKAGE;
03977     }
03978 
03983     String libraryVersion() {
03984         return VERSION;
03985     }
03986 
03987 } // namespace gig

Generated on Sun May 1 03:22:45 2011 for libgig by  doxygen 1.5.2