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

Generated on Wed Dec 6 19:25:57 2006 for libgig by  doxygen 1.5.1