gig.cpp

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

Generated on Tue Jul 8 10:08:18 2008 for libgig by  doxygen 1.4.7