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

Generated on Tue Dec 18 07:51:25 2007 for libgig by  doxygen 1.5.4