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 // *************** Other Internal functions  ***************
00259 // *
00260 
00261     static split_type_t __resolveSplitType(dimension_t dimension) {
00262         return (
00263             dimension == dimension_layer ||
00264             dimension == dimension_samplechannel ||
00265             dimension == dimension_releasetrigger ||
00266             dimension == dimension_keyboard ||
00267             dimension == dimension_roundrobin ||
00268             dimension == dimension_random ||
00269             dimension == dimension_smartmidi ||
00270             dimension == dimension_roundrobinkeyboard
00271         ) ? split_type_bit : split_type_normal;
00272     }
00273 
00274     static int __resolveZoneSize(dimension_def_t& dimension_definition) {
00275         return (dimension_definition.split_type == split_type_normal)
00276         ? int(128.0 / dimension_definition.zones) : 0;
00277     }
00278 
00279 
00280 
00281 // *************** Sample ***************
00282 // *
00283 
00284     unsigned int Sample::Instances = 0;
00285     buffer_t     Sample::InternalDecompressionBuffer;
00286 
00305     Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
00306         pInfo->UseFixedLengthStrings = true;
00307         Instances++;
00308         FileNo = fileNo;
00309 
00310         pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
00311         if (pCk3gix) {
00312             uint16_t iSampleGroup = pCk3gix->ReadInt16();
00313             pGroup = pFile->GetGroup(iSampleGroup);
00314         } else { // '3gix' chunk missing
00315             // by default assigned to that mandatory "Default Group"
00316             pGroup = pFile->GetGroup(0);
00317         }
00318 
00319         pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
00320         if (pCkSmpl) {
00321             Manufacturer  = pCkSmpl->ReadInt32();
00322             Product       = pCkSmpl->ReadInt32();
00323             SamplePeriod  = pCkSmpl->ReadInt32();
00324             MIDIUnityNote = pCkSmpl->ReadInt32();
00325             FineTune      = pCkSmpl->ReadInt32();
00326             pCkSmpl->Read(&SMPTEFormat, 1, 4);
00327             SMPTEOffset   = pCkSmpl->ReadInt32();
00328             Loops         = pCkSmpl->ReadInt32();
00329             pCkSmpl->ReadInt32(); // manufByt
00330             LoopID        = pCkSmpl->ReadInt32();
00331             pCkSmpl->Read(&LoopType, 1, 4);
00332             LoopStart     = pCkSmpl->ReadInt32();
00333             LoopEnd       = pCkSmpl->ReadInt32();
00334             LoopFraction  = pCkSmpl->ReadInt32();
00335             LoopPlayCount = pCkSmpl->ReadInt32();
00336         } else { // 'smpl' chunk missing
00337             // use default values
00338             Manufacturer  = 0;
00339             Product       = 0;
00340             SamplePeriod  = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
00341             MIDIUnityNote = 64;
00342             FineTune      = 0;
00343             SMPTEOffset   = 0;
00344             Loops         = 0;
00345             LoopID        = 0;
00346             LoopStart     = 0;
00347             LoopEnd       = 0;
00348             LoopFraction  = 0;
00349             LoopPlayCount = 0;
00350         }
00351 
00352         FrameTable                 = NULL;
00353         SamplePos                  = 0;
00354         RAMCache.Size              = 0;
00355         RAMCache.pStart            = NULL;
00356         RAMCache.NullExtensionSize = 0;
00357 
00358         if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
00359 
00360         RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
00361         Compressed        = ewav;
00362         Dithered          = false;
00363         TruncatedBits     = 0;
00364         if (Compressed) {
00365             uint32_t version = ewav->ReadInt32();
00366             if (version == 3 && BitDepth == 24) {
00367                 Dithered = ewav->ReadInt32();
00368                 ewav->SetPos(Channels == 2 ? 84 : 64);
00369                 TruncatedBits = ewav->ReadInt32();
00370             }
00371             ScanCompressedSample();
00372         }
00373 
00374         // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
00375         if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
00376             InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
00377             InternalDecompressionBuffer.Size   = INITIAL_SAMPLE_BUFFER_SIZE;
00378         }
00379         FrameOffset = 0; // just for streaming compressed samples
00380 
00381         LoopSize = LoopEnd - LoopStart + 1;
00382     }
00383 
00395     void Sample::UpdateChunks() {
00396         // first update base class's chunks
00397         DLS::Sample::UpdateChunks();
00398 
00399         // make sure 'smpl' chunk exists
00400         pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
00401         if (!pCkSmpl) pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
00402         // update 'smpl' chunk
00403         uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
00404         SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
00405         memcpy(&pData[0], &Manufacturer, 4);
00406         memcpy(&pData[4], &Product, 4);
00407         memcpy(&pData[8], &SamplePeriod, 4);
00408         memcpy(&pData[12], &MIDIUnityNote, 4);
00409         memcpy(&pData[16], &FineTune, 4);
00410         memcpy(&pData[20], &SMPTEFormat, 4);
00411         memcpy(&pData[24], &SMPTEOffset, 4);
00412         memcpy(&pData[28], &Loops, 4);
00413 
00414         // we skip 'manufByt' for now (4 bytes)
00415 
00416         memcpy(&pData[36], &LoopID, 4);
00417         memcpy(&pData[40], &LoopType, 4);
00418         memcpy(&pData[44], &LoopStart, 4);
00419         memcpy(&pData[48], &LoopEnd, 4);
00420         memcpy(&pData[52], &LoopFraction, 4);
00421         memcpy(&pData[56], &LoopPlayCount, 4);
00422 
00423         // make sure '3gix' chunk exists
00424         pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
00425         if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
00426         // determine appropriate sample group index (to be stored in chunk)
00427         uint16_t iSampleGroup = 0; // 0 refers to default sample group
00428         File* pFile = static_cast<File*>(pParent);
00429         if (pFile->pGroups) {
00430             std::list<Group*>::iterator iter = pFile->pGroups->begin();
00431             std::list<Group*>::iterator end  = pFile->pGroups->end();
00432             for (int i = 0; iter != end; i++, iter++) {
00433                 if (*iter == pGroup) {
00434                     iSampleGroup = i;
00435                     break; // found
00436                 }
00437             }
00438         }
00439         // update '3gix' chunk
00440         pData = (uint8_t*) pCk3gix->LoadChunkData();
00441         memcpy(&pData[0], &iSampleGroup, 2);
00442     }
00443 
00445     void Sample::ScanCompressedSample() {
00446         //TODO: we have to add some more scans here (e.g. determine compression rate)
00447         this->SamplesTotal = 0;
00448         std::list<unsigned long> frameOffsets;
00449 
00450         SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
00451         WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
00452 
00453         // Scanning
00454         pCkData->SetPos(0);
00455         if (Channels == 2) { // Stereo
00456             for (int i = 0 ; ; i++) {
00457                 // for 24 bit samples every 8:th frame offset is
00458                 // stored, to save some memory
00459                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00460 
00461                 const int mode_l = pCkData->ReadUint8();
00462                 const int mode_r = pCkData->ReadUint8();
00463                 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
00464                 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
00465 
00466                 if (pCkData->RemainingBytes() <= frameSize) {
00467                     SamplesInLastFrame =
00468                         ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
00469                         (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
00470                     SamplesTotal += SamplesInLastFrame;
00471                     break;
00472                 }
00473                 SamplesTotal += SamplesPerFrame;
00474                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00475             }
00476         }
00477         else { // Mono
00478             for (int i = 0 ; ; i++) {
00479                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00480 
00481                 const int mode = pCkData->ReadUint8();
00482                 if (mode > 5) throw gig::Exception("Unknown compression mode");
00483                 const unsigned long frameSize = bytesPerFrame[mode];
00484 
00485                 if (pCkData->RemainingBytes() <= frameSize) {
00486                     SamplesInLastFrame =
00487                         ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
00488                     SamplesTotal += SamplesInLastFrame;
00489                     break;
00490                 }
00491                 SamplesTotal += SamplesPerFrame;
00492                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00493             }
00494         }
00495         pCkData->SetPos(0);
00496 
00497         // Build the frames table (which is used for fast resolving of a frame's chunk offset)
00498         if (FrameTable) delete[] FrameTable;
00499         FrameTable = new unsigned long[frameOffsets.size()];
00500         std::list<unsigned long>::iterator end  = frameOffsets.end();
00501         std::list<unsigned long>::iterator iter = frameOffsets.begin();
00502         for (int i = 0; iter != end; i++, iter++) {
00503             FrameTable[i] = *iter;
00504         }
00505     }
00506 
00516     buffer_t Sample::LoadSampleData() {
00517         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
00518     }
00519 
00542     buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
00543         return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
00544     }
00545 
00565     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
00566         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
00567     }
00568 
00601     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
00602         if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
00603         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00604         unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
00605         RAMCache.pStart            = new int8_t[allocationsize];
00606         RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
00607         RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
00608         // fill the remaining buffer space with silence samples
00609         memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
00610         return GetCache();
00611     }
00612 
00623     buffer_t Sample::GetCache() {
00624         // return a copy of the buffer_t structure
00625         buffer_t result;
00626         result.Size              = this->RAMCache.Size;
00627         result.pStart            = this->RAMCache.pStart;
00628         result.NullExtensionSize = this->RAMCache.NullExtensionSize;
00629         return result;
00630     }
00631 
00638     void Sample::ReleaseSampleData() {
00639         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00640         RAMCache.pStart = NULL;
00641         RAMCache.Size   = 0;
00642     }
00643 
00674     void Sample::Resize(int iNewSize) {
00675         if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
00676         DLS::Sample::Resize(iNewSize);
00677     }
00678 
00700     unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
00701         if (Compressed) {
00702             switch (Whence) {
00703                 case RIFF::stream_curpos:
00704                     this->SamplePos += SampleCount;
00705                     break;
00706                 case RIFF::stream_end:
00707                     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
00708                     break;
00709                 case RIFF::stream_backward:
00710                     this->SamplePos -= SampleCount;
00711                     break;
00712                 case RIFF::stream_start: default:
00713                     this->SamplePos = SampleCount;
00714                     break;
00715             }
00716             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00717 
00718             unsigned long frame = this->SamplePos / 2048; // to which frame to jump
00719             this->FrameOffset   = this->SamplePos % 2048; // offset (in sample points) within that frame
00720             pCkData->SetPos(FrameTable[frame]);           // set chunk pointer to the start of sought frame
00721             return this->SamplePos;
00722         }
00723         else { // not compressed
00724             unsigned long orderedBytes = SampleCount * this->FrameSize;
00725             unsigned long result = pCkData->SetPos(orderedBytes, Whence);
00726             return (result == orderedBytes) ? SampleCount
00727                                             : result / this->FrameSize;
00728         }
00729     }
00730 
00734     unsigned long Sample::GetPos() {
00735         if (Compressed) return SamplePos;
00736         else            return pCkData->GetPos() / FrameSize;
00737     }
00738 
00773     unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState,
00774                                       DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
00775         unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
00776         uint8_t* pDst = (uint8_t*) pBuffer;
00777 
00778         SetPos(pPlaybackState->position); // recover position from the last time
00779 
00780         if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
00781 
00782             const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
00783             const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
00784 
00785             if (GetPos() <= loopEnd) {
00786                 switch (loop.LoopType) {
00787 
00788                     case loop_type_bidirectional: { //TODO: not tested yet!
00789                         do {
00790                             // if not endless loop check if max. number of loop cycles have been passed
00791                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00792 
00793                             if (!pPlaybackState->reverse) { // forward playback
00794                                 do {
00795                                     samplestoloopend  = loopEnd - GetPos();
00796                                     readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00797                                     samplestoread    -= readsamples;
00798                                     totalreadsamples += readsamples;
00799                                     if (readsamples == samplestoloopend) {
00800                                         pPlaybackState->reverse = true;
00801                                         break;
00802                                     }
00803                                 } while (samplestoread && readsamples);
00804                             }
00805                             else { // backward playback
00806 
00807                                 // as we can only read forward from disk, we have to
00808                                 // determine the end position within the loop first,
00809                                 // read forward from that 'end' and finally after
00810                                 // reading, swap all sample frames so it reflects
00811                                 // backward playback
00812 
00813                                 unsigned long swapareastart       = totalreadsamples;
00814                                 unsigned long loopoffset          = GetPos() - loop.LoopStart;
00815                                 unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
00816                                 unsigned long reverseplaybackend  = GetPos() - samplestoreadinloop;
00817 
00818                                 SetPos(reverseplaybackend);
00819 
00820                                 // read samples for backward playback
00821                                 do {
00822                                     readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
00823                                     samplestoreadinloop -= readsamples;
00824                                     samplestoread       -= readsamples;
00825                                     totalreadsamples    += readsamples;
00826                                 } while (samplestoreadinloop && readsamples);
00827 
00828                                 SetPos(reverseplaybackend); // pretend we really read backwards
00829 
00830                                 if (reverseplaybackend == loop.LoopStart) {
00831                                     pPlaybackState->loop_cycles_left--;
00832                                     pPlaybackState->reverse = false;
00833                                 }
00834 
00835                                 // reverse the sample frames for backward playback
00836                                 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00837                             }
00838                         } while (samplestoread && readsamples);
00839                         break;
00840                     }
00841 
00842                     case loop_type_backward: { // TODO: not tested yet!
00843                         // forward playback (not entered the loop yet)
00844                         if (!pPlaybackState->reverse) do {
00845                             samplestoloopend  = loopEnd - GetPos();
00846                             readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00847                             samplestoread    -= readsamples;
00848                             totalreadsamples += readsamples;
00849                             if (readsamples == samplestoloopend) {
00850                                 pPlaybackState->reverse = true;
00851                                 break;
00852                             }
00853                         } while (samplestoread && readsamples);
00854 
00855                         if (!samplestoread) break;
00856 
00857                         // as we can only read forward from disk, we have to
00858                         // determine the end position within the loop first,
00859                         // read forward from that 'end' and finally after
00860                         // reading, swap all sample frames so it reflects
00861                         // backward playback
00862 
00863                         unsigned long swapareastart       = totalreadsamples;
00864                         unsigned long loopoffset          = GetPos() - loop.LoopStart;
00865                         unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
00866                                                                                   : samplestoread;
00867                         unsigned long reverseplaybackend  = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
00868 
00869                         SetPos(reverseplaybackend);
00870 
00871                         // read samples for backward playback
00872                         do {
00873                             // if not endless loop check if max. number of loop cycles have been passed
00874                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00875                             samplestoloopend     = loopEnd - GetPos();
00876                             readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
00877                             samplestoreadinloop -= readsamples;
00878                             samplestoread       -= readsamples;
00879                             totalreadsamples    += readsamples;
00880                             if (readsamples == samplestoloopend) {
00881                                 pPlaybackState->loop_cycles_left--;
00882                                 SetPos(loop.LoopStart);
00883                             }
00884                         } while (samplestoreadinloop && readsamples);
00885 
00886                         SetPos(reverseplaybackend); // pretend we really read backwards
00887 
00888                         // reverse the sample frames for backward playback
00889                         SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00890                         break;
00891                     }
00892 
00893                     default: case loop_type_normal: {
00894                         do {
00895                             // if not endless loop check if max. number of loop cycles have been passed
00896                             if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00897                             samplestoloopend  = loopEnd - GetPos();
00898                             readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00899                             samplestoread    -= readsamples;
00900                             totalreadsamples += readsamples;
00901                             if (readsamples == samplestoloopend) {
00902                                 pPlaybackState->loop_cycles_left--;
00903                                 SetPos(loop.LoopStart);
00904                             }
00905                         } while (samplestoread && readsamples);
00906                         break;
00907                     }
00908                 }
00909             }
00910         }
00911 
00912         // read on without looping
00913         if (samplestoread) do {
00914             readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
00915             samplestoread    -= readsamples;
00916             totalreadsamples += readsamples;
00917         } while (readsamples && samplestoread);
00918 
00919         // store current position
00920         pPlaybackState->position = GetPos();
00921 
00922         return totalreadsamples;
00923     }
00924 
00947     unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
00948         if (SampleCount == 0) return 0;
00949         if (!Compressed) {
00950             if (BitDepth == 24) {
00951                 return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
00952             }
00953             else { // 16 bit
00954                 // (pCkData->Read does endian correction)
00955                 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
00956                                      : pCkData->Read(pBuffer, SampleCount, 2);
00957             }
00958         }
00959         else {
00960             if (this->SamplePos >= this->SamplesTotal) return 0;
00961             //TODO: efficiency: maybe we should test for an average compression rate
00962             unsigned long assumedsize      = GuessSize(SampleCount),
00963                           remainingbytes   = 0,           // remaining bytes in the local buffer
00964                           remainingsamples = SampleCount,
00965                           copysamples, skipsamples,
00966                           currentframeoffset = this->FrameOffset;  // offset in current sample frame since last Read()
00967             this->FrameOffset = 0;
00968 
00969             buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
00970 
00971             // if decompression buffer too small, then reduce amount of samples to read
00972             if (pDecompressionBuffer->Size < assumedsize) {
00973                 std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
00974                 SampleCount      = WorstCaseMaxSamples(pDecompressionBuffer);
00975                 remainingsamples = SampleCount;
00976                 assumedsize      = GuessSize(SampleCount);
00977             }
00978 
00979             unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
00980             int16_t* pDst = static_cast<int16_t*>(pBuffer);
00981             uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
00982             remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
00983 
00984             while (remainingsamples && remainingbytes) {
00985                 unsigned long framesamples = SamplesPerFrame;
00986                 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
00987 
00988                 int mode_l = *pSrc++, mode_r = 0;
00989 
00990                 if (Channels == 2) {
00991                     mode_r = *pSrc++;
00992                     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
00993                     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
00994                     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
00995                     if (remainingbytes < framebytes) { // last frame in sample
00996                         framesamples = SamplesInLastFrame;
00997                         if (mode_l == 4 && (framesamples & 1)) {
00998                             rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
00999                         }
01000                         else {
01001                             rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
01002                         }
01003                     }
01004                 }
01005                 else {
01006                     framebytes = bytesPerFrame[mode_l] + 1;
01007                     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
01008                     if (remainingbytes < framebytes) {
01009                         framesamples = SamplesInLastFrame;
01010                     }
01011                 }
01012 
01013                 // determine how many samples in this frame to skip and read
01014                 if (currentframeoffset + remainingsamples >= framesamples) {
01015                     if (currentframeoffset <= framesamples) {
01016                         copysamples = framesamples - currentframeoffset;
01017                         skipsamples = currentframeoffset;
01018                     }
01019                     else {
01020                         copysamples = 0;
01021                         skipsamples = framesamples;
01022                     }
01023                 }
01024                 else {
01025                     // This frame has enough data for pBuffer, but not
01026                     // all of the frame is needed. Set file position
01027                     // to start of this frame for next call to Read.
01028                     copysamples = remainingsamples;
01029                     skipsamples = currentframeoffset;
01030                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01031                     this->FrameOffset = currentframeoffset + copysamples;
01032                 }
01033                 remainingsamples -= copysamples;
01034 
01035                 if (remainingbytes > framebytes) {
01036                     remainingbytes -= framebytes;
01037                     if (remainingsamples == 0 &&
01038                         currentframeoffset + copysamples == framesamples) {
01039                         // This frame has enough data for pBuffer, and
01040                         // all of the frame is needed. Set file
01041                         // position to start of next frame for next
01042                         // call to Read. FrameOffset is 0.
01043                         pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01044                     }
01045                 }
01046                 else remainingbytes = 0;
01047 
01048                 currentframeoffset -= skipsamples;
01049 
01050                 if (copysamples == 0) {
01051                     // skip this frame
01052                     pSrc += framebytes - Channels;
01053                 }
01054                 else {
01055                     const unsigned char* const param_l = pSrc;
01056                     if (BitDepth == 24) {
01057                         if (mode_l != 2) pSrc += 12;
01058 
01059                         if (Channels == 2) { // Stereo
01060                             const unsigned char* const param_r = pSrc;
01061                             if (mode_r != 2) pSrc += 12;
01062 
01063                             Decompress24(mode_l, param_l, 6, pSrc, pDst24,
01064                                          skipsamples, copysamples, TruncatedBits);
01065                             Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
01066                                          skipsamples, copysamples, TruncatedBits);
01067                             pDst24 += copysamples * 6;
01068                         }
01069                         else { // Mono
01070                             Decompress24(mode_l, param_l, 3, pSrc, pDst24,
01071                                          skipsamples, copysamples, TruncatedBits);
01072                             pDst24 += copysamples * 3;
01073                         }
01074                     }
01075                     else { // 16 bit
01076                         if (mode_l) pSrc += 4;
01077 
01078                         int step;
01079                         if (Channels == 2) { // Stereo
01080                             const unsigned char* const param_r = pSrc;
01081                             if (mode_r) pSrc += 4;
01082 
01083                             step = (2 - mode_l) + (2 - mode_r);
01084                             Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
01085                             Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
01086                                          skipsamples, copysamples);
01087                             pDst += copysamples << 1;
01088                         }
01089                         else { // Mono
01090                             step = 2 - mode_l;
01091                             Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
01092                             pDst += copysamples;
01093                         }
01094                     }
01095                     pSrc += nextFrameOffset;
01096                 }
01097 
01098                 // reload from disk to local buffer if needed
01099                 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
01100                     assumedsize    = GuessSize(remainingsamples);
01101                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
01102                     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
01103                     remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
01104                     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
01105                 }
01106             } // while
01107 
01108             this->SamplePos += (SampleCount - remainingsamples);
01109             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
01110             return (SampleCount - remainingsamples);
01111         }
01112     }
01113 
01132     unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
01133         if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
01134         return DLS::Sample::Write(pBuffer, SampleCount);
01135     }
01136 
01153     buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
01154         buffer_t result;
01155         const double worstCaseHeaderOverhead =
01156                 (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
01157         result.Size              = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
01158         result.pStart            = new int8_t[result.Size];
01159         result.NullExtensionSize = 0;
01160         return result;
01161     }
01162 
01170     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
01171         if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
01172             delete[] (int8_t*) DecompressionBuffer.pStart;
01173             DecompressionBuffer.pStart = NULL;
01174             DecompressionBuffer.Size   = 0;
01175             DecompressionBuffer.NullExtensionSize = 0;
01176         }
01177     }
01178 
01187     Group* Sample::GetGroup() const {
01188         return pGroup;
01189     }
01190 
01191     Sample::~Sample() {
01192         Instances--;
01193         if (!Instances && InternalDecompressionBuffer.Size) {
01194             delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
01195             InternalDecompressionBuffer.pStart = NULL;
01196             InternalDecompressionBuffer.Size   = 0;
01197         }
01198         if (FrameTable) delete[] FrameTable;
01199         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
01200     }
01201 
01202 
01203 
01204 // *************** DimensionRegion ***************
01205 // *
01206 
01207     uint                               DimensionRegion::Instances       = 0;
01208     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
01209 
01210     DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
01211         Instances++;
01212 
01213         pSample = NULL;
01214 
01215         memcpy(&Crossfade, &SamplerOptions, 4);
01216         if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
01217 
01218         RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
01219         if (_3ewa) { // if '3ewa' chunk exists
01220             _3ewa->ReadInt32(); // unknown, always == chunk size ?
01221             LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01222             EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01223             _3ewa->ReadInt16(); // unknown
01224             LFO1InternalDepth = _3ewa->ReadUint16();
01225             _3ewa->ReadInt16(); // unknown
01226             LFO3InternalDepth = _3ewa->ReadInt16();
01227             _3ewa->ReadInt16(); // unknown
01228             LFO1ControlDepth = _3ewa->ReadUint16();
01229             _3ewa->ReadInt16(); // unknown
01230             LFO3ControlDepth = _3ewa->ReadInt16();
01231             EG1Attack           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01232             EG1Decay1           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01233             _3ewa->ReadInt16(); // unknown
01234             EG1Sustain          = _3ewa->ReadUint16();
01235             EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01236             EG1Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01237             uint8_t eg1ctrloptions        = _3ewa->ReadUint8();
01238             EG1ControllerInvert           = eg1ctrloptions & 0x01;
01239             EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
01240             EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
01241             EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
01242             EG2Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01243             uint8_t eg2ctrloptions        = _3ewa->ReadUint8();
01244             EG2ControllerInvert           = eg2ctrloptions & 0x01;
01245             EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
01246             EG2ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
01247             EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
01248             LFO1Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01249             EG2Attack        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01250             EG2Decay1        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01251             _3ewa->ReadInt16(); // unknown
01252             EG2Sustain       = _3ewa->ReadUint16();
01253             EG2Release       = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01254             _3ewa->ReadInt16(); // unknown
01255             LFO2ControlDepth = _3ewa->ReadUint16();
01256             LFO2Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01257             _3ewa->ReadInt16(); // unknown
01258             LFO2InternalDepth = _3ewa->ReadUint16();
01259             int32_t eg1decay2 = _3ewa->ReadInt32();
01260             EG1Decay2          = (double) GIG_EXP_DECODE(eg1decay2);
01261             EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
01262             _3ewa->ReadInt16(); // unknown
01263             EG1PreAttack      = _3ewa->ReadUint16();
01264             int32_t eg2decay2 = _3ewa->ReadInt32();
01265             EG2Decay2         = (double) GIG_EXP_DECODE(eg2decay2);
01266             EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
01267             _3ewa->ReadInt16(); // unknown
01268             EG2PreAttack      = _3ewa->ReadUint16();
01269             uint8_t velocityresponse = _3ewa->ReadUint8();
01270             if (velocityresponse < 5) {
01271                 VelocityResponseCurve = curve_type_nonlinear;
01272                 VelocityResponseDepth = velocityresponse;
01273             } else if (velocityresponse < 10) {
01274                 VelocityResponseCurve = curve_type_linear;
01275                 VelocityResponseDepth = velocityresponse - 5;
01276             } else if (velocityresponse < 15) {
01277                 VelocityResponseCurve = curve_type_special;
01278                 VelocityResponseDepth = velocityresponse - 10;
01279             } else {
01280                 VelocityResponseCurve = curve_type_unknown;
01281                 VelocityResponseDepth = 0;
01282             }
01283             uint8_t releasevelocityresponse = _3ewa->ReadUint8();
01284             if (releasevelocityresponse < 5) {
01285                 ReleaseVelocityResponseCurve = curve_type_nonlinear;
01286                 ReleaseVelocityResponseDepth = releasevelocityresponse;
01287             } else if (releasevelocityresponse < 10) {
01288                 ReleaseVelocityResponseCurve = curve_type_linear;
01289                 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
01290             } else if (releasevelocityresponse < 15) {
01291                 ReleaseVelocityResponseCurve = curve_type_special;
01292                 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
01293             } else {
01294                 ReleaseVelocityResponseCurve = curve_type_unknown;
01295                 ReleaseVelocityResponseDepth = 0;
01296             }
01297             VelocityResponseCurveScaling = _3ewa->ReadUint8();
01298             AttenuationControllerThreshold = _3ewa->ReadInt8();
01299             _3ewa->ReadInt32(); // unknown
01300             SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
01301             _3ewa->ReadInt16(); // unknown
01302             uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
01303             PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
01304             if      (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
01305             else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
01306             else                                       DimensionBypass = dim_bypass_ctrl_none;
01307             uint8_t pan = _3ewa->ReadUint8();
01308             Pan         = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
01309             SelfMask = _3ewa->ReadInt8() & 0x01;
01310             _3ewa->ReadInt8(); // unknown
01311             uint8_t lfo3ctrl = _3ewa->ReadUint8();
01312             LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
01313             LFO3Sync                 = lfo3ctrl & 0x20; // bit 5
01314             InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
01315             AttenuationController  = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01316             uint8_t lfo2ctrl       = _3ewa->ReadUint8();
01317             LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
01318             LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7
01319             LFO2Sync               = lfo2ctrl & 0x20; // bit 5
01320             bool extResonanceCtrl  = lfo2ctrl & 0x40; // bit 6
01321             uint8_t lfo1ctrl       = _3ewa->ReadUint8();
01322             LFO1Controller         = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
01323             LFO1FlipPhase          = lfo1ctrl & 0x80; // bit 7
01324             LFO1Sync               = lfo1ctrl & 0x40; // bit 6
01325             VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
01326                                                         : vcf_res_ctrl_none;
01327             uint16_t eg3depth = _3ewa->ReadUint16();
01328             EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
01329                                         : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
01330             _3ewa->ReadInt16(); // unknown
01331             ChannelOffset = _3ewa->ReadUint8() / 4;
01332             uint8_t regoptions = _3ewa->ReadUint8();
01333             MSDecode           = regoptions & 0x01; // bit 0
01334             SustainDefeat      = regoptions & 0x02; // bit 1
01335             _3ewa->ReadInt16(); // unknown
01336             VelocityUpperLimit = _3ewa->ReadInt8();
01337             _3ewa->ReadInt8(); // unknown
01338             _3ewa->ReadInt16(); // unknown
01339             ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
01340             _3ewa->ReadInt8(); // unknown
01341             _3ewa->ReadInt8(); // unknown
01342             EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
01343             uint8_t vcfcutoff = _3ewa->ReadUint8();
01344             VCFEnabled = vcfcutoff & 0x80; // bit 7
01345             VCFCutoff  = vcfcutoff & 0x7f; // lower 7 bits
01346             VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
01347             uint8_t vcfvelscale = _3ewa->ReadUint8();
01348             VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
01349             VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
01350             _3ewa->ReadInt8(); // unknown
01351             uint8_t vcfresonance = _3ewa->ReadUint8();
01352             VCFResonance = vcfresonance & 0x7f; // lower 7 bits
01353             VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
01354             uint8_t vcfbreakpoint         = _3ewa->ReadUint8();
01355             VCFKeyboardTracking           = vcfbreakpoint & 0x80; // bit 7
01356             VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
01357             uint8_t vcfvelocity = _3ewa->ReadUint8();
01358             VCFVelocityDynamicRange = vcfvelocity % 5;
01359             VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
01360             VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
01361             if (VCFType == vcf_type_lowpass) {
01362                 if (lfo3ctrl & 0x40) // bit 6
01363                     VCFType = vcf_type_lowpassturbo;
01364             }
01365             if (_3ewa->RemainingBytes() >= 8) {
01366                 _3ewa->Read(DimensionUpperLimits, 1, 8);
01367             } else {
01368                 memset(DimensionUpperLimits, 0, 8);
01369             }
01370         } else { // '3ewa' chunk does not exist yet
01371             // use default values
01372             LFO3Frequency                   = 1.0;
01373             EG3Attack                       = 0.0;
01374             LFO1InternalDepth               = 0;
01375             LFO3InternalDepth               = 0;
01376             LFO1ControlDepth                = 0;
01377             LFO3ControlDepth                = 0;
01378             EG1Attack                       = 0.0;
01379             EG1Decay1                       = 0.0;
01380             EG1Sustain                      = 0;
01381             EG1Release                      = 0.0;
01382             EG1Controller.type              = eg1_ctrl_t::type_none;
01383             EG1Controller.controller_number = 0;
01384             EG1ControllerInvert             = false;
01385             EG1ControllerAttackInfluence    = 0;
01386             EG1ControllerDecayInfluence     = 0;
01387             EG1ControllerReleaseInfluence   = 0;
01388             EG2Controller.type              = eg2_ctrl_t::type_none;
01389             EG2Controller.controller_number = 0;
01390             EG2ControllerInvert             = false;
01391             EG2ControllerAttackInfluence    = 0;
01392             EG2ControllerDecayInfluence     = 0;
01393             EG2ControllerReleaseInfluence   = 0;
01394             LFO1Frequency                   = 1.0;
01395             EG2Attack                       = 0.0;
01396             EG2Decay1                       = 0.0;
01397             EG2Sustain                      = 0;
01398             EG2Release                      = 0.0;
01399             LFO2ControlDepth                = 0;
01400             LFO2Frequency                   = 1.0;
01401             LFO2InternalDepth               = 0;
01402             EG1Decay2                       = 0.0;
01403             EG1InfiniteSustain              = false;
01404             EG1PreAttack                    = 1000;
01405             EG2Decay2                       = 0.0;
01406             EG2InfiniteSustain              = false;
01407             EG2PreAttack                    = 1000;
01408             VelocityResponseCurve           = curve_type_nonlinear;
01409             VelocityResponseDepth           = 3;
01410             ReleaseVelocityResponseCurve    = curve_type_nonlinear;
01411             ReleaseVelocityResponseDepth    = 3;
01412             VelocityResponseCurveScaling    = 32;
01413             AttenuationControllerThreshold  = 0;
01414             SampleStartOffset               = 0;
01415             PitchTrack                      = true;
01416             DimensionBypass                 = dim_bypass_ctrl_none;
01417             Pan                             = 0;
01418             SelfMask                        = true;
01419             LFO3Controller                  = lfo3_ctrl_modwheel;
01420             LFO3Sync                        = false;
01421             InvertAttenuationController     = false;
01422             AttenuationController.type      = attenuation_ctrl_t::type_none;
01423             AttenuationController.controller_number = 0;
01424             LFO2Controller                  = lfo2_ctrl_internal;
01425             LFO2FlipPhase                   = false;
01426             LFO2Sync                        = false;
01427             LFO1Controller                  = lfo1_ctrl_internal;
01428             LFO1FlipPhase                   = false;
01429             LFO1Sync                        = false;
01430             VCFResonanceController          = vcf_res_ctrl_none;
01431             EG3Depth                        = 0;
01432             ChannelOffset                   = 0;
01433             MSDecode                        = false;
01434             SustainDefeat                   = false;
01435             VelocityUpperLimit              = 0;
01436             ReleaseTriggerDecay             = 0;
01437             EG1Hold                         = false;
01438             VCFEnabled                      = false;
01439             VCFCutoff                       = 0;
01440             VCFCutoffController             = vcf_cutoff_ctrl_none;
01441             VCFCutoffControllerInvert       = false;
01442             VCFVelocityScale                = 0;
01443             VCFResonance                    = 0;
01444             VCFResonanceDynamic             = false;
01445             VCFKeyboardTracking             = false;
01446             VCFKeyboardTrackingBreakpoint   = 0;
01447             VCFVelocityDynamicRange         = 0x04;
01448             VCFVelocityCurve                = curve_type_linear;
01449             VCFType                         = vcf_type_lowpass;
01450             memset(DimensionUpperLimits, 0, 8);
01451         }
01452 
01453         pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
01454                                                      VelocityResponseDepth,
01455                                                      VelocityResponseCurveScaling);
01456 
01457         curve_type_t curveType = ReleaseVelocityResponseCurve;
01458         uint8_t depth = ReleaseVelocityResponseDepth;
01459 
01460         // this models a strange behaviour or bug in GSt: two of the
01461         // velocity response curves for release time are not used even
01462         // if specified, instead another curve is chosen.
01463         if ((curveType == curve_type_nonlinear && depth == 0) ||
01464             (curveType == curve_type_special   && depth == 4)) {
01465             curveType = curve_type_nonlinear;
01466             depth = 3;
01467         }
01468         pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);
01469 
01470         curveType = VCFVelocityCurve;
01471         depth = VCFVelocityDynamicRange;
01472 
01473         // even stranger GSt: two of the velocity response curves for
01474         // filter cutoff are not used, instead another special curve
01475         // is chosen. This curve is not used anywhere else.
01476         if ((curveType == curve_type_nonlinear && depth == 0) ||
01477             (curveType == curve_type_special   && depth == 4)) {
01478             curveType = curve_type_special;
01479             depth = 5;
01480         }
01481         pVelocityCutoffTable = GetVelocityTable(curveType, depth,
01482                                                 VCFCutoffController <= vcf_cutoff_ctrl_none2 ? VCFVelocityScale : 0);
01483 
01484         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01485         VelocityTable = 0;
01486     }
01487 
01495     void DimensionRegion::UpdateChunks() {
01496         // first update base class's chunk
01497         DLS::Sampler::UpdateChunks();
01498 
01499         // make sure '3ewa' chunk exists
01500         RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
01501         if (!_3ewa)  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, 140);
01502         uint8_t* pData = (uint8_t*) _3ewa->LoadChunkData();
01503 
01504         // update '3ewa' chunk with DimensionRegion's current settings
01505 
01506         const uint32_t chunksize = _3ewa->GetSize();
01507         memcpy(&pData[0], &chunksize, 4); // unknown, always chunk size?
01508 
01509         const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
01510         memcpy(&pData[4], &lfo3freq, 4);
01511 
01512         const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
01513         memcpy(&pData[8], &eg3attack, 4);
01514 
01515         // next 2 bytes unknown
01516 
01517         memcpy(&pData[14], &LFO1InternalDepth, 2);
01518 
01519         // next 2 bytes unknown
01520 
01521         memcpy(&pData[18], &LFO3InternalDepth, 2);
01522 
01523         // next 2 bytes unknown
01524 
01525         memcpy(&pData[22], &LFO1ControlDepth, 2);
01526 
01527         // next 2 bytes unknown
01528 
01529         memcpy(&pData[26], &LFO3ControlDepth, 2);
01530 
01531         const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
01532         memcpy(&pData[28], &eg1attack, 4);
01533 
01534         const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
01535         memcpy(&pData[32], &eg1decay1, 4);
01536 
01537         // next 2 bytes unknown
01538 
01539         memcpy(&pData[38], &EG1Sustain, 2);
01540 
01541         const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
01542         memcpy(&pData[40], &eg1release, 4);
01543 
01544         const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
01545         memcpy(&pData[44], &eg1ctl, 1);
01546 
01547         const uint8_t eg1ctrloptions =
01548             (EG1ControllerInvert) ? 0x01 : 0x00 |
01549             GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
01550             GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
01551             GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
01552         memcpy(&pData[45], &eg1ctrloptions, 1);
01553 
01554         const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
01555         memcpy(&pData[46], &eg2ctl, 1);
01556 
01557         const uint8_t eg2ctrloptions =
01558             (EG2ControllerInvert) ? 0x01 : 0x00 |
01559             GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
01560             GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
01561             GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
01562         memcpy(&pData[47], &eg2ctrloptions, 1);
01563 
01564         const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
01565         memcpy(&pData[48], &lfo1freq, 4);
01566 
01567         const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
01568         memcpy(&pData[52], &eg2attack, 4);
01569 
01570         const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
01571         memcpy(&pData[56], &eg2decay1, 4);
01572 
01573         // next 2 bytes unknown
01574 
01575         memcpy(&pData[62], &EG2Sustain, 2);
01576 
01577         const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
01578         memcpy(&pData[64], &eg2release, 4);
01579 
01580         // next 2 bytes unknown
01581 
01582         memcpy(&pData[70], &LFO2ControlDepth, 2);
01583 
01584         const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
01585         memcpy(&pData[72], &lfo2freq, 4);
01586 
01587         // next 2 bytes unknown
01588 
01589         memcpy(&pData[78], &LFO2InternalDepth, 2);
01590 
01591         const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
01592         memcpy(&pData[80], &eg1decay2, 4);
01593 
01594         // next 2 bytes unknown
01595 
01596         memcpy(&pData[86], &EG1PreAttack, 2);
01597 
01598         const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
01599         memcpy(&pData[88], &eg2decay2, 4);
01600 
01601         // next 2 bytes unknown
01602 
01603         memcpy(&pData[94], &EG2PreAttack, 2);
01604 
01605         {
01606             if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
01607             uint8_t velocityresponse = VelocityResponseDepth;
01608             switch (VelocityResponseCurve) {
01609                 case curve_type_nonlinear:
01610                     break;
01611                 case curve_type_linear:
01612                     velocityresponse += 5;
01613                     break;
01614                 case curve_type_special:
01615                     velocityresponse += 10;
01616                     break;
01617                 case curve_type_unknown:
01618                 default:
01619                     throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
01620             }
01621             memcpy(&pData[96], &velocityresponse, 1);
01622         }
01623 
01624         {
01625             if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
01626             uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
01627             switch (ReleaseVelocityResponseCurve) {
01628                 case curve_type_nonlinear:
01629                     break;
01630                 case curve_type_linear:
01631                     releasevelocityresponse += 5;
01632                     break;
01633                 case curve_type_special:
01634                     releasevelocityresponse += 10;
01635                     break;
01636                 case curve_type_unknown:
01637                 default:
01638                     throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
01639             }
01640             memcpy(&pData[97], &releasevelocityresponse, 1);
01641         }
01642 
01643         memcpy(&pData[98], &VelocityResponseCurveScaling, 1);
01644 
01645         memcpy(&pData[99], &AttenuationControllerThreshold, 1);
01646 
01647         // next 4 bytes unknown
01648 
01649         memcpy(&pData[104], &SampleStartOffset, 2);
01650 
01651         // next 2 bytes unknown
01652 
01653         {
01654             uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
01655             switch (DimensionBypass) {
01656                 case dim_bypass_ctrl_94:
01657                     pitchTrackDimensionBypass |= 0x10;
01658                     break;
01659                 case dim_bypass_ctrl_95:
01660                     pitchTrackDimensionBypass |= 0x20;
01661                     break;
01662                 case dim_bypass_ctrl_none:
01663                     //FIXME: should we set anything here?
01664                     break;
01665                 default:
01666                     throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
01667             }
01668             memcpy(&pData[108], &pitchTrackDimensionBypass, 1);
01669         }
01670 
01671         const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
01672         memcpy(&pData[109], &pan, 1);
01673 
01674         const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
01675         memcpy(&pData[110], &selfmask, 1);
01676 
01677         // next byte unknown
01678 
01679         {
01680             uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
01681             if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
01682             if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
01683             if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
01684             memcpy(&pData[112], &lfo3ctrl, 1);
01685         }
01686 
01687         const uint8_t attenctl = EncodeLeverageController(AttenuationController);
01688         memcpy(&pData[113], &attenctl, 1);
01689 
01690         {
01691             uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
01692             if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
01693             if (LFO2Sync)      lfo2ctrl |= 0x20; // bit 5
01694             if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
01695             memcpy(&pData[114], &lfo2ctrl, 1);
01696         }
01697 
01698         {
01699             uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
01700             if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
01701             if (LFO1Sync)      lfo1ctrl |= 0x40; // bit 6
01702             if (VCFResonanceController != vcf_res_ctrl_none)
01703                 lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
01704             memcpy(&pData[115], &lfo1ctrl, 1);
01705         }
01706 
01707         const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
01708                                                   : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
01709         memcpy(&pData[116], &eg3depth, 1);
01710 
01711         // next 2 bytes unknown
01712 
01713         const uint8_t channeloffset = ChannelOffset * 4;
01714         memcpy(&pData[120], &channeloffset, 1);
01715 
01716         {
01717             uint8_t regoptions = 0;
01718             if (MSDecode)      regoptions |= 0x01; // bit 0
01719             if (SustainDefeat) regoptions |= 0x02; // bit 1
01720             memcpy(&pData[121], &regoptions, 1);
01721         }
01722 
01723         // next 2 bytes unknown
01724 
01725         memcpy(&pData[124], &VelocityUpperLimit, 1);
01726 
01727         // next 3 bytes unknown
01728 
01729         memcpy(&pData[128], &ReleaseTriggerDecay, 1);
01730 
01731         // next 2 bytes unknown
01732 
01733         const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
01734         memcpy(&pData[131], &eg1hold, 1);
01735 
01736         const uint8_t vcfcutoff = (VCFEnabled) ? 0x80 : 0x00 |  /* bit 7 */
01737                                   (VCFCutoff & 0x7f);   /* lower 7 bits */
01738         memcpy(&pData[132], &vcfcutoff, 1);
01739 
01740         memcpy(&pData[133], &VCFCutoffController, 1);
01741 
01742         const uint8_t vcfvelscale = (VCFCutoffControllerInvert) ? 0x80 : 0x00 | /* bit 7 */
01743                                     (VCFVelocityScale & 0x7f); /* lower 7 bits */
01744         memcpy(&pData[134], &vcfvelscale, 1);
01745 
01746         // next byte unknown
01747 
01748         const uint8_t vcfresonance = (VCFResonanceDynamic) ? 0x00 : 0x80 | /* bit 7 */
01749                                      (VCFResonance & 0x7f); /* lower 7 bits */
01750         memcpy(&pData[136], &vcfresonance, 1);
01751 
01752         const uint8_t vcfbreakpoint = (VCFKeyboardTracking) ? 0x80 : 0x00 | /* bit 7 */
01753                                       (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
01754         memcpy(&pData[137], &vcfbreakpoint, 1);
01755 
01756         const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |
01757                                     VCFVelocityCurve * 5;
01758         memcpy(&pData[138], &vcfvelocity, 1);
01759 
01760         const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
01761         memcpy(&pData[139], &vcftype, 1);
01762 
01763         if (chunksize >= 148) {
01764             memcpy(&pData[140], DimensionUpperLimits, 8);
01765         }
01766     }
01767 
01768     // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
01769     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
01770     {
01771         double* table;
01772         uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
01773         if (pVelocityTables->count(tableKey)) { // if key exists
01774             table = (*pVelocityTables)[tableKey];
01775         }
01776         else {
01777             table = CreateVelocityTable(curveType, depth, scaling);
01778             (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
01779         }
01780         return table;
01781     }
01782 
01783     leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
01784         leverage_ctrl_t decodedcontroller;
01785         switch (EncodedController) {
01786             // special controller
01787             case _lev_ctrl_none:
01788                 decodedcontroller.type = leverage_ctrl_t::type_none;
01789                 decodedcontroller.controller_number = 0;
01790                 break;
01791             case _lev_ctrl_velocity:
01792                 decodedcontroller.type = leverage_ctrl_t::type_velocity;
01793                 decodedcontroller.controller_number = 0;
01794                 break;
01795             case _lev_ctrl_channelaftertouch:
01796                 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
01797                 decodedcontroller.controller_number = 0;
01798                 break;
01799 
01800             // ordinary MIDI control change controller
01801             case _lev_ctrl_modwheel:
01802                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01803                 decodedcontroller.controller_number = 1;
01804                 break;
01805             case _lev_ctrl_breath:
01806                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01807                 decodedcontroller.controller_number = 2;
01808                 break;
01809             case _lev_ctrl_foot:
01810                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01811                 decodedcontroller.controller_number = 4;
01812                 break;
01813             case _lev_ctrl_effect1:
01814                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01815                 decodedcontroller.controller_number = 12;
01816                 break;
01817             case _lev_ctrl_effect2:
01818                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01819                 decodedcontroller.controller_number = 13;
01820                 break;
01821             case _lev_ctrl_genpurpose1:
01822                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01823                 decodedcontroller.controller_number = 16;
01824                 break;
01825             case _lev_ctrl_genpurpose2:
01826                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01827                 decodedcontroller.controller_number = 17;
01828                 break;
01829             case _lev_ctrl_genpurpose3:
01830                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01831                 decodedcontroller.controller_number = 18;
01832                 break;
01833             case _lev_ctrl_genpurpose4:
01834                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01835                 decodedcontroller.controller_number = 19;
01836                 break;
01837             case _lev_ctrl_portamentotime:
01838                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01839                 decodedcontroller.controller_number = 5;
01840                 break;
01841             case _lev_ctrl_sustainpedal:
01842                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01843                 decodedcontroller.controller_number = 64;
01844                 break;
01845             case _lev_ctrl_portamento:
01846                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01847                 decodedcontroller.controller_number = 65;
01848                 break;
01849             case _lev_ctrl_sostenutopedal:
01850                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01851                 decodedcontroller.controller_number = 66;
01852                 break;
01853             case _lev_ctrl_softpedal:
01854                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01855                 decodedcontroller.controller_number = 67;
01856                 break;
01857             case _lev_ctrl_genpurpose5:
01858                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01859                 decodedcontroller.controller_number = 80;
01860                 break;
01861             case _lev_ctrl_genpurpose6:
01862                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01863                 decodedcontroller.controller_number = 81;
01864                 break;
01865             case _lev_ctrl_genpurpose7:
01866                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01867                 decodedcontroller.controller_number = 82;
01868                 break;
01869             case _lev_ctrl_genpurpose8:
01870                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01871                 decodedcontroller.controller_number = 83;
01872                 break;
01873             case _lev_ctrl_effect1depth:
01874                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01875                 decodedcontroller.controller_number = 91;
01876                 break;
01877             case _lev_ctrl_effect2depth:
01878                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01879                 decodedcontroller.controller_number = 92;
01880                 break;
01881             case _lev_ctrl_effect3depth:
01882                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01883                 decodedcontroller.controller_number = 93;
01884                 break;
01885             case _lev_ctrl_effect4depth:
01886                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01887                 decodedcontroller.controller_number = 94;
01888                 break;
01889             case _lev_ctrl_effect5depth:
01890                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01891                 decodedcontroller.controller_number = 95;
01892                 break;
01893 
01894             // unknown controller type
01895             default:
01896                 throw gig::Exception("Unknown leverage controller type.");
01897         }
01898         return decodedcontroller;
01899     }
01900 
01901     DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
01902         _lev_ctrl_t encodedcontroller;
01903         switch (DecodedController.type) {
01904             // special controller
01905             case leverage_ctrl_t::type_none:
01906                 encodedcontroller = _lev_ctrl_none;
01907                 break;
01908             case leverage_ctrl_t::type_velocity:
01909                 encodedcontroller = _lev_ctrl_velocity;
01910                 break;
01911             case leverage_ctrl_t::type_channelaftertouch:
01912                 encodedcontroller = _lev_ctrl_channelaftertouch;
01913                 break;
01914 
01915             // ordinary MIDI control change controller
01916             case leverage_ctrl_t::type_controlchange:
01917                 switch (DecodedController.controller_number) {
01918                     case 1:
01919                         encodedcontroller = _lev_ctrl_modwheel;
01920                         break;
01921                     case 2:
01922                         encodedcontroller = _lev_ctrl_breath;
01923                         break;
01924                     case 4:
01925                         encodedcontroller = _lev_ctrl_foot;
01926                         break;
01927                     case 12:
01928                         encodedcontroller = _lev_ctrl_effect1;
01929                         break;
01930                     case 13:
01931                         encodedcontroller = _lev_ctrl_effect2;
01932                         break;
01933                     case 16:
01934                         encodedcontroller = _lev_ctrl_genpurpose1;
01935                         break;
01936                     case 17:
01937                         encodedcontroller = _lev_ctrl_genpurpose2;
01938                         break;
01939                     case 18:
01940                         encodedcontroller = _lev_ctrl_genpurpose3;
01941                         break;
01942                     case 19:
01943                         encodedcontroller = _lev_ctrl_genpurpose4;
01944                         break;
01945                     case 5:
01946                         encodedcontroller = _lev_ctrl_portamentotime;
01947                         break;
01948                     case 64:
01949                         encodedcontroller = _lev_ctrl_sustainpedal;
01950                         break;
01951                     case 65:
01952                         encodedcontroller = _lev_ctrl_portamento;
01953                         break;
01954                     case 66:
01955                         encodedcontroller = _lev_ctrl_sostenutopedal;
01956                         break;
01957                     case 67:
01958                         encodedcontroller = _lev_ctrl_softpedal;
01959                         break;
01960                     case 80:
01961                         encodedcontroller = _lev_ctrl_genpurpose5;
01962                         break;
01963                     case 81:
01964                         encodedcontroller = _lev_ctrl_genpurpose6;
01965                         break;
01966                     case 82:
01967                         encodedcontroller = _lev_ctrl_genpurpose7;
01968                         break;
01969                     case 83:
01970                         encodedcontroller = _lev_ctrl_genpurpose8;
01971                         break;
01972                     case 91:
01973                         encodedcontroller = _lev_ctrl_effect1depth;
01974                         break;
01975                     case 92:
01976                         encodedcontroller = _lev_ctrl_effect2depth;
01977                         break;
01978                     case 93:
01979                         encodedcontroller = _lev_ctrl_effect3depth;
01980                         break;
01981                     case 94:
01982                         encodedcontroller = _lev_ctrl_effect4depth;
01983                         break;
01984                     case 95:
01985                         encodedcontroller = _lev_ctrl_effect5depth;
01986                         break;
01987                     default:
01988                         throw gig::Exception("leverage controller number is not supported by the gig format");
01989                 }
01990             default:
01991                 throw gig::Exception("Unknown leverage controller type.");
01992         }
01993         return encodedcontroller;
01994     }
01995 
01996     DimensionRegion::~DimensionRegion() {
01997         Instances--;
01998         if (!Instances) {
01999             // delete the velocity->volume tables
02000             VelocityTableMap::iterator iter;
02001             for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
02002                 double* pTable = iter->second;
02003                 if (pTable) delete[] pTable;
02004             }
02005             pVelocityTables->clear();
02006             delete pVelocityTables;
02007             pVelocityTables = NULL;
02008         }
02009         if (VelocityTable) delete[] VelocityTable;
02010     }
02011 
02023     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
02024         return pVelocityAttenuationTable[MIDIKeyVelocity];
02025     }
02026 
02027     double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
02028         return pVelocityReleaseTable[MIDIKeyVelocity];
02029     }
02030 
02031     double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
02032         return pVelocityCutoffTable[MIDIKeyVelocity];
02033     }
02034 
02035     double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
02036 
02037         // line-segment approximations of the 15 velocity curves
02038 
02039         // linear
02040         const int lin0[] = { 1, 1, 127, 127 };
02041         const int lin1[] = { 1, 21, 127, 127 };
02042         const int lin2[] = { 1, 45, 127, 127 };
02043         const int lin3[] = { 1, 74, 127, 127 };
02044         const int lin4[] = { 1, 127, 127, 127 };
02045 
02046         // non-linear
02047         const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
02048         const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
02049                              127, 127 };
02050         const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
02051                              127, 127 };
02052         const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
02053                              127, 127 };
02054         const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
02055 
02056         // special
02057         const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
02058                              113, 127, 127, 127 };
02059         const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
02060                              118, 127, 127, 127 };
02061         const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
02062                              85, 90, 91, 127, 127, 127 };
02063         const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
02064                              117, 127, 127, 127 };
02065         const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
02066                              127, 127 };
02067 
02068         // this is only used by the VCF velocity curve
02069         const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
02070                              91, 127, 127, 127 };
02071 
02072         const int* const curves[] = { non0, non1, non2, non3, non4,
02073                                       lin0, lin1, lin2, lin3, lin4,
02074                                       spe0, spe1, spe2, spe3, spe4, spe5 };
02075 
02076         double* const table = new double[128];
02077 
02078         const int* curve = curves[curveType * 5 + depth];
02079         const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
02080 
02081         table[0] = 0;
02082         for (int x = 1 ; x < 128 ; x++) {
02083 
02084             if (x > curve[2]) curve += 2;
02085             double y = curve[1] + (x - curve[0]) *
02086                 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
02087             y = y / 127;
02088 
02089             // Scale up for s > 20, down for s < 20. When
02090             // down-scaling, the curve still ends at 1.0.
02091             if (s < 20 && y >= 0.5)
02092                 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
02093             else
02094                 y = y * (s / 20.0);
02095             if (y > 1) y = 1;
02096 
02097             table[x] = y;
02098         }
02099         return table;
02100     }
02101 
02102 
02103 // *************** Region ***************
02104 // *
02105 
02106     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
02107         pInfo->UseFixedLengthStrings = true;
02108 
02109         // Initialization
02110         Dimensions = 0;
02111         for (int i = 0; i < 256; i++) {
02112             pDimensionRegions[i] = NULL;
02113         }
02114         Layers = 1;
02115         File* file = (File*) GetParent()->GetParent();
02116         int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
02117 
02118         // Actual Loading
02119 
02120         LoadDimensionRegions(rgnList);
02121 
02122         RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
02123         if (_3lnk) {
02124             DimensionRegions = _3lnk->ReadUint32();
02125             for (int i = 0; i < dimensionBits; i++) {
02126                 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
02127                 uint8_t     bits      = _3lnk->ReadUint8();
02128                 _3lnk->ReadUint8(); // probably the position of the dimension
02129                 _3lnk->ReadUint8(); // unknown
02130                 uint8_t     zones     = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
02131                 if (dimension == dimension_none) { // inactive dimension
02132                     pDimensionDefinitions[i].dimension  = dimension_none;
02133                     pDimensionDefinitions[i].bits       = 0;
02134                     pDimensionDefinitions[i].zones      = 0;
02135                     pDimensionDefinitions[i].split_type = split_type_bit;
02136                     pDimensionDefinitions[i].zone_size  = 0;
02137                 }
02138                 else { // active dimension
02139                     pDimensionDefinitions[i].dimension = dimension;
02140                     pDimensionDefinitions[i].bits      = bits;
02141                     pDimensionDefinitions[i].zones     = zones ? zones : 0x01 << bits; // = pow(2,bits)
02142                     pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
02143                     pDimensionDefinitions[i].zone_size  = __resolveZoneSize(pDimensionDefinitions[i]);
02144                     Dimensions++;
02145 
02146                     // if this is a layer dimension, remember the amount of layers
02147                     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
02148                 }
02149                 _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
02150             }
02151             for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
02152 
02153             // if there's a velocity dimension and custom velocity zone splits are used,
02154             // update the VelocityTables in the dimension regions
02155             UpdateVelocityTable();
02156 
02157             // jump to start of the wave pool indices (if not already there)
02158             if (file->pVersion && file->pVersion->major == 3)
02159                 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
02160             else
02161                 _3lnk->SetPos(44);
02162 
02163             // load sample references
02164             for (uint i = 0; i < DimensionRegions; i++) {
02165                 uint32_t wavepoolindex = _3lnk->ReadUint32();
02166                 if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
02167             }
02168             GetSample(); // load global region sample reference
02169         } else {
02170             DimensionRegions = 0;
02171         }
02172 
02173         // make sure there is at least one dimension region
02174         if (!DimensionRegions) {
02175             RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
02176             if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
02177             RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
02178             pDimensionRegions[0] = new DimensionRegion(_3ewl);
02179             DimensionRegions = 1;
02180         }
02181     }
02182 
02192     void Region::UpdateChunks() {
02193         // in the gig format we don't care about the Region's sample reference
02194         // but we still have to provide some existing one to not corrupt the
02195         // file, so to avoid the latter we simply always assign the sample of
02196         // the first dimension region of this region
02197         pSample = pDimensionRegions[0]->pSample;
02198 
02199         // first update base class's chunks
02200         DLS::Region::UpdateChunks();
02201 
02202         // update dimension region's chunks
02203         for (int i = 0; i < DimensionRegions; i++) {
02204             pDimensionRegions[i]->UpdateChunks();
02205         }
02206 
02207         File* pFile = (File*) GetParent()->GetParent();
02208         const int iMaxDimensions = (pFile->pVersion && pFile->pVersion->major == 3) ? 8 : 5;
02209         const int iMaxDimensionRegions = (pFile->pVersion && pFile->pVersion->major == 3) ? 256 : 32;
02210 
02211         // make sure '3lnk' chunk exists
02212         RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
02213         if (!_3lnk) {
02214             const int _3lnkChunkSize = (pFile->pVersion && pFile->pVersion->major == 3) ? 1092 : 172;
02215             _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
02216         }
02217 
02218         // update dimension definitions in '3lnk' chunk
02219         uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
02220         memcpy(&pData[0], &DimensionRegions, 4);
02221         for (int i = 0; i < iMaxDimensions; i++) {
02222             pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
02223             pData[5 + i * 8] = pDimensionDefinitions[i].bits;
02224             // next 2 bytes unknown
02225             pData[8 + i * 8] = pDimensionDefinitions[i].zones;
02226             // next 3 bytes unknown
02227         }
02228 
02229         // update wave pool table in '3lnk' chunk
02230         const int iWavePoolOffset = (pFile->pVersion && pFile->pVersion->major == 3) ? 68 : 44;
02231         for (uint i = 0; i < iMaxDimensionRegions; i++) {
02232             int iWaveIndex = -1;
02233             if (i < DimensionRegions) {
02234                 if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
02235                 File::SampleList::iterator iter = pFile->pSamples->begin();
02236                 File::SampleList::iterator end  = pFile->pSamples->end();
02237                 for (int index = 0; iter != end; ++iter, ++index) {
02238                     if (*iter == pDimensionRegions[i]->pSample) {
02239                         iWaveIndex = index;
02240                         break;
02241                     }
02242                 }
02243                 if (iWaveIndex < 0) throw gig::Exception("Could not update gig::Region, could not find DimensionRegion's sample");
02244             }
02245             memcpy(&pData[iWavePoolOffset + i * 4], &iWaveIndex, 4);
02246         }
02247     }
02248 
02249     void Region::LoadDimensionRegions(RIFF::List* rgn) {
02250         RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
02251         if (_3prg) {
02252             int dimensionRegionNr = 0;
02253             RIFF::List* _3ewl = _3prg->GetFirstSubList();
02254             while (_3ewl) {
02255                 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
02256                     pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
02257                     dimensionRegionNr++;
02258                 }
02259                 _3ewl = _3prg->GetNextSubList();
02260             }
02261             if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
02262         }
02263     }
02264 
02265     void Region::UpdateVelocityTable() {
02266         // get velocity dimension's index
02267         int veldim = -1;
02268         for (int i = 0 ; i < Dimensions ; i++) {
02269             if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
02270                 veldim = i;
02271                 break;
02272             }
02273         }
02274         if (veldim == -1) return;
02275 
02276         int step = 1;
02277         for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
02278         int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
02279         int end = step * pDimensionDefinitions[veldim].zones;
02280 
02281         // loop through all dimension regions for all dimensions except the velocity dimension
02282         int dim[8] = { 0 };
02283         for (int i = 0 ; i < DimensionRegions ; i++) {
02284 
02285             if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
02286                 pDimensionRegions[i]->VelocityUpperLimit) {
02287                 // create the velocity table
02288                 uint8_t* table = pDimensionRegions[i]->VelocityTable;
02289                 if (!table) {
02290                     table = new uint8_t[128];
02291                     pDimensionRegions[i]->VelocityTable = table;
02292                 }
02293                 int tableidx = 0;
02294                 int velocityZone = 0;
02295                 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
02296                     for (int k = i ; k < end ; k += step) {
02297                         DimensionRegion *d = pDimensionRegions[k];
02298                         for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
02299                         velocityZone++;
02300                     }
02301                 } else { // gig2
02302                     for (int k = i ; k < end ; k += step) {
02303                         DimensionRegion *d = pDimensionRegions[k];
02304                         for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
02305                         velocityZone++;
02306                     }
02307                 }
02308             } else {
02309                 if (pDimensionRegions[i]->VelocityTable) {
02310                     delete[] pDimensionRegions[i]->VelocityTable;
02311                     pDimensionRegions[i]->VelocityTable = 0;
02312                 }
02313             }
02314 
02315             int j;
02316             int shift = 0;
02317             for (j = 0 ; j < Dimensions ; j++) {
02318                 if (j == veldim) i += skipveldim; // skip velocity dimension
02319                 else {
02320                     dim[j]++;
02321                     if (dim[j] < pDimensionDefinitions[j].zones) break;
02322                     else {
02323                         // skip unused dimension regions
02324                         dim[j] = 0;
02325                         i += ((1 << pDimensionDefinitions[j].bits) -
02326                               pDimensionDefinitions[j].zones) << shift;
02327                     }
02328                 }
02329                 shift += pDimensionDefinitions[j].bits;
02330             }
02331             if (j == Dimensions) break;
02332         }
02333     }
02334 
02350     void Region::AddDimension(dimension_def_t* pDimDef) {
02351         // check if max. amount of dimensions reached
02352         File* file = (File*) GetParent()->GetParent();
02353         const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
02354         if (Dimensions >= iMaxDimensions)
02355             throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
02356         // check if max. amount of dimension bits reached
02357         int iCurrentBits = 0;
02358         for (int i = 0; i < Dimensions; i++)
02359             iCurrentBits += pDimensionDefinitions[i].bits;
02360         if (iCurrentBits >= iMaxDimensions)
02361             throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
02362         const int iNewBits = iCurrentBits + pDimDef->bits;
02363         if (iNewBits > iMaxDimensions)
02364             throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
02365         // check if there's already a dimensions of the same type
02366         for (int i = 0; i < Dimensions; i++)
02367             if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
02368                 throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
02369 
02370         // assign definition of new dimension
02371         pDimensionDefinitions[Dimensions] = *pDimDef;
02372 
02373         // auto correct certain dimension definition fields (where possible)
02374         pDimensionDefinitions[Dimensions].split_type  =
02375             __resolveSplitType(pDimensionDefinitions[Dimensions].dimension);
02376         pDimensionDefinitions[Dimensions].zone_size =
02377             __resolveZoneSize(pDimensionDefinitions[Dimensions]);
02378 
02379         // create new dimension region(s) for this new dimension
02380         for (int i = 1 << iCurrentBits; i < 1 << iNewBits; i++) {
02381             //TODO: maybe we should copy existing dimension regions if possible instead of simply creating new ones with default values
02382             RIFF::List* pNewDimRgnListChunk = pCkRegion->AddSubList(LIST_TYPE_3EWL);
02383             pDimensionRegions[i] = new DimensionRegion(pNewDimRgnListChunk);
02384             DimensionRegions++;
02385         }
02386 
02387         Dimensions++;
02388 
02389         // if this is a layer dimension, update 'Layers' attribute
02390         if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
02391 
02392         UpdateVelocityTable();
02393     }
02394 
02406     void Region::DeleteDimension(dimension_def_t* pDimDef) {
02407         // get dimension's index
02408         int iDimensionNr = -1;
02409         for (int i = 0; i < Dimensions; i++) {
02410             if (&pDimensionDefinitions[i] == pDimDef) {
02411                 iDimensionNr = i;
02412                 break;
02413             }
02414         }
02415         if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
02416 
02417         // get amount of bits below the dimension to delete
02418         int iLowerBits = 0;
02419         for (int i = 0; i < iDimensionNr; i++)
02420             iLowerBits += pDimensionDefinitions[i].bits;
02421 
02422         // get amount ot bits above the dimension to delete
02423         int iUpperBits = 0;
02424         for (int i = iDimensionNr + 1; i < Dimensions; i++)
02425             iUpperBits += pDimensionDefinitions[i].bits;
02426 
02427         // delete dimension regions which belong to the given dimension
02428         // (that is where the dimension's bit > 0)
02429         for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
02430             for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
02431                 for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
02432                     int iToDelete = iUpperBit    << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
02433                                     iObsoleteBit << iLowerBits |
02434                                     iLowerBit;
02435                     delete pDimensionRegions[iToDelete];
02436                     pDimensionRegions[iToDelete] = NULL;
02437                     DimensionRegions--;
02438                 }
02439             }
02440         }
02441 
02442         // defrag pDimensionRegions array
02443         // (that is remove the NULL spaces within the pDimensionRegions array)
02444         for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
02445             if (!pDimensionRegions[iTo]) {
02446                 if (iFrom <= iTo) iFrom = iTo + 1;
02447                 while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
02448                 if (iFrom < 256 && pDimensionRegions[iFrom]) {
02449                     pDimensionRegions[iTo]   = pDimensionRegions[iFrom];
02450                     pDimensionRegions[iFrom] = NULL;
02451                 }
02452             }
02453         }
02454 
02455         // 'remove' dimension definition
02456         for (int i = iDimensionNr + 1; i < Dimensions; i++) {
02457             pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
02458         }
02459         pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
02460         pDimensionDefinitions[Dimensions - 1].bits      = 0;
02461         pDimensionDefinitions[Dimensions - 1].zones     = 0;
02462 
02463         Dimensions--;
02464 
02465         // if this was a layer dimension, update 'Layers' attribute
02466         if (pDimDef->dimension == dimension_layer) Layers = 1;
02467     }
02468 
02469     Region::~Region() {
02470         for (int i = 0; i < 256; i++) {
02471             if (pDimensionRegions[i]) delete pDimensionRegions[i];
02472         }
02473     }
02474 
02493     DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
02494         uint8_t bits;
02495         int veldim = -1;
02496         int velbitpos;
02497         int bitpos = 0;
02498         int dimregidx = 0;
02499         for (uint i = 0; i < Dimensions; i++) {
02500             if (pDimensionDefinitions[i].dimension == dimension_velocity) {
02501                 // the velocity dimension must be handled after the other dimensions
02502                 veldim = i;
02503                 velbitpos = bitpos;
02504             } else {
02505                 switch (pDimensionDefinitions[i].split_type) {
02506                     case split_type_normal:
02507                         if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
02508                             // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
02509                             for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
02510                                 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
02511                             }
02512                         } else {
02513                             // gig2: evenly sized zones
02514                             bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
02515                         }
02516                         break;
02517                     case split_type_bit: // the value is already the sought dimension bit number
02518                         const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
02519                         bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
02520                         break;
02521                 }
02522                 dimregidx |= bits << bitpos;
02523             }
02524             bitpos += pDimensionDefinitions[i].bits;
02525         }
02526         DimensionRegion* dimreg = pDimensionRegions[dimregidx];
02527         if (veldim != -1) {
02528             // (dimreg is now the dimension region for the lowest velocity)
02529             if (dimreg->VelocityTable) // custom defined zone ranges
02530                 bits = dimreg->VelocityTable[DimValues[veldim]];
02531             else // normal split type
02532                 bits = uint8_t(DimValues[veldim] / pDimensionDefinitions[veldim].zone_size);
02533 
02534             dimregidx |= bits << velbitpos;
02535             dimreg = pDimensionRegions[dimregidx];
02536         }
02537         return dimreg;
02538     }
02539 
02550     DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
02551         return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
02552                                                   << pDimensionDefinitions[5].bits | DimBits[5])
02553                                                   << pDimensionDefinitions[4].bits | DimBits[4])
02554                                                   << pDimensionDefinitions[3].bits | DimBits[3])
02555                                                   << pDimensionDefinitions[2].bits | DimBits[2])
02556                                                   << pDimensionDefinitions[1].bits | DimBits[1])
02557                                                   << pDimensionDefinitions[0].bits | DimBits[0]];
02558     }
02559 
02569     Sample* Region::GetSample() {
02570         if (pSample) return static_cast<gig::Sample*>(pSample);
02571         else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
02572     }
02573 
02574     Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
02575         if ((int32_t)WavePoolTableIndex == -1) return NULL;
02576         File* file = (File*) GetParent()->GetParent();
02577         if (!file->pWavePoolTable) return NULL;
02578         unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
02579         unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
02580         Sample* sample = file->GetFirstSample(pProgress);
02581         while (sample) {
02582             if (sample->ulWavePoolOffset == soughtoffset &&
02583                 sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
02584             sample = file->GetNextSample();
02585         }
02586         return NULL;
02587     }
02588 
02589 
02590 
02591 // *************** Instrument ***************
02592 // *
02593 
02594     Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
02595         pInfo->UseFixedLengthStrings = true;
02596 
02597         // Initialization
02598         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
02599 
02600         // Loading
02601         RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
02602         if (lart) {
02603             RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
02604             if (_3ewg) {
02605                 EffectSend             = _3ewg->ReadUint16();
02606                 Attenuation            = _3ewg->ReadInt32();
02607                 FineTune               = _3ewg->ReadInt16();
02608                 PitchbendRange         = _3ewg->ReadInt16();
02609                 uint8_t dimkeystart    = _3ewg->ReadUint8();
02610                 PianoReleaseMode       = dimkeystart & 0x01;
02611                 DimensionKeyRange.low  = dimkeystart >> 1;
02612                 DimensionKeyRange.high = _3ewg->ReadUint8();
02613             }
02614         }
02615 
02616         if (!pRegions) pRegions = new RegionList;
02617         RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
02618         if (lrgn) {
02619             RIFF::List* rgn = lrgn->GetFirstSubList();
02620             while (rgn) {
02621                 if (rgn->GetListType() == LIST_TYPE_RGN) {
02622                     __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
02623                     pRegions->push_back(new Region(this, rgn));
02624                 }
02625                 rgn = lrgn->GetNextSubList();
02626             }
02627             // Creating Region Key Table for fast lookup
02628             UpdateRegionKeyTable();
02629         }
02630 
02631         __notify_progress(pProgress, 1.0f); // notify done
02632     }
02633 
02634     void Instrument::UpdateRegionKeyTable() {
02635         RegionList::iterator iter = pRegions->begin();
02636         RegionList::iterator end  = pRegions->end();
02637         for (; iter != end; ++iter) {
02638             gig::Region* pRegion = static_cast<gig::Region*>(*iter);
02639             for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
02640                 RegionKeyTable[iKey] = pRegion;
02641             }
02642         }
02643     }
02644 
02645     Instrument::~Instrument() {
02646     }
02647 
02657     void Instrument::UpdateChunks() {
02658         // first update base classes' chunks
02659         DLS::Instrument::UpdateChunks();
02660 
02661         // update Regions' chunks
02662         {
02663             RegionList::iterator iter = pRegions->begin();
02664             RegionList::iterator end  = pRegions->end();
02665             for (; iter != end; ++iter)
02666                 (*iter)->UpdateChunks();
02667         }
02668 
02669         // make sure 'lart' RIFF list chunk exists
02670         RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
02671         if (!lart)  lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
02672         // make sure '3ewg' RIFF chunk exists
02673         RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
02674         if (!_3ewg)  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, 12);
02675         // update '3ewg' RIFF chunk
02676         uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
02677         memcpy(&pData[0], &EffectSend, 2);
02678         memcpy(&pData[2], &Attenuation, 4);
02679         memcpy(&pData[6], &FineTune, 2);
02680         memcpy(&pData[8], &PitchbendRange, 2);
02681         const uint8_t dimkeystart = (PianoReleaseMode) ? 0x01 : 0x00 |
02682                                     DimensionKeyRange.low << 1;
02683         memcpy(&pData[10], &dimkeystart, 1);
02684         memcpy(&pData[11], &DimensionKeyRange.high, 1);
02685     }
02686 
02694     Region* Instrument::GetRegion(unsigned int Key) {
02695         if (!pRegions || !pRegions->size() || Key > 127) return NULL;
02696         return RegionKeyTable[Key];
02697 
02698         /*for (int i = 0; i < Regions; i++) {
02699             if (Key <= pRegions[i]->KeyRange.high &&
02700                 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
02701         }
02702         return NULL;*/
02703     }
02704 
02712     Region* Instrument::GetFirstRegion() {
02713         if (!pRegions) return NULL;
02714         RegionsIterator = pRegions->begin();
02715         return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
02716     }
02717 
02726     Region* Instrument::GetNextRegion() {
02727         if (!pRegions) return NULL;
02728         RegionsIterator++;
02729         return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
02730     }
02731 
02732     Region* Instrument::AddRegion() {
02733         // create new Region object (and its RIFF chunks)
02734         RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
02735         if (!lrgn)  lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
02736         RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
02737         Region* pNewRegion = new Region(this, rgn);
02738         pRegions->push_back(pNewRegion);
02739         Regions = pRegions->size();
02740         // update Region key table for fast lookup
02741         UpdateRegionKeyTable();
02742         // done
02743         return pNewRegion;
02744     }
02745 
02746     void Instrument::DeleteRegion(Region* pRegion) {
02747         if (!pRegions) return;
02748         DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
02749         // update Region key table for fast lookup
02750         UpdateRegionKeyTable();
02751     }
02752 
02753 
02754 
02755 // *************** Group ***************
02756 // *
02757 
02764     Group::Group(File* file, RIFF::Chunk* ck3gnm) {
02765         pFile      = file;
02766         pNameChunk = ck3gnm;
02767         ::LoadString(pNameChunk, Name);
02768     }
02769 
02770     Group::~Group() {
02771         // remove the chunk associated with this group (if any)
02772         if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
02773     }
02774 
02783     void Group::UpdateChunks() {
02784         // make sure <3gri> and <3gnl> list chunks exist
02785         RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
02786         if (!_3gri) _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
02787         RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
02788         if (!_3gnl) _3gnl = pFile->pRIFF->AddSubList(LIST_TYPE_3GNL);
02789         // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
02790         ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
02791     }
02792 
02804     Sample* Group::GetFirstSample() {
02805         // FIXME: lazy und unsafe implementation, should be an autonomous iterator
02806         for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
02807             if (pSample->GetGroup() == this) return pSample;
02808         }
02809         return NULL;
02810     }
02811 
02822     Sample* Group::GetNextSample() {
02823         // FIXME: lazy und unsafe implementation, should be an autonomous iterator
02824         for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
02825             if (pSample->GetGroup() == this) return pSample;
02826         }
02827         return NULL;
02828     }
02829 
02833     void Group::AddSample(Sample* pSample) {
02834         pSample->pGroup = this;
02835     }
02836 
02843     void Group::MoveAll() {
02844         // get "that" other group first
02845         Group* pOtherGroup = NULL;
02846         for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
02847             if (pOtherGroup != this) break;
02848         }
02849         if (!pOtherGroup) throw Exception(
02850             "Could not move samples to another group, since there is no "
02851             "other Group. This is a bug, report it!"
02852         );
02853         // now move all samples of this group to the other group
02854         for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
02855             pOtherGroup->AddSample(pSample);
02856         }
02857     }
02858 
02859 
02860 
02861 // *************** File ***************
02862 // *
02863 
02864     File::File() : DLS::File() {
02865         pGroups = NULL;
02866         pInfo->UseFixedLengthStrings = true;
02867     }
02868 
02869     File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
02870         pGroups = NULL;
02871         pInfo->UseFixedLengthStrings = true;
02872     }
02873 
02874     File::~File() {
02875         if (pGroups) {
02876             std::list<Group*>::iterator iter = pGroups->begin();
02877             std::list<Group*>::iterator end  = pGroups->end();
02878             while (iter != end) {
02879                 delete *iter;
02880                 ++iter;
02881             }
02882             delete pGroups;
02883         }
02884     }
02885 
02886     Sample* File::GetFirstSample(progress_t* pProgress) {
02887         if (!pSamples) LoadSamples(pProgress);
02888         if (!pSamples) return NULL;
02889         SamplesIterator = pSamples->begin();
02890         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
02891     }
02892 
02893     Sample* File::GetNextSample() {
02894         if (!pSamples) return NULL;
02895         SamplesIterator++;
02896         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
02897     }
02898 
02906     Sample* File::AddSample() {
02907        if (!pSamples) LoadSamples();
02908        __ensureMandatoryChunksExist();
02909        RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
02910        // create new Sample object and its respective 'wave' list chunk
02911        RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
02912        Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
02913        pSamples->push_back(pSample);
02914        return pSample;
02915     }
02916 
02925     void File::DeleteSample(Sample* pSample) {
02926         if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
02927         SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
02928         if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
02929         if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
02930         pSamples->erase(iter);
02931         delete pSample;
02932     }
02933 
02934     void File::LoadSamples() {
02935         LoadSamples(NULL);
02936     }
02937 
02938     void File::LoadSamples(progress_t* pProgress) {
02939         // Groups must be loaded before samples, because samples will try
02940         // to resolve the group they belong to
02941         LoadGroups();
02942 
02943         if (!pSamples) pSamples = new SampleList;
02944 
02945         RIFF::File* file = pRIFF;
02946 
02947         // just for progress calculation
02948         int iSampleIndex  = 0;
02949         int iTotalSamples = WavePoolCount;
02950 
02951         // check if samples should be loaded from extension files
02952         int lastFileNo = 0;
02953         for (int i = 0 ; i < WavePoolCount ; i++) {
02954             if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
02955         }
02956         String name(pRIFF->GetFileName());
02957         int nameLen = name.length();
02958         char suffix[6];
02959         if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
02960 
02961         for (int fileNo = 0 ; ; ) {
02962             RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
02963             if (wvpl) {
02964                 unsigned long wvplFileOffset = wvpl->GetFilePos();
02965                 RIFF::List* wave = wvpl->GetFirstSubList();
02966                 while (wave) {
02967                     if (wave->GetListType() == LIST_TYPE_WAVE) {
02968                         // notify current progress
02969                         const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
02970                         __notify_progress(pProgress, subprogress);
02971 
02972                         unsigned long waveFileOffset = wave->GetFilePos();
02973                         pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
02974 
02975                         iSampleIndex++;
02976                     }
02977                     wave = wvpl->GetNextSubList();
02978                 }
02979 
02980                 if (fileNo == lastFileNo) break;
02981 
02982                 // open extension file (*.gx01, *.gx02, ...)
02983                 fileNo++;
02984                 sprintf(suffix, ".gx%02d", fileNo);
02985                 name.replace(nameLen, 5, suffix);
02986                 file = new RIFF::File(name);
02987                 ExtensionFiles.push_back(file);
02988             } else break;
02989         }
02990 
02991         __notify_progress(pProgress, 1.0); // notify done
02992     }
02993 
02994     Instrument* File::GetFirstInstrument() {
02995         if (!pInstruments) LoadInstruments();
02996         if (!pInstruments) return NULL;
02997         InstrumentsIterator = pInstruments->begin();
02998         return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
02999     }
03000 
03001     Instrument* File::GetNextInstrument() {
03002         if (!pInstruments) return NULL;
03003         InstrumentsIterator++;
03004         return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
03005     }
03006 
03014     Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
03015         if (!pInstruments) {
03016             // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
03017 
03018             // sample loading subtask
03019             progress_t subprogress;
03020             __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
03021             __notify_progress(&subprogress, 0.0f);
03022             GetFirstSample(&subprogress); // now force all samples to be loaded
03023             __notify_progress(&subprogress, 1.0f);
03024 
03025             // instrument loading subtask
03026             if (pProgress && pProgress->callback) {
03027                 subprogress.__range_min = subprogress.__range_max;
03028                 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
03029             }
03030             __notify_progress(&subprogress, 0.0f);
03031             LoadInstruments(&subprogress);
03032             __notify_progress(&subprogress, 1.0f);
03033         }
03034         if (!pInstruments) return NULL;
03035         InstrumentsIterator = pInstruments->begin();
03036         for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
03037             if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
03038             InstrumentsIterator++;
03039         }
03040         return NULL;
03041     }
03042 
03050     Instrument* File::AddInstrument() {
03051        if (!pInstruments) LoadInstruments();
03052        __ensureMandatoryChunksExist();
03053        RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
03054        RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
03055        Instrument* pInstrument = new Instrument(this, lstInstr);
03056        pInstruments->push_back(pInstrument);
03057        return pInstrument;
03058     }
03059 
03068     void File::DeleteInstrument(Instrument* pInstrument) {
03069         if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
03070         InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
03071         if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
03072         pInstruments->erase(iter);
03073         delete pInstrument;
03074     }
03075 
03076     void File::LoadInstruments() {
03077         LoadInstruments(NULL);
03078     }
03079 
03080     void File::LoadInstruments(progress_t* pProgress) {
03081         if (!pInstruments) pInstruments = new InstrumentList;
03082         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
03083         if (lstInstruments) {
03084             int iInstrumentIndex = 0;
03085             RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
03086             while (lstInstr) {
03087                 if (lstInstr->GetListType() == LIST_TYPE_INS) {
03088                     // notify current progress
03089                     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
03090                     __notify_progress(pProgress, localProgress);
03091 
03092                     // divide local progress into subprogress for loading current Instrument
03093                     progress_t subprogress;
03094                     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
03095 
03096                     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
03097 
03098                     iInstrumentIndex++;
03099                 }
03100                 lstInstr = lstInstruments->GetNextSubList();
03101             }
03102             __notify_progress(pProgress, 1.0); // notify done
03103         }
03104     }
03105 
03106     Group* File::GetFirstGroup() {
03107         if (!pGroups) LoadGroups();
03108         // there must always be at least one group
03109         GroupsIterator = pGroups->begin();
03110         return *GroupsIterator;
03111     }
03112 
03113     Group* File::GetNextGroup() {
03114         if (!pGroups) return NULL;
03115         ++GroupsIterator;
03116         return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
03117     }
03118 
03125     Group* File::GetGroup(uint index) {
03126         if (!pGroups) LoadGroups();
03127         GroupsIterator = pGroups->begin();
03128         for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
03129             if (i == index) return *GroupsIterator;
03130             ++GroupsIterator;
03131         }
03132         return NULL;
03133     }
03134 
03135     Group* File::AddGroup() {
03136         if (!pGroups) LoadGroups();
03137         // there must always be at least one group
03138         __ensureMandatoryChunksExist();
03139         Group* pGroup = new Group(this, NULL);
03140         pGroups->push_back(pGroup);
03141         return pGroup;
03142     }
03143 
03153     void File::DeleteGroup(Group* pGroup) {
03154         if (!pGroups) LoadGroups();
03155         std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
03156         if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
03157         if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
03158         // delete all members of this group
03159         for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
03160             DeleteSample(pSample);
03161         }
03162         // now delete this group object
03163         pGroups->erase(iter);
03164         delete pGroup;
03165     }
03166 
03177     void File::DeleteGroupOnly(Group* pGroup) {
03178         if (!pGroups) LoadGroups();
03179         std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
03180         if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
03181         if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
03182         // move all members of this group to another group
03183         pGroup->MoveAll();
03184         pGroups->erase(iter);
03185         delete pGroup;
03186     }
03187 
03188     void File::LoadGroups() {
03189         if (!pGroups) pGroups = new std::list<Group*>;
03190         // try to read defined groups from file
03191         RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
03192         if (lst3gri) {
03193             RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
03194             if (lst3gnl) {
03195                 RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
03196                 while (ck) {
03197                     if (ck->GetChunkID() == CHUNK_ID_3GNM) {
03198                         pGroups->push_back(new Group(this, ck));
03199                     }
03200                     ck = lst3gnl->GetNextSubChunk();
03201                 }
03202             }
03203         }
03204         // if there were no group(s), create at least the mandatory default group
03205         if (!pGroups->size()) {
03206             Group* pGroup = new Group(this, NULL);
03207             pGroup->Name = "Default Group";
03208             pGroups->push_back(pGroup);
03209         }
03210     }
03211 
03222     void File::UpdateChunks() {
03223         // first update base class's chunks
03224         DLS::File::UpdateChunks();
03225 
03226         // update group's chunks
03227         if (pGroups) {
03228             std::list<Group*>::iterator iter = pGroups->begin();
03229             std::list<Group*>::iterator end  = pGroups->end();
03230             for (; iter != end; ++iter) {
03231                 (*iter)->UpdateChunks();
03232             }
03233         }
03234     }
03235 
03236 
03237 
03238 // *************** Exception ***************
03239 // *
03240 
03241     Exception::Exception(String Message) : DLS::Exception(Message) {
03242     }
03243 
03244     void Exception::PrintMessage() {
03245         std::cout << "gig::Exception: " << Message << std::endl;
03246     }
03247 
03248 
03249 // *************** functions ***************
03250 // *
03251 
03257     String libraryName() {
03258         return PACKAGE;
03259     }
03260 
03265     String libraryVersion() {
03266         return VERSION;
03267     }
03268 
03269 } // namespace gig

Generated on Thu Aug 16 10:13:49 2007 for libgig by  doxygen 1.5.3