Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

gig.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libgig - C++ cross-platform Gigasampler format file loader library    *
00004  *                                                                         *
00005  *   Copyright (C) 2003-2005 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 <iostream>
00027 
00028 namespace gig {
00029 
00030 // *************** progress_t ***************
00031 // *
00032 
00033     progress_t::progress_t() {
00034         callback    = NULL;
00035         custom      = NULL;
00036         __range_min = 0.0f;
00037         __range_max = 1.0f;
00038     }
00039 
00040     // private helper function to convert progress of a subprocess into the global progress
00041     static void __notify_progress(progress_t* pProgress, float subprogress) {
00042         if (pProgress && pProgress->callback) {
00043             const float totalrange    = pProgress->__range_max - pProgress->__range_min;
00044             const float totalprogress = pProgress->__range_min + subprogress * totalrange;
00045             pProgress->factor         = totalprogress;
00046             pProgress->callback(pProgress); // now actually notify about the progress
00047         }
00048     }
00049 
00050     // private helper function to divide a progress into subprogresses
00051     static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) {
00052         if (pParentProgress && pParentProgress->callback) {
00053             const float totalrange    = pParentProgress->__range_max - pParentProgress->__range_min;
00054             pSubProgress->callback    = pParentProgress->callback;
00055             pSubProgress->custom      = pParentProgress->custom;
00056             pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks;
00057             pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks;
00058         }
00059     }
00060 
00061 
00062 // *************** Internal functions for sample decopmression ***************
00063 // *
00064 
00065 namespace {
00066 
00067     inline int get12lo(const unsigned char* pSrc)
00068     {
00069         const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
00070         return x & 0x800 ? x - 0x1000 : x;
00071     }
00072 
00073     inline int get12hi(const unsigned char* pSrc)
00074     {
00075         const int x = pSrc[1] >> 4 | pSrc[2] << 4;
00076         return x & 0x800 ? x - 0x1000 : x;
00077     }
00078 
00079     inline int16_t get16(const unsigned char* pSrc)
00080     {
00081         return int16_t(pSrc[0] | pSrc[1] << 8);
00082     }
00083 
00084     inline int get24(const unsigned char* pSrc)
00085     {
00086         const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
00087         return x & 0x800000 ? x - 0x1000000 : x;
00088     }
00089 
00090     void Decompress16(int compressionmode, const unsigned char* params,
00091                       int srcStep, int dstStep,
00092                       const unsigned char* pSrc, int16_t* pDst,
00093                       unsigned long currentframeoffset,
00094                       unsigned long copysamples)
00095     {
00096         switch (compressionmode) {
00097             case 0: // 16 bit uncompressed
00098                 pSrc += currentframeoffset * srcStep;
00099                 while (copysamples) {
00100                     *pDst = get16(pSrc);
00101                     pDst += dstStep;
00102                     pSrc += srcStep;
00103                     copysamples--;
00104                 }
00105                 break;
00106 
00107             case 1: // 16 bit compressed to 8 bit
00108                 int y  = get16(params);
00109                 int dy = get16(params + 2);
00110                 while (currentframeoffset) {
00111                     dy -= int8_t(*pSrc);
00112                     y  -= dy;
00113                     pSrc += srcStep;
00114                     currentframeoffset--;
00115                 }
00116                 while (copysamples) {
00117                     dy -= int8_t(*pSrc);
00118                     y  -= dy;
00119                     *pDst = y;
00120                     pDst += dstStep;
00121                     pSrc += srcStep;
00122                     copysamples--;
00123                 }
00124                 break;
00125         }
00126     }
00127 
00128     void Decompress24(int compressionmode, const unsigned char* params,
00129                       int dstStep, const unsigned char* pSrc, int16_t* pDst,
00130                       unsigned long currentframeoffset,
00131                       unsigned long copysamples, int truncatedBits)
00132     {
00133         // Note: The 24 bits are truncated to 16 bits for now.
00134 
00135         // Note: The calculation of the initial value of y is strange
00136         // and not 100% correct. What should the first two parameters
00137         // really be used for? Why are they two? The correct value for
00138         // y seems to lie somewhere between the values of the first
00139         // two parameters.
00140         //
00141         // Strange thing #2: The formula in SKIP_ONE gives values for
00142         // y that are twice as high as they should be. That's why
00143         // COPY_ONE shifts an extra step, and also why y is
00144         // initialized with a sum instead of a mean value.
00145 
00146         int y, dy, ddy;
00147 
00148         const int shift = 8 - truncatedBits;
00149         const int shift1 = shift + 1;
00150 
00151 #define GET_PARAMS(params)                              \
00152         y = (get24(params) + get24((params) + 3));      \
00153         dy  = get24((params) + 6);                      \
00154         ddy = get24((params) + 9)
00155 
00156 #define SKIP_ONE(x)                             \
00157         ddy -= (x);                             \
00158         dy -= ddy;                              \
00159         y -= dy
00160 
00161 #define COPY_ONE(x)                             \
00162         SKIP_ONE(x);                            \
00163         *pDst = y >> shift1;                    \
00164         pDst += dstStep
00165 
00166         switch (compressionmode) {
00167             case 2: // 24 bit uncompressed
00168                 pSrc += currentframeoffset * 3;
00169                 while (copysamples) {
00170                     *pDst = get24(pSrc) >> shift;
00171                     pDst += dstStep;
00172                     pSrc += 3;
00173                     copysamples--;
00174                 }
00175                 break;
00176 
00177             case 3: // 24 bit compressed to 16 bit
00178                 GET_PARAMS(params);
00179                 while (currentframeoffset) {
00180                     SKIP_ONE(get16(pSrc));
00181                     pSrc += 2;
00182                     currentframeoffset--;
00183                 }
00184                 while (copysamples) {
00185                     COPY_ONE(get16(pSrc));
00186                     pSrc += 2;
00187                     copysamples--;
00188                 }
00189                 break;
00190 
00191             case 4: // 24 bit compressed to 12 bit
00192                 GET_PARAMS(params);
00193                 while (currentframeoffset > 1) {
00194                     SKIP_ONE(get12lo(pSrc));
00195                     SKIP_ONE(get12hi(pSrc));
00196                     pSrc += 3;
00197                     currentframeoffset -= 2;
00198                 }
00199                 if (currentframeoffset) {
00200                     SKIP_ONE(get12lo(pSrc));
00201                     currentframeoffset--;
00202                     if (copysamples) {
00203                         COPY_ONE(get12hi(pSrc));
00204                         pSrc += 3;
00205                         copysamples--;
00206                     }
00207                 }
00208                 while (copysamples > 1) {
00209                     COPY_ONE(get12lo(pSrc));
00210                     COPY_ONE(get12hi(pSrc));
00211                     pSrc += 3;
00212                     copysamples -= 2;
00213                 }
00214                 if (copysamples) {
00215                     COPY_ONE(get12lo(pSrc));
00216                 }
00217                 break;
00218 
00219             case 5: // 24 bit compressed to 8 bit
00220                 GET_PARAMS(params);
00221                 while (currentframeoffset) {
00222                     SKIP_ONE(int8_t(*pSrc++));
00223                     currentframeoffset--;
00224                 }
00225                 while (copysamples) {
00226                     COPY_ONE(int8_t(*pSrc++));
00227                     copysamples--;
00228                 }
00229                 break;
00230         }
00231     }
00232 
00233     const int bytesPerFrame[] =      { 4096, 2052, 768, 524, 396, 268 };
00234     const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
00235     const int headerSize[] =         { 0, 4, 0, 12, 12, 12 };
00236     const int bitsPerSample[] =      { 16, 8, 24, 16, 12, 8 };
00237 }
00238 
00239 
00240 // *************** Sample ***************
00241 // *
00242 
00243     unsigned int Sample::Instances = 0;
00244     buffer_t     Sample::InternalDecompressionBuffer;
00245 
00246     Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
00247         Instances++;
00248 
00249         RIFF::Chunk* _3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
00250         if (!_3gix) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
00251         SampleGroup = _3gix->ReadInt16();
00252 
00253         RIFF::Chunk* smpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
00254         if (!smpl) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
00255         Manufacturer      = smpl->ReadInt32();
00256         Product           = smpl->ReadInt32();
00257         SamplePeriod      = smpl->ReadInt32();
00258         MIDIUnityNote     = smpl->ReadInt32();
00259         FineTune          = smpl->ReadInt32();
00260         smpl->Read(&SMPTEFormat, 1, 4);
00261         SMPTEOffset       = smpl->ReadInt32();
00262         Loops             = smpl->ReadInt32();
00263         smpl->ReadInt32(); // manufByt
00264         LoopID            = smpl->ReadInt32();
00265         smpl->Read(&LoopType, 1, 4);
00266         LoopStart         = smpl->ReadInt32();
00267         LoopEnd           = smpl->ReadInt32();
00268         LoopFraction      = smpl->ReadInt32();
00269         LoopPlayCount     = smpl->ReadInt32();
00270 
00271         FrameTable                 = NULL;
00272         SamplePos                  = 0;
00273         RAMCache.Size              = 0;
00274         RAMCache.pStart            = NULL;
00275         RAMCache.NullExtensionSize = 0;
00276 
00277         if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
00278 
00279         RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
00280         Compressed        = ewav;
00281         Dithered          = false;
00282         TruncatedBits     = 0;
00283         if (Compressed) {
00284             uint32_t version = ewav->ReadInt32();
00285             if (version == 3 && BitDepth == 24) {
00286                 Dithered = ewav->ReadInt32();
00287                 ewav->SetPos(Channels == 2 ? 84 : 64);
00288                 TruncatedBits = ewav->ReadInt32();
00289             }
00290             ScanCompressedSample();
00291         }
00292 
00293         // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
00294         if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
00295             InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
00296             InternalDecompressionBuffer.Size   = INITIAL_SAMPLE_BUFFER_SIZE;
00297         }
00298         FrameOffset = 0; // just for streaming compressed samples
00299 
00300         LoopSize = LoopEnd - LoopStart;
00301     }
00302 
00304     void Sample::ScanCompressedSample() {
00305         //TODO: we have to add some more scans here (e.g. determine compression rate)
00306         this->SamplesTotal = 0;
00307         std::list<unsigned long> frameOffsets;
00308 
00309         SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
00310         WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
00311 
00312         // Scanning
00313         pCkData->SetPos(0);
00314         if (Channels == 2) { // Stereo
00315             for (int i = 0 ; ; i++) {
00316                 // for 24 bit samples every 8:th frame offset is
00317                 // stored, to save some memory
00318                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00319 
00320                 const int mode_l = pCkData->ReadUint8();
00321                 const int mode_r = pCkData->ReadUint8();
00322                 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
00323                 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
00324 
00325                 if (pCkData->RemainingBytes() <= frameSize) {
00326                     SamplesInLastFrame =
00327                         ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
00328                         (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
00329                     SamplesTotal += SamplesInLastFrame;
00330                     break;
00331                 }
00332                 SamplesTotal += SamplesPerFrame;
00333                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00334             }
00335         }
00336         else { // Mono
00337             for (int i = 0 ; ; i++) {
00338                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00339 
00340                 const int mode = pCkData->ReadUint8();
00341                 if (mode > 5) throw gig::Exception("Unknown compression mode");
00342                 const unsigned long frameSize = bytesPerFrame[mode];
00343 
00344                 if (pCkData->RemainingBytes() <= frameSize) {
00345                     SamplesInLastFrame =
00346                         ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
00347                     SamplesTotal += SamplesInLastFrame;
00348                     break;
00349                 }
00350                 SamplesTotal += SamplesPerFrame;
00351                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00352             }
00353         }
00354         pCkData->SetPos(0);
00355 
00356         // Build the frames table (which is used for fast resolving of a frame's chunk offset)
00357         if (FrameTable) delete[] FrameTable;
00358         FrameTable = new unsigned long[frameOffsets.size()];
00359         std::list<unsigned long>::iterator end  = frameOffsets.end();
00360         std::list<unsigned long>::iterator iter = frameOffsets.begin();
00361         for (int i = 0; iter != end; i++, iter++) {
00362             FrameTable[i] = *iter;
00363         }
00364     }
00365 
00375     buffer_t Sample::LoadSampleData() {
00376         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
00377     }
00378 
00401     buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
00402         return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
00403     }
00404 
00424     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
00425         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
00426     }
00427 
00460     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
00461         if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
00462         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00463         unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
00464         RAMCache.pStart            = new int8_t[allocationsize];
00465         RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
00466         RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
00467         // fill the remaining buffer space with silence samples
00468         memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
00469         return GetCache();
00470     }
00471 
00482     buffer_t Sample::GetCache() {
00483         // return a copy of the buffer_t structure
00484         buffer_t result;
00485         result.Size              = this->RAMCache.Size;
00486         result.pStart            = this->RAMCache.pStart;
00487         result.NullExtensionSize = this->RAMCache.NullExtensionSize;
00488         return result;
00489     }
00490 
00497     void Sample::ReleaseSampleData() {
00498         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00499         RAMCache.pStart = NULL;
00500         RAMCache.Size   = 0;
00501     }
00502 
00524     unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
00525         if (Compressed) {
00526             switch (Whence) {
00527                 case RIFF::stream_curpos:
00528                     this->SamplePos += SampleCount;
00529                     break;
00530                 case RIFF::stream_end:
00531                     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
00532                     break;
00533                 case RIFF::stream_backward:
00534                     this->SamplePos -= SampleCount;
00535                     break;
00536                 case RIFF::stream_start: default:
00537                     this->SamplePos = SampleCount;
00538                     break;
00539             }
00540             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00541 
00542             unsigned long frame = this->SamplePos / 2048; // to which frame to jump
00543             this->FrameOffset   = this->SamplePos % 2048; // offset (in sample points) within that frame
00544             pCkData->SetPos(FrameTable[frame]);           // set chunk pointer to the start of sought frame
00545             return this->SamplePos;
00546         }
00547         else { // not compressed
00548             unsigned long orderedBytes = SampleCount * this->FrameSize;
00549             unsigned long result = pCkData->SetPos(orderedBytes, Whence);
00550             return (result == orderedBytes) ? SampleCount
00551                                             : result / this->FrameSize;
00552         }
00553     }
00554 
00558     unsigned long Sample::GetPos() {
00559         if (Compressed) return SamplePos;
00560         else            return pCkData->GetPos() / FrameSize;
00561     }
00562 
00596     unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, buffer_t* pExternalDecompressionBuffer) {
00597         unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
00598         uint8_t* pDst = (uint8_t*) pBuffer;
00599 
00600         SetPos(pPlaybackState->position); // recover position from the last time
00601 
00602         if (this->Loops && GetPos() <= this->LoopEnd) { // honor looping if there are loop points defined
00603 
00604             switch (this->LoopType) {
00605 
00606                 case loop_type_bidirectional: { //TODO: not tested yet!
00607                     do {
00608                         // if not endless loop check if max. number of loop cycles have been passed
00609                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00610 
00611                         if (!pPlaybackState->reverse) { // forward playback
00612                             do {
00613                                 samplestoloopend  = this->LoopEnd - GetPos();
00614                                 readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00615                                 samplestoread    -= readsamples;
00616                                 totalreadsamples += readsamples;
00617                                 if (readsamples == samplestoloopend) {
00618                                     pPlaybackState->reverse = true;
00619                                     break;
00620                                 }
00621                             } while (samplestoread && readsamples);
00622                         }
00623                         else { // backward playback
00624 
00625                             // as we can only read forward from disk, we have to
00626                             // determine the end position within the loop first,
00627                             // read forward from that 'end' and finally after
00628                             // reading, swap all sample frames so it reflects
00629                             // backward playback
00630 
00631                             unsigned long swapareastart       = totalreadsamples;
00632                             unsigned long loopoffset          = GetPos() - this->LoopStart;
00633                             unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
00634                             unsigned long reverseplaybackend  = GetPos() - samplestoreadinloop;
00635 
00636                             SetPos(reverseplaybackend);
00637 
00638                             // read samples for backward playback
00639                             do {
00640                                 readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
00641                                 samplestoreadinloop -= readsamples;
00642                                 samplestoread       -= readsamples;
00643                                 totalreadsamples    += readsamples;
00644                             } while (samplestoreadinloop && readsamples);
00645 
00646                             SetPos(reverseplaybackend); // pretend we really read backwards
00647 
00648                             if (reverseplaybackend == this->LoopStart) {
00649                                 pPlaybackState->loop_cycles_left--;
00650                                 pPlaybackState->reverse = false;
00651                             }
00652 
00653                             // reverse the sample frames for backward playback
00654                             SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00655                         }
00656                     } while (samplestoread && readsamples);
00657                     break;
00658                 }
00659 
00660                 case loop_type_backward: { // TODO: not tested yet!
00661                     // forward playback (not entered the loop yet)
00662                     if (!pPlaybackState->reverse) do {
00663                         samplestoloopend  = this->LoopEnd - GetPos();
00664                         readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00665                         samplestoread    -= readsamples;
00666                         totalreadsamples += readsamples;
00667                         if (readsamples == samplestoloopend) {
00668                             pPlaybackState->reverse = true;
00669                             break;
00670                         }
00671                     } while (samplestoread && readsamples);
00672 
00673                     if (!samplestoread) break;
00674 
00675                     // as we can only read forward from disk, we have to
00676                     // determine the end position within the loop first,
00677                     // read forward from that 'end' and finally after
00678                     // reading, swap all sample frames so it reflects
00679                     // backward playback
00680 
00681                     unsigned long swapareastart       = totalreadsamples;
00682                     unsigned long loopoffset          = GetPos() - this->LoopStart;
00683                     unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * LoopSize - loopoffset)
00684                                                                               : samplestoread;
00685                     unsigned long reverseplaybackend  = this->LoopStart + Abs((loopoffset - samplestoreadinloop) % this->LoopSize);
00686 
00687                     SetPos(reverseplaybackend);
00688 
00689                     // read samples for backward playback
00690                     do {
00691                         // if not endless loop check if max. number of loop cycles have been passed
00692                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00693                         samplestoloopend     = this->LoopEnd - GetPos();
00694                         readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
00695                         samplestoreadinloop -= readsamples;
00696                         samplestoread       -= readsamples;
00697                         totalreadsamples    += readsamples;
00698                         if (readsamples == samplestoloopend) {
00699                             pPlaybackState->loop_cycles_left--;
00700                             SetPos(this->LoopStart);
00701                         }
00702                     } while (samplestoreadinloop && readsamples);
00703 
00704                     SetPos(reverseplaybackend); // pretend we really read backwards
00705 
00706                     // reverse the sample frames for backward playback
00707                     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00708                     break;
00709                 }
00710 
00711                 default: case loop_type_normal: {
00712                     do {
00713                         // if not endless loop check if max. number of loop cycles have been passed
00714                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00715                         samplestoloopend  = this->LoopEnd - GetPos();
00716                         readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00717                         samplestoread    -= readsamples;
00718                         totalreadsamples += readsamples;
00719                         if (readsamples == samplestoloopend) {
00720                             pPlaybackState->loop_cycles_left--;
00721                             SetPos(this->LoopStart);
00722                         }
00723                     } while (samplestoread && readsamples);
00724                     break;
00725                 }
00726             }
00727         }
00728 
00729         // read on without looping
00730         if (samplestoread) do {
00731             readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
00732             samplestoread    -= readsamples;
00733             totalreadsamples += readsamples;
00734         } while (readsamples && samplestoread);
00735 
00736         // store current position
00737         pPlaybackState->position = GetPos();
00738 
00739         return totalreadsamples;
00740     }
00741 
00760     unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
00761         if (SampleCount == 0) return 0;
00762         if (!Compressed) {
00763             if (BitDepth == 24) {
00764                 // 24 bit sample. For now just truncate to 16 bit.
00765                 unsigned char* pSrc = (unsigned char*) ((pExternalDecompressionBuffer) ? pExternalDecompressionBuffer->pStart : this->InternalDecompressionBuffer.pStart);
00766                 int16_t* pDst = static_cast<int16_t*>(pBuffer);
00767                 if (Channels == 2) { // Stereo
00768                     unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 6, 1);
00769                     pSrc++;
00770                     for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
00771                         *pDst++ = get16(pSrc);
00772                         pSrc += 3;
00773                     }
00774                     return (pDst - static_cast<int16_t*>(pBuffer)) >> 1;
00775                 }
00776                 else { // Mono
00777                     unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 3, 1);
00778                     pSrc++;
00779                     for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
00780                         *pDst++ = get16(pSrc);
00781                         pSrc += 3;
00782                     }
00783                     return pDst - static_cast<int16_t*>(pBuffer);
00784                 }
00785             }
00786             else { // 16 bit
00787                 // (pCkData->Read does endian correction)
00788                 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
00789                                      : pCkData->Read(pBuffer, SampleCount, 2);
00790             }
00791         }
00792         else {
00793             if (this->SamplePos >= this->SamplesTotal) return 0;
00794             //TODO: efficiency: maybe we should test for an average compression rate
00795             unsigned long assumedsize      = GuessSize(SampleCount),
00796                           remainingbytes   = 0,           // remaining bytes in the local buffer
00797                           remainingsamples = SampleCount,
00798                           copysamples, skipsamples,
00799                           currentframeoffset = this->FrameOffset;  // offset in current sample frame since last Read()
00800             this->FrameOffset = 0;
00801 
00802             buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
00803 
00804             // if decompression buffer too small, then reduce amount of samples to read
00805             if (pDecompressionBuffer->Size < assumedsize) {
00806                 std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
00807                 SampleCount      = WorstCaseMaxSamples(pDecompressionBuffer);
00808                 remainingsamples = SampleCount;
00809                 assumedsize      = GuessSize(SampleCount);
00810             }
00811 
00812             unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
00813             int16_t* pDst = static_cast<int16_t*>(pBuffer);
00814             remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
00815 
00816             while (remainingsamples && remainingbytes) {
00817                 unsigned long framesamples = SamplesPerFrame;
00818                 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
00819 
00820                 int mode_l = *pSrc++, mode_r = 0;
00821 
00822                 if (Channels == 2) {
00823                     mode_r = *pSrc++;
00824                     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
00825                     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
00826                     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
00827                     if (remainingbytes < framebytes) { // last frame in sample
00828                         framesamples = SamplesInLastFrame;
00829                         if (mode_l == 4 && (framesamples & 1)) {
00830                             rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
00831                         }
00832                         else {
00833                             rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
00834                         }
00835                     }
00836                 }
00837                 else {
00838                     framebytes = bytesPerFrame[mode_l] + 1;
00839                     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
00840                     if (remainingbytes < framebytes) {
00841                         framesamples = SamplesInLastFrame;
00842                     }
00843                 }
00844 
00845                 // determine how many samples in this frame to skip and read
00846                 if (currentframeoffset + remainingsamples >= framesamples) {
00847                     if (currentframeoffset <= framesamples) {
00848                         copysamples = framesamples - currentframeoffset;
00849                         skipsamples = currentframeoffset;
00850                     }
00851                     else {
00852                         copysamples = 0;
00853                         skipsamples = framesamples;
00854                     }
00855                 }
00856                 else {
00857                     // This frame has enough data for pBuffer, but not
00858                     // all of the frame is needed. Set file position
00859                     // to start of this frame for next call to Read.
00860                     copysamples = remainingsamples;
00861                     skipsamples = currentframeoffset;
00862                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00863                     this->FrameOffset = currentframeoffset + copysamples;
00864                 }
00865                 remainingsamples -= copysamples;
00866 
00867                 if (remainingbytes > framebytes) {
00868                     remainingbytes -= framebytes;
00869                     if (remainingsamples == 0 &&
00870                         currentframeoffset + copysamples == framesamples) {
00871                         // This frame has enough data for pBuffer, and
00872                         // all of the frame is needed. Set file
00873                         // position to start of next frame for next
00874                         // call to Read. FrameOffset is 0.
00875                         pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00876                     }
00877                 }
00878                 else remainingbytes = 0;
00879 
00880                 currentframeoffset -= skipsamples;
00881 
00882                 if (copysamples == 0) {
00883                     // skip this frame
00884                     pSrc += framebytes - Channels;
00885                 }
00886                 else {
00887                     const unsigned char* const param_l = pSrc;
00888                     if (BitDepth == 24) {
00889                         if (mode_l != 2) pSrc += 12;
00890 
00891                         if (Channels == 2) { // Stereo
00892                             const unsigned char* const param_r = pSrc;
00893                             if (mode_r != 2) pSrc += 12;
00894 
00895                             Decompress24(mode_l, param_l, 2, pSrc, pDst,
00896                                          skipsamples, copysamples, TruncatedBits);
00897                             Decompress24(mode_r, param_r, 2, pSrc + rightChannelOffset, pDst + 1,
00898                                          skipsamples, copysamples, TruncatedBits);
00899                             pDst += copysamples << 1;
00900                         }
00901                         else { // Mono
00902                             Decompress24(mode_l, param_l, 1, pSrc, pDst,
00903                                          skipsamples, copysamples, TruncatedBits);
00904                             pDst += copysamples;
00905                         }
00906                     }
00907                     else { // 16 bit
00908                         if (mode_l) pSrc += 4;
00909 
00910                         int step;
00911                         if (Channels == 2) { // Stereo
00912                             const unsigned char* const param_r = pSrc;
00913                             if (mode_r) pSrc += 4;
00914 
00915                             step = (2 - mode_l) + (2 - mode_r);
00916                             Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
00917                             Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
00918                                          skipsamples, copysamples);
00919                             pDst += copysamples << 1;
00920                         }
00921                         else { // Mono
00922                             step = 2 - mode_l;
00923                             Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
00924                             pDst += copysamples;
00925                         }
00926                     }
00927                     pSrc += nextFrameOffset;
00928                 }
00929 
00930                 // reload from disk to local buffer if needed
00931                 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
00932                     assumedsize    = GuessSize(remainingsamples);
00933                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00934                     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
00935                     remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
00936                     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
00937                 }
00938             } // while
00939 
00940             this->SamplePos += (SampleCount - remainingsamples);
00941             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00942             return (SampleCount - remainingsamples);
00943         }
00944     }
00945 
00962     buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
00963         buffer_t result;
00964         const double worstCaseHeaderOverhead =
00965                 (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
00966         result.Size              = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
00967         result.pStart            = new int8_t[result.Size];
00968         result.NullExtensionSize = 0;
00969         return result;
00970     }
00971 
00979     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
00980         if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
00981             delete[] (int8_t*) DecompressionBuffer.pStart;
00982             DecompressionBuffer.pStart = NULL;
00983             DecompressionBuffer.Size   = 0;
00984             DecompressionBuffer.NullExtensionSize = 0;
00985         }
00986     }
00987 
00988     Sample::~Sample() {
00989         Instances--;
00990         if (!Instances && InternalDecompressionBuffer.Size) {
00991             delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
00992             InternalDecompressionBuffer.pStart = NULL;
00993             InternalDecompressionBuffer.Size   = 0;
00994         }
00995         if (FrameTable) delete[] FrameTable;
00996         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00997     }
00998 
00999 
01000 
01001 // *************** DimensionRegion ***************
01002 // *
01003 
01004     uint                               DimensionRegion::Instances       = 0;
01005     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
01006 
01007     DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
01008         Instances++;
01009 
01010         memcpy(&Crossfade, &SamplerOptions, 4);
01011         if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
01012 
01013         RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
01014         _3ewa->ReadInt32(); // unknown, always 0x0000008C ?
01015         LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01016         EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01017         _3ewa->ReadInt16(); // unknown
01018         LFO1InternalDepth = _3ewa->ReadUint16();
01019         _3ewa->ReadInt16(); // unknown
01020         LFO3InternalDepth = _3ewa->ReadInt16();
01021         _3ewa->ReadInt16(); // unknown
01022         LFO1ControlDepth = _3ewa->ReadUint16();
01023         _3ewa->ReadInt16(); // unknown
01024         LFO3ControlDepth = _3ewa->ReadInt16();
01025         EG1Attack           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01026         EG1Decay1           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01027         _3ewa->ReadInt16(); // unknown
01028         EG1Sustain          = _3ewa->ReadUint16();
01029         EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01030         EG1Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01031         uint8_t eg1ctrloptions        = _3ewa->ReadUint8();
01032         EG1ControllerInvert           = eg1ctrloptions & 0x01;
01033         EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
01034         EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
01035         EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
01036         EG2Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01037         uint8_t eg2ctrloptions        = _3ewa->ReadUint8();
01038         EG2ControllerInvert           = eg2ctrloptions & 0x01;
01039         EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
01040         EG2ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
01041         EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
01042         LFO1Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01043         EG2Attack        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01044         EG2Decay1        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01045         _3ewa->ReadInt16(); // unknown
01046         EG2Sustain       = _3ewa->ReadUint16();
01047         EG2Release       = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01048         _3ewa->ReadInt16(); // unknown
01049         LFO2ControlDepth = _3ewa->ReadUint16();
01050         LFO2Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01051         _3ewa->ReadInt16(); // unknown
01052         LFO2InternalDepth = _3ewa->ReadUint16();
01053         int32_t eg1decay2 = _3ewa->ReadInt32();
01054         EG1Decay2          = (double) GIG_EXP_DECODE(eg1decay2);
01055         EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
01056         _3ewa->ReadInt16(); // unknown
01057         EG1PreAttack      = _3ewa->ReadUint16();
01058         int32_t eg2decay2 = _3ewa->ReadInt32();
01059         EG2Decay2         = (double) GIG_EXP_DECODE(eg2decay2);
01060         EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
01061         _3ewa->ReadInt16(); // unknown
01062         EG2PreAttack      = _3ewa->ReadUint16();
01063         uint8_t velocityresponse = _3ewa->ReadUint8();
01064         if (velocityresponse < 5) {
01065             VelocityResponseCurve = curve_type_nonlinear;
01066             VelocityResponseDepth = velocityresponse;
01067         }
01068         else if (velocityresponse < 10) {
01069             VelocityResponseCurve = curve_type_linear;
01070             VelocityResponseDepth = velocityresponse - 5;
01071         }
01072         else if (velocityresponse < 15) {
01073             VelocityResponseCurve = curve_type_special;
01074             VelocityResponseDepth = velocityresponse - 10;
01075         }
01076         else {
01077             VelocityResponseCurve = curve_type_unknown;
01078             VelocityResponseDepth = 0;
01079         }
01080         uint8_t releasevelocityresponse = _3ewa->ReadUint8();
01081         if (releasevelocityresponse < 5) {
01082             ReleaseVelocityResponseCurve = curve_type_nonlinear;
01083             ReleaseVelocityResponseDepth = releasevelocityresponse;
01084         }
01085         else if (releasevelocityresponse < 10) {
01086             ReleaseVelocityResponseCurve = curve_type_linear;
01087             ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
01088         }
01089         else if (releasevelocityresponse < 15) {
01090             ReleaseVelocityResponseCurve = curve_type_special;
01091             ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
01092         }
01093         else {
01094             ReleaseVelocityResponseCurve = curve_type_unknown;
01095             ReleaseVelocityResponseDepth = 0;
01096         }
01097         VelocityResponseCurveScaling = _3ewa->ReadUint8();
01098         AttenuationControllerThreshold = _3ewa->ReadInt8();
01099         _3ewa->ReadInt32(); // unknown
01100         SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
01101         _3ewa->ReadInt16(); // unknown
01102         uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
01103         PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
01104         if      (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
01105         else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
01106         else                                       DimensionBypass = dim_bypass_ctrl_none;
01107         uint8_t pan = _3ewa->ReadUint8();
01108         Pan         = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
01109         SelfMask = _3ewa->ReadInt8() & 0x01;
01110         _3ewa->ReadInt8(); // unknown
01111         uint8_t lfo3ctrl = _3ewa->ReadUint8();
01112         LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
01113         LFO3Sync                 = lfo3ctrl & 0x20; // bit 5
01114         InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
01115         AttenuationController  = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01116         uint8_t lfo2ctrl       = _3ewa->ReadUint8();
01117         LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
01118         LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7
01119         LFO2Sync               = lfo2ctrl & 0x20; // bit 5
01120         bool extResonanceCtrl  = lfo2ctrl & 0x40; // bit 6
01121         uint8_t lfo1ctrl       = _3ewa->ReadUint8();
01122         LFO1Controller         = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
01123         LFO1FlipPhase          = lfo1ctrl & 0x80; // bit 7
01124         LFO1Sync               = lfo1ctrl & 0x40; // bit 6
01125         VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
01126                                                     : vcf_res_ctrl_none;
01127         uint16_t eg3depth = _3ewa->ReadUint16();
01128         EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
01129                                       : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
01130         _3ewa->ReadInt16(); // unknown
01131         ChannelOffset = _3ewa->ReadUint8() / 4;
01132         uint8_t regoptions = _3ewa->ReadUint8();
01133         MSDecode           = regoptions & 0x01; // bit 0
01134         SustainDefeat      = regoptions & 0x02; // bit 1
01135         _3ewa->ReadInt16(); // unknown
01136         VelocityUpperLimit = _3ewa->ReadInt8();
01137         _3ewa->ReadInt8(); // unknown
01138         _3ewa->ReadInt16(); // unknown
01139         ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
01140         _3ewa->ReadInt8(); // unknown
01141         _3ewa->ReadInt8(); // unknown
01142         EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
01143         uint8_t vcfcutoff = _3ewa->ReadUint8();
01144         VCFEnabled = vcfcutoff & 0x80; // bit 7
01145         VCFCutoff  = vcfcutoff & 0x7f; // lower 7 bits
01146         VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
01147         VCFVelocityScale = _3ewa->ReadUint8();
01148         _3ewa->ReadInt8(); // unknown
01149         uint8_t vcfresonance = _3ewa->ReadUint8();
01150         VCFResonance = vcfresonance & 0x7f; // lower 7 bits
01151         VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
01152         uint8_t vcfbreakpoint         = _3ewa->ReadUint8();
01153         VCFKeyboardTracking           = vcfbreakpoint & 0x80; // bit 7
01154         VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
01155         uint8_t vcfvelocity = _3ewa->ReadUint8();
01156         VCFVelocityDynamicRange = vcfvelocity % 5;
01157         VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
01158         VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
01159         if (VCFType == vcf_type_lowpass) {
01160             if (lfo3ctrl & 0x40) // bit 6
01161                 VCFType = vcf_type_lowpassturbo;
01162         }
01163 
01164         // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
01165         uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
01166         if (pVelocityTables->count(tableKey)) { // if key exists
01167             pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
01168         }
01169         else {
01170             pVelocityAttenuationTable =
01171                 CreateVelocityTable(VelocityResponseCurve,
01172                                     VelocityResponseDepth,
01173                                     VelocityResponseCurveScaling);
01174             (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
01175         }
01176 
01177         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01178     }
01179 
01180     leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
01181         leverage_ctrl_t decodedcontroller;
01182         switch (EncodedController) {
01183             // special controller
01184             case _lev_ctrl_none:
01185                 decodedcontroller.type = leverage_ctrl_t::type_none;
01186                 decodedcontroller.controller_number = 0;
01187                 break;
01188             case _lev_ctrl_velocity:
01189                 decodedcontroller.type = leverage_ctrl_t::type_velocity;
01190                 decodedcontroller.controller_number = 0;
01191                 break;
01192             case _lev_ctrl_channelaftertouch:
01193                 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
01194                 decodedcontroller.controller_number = 0;
01195                 break;
01196 
01197             // ordinary MIDI control change controller
01198             case _lev_ctrl_modwheel:
01199                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01200                 decodedcontroller.controller_number = 1;
01201                 break;
01202             case _lev_ctrl_breath:
01203                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01204                 decodedcontroller.controller_number = 2;
01205                 break;
01206             case _lev_ctrl_foot:
01207                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01208                 decodedcontroller.controller_number = 4;
01209                 break;
01210             case _lev_ctrl_effect1:
01211                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01212                 decodedcontroller.controller_number = 12;
01213                 break;
01214             case _lev_ctrl_effect2:
01215                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01216                 decodedcontroller.controller_number = 13;
01217                 break;
01218             case _lev_ctrl_genpurpose1:
01219                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01220                 decodedcontroller.controller_number = 16;
01221                 break;
01222             case _lev_ctrl_genpurpose2:
01223                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01224                 decodedcontroller.controller_number = 17;
01225                 break;
01226             case _lev_ctrl_genpurpose3:
01227                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01228                 decodedcontroller.controller_number = 18;
01229                 break;
01230             case _lev_ctrl_genpurpose4:
01231                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01232                 decodedcontroller.controller_number = 19;
01233                 break;
01234             case _lev_ctrl_portamentotime:
01235                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01236                 decodedcontroller.controller_number = 5;
01237                 break;
01238             case _lev_ctrl_sustainpedal:
01239                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01240                 decodedcontroller.controller_number = 64;
01241                 break;
01242             case _lev_ctrl_portamento:
01243                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01244                 decodedcontroller.controller_number = 65;
01245                 break;
01246             case _lev_ctrl_sostenutopedal:
01247                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01248                 decodedcontroller.controller_number = 66;
01249                 break;
01250             case _lev_ctrl_softpedal:
01251                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01252                 decodedcontroller.controller_number = 67;
01253                 break;
01254             case _lev_ctrl_genpurpose5:
01255                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01256                 decodedcontroller.controller_number = 80;
01257                 break;
01258             case _lev_ctrl_genpurpose6:
01259                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01260                 decodedcontroller.controller_number = 81;
01261                 break;
01262             case _lev_ctrl_genpurpose7:
01263                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01264                 decodedcontroller.controller_number = 82;
01265                 break;
01266             case _lev_ctrl_genpurpose8:
01267                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01268                 decodedcontroller.controller_number = 83;
01269                 break;
01270             case _lev_ctrl_effect1depth:
01271                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01272                 decodedcontroller.controller_number = 91;
01273                 break;
01274             case _lev_ctrl_effect2depth:
01275                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01276                 decodedcontroller.controller_number = 92;
01277                 break;
01278             case _lev_ctrl_effect3depth:
01279                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01280                 decodedcontroller.controller_number = 93;
01281                 break;
01282             case _lev_ctrl_effect4depth:
01283                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01284                 decodedcontroller.controller_number = 94;
01285                 break;
01286             case _lev_ctrl_effect5depth:
01287                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01288                 decodedcontroller.controller_number = 95;
01289                 break;
01290 
01291             // unknown controller type
01292             default:
01293                 throw gig::Exception("Unknown leverage controller type.");
01294         }
01295         return decodedcontroller;
01296     }
01297 
01298     DimensionRegion::~DimensionRegion() {
01299         Instances--;
01300         if (!Instances) {
01301             // delete the velocity->volume tables
01302             VelocityTableMap::iterator iter;
01303             for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
01304                 double* pTable = iter->second;
01305                 if (pTable) delete[] pTable;
01306             }
01307             pVelocityTables->clear();
01308             delete pVelocityTables;
01309             pVelocityTables = NULL;
01310         }
01311     }
01312 
01324     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
01325         return pVelocityAttenuationTable[MIDIKeyVelocity];
01326     }
01327 
01328     double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
01329 
01330         // line-segment approximations of the 15 velocity curves
01331 
01332         // linear
01333         const int lin0[] = { 1, 1, 127, 127 };
01334         const int lin1[] = { 1, 21, 127, 127 };
01335         const int lin2[] = { 1, 45, 127, 127 };
01336         const int lin3[] = { 1, 74, 127, 127 };
01337         const int lin4[] = { 1, 127, 127, 127 };
01338 
01339         // non-linear
01340         const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
01341         const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
01342                              127, 127 };
01343         const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
01344                              127, 127 };
01345         const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
01346                              127, 127 };
01347         const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
01348 
01349         // special
01350         const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
01351                              113, 127, 127, 127 };
01352         const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
01353                              118, 127, 127, 127 };
01354         const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
01355                              85, 90, 91, 127, 127, 127 };
01356         const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
01357                              117, 127, 127, 127 };
01358         const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
01359                              127, 127 };
01360 
01361         const int* const curves[] = { non0, non1, non2, non3, non4,
01362                                       lin0, lin1, lin2, lin3, lin4,
01363                                       spe0, spe1, spe2, spe3, spe4 };
01364 
01365         double* const table = new double[128];
01366 
01367         const int* curve = curves[curveType * 5 + depth];
01368         const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
01369 
01370         table[0] = 0;
01371         for (int x = 1 ; x < 128 ; x++) {
01372 
01373             if (x > curve[2]) curve += 2;
01374             double y = curve[1] + (x - curve[0]) *
01375                 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
01376             y = y / 127;
01377 
01378             // Scale up for s > 20, down for s < 20. When
01379             // down-scaling, the curve still ends at 1.0.
01380             if (s < 20 && y >= 0.5)
01381                 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
01382             else
01383                 y = y * (s / 20.0);
01384             if (y > 1) y = 1;
01385 
01386             table[x] = y;
01387         }
01388         return table;
01389     }
01390 
01391 
01392 // *************** Region ***************
01393 // *
01394 
01395     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
01396         // Initialization
01397         Dimensions = 0;
01398         for (int i = 0; i < 256; i++) {
01399             pDimensionRegions[i] = NULL;
01400         }
01401         Layers = 1;
01402         File* file = (File*) GetParent()->GetParent();
01403         int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
01404 
01405         // Actual Loading
01406 
01407         LoadDimensionRegions(rgnList);
01408 
01409         RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
01410         if (_3lnk) {
01411             DimensionRegions = _3lnk->ReadUint32();
01412             for (int i = 0; i < dimensionBits; i++) {
01413                 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
01414                 uint8_t     bits      = _3lnk->ReadUint8();
01415                 if (dimension == dimension_none) { // inactive dimension
01416                     pDimensionDefinitions[i].dimension  = dimension_none;
01417                     pDimensionDefinitions[i].bits       = 0;
01418                     pDimensionDefinitions[i].zones      = 0;
01419                     pDimensionDefinitions[i].split_type = split_type_bit;
01420                     pDimensionDefinitions[i].ranges     = NULL;
01421                     pDimensionDefinitions[i].zone_size  = 0;
01422                 }
01423                 else { // active dimension
01424                     pDimensionDefinitions[i].dimension = dimension;
01425                     pDimensionDefinitions[i].bits      = bits;
01426                     pDimensionDefinitions[i].zones     = 0x01 << bits; // = pow(2,bits)
01427                     pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
01428                                                            dimension == dimension_samplechannel ||
01429                                                            dimension == dimension_releasetrigger ||
01430                                                            dimension == dimension_roundrobin ||
01431                                                            dimension == dimension_random) ? split_type_bit
01432                                                                                           : split_type_normal;
01433                     pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
01434                     pDimensionDefinitions[i].zone_size  =
01435                         (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
01436                                                                                    : 0;
01437                     Dimensions++;
01438 
01439                     // if this is a layer dimension, remember the amount of layers
01440                     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
01441                 }
01442                 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
01443             }
01444 
01445             // check velocity dimension (if there is one) for custom defined zone ranges
01446             for (uint i = 0; i < Dimensions; i++) {
01447                 dimension_def_t* pDimDef = pDimensionDefinitions + i;
01448                 if (pDimDef->dimension == dimension_velocity) {
01449                     if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
01450                         // no custom defined ranges
01451                         pDimDef->split_type = split_type_normal;
01452                         pDimDef->ranges     = NULL;
01453                     }
01454                     else { // custom defined ranges
01455                         pDimDef->split_type = split_type_customvelocity;
01456                         pDimDef->ranges     = new range_t[pDimDef->zones];
01457                         uint8_t bits[8] = { 0 };
01458                         int previousUpperLimit = -1;
01459                         for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
01460                             bits[i] = velocityZone;
01461                             DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits);
01462 
01463                             pDimDef->ranges[velocityZone].low  = previousUpperLimit + 1;
01464                             pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
01465                             previousUpperLimit = pDimDef->ranges[velocityZone].high;
01466                             // fill velocity table
01467                             for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
01468                                 VelocityTable[i] = velocityZone;
01469                             }
01470                         }
01471                     }
01472                 }
01473             }
01474 
01475             // jump to start of the wave pool indices (if not already there)
01476             File* file = (File*) GetParent()->GetParent();
01477             if (file->pVersion && file->pVersion->major == 3)
01478                 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
01479             else
01480                 _3lnk->SetPos(44);
01481 
01482             // load sample references
01483             for (uint i = 0; i < DimensionRegions; i++) {
01484                 uint32_t wavepoolindex = _3lnk->ReadUint32();
01485                 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
01486             }
01487         }
01488         else throw gig::Exception("Mandatory <3lnk> chunk not found.");
01489     }
01490 
01491     void Region::LoadDimensionRegions(RIFF::List* rgn) {
01492         RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
01493         if (_3prg) {
01494             int dimensionRegionNr = 0;
01495             RIFF::List* _3ewl = _3prg->GetFirstSubList();
01496             while (_3ewl) {
01497                 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
01498                     pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
01499                     dimensionRegionNr++;
01500                 }
01501                 _3ewl = _3prg->GetNextSubList();
01502             }
01503             if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
01504         }
01505     }
01506 
01507     Region::~Region() {
01508         for (uint i = 0; i < Dimensions; i++) {
01509             if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
01510         }
01511         for (int i = 0; i < 256; i++) {
01512             if (pDimensionRegions[i]) delete pDimensionRegions[i];
01513         }
01514     }
01515 
01534     DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
01535         uint8_t bits[8] = { 0 };
01536         for (uint i = 0; i < Dimensions; i++) {
01537             bits[i] = DimValues[i];
01538             switch (pDimensionDefinitions[i].split_type) {
01539                 case split_type_normal:
01540                     bits[i] /= pDimensionDefinitions[i].zone_size;
01541                     break;
01542                 case split_type_customvelocity:
01543                     bits[i] = VelocityTable[bits[i]];
01544                     break;
01545                 case split_type_bit: // the value is already the sought dimension bit number
01546                     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
01547                     bits[i] = bits[i] & limiter_mask; // just make sure the value don't uses more bits than allowed
01548                     break;
01549             }
01550         }
01551         return GetDimensionRegionByBit(bits);
01552     }
01553 
01564     DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
01565         return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
01566                                                   << pDimensionDefinitions[5].bits | DimBits[5])
01567                                                   << pDimensionDefinitions[4].bits | DimBits[4])
01568                                                   << pDimensionDefinitions[3].bits | DimBits[3])
01569                                                   << pDimensionDefinitions[2].bits | DimBits[2])
01570                                                   << pDimensionDefinitions[1].bits | DimBits[1])
01571                                                   << pDimensionDefinitions[0].bits | DimBits[0]];
01572     }
01573 
01583     Sample* Region::GetSample() {
01584         if (pSample) return static_cast<gig::Sample*>(pSample);
01585         else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
01586     }
01587 
01588     Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
01589         if ((int32_t)WavePoolTableIndex == -1) return NULL;
01590         File* file = (File*) GetParent()->GetParent();
01591         unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
01592         Sample* sample = file->GetFirstSample(pProgress);
01593         while (sample) {
01594             if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
01595             sample = file->GetNextSample();
01596         }
01597         return NULL;
01598     }
01599 
01600 
01601 
01602 // *************** Instrument ***************
01603 // *
01604 
01605     Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
01606         // Initialization
01607         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
01608         RegionIndex = -1;
01609 
01610         // Loading
01611         RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
01612         if (lart) {
01613             RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
01614             if (_3ewg) {
01615                 EffectSend             = _3ewg->ReadUint16();
01616                 Attenuation            = _3ewg->ReadInt32();
01617                 FineTune               = _3ewg->ReadInt16();
01618                 PitchbendRange         = _3ewg->ReadInt16();
01619                 uint8_t dimkeystart    = _3ewg->ReadUint8();
01620                 PianoReleaseMode       = dimkeystart & 0x01;
01621                 DimensionKeyRange.low  = dimkeystart >> 1;
01622                 DimensionKeyRange.high = _3ewg->ReadUint8();
01623             }
01624             else throw gig::Exception("Mandatory <3ewg> chunk not found.");
01625         }
01626         else throw gig::Exception("Mandatory <lart> list chunk not found.");
01627 
01628         RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
01629         if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
01630         pRegions = new Region*[Regions];
01631         for (uint i = 0; i < Regions; i++) pRegions[i] = NULL;
01632         RIFF::List* rgn = lrgn->GetFirstSubList();
01633         unsigned int iRegion = 0;
01634         while (rgn) {
01635             if (rgn->GetListType() == LIST_TYPE_RGN) {
01636                 __notify_progress(pProgress, (float) iRegion / (float) Regions);
01637                 pRegions[iRegion] = new Region(this, rgn);
01638                 iRegion++;
01639             }
01640             rgn = lrgn->GetNextSubList();
01641         }
01642 
01643         // Creating Region Key Table for fast lookup
01644         for (uint iReg = 0; iReg < Regions; iReg++) {
01645             for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
01646                 RegionKeyTable[iKey] = pRegions[iReg];
01647             }
01648         }
01649 
01650         __notify_progress(pProgress, 1.0f); // notify done
01651     }
01652 
01653     Instrument::~Instrument() {
01654         for (uint i = 0; i < Regions; i++) {
01655             if (pRegions) {
01656                 if (pRegions[i]) delete (pRegions[i]);
01657             }
01658         }
01659         if (pRegions) delete[] pRegions;
01660     }
01661 
01669     Region* Instrument::GetRegion(unsigned int Key) {
01670         if (!pRegions || Key > 127) return NULL;
01671         return RegionKeyTable[Key];
01672         /*for (int i = 0; i < Regions; i++) {
01673             if (Key <= pRegions[i]->KeyRange.high &&
01674                 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
01675         }
01676         return NULL;*/
01677     }
01678 
01686     Region* Instrument::GetFirstRegion() {
01687         if (!Regions) return NULL;
01688         RegionIndex = 1;
01689         return pRegions[0];
01690     }
01691 
01700     Region* Instrument::GetNextRegion() {
01701         if (RegionIndex < 0 || uint32_t(RegionIndex) >= Regions) return NULL;
01702         return pRegions[RegionIndex++];
01703     }
01704 
01705 
01706 
01707 // *************** File ***************
01708 // *
01709 
01710     File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
01711         pSamples     = NULL;
01712         pInstruments = NULL;
01713     }
01714 
01715     File::~File() {
01716         // free samples
01717         if (pSamples) {
01718             SamplesIterator = pSamples->begin();
01719             while (SamplesIterator != pSamples->end() ) {
01720                 delete (*SamplesIterator);
01721                 SamplesIterator++;
01722             }
01723             pSamples->clear();
01724             delete pSamples;
01725 
01726         }
01727         // free instruments
01728         if (pInstruments) {
01729             InstrumentsIterator = pInstruments->begin();
01730             while (InstrumentsIterator != pInstruments->end() ) {
01731                 delete (*InstrumentsIterator);
01732                 InstrumentsIterator++;
01733             }
01734             pInstruments->clear();
01735             delete pInstruments;
01736         }
01737     }
01738 
01739     Sample* File::GetFirstSample(progress_t* pProgress) {
01740         if (!pSamples) LoadSamples(pProgress);
01741         if (!pSamples) return NULL;
01742         SamplesIterator = pSamples->begin();
01743         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01744     }
01745 
01746     Sample* File::GetNextSample() {
01747         if (!pSamples) return NULL;
01748         SamplesIterator++;
01749         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01750     }
01751 
01752     void File::LoadSamples(progress_t* pProgress) {
01753         RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
01754         if (wvpl) {
01755             // just for progress calculation
01756             int iSampleIndex  = 0;
01757             int iTotalSamples = wvpl->CountSubLists(LIST_TYPE_WAVE);
01758 
01759             unsigned long wvplFileOffset = wvpl->GetFilePos();
01760             RIFF::List* wave = wvpl->GetFirstSubList();
01761             while (wave) {
01762                 if (wave->GetListType() == LIST_TYPE_WAVE) {
01763                     // notify current progress
01764                     const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
01765                     __notify_progress(pProgress, subprogress);
01766 
01767                     if (!pSamples) pSamples = new SampleList;
01768                     unsigned long waveFileOffset = wave->GetFilePos();
01769                     pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
01770 
01771                     iSampleIndex++;
01772                 }
01773                 wave = wvpl->GetNextSubList();
01774             }
01775             __notify_progress(pProgress, 1.0); // notify done
01776         }
01777         else throw gig::Exception("Mandatory <wvpl> chunk not found.");
01778     }
01779 
01780     Instrument* File::GetFirstInstrument() {
01781         if (!pInstruments) LoadInstruments();
01782         if (!pInstruments) return NULL;
01783         InstrumentsIterator = pInstruments->begin();
01784         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01785     }
01786 
01787     Instrument* File::GetNextInstrument() {
01788         if (!pInstruments) return NULL;
01789         InstrumentsIterator++;
01790         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01791     }
01792 
01800     Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
01801         if (!pInstruments) {
01802             // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
01803 
01804             // sample loading subtask
01805             progress_t subprogress;
01806             __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
01807             __notify_progress(&subprogress, 0.0f);
01808             GetFirstSample(&subprogress); // now force all samples to be loaded
01809             __notify_progress(&subprogress, 1.0f);
01810 
01811             // instrument loading subtask
01812             if (pProgress && pProgress->callback) {
01813                 subprogress.__range_min = subprogress.__range_max;
01814                 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
01815             }
01816             __notify_progress(&subprogress, 0.0f);
01817             LoadInstruments(&subprogress);
01818             __notify_progress(&subprogress, 1.0f);
01819         }
01820         if (!pInstruments) return NULL;
01821         InstrumentsIterator = pInstruments->begin();
01822         for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
01823             if (i == index) return *InstrumentsIterator;
01824             InstrumentsIterator++;
01825         }
01826         return NULL;
01827     }
01828 
01829     void File::LoadInstruments(progress_t* pProgress) {
01830         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
01831         if (lstInstruments) {
01832             int iInstrumentIndex = 0;
01833             RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
01834             while (lstInstr) {
01835                 if (lstInstr->GetListType() == LIST_TYPE_INS) {
01836                     // notify current progress
01837                     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
01838                     __notify_progress(pProgress, localProgress);
01839 
01840                     // divide local progress into subprogress for loading current Instrument
01841                     progress_t subprogress;
01842                     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
01843 
01844                     if (!pInstruments) pInstruments = new InstrumentList;
01845                     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
01846 
01847                     iInstrumentIndex++;
01848                 }
01849                 lstInstr = lstInstruments->GetNextSubList();
01850             }
01851             __notify_progress(pProgress, 1.0); // notify done
01852         }
01853         else throw gig::Exception("Mandatory <lins> list chunk not found.");
01854     }
01855 
01856 
01857 
01858 // *************** Exception ***************
01859 // *
01860 
01861     Exception::Exception(String Message) : DLS::Exception(Message) {
01862     }
01863 
01864     void Exception::PrintMessage() {
01865         std::cout << "gig::Exception: " << Message << std::endl;
01866     }
01867 
01868 
01869 // *************** functions ***************
01870 // *
01871 
01877     String libraryName() {
01878         return PACKAGE;
01879     }
01880 
01885     String libraryVersion() {
01886         return VERSION;
01887     }
01888 
01889 } // namespace gig

Generated on Thu May 26 00:50:17 2005 for libgig by  doxygen 1.4.2