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         int y, dy, ddy, dddy;
00136         const int shift = 8 - truncatedBits;
00137 
00138 #define GET_PARAMS(params)                      \
00139         y    = get24(params);                   \
00140         dy   = y - get24((params) + 3);         \
00141         ddy  = get24((params) + 6);             \
00142         dddy = get24((params) + 9)
00143 
00144 #define SKIP_ONE(x)                             \
00145         dddy -= (x);                            \
00146         ddy  -= dddy;                           \
00147         dy   =  -dy - ddy;                      \
00148         y    += dy
00149 
00150 #define COPY_ONE(x)                             \
00151         SKIP_ONE(x);                            \
00152         *pDst = y >> shift;                     \
00153         pDst += dstStep
00154 
00155         switch (compressionmode) {
00156             case 2: // 24 bit uncompressed
00157                 pSrc += currentframeoffset * 3;
00158                 while (copysamples) {
00159                     *pDst = get24(pSrc) >> shift;
00160                     pDst += dstStep;
00161                     pSrc += 3;
00162                     copysamples--;
00163                 }
00164                 break;
00165 
00166             case 3: // 24 bit compressed to 16 bit
00167                 GET_PARAMS(params);
00168                 while (currentframeoffset) {
00169                     SKIP_ONE(get16(pSrc));
00170                     pSrc += 2;
00171                     currentframeoffset--;
00172                 }
00173                 while (copysamples) {
00174                     COPY_ONE(get16(pSrc));
00175                     pSrc += 2;
00176                     copysamples--;
00177                 }
00178                 break;
00179 
00180             case 4: // 24 bit compressed to 12 bit
00181                 GET_PARAMS(params);
00182                 while (currentframeoffset > 1) {
00183                     SKIP_ONE(get12lo(pSrc));
00184                     SKIP_ONE(get12hi(pSrc));
00185                     pSrc += 3;
00186                     currentframeoffset -= 2;
00187                 }
00188                 if (currentframeoffset) {
00189                     SKIP_ONE(get12lo(pSrc));
00190                     currentframeoffset--;
00191                     if (copysamples) {
00192                         COPY_ONE(get12hi(pSrc));
00193                         pSrc += 3;
00194                         copysamples--;
00195                     }
00196                 }
00197                 while (copysamples > 1) {
00198                     COPY_ONE(get12lo(pSrc));
00199                     COPY_ONE(get12hi(pSrc));
00200                     pSrc += 3;
00201                     copysamples -= 2;
00202                 }
00203                 if (copysamples) {
00204                     COPY_ONE(get12lo(pSrc));
00205                 }
00206                 break;
00207 
00208             case 5: // 24 bit compressed to 8 bit
00209                 GET_PARAMS(params);
00210                 while (currentframeoffset) {
00211                     SKIP_ONE(int8_t(*pSrc++));
00212                     currentframeoffset--;
00213                 }
00214                 while (copysamples) {
00215                     COPY_ONE(int8_t(*pSrc++));
00216                     copysamples--;
00217                 }
00218                 break;
00219         }
00220     }
00221 
00222     const int bytesPerFrame[] =      { 4096, 2052, 768, 524, 396, 268 };
00223     const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
00224     const int headerSize[] =         { 0, 4, 0, 12, 12, 12 };
00225     const int bitsPerSample[] =      { 16, 8, 24, 16, 12, 8 };
00226 }
00227 
00228 
00229 // *************** Sample ***************
00230 // *
00231 
00232     unsigned int Sample::Instances = 0;
00233     buffer_t     Sample::InternalDecompressionBuffer;
00234 
00235     Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
00236         Instances++;
00237         FileNo = fileNo;
00238 
00239         RIFF::Chunk* _3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
00240         if (!_3gix) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
00241         SampleGroup = _3gix->ReadInt16();
00242 
00243         RIFF::Chunk* smpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
00244         if (!smpl) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
00245         Manufacturer      = smpl->ReadInt32();
00246         Product           = smpl->ReadInt32();
00247         SamplePeriod      = smpl->ReadInt32();
00248         MIDIUnityNote     = smpl->ReadInt32();
00249         FineTune          = smpl->ReadInt32();
00250         smpl->Read(&SMPTEFormat, 1, 4);
00251         SMPTEOffset       = smpl->ReadInt32();
00252         Loops             = smpl->ReadInt32();
00253         smpl->ReadInt32(); // manufByt
00254         LoopID            = smpl->ReadInt32();
00255         smpl->Read(&LoopType, 1, 4);
00256         LoopStart         = smpl->ReadInt32();
00257         LoopEnd           = smpl->ReadInt32();
00258         LoopFraction      = smpl->ReadInt32();
00259         LoopPlayCount     = smpl->ReadInt32();
00260 
00261         FrameTable                 = NULL;
00262         SamplePos                  = 0;
00263         RAMCache.Size              = 0;
00264         RAMCache.pStart            = NULL;
00265         RAMCache.NullExtensionSize = 0;
00266 
00267         if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
00268 
00269         RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
00270         Compressed        = ewav;
00271         Dithered          = false;
00272         TruncatedBits     = 0;
00273         if (Compressed) {
00274             uint32_t version = ewav->ReadInt32();
00275             if (version == 3 && BitDepth == 24) {
00276                 Dithered = ewav->ReadInt32();
00277                 ewav->SetPos(Channels == 2 ? 84 : 64);
00278                 TruncatedBits = ewav->ReadInt32();
00279             }
00280             ScanCompressedSample();
00281         }
00282 
00283         // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
00284         if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
00285             InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
00286             InternalDecompressionBuffer.Size   = INITIAL_SAMPLE_BUFFER_SIZE;
00287         }
00288         FrameOffset = 0; // just for streaming compressed samples
00289 
00290         LoopSize = LoopEnd - LoopStart;
00291     }
00292 
00294     void Sample::ScanCompressedSample() {
00295         //TODO: we have to add some more scans here (e.g. determine compression rate)
00296         this->SamplesTotal = 0;
00297         std::list<unsigned long> frameOffsets;
00298 
00299         SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
00300         WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
00301 
00302         // Scanning
00303         pCkData->SetPos(0);
00304         if (Channels == 2) { // Stereo
00305             for (int i = 0 ; ; i++) {
00306                 // for 24 bit samples every 8:th frame offset is
00307                 // stored, to save some memory
00308                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00309 
00310                 const int mode_l = pCkData->ReadUint8();
00311                 const int mode_r = pCkData->ReadUint8();
00312                 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
00313                 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
00314 
00315                 if (pCkData->RemainingBytes() <= frameSize) {
00316                     SamplesInLastFrame =
00317                         ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
00318                         (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
00319                     SamplesTotal += SamplesInLastFrame;
00320                     break;
00321                 }
00322                 SamplesTotal += SamplesPerFrame;
00323                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00324             }
00325         }
00326         else { // Mono
00327             for (int i = 0 ; ; i++) {
00328                 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
00329 
00330                 const int mode = pCkData->ReadUint8();
00331                 if (mode > 5) throw gig::Exception("Unknown compression mode");
00332                 const unsigned long frameSize = bytesPerFrame[mode];
00333 
00334                 if (pCkData->RemainingBytes() <= frameSize) {
00335                     SamplesInLastFrame =
00336                         ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
00337                     SamplesTotal += SamplesInLastFrame;
00338                     break;
00339                 }
00340                 SamplesTotal += SamplesPerFrame;
00341                 pCkData->SetPos(frameSize, RIFF::stream_curpos);
00342             }
00343         }
00344         pCkData->SetPos(0);
00345 
00346         // Build the frames table (which is used for fast resolving of a frame's chunk offset)
00347         if (FrameTable) delete[] FrameTable;
00348         FrameTable = new unsigned long[frameOffsets.size()];
00349         std::list<unsigned long>::iterator end  = frameOffsets.end();
00350         std::list<unsigned long>::iterator iter = frameOffsets.begin();
00351         for (int i = 0; iter != end; i++, iter++) {
00352             FrameTable[i] = *iter;
00353         }
00354     }
00355 
00365     buffer_t Sample::LoadSampleData() {
00366         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
00367     }
00368 
00391     buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
00392         return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
00393     }
00394 
00414     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
00415         return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
00416     }
00417 
00450     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
00451         if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
00452         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00453         unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
00454         RAMCache.pStart            = new int8_t[allocationsize];
00455         RAMCache.Size              = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
00456         RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
00457         // fill the remaining buffer space with silence samples
00458         memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
00459         return GetCache();
00460     }
00461 
00472     buffer_t Sample::GetCache() {
00473         // return a copy of the buffer_t structure
00474         buffer_t result;
00475         result.Size              = this->RAMCache.Size;
00476         result.pStart            = this->RAMCache.pStart;
00477         result.NullExtensionSize = this->RAMCache.NullExtensionSize;
00478         return result;
00479     }
00480 
00487     void Sample::ReleaseSampleData() {
00488         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00489         RAMCache.pStart = NULL;
00490         RAMCache.Size   = 0;
00491     }
00492 
00514     unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
00515         if (Compressed) {
00516             switch (Whence) {
00517                 case RIFF::stream_curpos:
00518                     this->SamplePos += SampleCount;
00519                     break;
00520                 case RIFF::stream_end:
00521                     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
00522                     break;
00523                 case RIFF::stream_backward:
00524                     this->SamplePos -= SampleCount;
00525                     break;
00526                 case RIFF::stream_start: default:
00527                     this->SamplePos = SampleCount;
00528                     break;
00529             }
00530             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00531 
00532             unsigned long frame = this->SamplePos / 2048; // to which frame to jump
00533             this->FrameOffset   = this->SamplePos % 2048; // offset (in sample points) within that frame
00534             pCkData->SetPos(FrameTable[frame]);           // set chunk pointer to the start of sought frame
00535             return this->SamplePos;
00536         }
00537         else { // not compressed
00538             unsigned long orderedBytes = SampleCount * this->FrameSize;
00539             unsigned long result = pCkData->SetPos(orderedBytes, Whence);
00540             return (result == orderedBytes) ? SampleCount
00541                                             : result / this->FrameSize;
00542         }
00543     }
00544 
00548     unsigned long Sample::GetPos() {
00549         if (Compressed) return SamplePos;
00550         else            return pCkData->GetPos() / FrameSize;
00551     }
00552 
00586     unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, buffer_t* pExternalDecompressionBuffer) {
00587         unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
00588         uint8_t* pDst = (uint8_t*) pBuffer;
00589 
00590         SetPos(pPlaybackState->position); // recover position from the last time
00591 
00592         if (this->Loops && GetPos() <= this->LoopEnd) { // honor looping if there are loop points defined
00593 
00594             switch (this->LoopType) {
00595 
00596                 case loop_type_bidirectional: { //TODO: not tested yet!
00597                     do {
00598                         // if not endless loop check if max. number of loop cycles have been passed
00599                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00600 
00601                         if (!pPlaybackState->reverse) { // forward playback
00602                             do {
00603                                 samplestoloopend  = this->LoopEnd - GetPos();
00604                                 readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00605                                 samplestoread    -= readsamples;
00606                                 totalreadsamples += readsamples;
00607                                 if (readsamples == samplestoloopend) {
00608                                     pPlaybackState->reverse = true;
00609                                     break;
00610                                 }
00611                             } while (samplestoread && readsamples);
00612                         }
00613                         else { // backward playback
00614 
00615                             // as we can only read forward from disk, we have to
00616                             // determine the end position within the loop first,
00617                             // read forward from that 'end' and finally after
00618                             // reading, swap all sample frames so it reflects
00619                             // backward playback
00620 
00621                             unsigned long swapareastart       = totalreadsamples;
00622                             unsigned long loopoffset          = GetPos() - this->LoopStart;
00623                             unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
00624                             unsigned long reverseplaybackend  = GetPos() - samplestoreadinloop;
00625 
00626                             SetPos(reverseplaybackend);
00627 
00628                             // read samples for backward playback
00629                             do {
00630                                 readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
00631                                 samplestoreadinloop -= readsamples;
00632                                 samplestoread       -= readsamples;
00633                                 totalreadsamples    += readsamples;
00634                             } while (samplestoreadinloop && readsamples);
00635 
00636                             SetPos(reverseplaybackend); // pretend we really read backwards
00637 
00638                             if (reverseplaybackend == this->LoopStart) {
00639                                 pPlaybackState->loop_cycles_left--;
00640                                 pPlaybackState->reverse = false;
00641                             }
00642 
00643                             // reverse the sample frames for backward playback
00644                             SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00645                         }
00646                     } while (samplestoread && readsamples);
00647                     break;
00648                 }
00649 
00650                 case loop_type_backward: { // TODO: not tested yet!
00651                     // forward playback (not entered the loop yet)
00652                     if (!pPlaybackState->reverse) do {
00653                         samplestoloopend  = this->LoopEnd - GetPos();
00654                         readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00655                         samplestoread    -= readsamples;
00656                         totalreadsamples += readsamples;
00657                         if (readsamples == samplestoloopend) {
00658                             pPlaybackState->reverse = true;
00659                             break;
00660                         }
00661                     } while (samplestoread && readsamples);
00662 
00663                     if (!samplestoread) break;
00664 
00665                     // as we can only read forward from disk, we have to
00666                     // determine the end position within the loop first,
00667                     // read forward from that 'end' and finally after
00668                     // reading, swap all sample frames so it reflects
00669                     // backward playback
00670 
00671                     unsigned long swapareastart       = totalreadsamples;
00672                     unsigned long loopoffset          = GetPos() - this->LoopStart;
00673                     unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * LoopSize - loopoffset)
00674                                                                               : samplestoread;
00675                     unsigned long reverseplaybackend  = this->LoopStart + Abs((loopoffset - samplestoreadinloop) % this->LoopSize);
00676 
00677                     SetPos(reverseplaybackend);
00678 
00679                     // read samples for backward playback
00680                     do {
00681                         // if not endless loop check if max. number of loop cycles have been passed
00682                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00683                         samplestoloopend     = this->LoopEnd - GetPos();
00684                         readsamples          = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
00685                         samplestoreadinloop -= readsamples;
00686                         samplestoread       -= readsamples;
00687                         totalreadsamples    += readsamples;
00688                         if (readsamples == samplestoloopend) {
00689                             pPlaybackState->loop_cycles_left--;
00690                             SetPos(this->LoopStart);
00691                         }
00692                     } while (samplestoreadinloop && readsamples);
00693 
00694                     SetPos(reverseplaybackend); // pretend we really read backwards
00695 
00696                     // reverse the sample frames for backward playback
00697                     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
00698                     break;
00699                 }
00700 
00701                 default: case loop_type_normal: {
00702                     do {
00703                         // if not endless loop check if max. number of loop cycles have been passed
00704                         if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
00705                         samplestoloopend  = this->LoopEnd - GetPos();
00706                         readsamples       = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
00707                         samplestoread    -= readsamples;
00708                         totalreadsamples += readsamples;
00709                         if (readsamples == samplestoloopend) {
00710                             pPlaybackState->loop_cycles_left--;
00711                             SetPos(this->LoopStart);
00712                         }
00713                     } while (samplestoread && readsamples);
00714                     break;
00715                 }
00716             }
00717         }
00718 
00719         // read on without looping
00720         if (samplestoread) do {
00721             readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
00722             samplestoread    -= readsamples;
00723             totalreadsamples += readsamples;
00724         } while (readsamples && samplestoread);
00725 
00726         // store current position
00727         pPlaybackState->position = GetPos();
00728 
00729         return totalreadsamples;
00730     }
00731 
00750     unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
00751         if (SampleCount == 0) return 0;
00752         if (!Compressed) {
00753             if (BitDepth == 24) {
00754                 // 24 bit sample. For now just truncate to 16 bit.
00755                 unsigned char* pSrc = (unsigned char*) ((pExternalDecompressionBuffer) ? pExternalDecompressionBuffer->pStart : this->InternalDecompressionBuffer.pStart);
00756                 int16_t* pDst = static_cast<int16_t*>(pBuffer);
00757                 if (Channels == 2) { // Stereo
00758                     unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 6, 1);
00759                     pSrc++;
00760                     for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
00761                         *pDst++ = get16(pSrc);
00762                         pSrc += 3;
00763                     }
00764                     return (pDst - static_cast<int16_t*>(pBuffer)) >> 1;
00765                 }
00766                 else { // Mono
00767                     unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 3, 1);
00768                     pSrc++;
00769                     for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
00770                         *pDst++ = get16(pSrc);
00771                         pSrc += 3;
00772                     }
00773                     return pDst - static_cast<int16_t*>(pBuffer);
00774                 }
00775             }
00776             else { // 16 bit
00777                 // (pCkData->Read does endian correction)
00778                 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
00779                                      : pCkData->Read(pBuffer, SampleCount, 2);
00780             }
00781         }
00782         else {
00783             if (this->SamplePos >= this->SamplesTotal) return 0;
00784             //TODO: efficiency: maybe we should test for an average compression rate
00785             unsigned long assumedsize      = GuessSize(SampleCount),
00786                           remainingbytes   = 0,           // remaining bytes in the local buffer
00787                           remainingsamples = SampleCount,
00788                           copysamples, skipsamples,
00789                           currentframeoffset = this->FrameOffset;  // offset in current sample frame since last Read()
00790             this->FrameOffset = 0;
00791 
00792             buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
00793 
00794             // if decompression buffer too small, then reduce amount of samples to read
00795             if (pDecompressionBuffer->Size < assumedsize) {
00796                 std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
00797                 SampleCount      = WorstCaseMaxSamples(pDecompressionBuffer);
00798                 remainingsamples = SampleCount;
00799                 assumedsize      = GuessSize(SampleCount);
00800             }
00801 
00802             unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
00803             int16_t* pDst = static_cast<int16_t*>(pBuffer);
00804             remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
00805 
00806             while (remainingsamples && remainingbytes) {
00807                 unsigned long framesamples = SamplesPerFrame;
00808                 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
00809 
00810                 int mode_l = *pSrc++, mode_r = 0;
00811 
00812                 if (Channels == 2) {
00813                     mode_r = *pSrc++;
00814                     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
00815                     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
00816                     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
00817                     if (remainingbytes < framebytes) { // last frame in sample
00818                         framesamples = SamplesInLastFrame;
00819                         if (mode_l == 4 && (framesamples & 1)) {
00820                             rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
00821                         }
00822                         else {
00823                             rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
00824                         }
00825                     }
00826                 }
00827                 else {
00828                     framebytes = bytesPerFrame[mode_l] + 1;
00829                     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
00830                     if (remainingbytes < framebytes) {
00831                         framesamples = SamplesInLastFrame;
00832                     }
00833                 }
00834 
00835                 // determine how many samples in this frame to skip and read
00836                 if (currentframeoffset + remainingsamples >= framesamples) {
00837                     if (currentframeoffset <= framesamples) {
00838                         copysamples = framesamples - currentframeoffset;
00839                         skipsamples = currentframeoffset;
00840                     }
00841                     else {
00842                         copysamples = 0;
00843                         skipsamples = framesamples;
00844                     }
00845                 }
00846                 else {
00847                     // This frame has enough data for pBuffer, but not
00848                     // all of the frame is needed. Set file position
00849                     // to start of this frame for next call to Read.
00850                     copysamples = remainingsamples;
00851                     skipsamples = currentframeoffset;
00852                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00853                     this->FrameOffset = currentframeoffset + copysamples;
00854                 }
00855                 remainingsamples -= copysamples;
00856 
00857                 if (remainingbytes > framebytes) {
00858                     remainingbytes -= framebytes;
00859                     if (remainingsamples == 0 &&
00860                         currentframeoffset + copysamples == framesamples) {
00861                         // This frame has enough data for pBuffer, and
00862                         // all of the frame is needed. Set file
00863                         // position to start of next frame for next
00864                         // call to Read. FrameOffset is 0.
00865                         pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00866                     }
00867                 }
00868                 else remainingbytes = 0;
00869 
00870                 currentframeoffset -= skipsamples;
00871 
00872                 if (copysamples == 0) {
00873                     // skip this frame
00874                     pSrc += framebytes - Channels;
00875                 }
00876                 else {
00877                     const unsigned char* const param_l = pSrc;
00878                     if (BitDepth == 24) {
00879                         if (mode_l != 2) pSrc += 12;
00880 
00881                         if (Channels == 2) { // Stereo
00882                             const unsigned char* const param_r = pSrc;
00883                             if (mode_r != 2) pSrc += 12;
00884 
00885                             Decompress24(mode_l, param_l, 2, pSrc, pDst,
00886                                          skipsamples, copysamples, TruncatedBits);
00887                             Decompress24(mode_r, param_r, 2, pSrc + rightChannelOffset, pDst + 1,
00888                                          skipsamples, copysamples, TruncatedBits);
00889                             pDst += copysamples << 1;
00890                         }
00891                         else { // Mono
00892                             Decompress24(mode_l, param_l, 1, pSrc, pDst,
00893                                          skipsamples, copysamples, TruncatedBits);
00894                             pDst += copysamples;
00895                         }
00896                     }
00897                     else { // 16 bit
00898                         if (mode_l) pSrc += 4;
00899 
00900                         int step;
00901                         if (Channels == 2) { // Stereo
00902                             const unsigned char* const param_r = pSrc;
00903                             if (mode_r) pSrc += 4;
00904 
00905                             step = (2 - mode_l) + (2 - mode_r);
00906                             Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
00907                             Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
00908                                          skipsamples, copysamples);
00909                             pDst += copysamples << 1;
00910                         }
00911                         else { // Mono
00912                             step = 2 - mode_l;
00913                             Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
00914                             pDst += copysamples;
00915                         }
00916                     }
00917                     pSrc += nextFrameOffset;
00918                 }
00919 
00920                 // reload from disk to local buffer if needed
00921                 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
00922                     assumedsize    = GuessSize(remainingsamples);
00923                     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
00924                     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
00925                     remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
00926                     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
00927                 }
00928             } // while
00929 
00930             this->SamplePos += (SampleCount - remainingsamples);
00931             if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
00932             return (SampleCount - remainingsamples);
00933         }
00934     }
00935 
00952     buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
00953         buffer_t result;
00954         const double worstCaseHeaderOverhead =
00955                 (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
00956         result.Size              = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
00957         result.pStart            = new int8_t[result.Size];
00958         result.NullExtensionSize = 0;
00959         return result;
00960     }
00961 
00969     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
00970         if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
00971             delete[] (int8_t*) DecompressionBuffer.pStart;
00972             DecompressionBuffer.pStart = NULL;
00973             DecompressionBuffer.Size   = 0;
00974             DecompressionBuffer.NullExtensionSize = 0;
00975         }
00976     }
00977 
00978     Sample::~Sample() {
00979         Instances--;
00980         if (!Instances && InternalDecompressionBuffer.Size) {
00981             delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
00982             InternalDecompressionBuffer.pStart = NULL;
00983             InternalDecompressionBuffer.Size   = 0;
00984         }
00985         if (FrameTable) delete[] FrameTable;
00986         if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
00987     }
00988 
00989 
00990 
00991 // *************** DimensionRegion ***************
00992 // *
00993 
00994     uint                               DimensionRegion::Instances       = 0;
00995     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
00996 
00997     DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
00998         Instances++;
00999 
01000         memcpy(&Crossfade, &SamplerOptions, 4);
01001         if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
01002 
01003         RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
01004         _3ewa->ReadInt32(); // unknown, always 0x0000008C ?
01005         LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01006         EG3Attack     = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01007         _3ewa->ReadInt16(); // unknown
01008         LFO1InternalDepth = _3ewa->ReadUint16();
01009         _3ewa->ReadInt16(); // unknown
01010         LFO3InternalDepth = _3ewa->ReadInt16();
01011         _3ewa->ReadInt16(); // unknown
01012         LFO1ControlDepth = _3ewa->ReadUint16();
01013         _3ewa->ReadInt16(); // unknown
01014         LFO3ControlDepth = _3ewa->ReadInt16();
01015         EG1Attack           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01016         EG1Decay1           = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01017         _3ewa->ReadInt16(); // unknown
01018         EG1Sustain          = _3ewa->ReadUint16();
01019         EG1Release          = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01020         EG1Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01021         uint8_t eg1ctrloptions        = _3ewa->ReadUint8();
01022         EG1ControllerInvert           = eg1ctrloptions & 0x01;
01023         EG1ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
01024         EG1ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
01025         EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
01026         EG2Controller       = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01027         uint8_t eg2ctrloptions        = _3ewa->ReadUint8();
01028         EG2ControllerInvert           = eg2ctrloptions & 0x01;
01029         EG2ControllerAttackInfluence  = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
01030         EG2ControllerDecayInfluence   = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
01031         EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
01032         LFO1Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01033         EG2Attack        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01034         EG2Decay1        = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01035         _3ewa->ReadInt16(); // unknown
01036         EG2Sustain       = _3ewa->ReadUint16();
01037         EG2Release       = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01038         _3ewa->ReadInt16(); // unknown
01039         LFO2ControlDepth = _3ewa->ReadUint16();
01040         LFO2Frequency    = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
01041         _3ewa->ReadInt16(); // unknown
01042         LFO2InternalDepth = _3ewa->ReadUint16();
01043         int32_t eg1decay2 = _3ewa->ReadInt32();
01044         EG1Decay2          = (double) GIG_EXP_DECODE(eg1decay2);
01045         EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
01046         _3ewa->ReadInt16(); // unknown
01047         EG1PreAttack      = _3ewa->ReadUint16();
01048         int32_t eg2decay2 = _3ewa->ReadInt32();
01049         EG2Decay2         = (double) GIG_EXP_DECODE(eg2decay2);
01050         EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
01051         _3ewa->ReadInt16(); // unknown
01052         EG2PreAttack      = _3ewa->ReadUint16();
01053         uint8_t velocityresponse = _3ewa->ReadUint8();
01054         if (velocityresponse < 5) {
01055             VelocityResponseCurve = curve_type_nonlinear;
01056             VelocityResponseDepth = velocityresponse;
01057         }
01058         else if (velocityresponse < 10) {
01059             VelocityResponseCurve = curve_type_linear;
01060             VelocityResponseDepth = velocityresponse - 5;
01061         }
01062         else if (velocityresponse < 15) {
01063             VelocityResponseCurve = curve_type_special;
01064             VelocityResponseDepth = velocityresponse - 10;
01065         }
01066         else {
01067             VelocityResponseCurve = curve_type_unknown;
01068             VelocityResponseDepth = 0;
01069         }
01070         uint8_t releasevelocityresponse = _3ewa->ReadUint8();
01071         if (releasevelocityresponse < 5) {
01072             ReleaseVelocityResponseCurve = curve_type_nonlinear;
01073             ReleaseVelocityResponseDepth = releasevelocityresponse;
01074         }
01075         else if (releasevelocityresponse < 10) {
01076             ReleaseVelocityResponseCurve = curve_type_linear;
01077             ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
01078         }
01079         else if (releasevelocityresponse < 15) {
01080             ReleaseVelocityResponseCurve = curve_type_special;
01081             ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
01082         }
01083         else {
01084             ReleaseVelocityResponseCurve = curve_type_unknown;
01085             ReleaseVelocityResponseDepth = 0;
01086         }
01087         VelocityResponseCurveScaling = _3ewa->ReadUint8();
01088         AttenuationControllerThreshold = _3ewa->ReadInt8();
01089         _3ewa->ReadInt32(); // unknown
01090         SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
01091         _3ewa->ReadInt16(); // unknown
01092         uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
01093         PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
01094         if      (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
01095         else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
01096         else                                       DimensionBypass = dim_bypass_ctrl_none;
01097         uint8_t pan = _3ewa->ReadUint8();
01098         Pan         = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
01099         SelfMask = _3ewa->ReadInt8() & 0x01;
01100         _3ewa->ReadInt8(); // unknown
01101         uint8_t lfo3ctrl = _3ewa->ReadUint8();
01102         LFO3Controller           = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
01103         LFO3Sync                 = lfo3ctrl & 0x20; // bit 5
01104         InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
01105         AttenuationController  = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
01106         uint8_t lfo2ctrl       = _3ewa->ReadUint8();
01107         LFO2Controller         = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
01108         LFO2FlipPhase          = lfo2ctrl & 0x80; // bit 7
01109         LFO2Sync               = lfo2ctrl & 0x20; // bit 5
01110         bool extResonanceCtrl  = lfo2ctrl & 0x40; // bit 6
01111         uint8_t lfo1ctrl       = _3ewa->ReadUint8();
01112         LFO1Controller         = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
01113         LFO1FlipPhase          = lfo1ctrl & 0x80; // bit 7
01114         LFO1Sync               = lfo1ctrl & 0x40; // bit 6
01115         VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
01116                                                     : vcf_res_ctrl_none;
01117         uint16_t eg3depth = _3ewa->ReadUint16();
01118         EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
01119                                       : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
01120         _3ewa->ReadInt16(); // unknown
01121         ChannelOffset = _3ewa->ReadUint8() / 4;
01122         uint8_t regoptions = _3ewa->ReadUint8();
01123         MSDecode           = regoptions & 0x01; // bit 0
01124         SustainDefeat      = regoptions & 0x02; // bit 1
01125         _3ewa->ReadInt16(); // unknown
01126         VelocityUpperLimit = _3ewa->ReadInt8();
01127         _3ewa->ReadInt8(); // unknown
01128         _3ewa->ReadInt16(); // unknown
01129         ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
01130         _3ewa->ReadInt8(); // unknown
01131         _3ewa->ReadInt8(); // unknown
01132         EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
01133         uint8_t vcfcutoff = _3ewa->ReadUint8();
01134         VCFEnabled = vcfcutoff & 0x80; // bit 7
01135         VCFCutoff  = vcfcutoff & 0x7f; // lower 7 bits
01136         VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
01137         uint8_t vcfvelscale = _3ewa->ReadUint8();
01138         VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
01139         VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
01140         _3ewa->ReadInt8(); // unknown
01141         uint8_t vcfresonance = _3ewa->ReadUint8();
01142         VCFResonance = vcfresonance & 0x7f; // lower 7 bits
01143         VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
01144         uint8_t vcfbreakpoint         = _3ewa->ReadUint8();
01145         VCFKeyboardTracking           = vcfbreakpoint & 0x80; // bit 7
01146         VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
01147         uint8_t vcfvelocity = _3ewa->ReadUint8();
01148         VCFVelocityDynamicRange = vcfvelocity % 5;
01149         VCFVelocityCurve        = static_cast<curve_type_t>(vcfvelocity / 5);
01150         VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
01151         if (VCFType == vcf_type_lowpass) {
01152             if (lfo3ctrl & 0x40) // bit 6
01153                 VCFType = vcf_type_lowpassturbo;
01154         }
01155 
01156         pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
01157                                                      VelocityResponseDepth,
01158                                                      VelocityResponseCurveScaling);
01159 
01160         curve_type_t curveType = ReleaseVelocityResponseCurve;
01161         uint8_t depth = ReleaseVelocityResponseDepth;
01162 
01163         // this models a strange behaviour or bug in GSt: two of the
01164         // velocity response curves for release time are not used even
01165         // if specified, instead another curve is chosen.
01166         if ((curveType == curve_type_nonlinear && depth == 0) ||
01167             (curveType == curve_type_special   && depth == 4)) {
01168             curveType = curve_type_nonlinear;
01169             depth = 3;
01170         }
01171         pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);
01172 
01173         curveType = VCFVelocityCurve;
01174         depth = VCFVelocityDynamicRange;
01175 
01176         // even stranger GSt: two of the velocity response curves for
01177         // filter cutoff are not used, instead another special curve
01178         // is chosen. This curve is not used anywhere else.
01179         if ((curveType == curve_type_nonlinear && depth == 0) ||
01180             (curveType == curve_type_special   && depth == 4)) {
01181             curveType = curve_type_special;
01182             depth = 5;
01183         }
01184         pVelocityCutoffTable = GetVelocityTable(curveType, depth,
01185                                                 VCFCutoffController == vcf_cutoff_ctrl_none ? VCFVelocityScale : 0);
01186 
01187         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01188     }
01189 
01190     // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
01191     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
01192     {
01193         double* table;
01194         uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
01195         if (pVelocityTables->count(tableKey)) { // if key exists
01196             table = (*pVelocityTables)[tableKey];
01197         }
01198         else {
01199             table = CreateVelocityTable(curveType, depth, scaling);
01200             (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
01201         }
01202         return table;
01203     }
01204 
01205     leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
01206         leverage_ctrl_t decodedcontroller;
01207         switch (EncodedController) {
01208             // special controller
01209             case _lev_ctrl_none:
01210                 decodedcontroller.type = leverage_ctrl_t::type_none;
01211                 decodedcontroller.controller_number = 0;
01212                 break;
01213             case _lev_ctrl_velocity:
01214                 decodedcontroller.type = leverage_ctrl_t::type_velocity;
01215                 decodedcontroller.controller_number = 0;
01216                 break;
01217             case _lev_ctrl_channelaftertouch:
01218                 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
01219                 decodedcontroller.controller_number = 0;
01220                 break;
01221 
01222             // ordinary MIDI control change controller
01223             case _lev_ctrl_modwheel:
01224                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01225                 decodedcontroller.controller_number = 1;
01226                 break;
01227             case _lev_ctrl_breath:
01228                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01229                 decodedcontroller.controller_number = 2;
01230                 break;
01231             case _lev_ctrl_foot:
01232                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01233                 decodedcontroller.controller_number = 4;
01234                 break;
01235             case _lev_ctrl_effect1:
01236                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01237                 decodedcontroller.controller_number = 12;
01238                 break;
01239             case _lev_ctrl_effect2:
01240                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01241                 decodedcontroller.controller_number = 13;
01242                 break;
01243             case _lev_ctrl_genpurpose1:
01244                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01245                 decodedcontroller.controller_number = 16;
01246                 break;
01247             case _lev_ctrl_genpurpose2:
01248                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01249                 decodedcontroller.controller_number = 17;
01250                 break;
01251             case _lev_ctrl_genpurpose3:
01252                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01253                 decodedcontroller.controller_number = 18;
01254                 break;
01255             case _lev_ctrl_genpurpose4:
01256                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01257                 decodedcontroller.controller_number = 19;
01258                 break;
01259             case _lev_ctrl_portamentotime:
01260                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01261                 decodedcontroller.controller_number = 5;
01262                 break;
01263             case _lev_ctrl_sustainpedal:
01264                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01265                 decodedcontroller.controller_number = 64;
01266                 break;
01267             case _lev_ctrl_portamento:
01268                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01269                 decodedcontroller.controller_number = 65;
01270                 break;
01271             case _lev_ctrl_sostenutopedal:
01272                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01273                 decodedcontroller.controller_number = 66;
01274                 break;
01275             case _lev_ctrl_softpedal:
01276                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01277                 decodedcontroller.controller_number = 67;
01278                 break;
01279             case _lev_ctrl_genpurpose5:
01280                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01281                 decodedcontroller.controller_number = 80;
01282                 break;
01283             case _lev_ctrl_genpurpose6:
01284                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01285                 decodedcontroller.controller_number = 81;
01286                 break;
01287             case _lev_ctrl_genpurpose7:
01288                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01289                 decodedcontroller.controller_number = 82;
01290                 break;
01291             case _lev_ctrl_genpurpose8:
01292                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01293                 decodedcontroller.controller_number = 83;
01294                 break;
01295             case _lev_ctrl_effect1depth:
01296                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01297                 decodedcontroller.controller_number = 91;
01298                 break;
01299             case _lev_ctrl_effect2depth:
01300                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01301                 decodedcontroller.controller_number = 92;
01302                 break;
01303             case _lev_ctrl_effect3depth:
01304                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01305                 decodedcontroller.controller_number = 93;
01306                 break;
01307             case _lev_ctrl_effect4depth:
01308                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01309                 decodedcontroller.controller_number = 94;
01310                 break;
01311             case _lev_ctrl_effect5depth:
01312                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01313                 decodedcontroller.controller_number = 95;
01314                 break;
01315 
01316             // unknown controller type
01317             default:
01318                 throw gig::Exception("Unknown leverage controller type.");
01319         }
01320         return decodedcontroller;
01321     }
01322 
01323     DimensionRegion::~DimensionRegion() {
01324         Instances--;
01325         if (!Instances) {
01326             // delete the velocity->volume tables
01327             VelocityTableMap::iterator iter;
01328             for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
01329                 double* pTable = iter->second;
01330                 if (pTable) delete[] pTable;
01331             }
01332             pVelocityTables->clear();
01333             delete pVelocityTables;
01334             pVelocityTables = NULL;
01335         }
01336     }
01337 
01349     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
01350         return pVelocityAttenuationTable[MIDIKeyVelocity];
01351     }
01352 
01353     double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
01354         return pVelocityReleaseTable[MIDIKeyVelocity];
01355     }
01356 
01357     double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
01358         return pVelocityCutoffTable[MIDIKeyVelocity];
01359     }
01360 
01361     double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
01362 
01363         // line-segment approximations of the 15 velocity curves
01364 
01365         // linear
01366         const int lin0[] = { 1, 1, 127, 127 };
01367         const int lin1[] = { 1, 21, 127, 127 };
01368         const int lin2[] = { 1, 45, 127, 127 };
01369         const int lin3[] = { 1, 74, 127, 127 };
01370         const int lin4[] = { 1, 127, 127, 127 };
01371 
01372         // non-linear
01373         const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
01374         const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
01375                              127, 127 };
01376         const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
01377                              127, 127 };
01378         const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
01379                              127, 127 };
01380         const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
01381 
01382         // special
01383         const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
01384                              113, 127, 127, 127 };
01385         const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
01386                              118, 127, 127, 127 };
01387         const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
01388                              85, 90, 91, 127, 127, 127 };
01389         const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
01390                              117, 127, 127, 127 };
01391         const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
01392                              127, 127 };
01393 
01394         // this is only used by the VCF velocity curve
01395         const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
01396                              91, 127, 127, 127 };
01397 
01398         const int* const curves[] = { non0, non1, non2, non3, non4,
01399                                       lin0, lin1, lin2, lin3, lin4,
01400                                       spe0, spe1, spe2, spe3, spe4, spe5 };
01401 
01402         double* const table = new double[128];
01403 
01404         const int* curve = curves[curveType * 5 + depth];
01405         const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
01406 
01407         table[0] = 0;
01408         for (int x = 1 ; x < 128 ; x++) {
01409 
01410             if (x > curve[2]) curve += 2;
01411             double y = curve[1] + (x - curve[0]) *
01412                 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
01413             y = y / 127;
01414 
01415             // Scale up for s > 20, down for s < 20. When
01416             // down-scaling, the curve still ends at 1.0.
01417             if (s < 20 && y >= 0.5)
01418                 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
01419             else
01420                 y = y * (s / 20.0);
01421             if (y > 1) y = 1;
01422 
01423             table[x] = y;
01424         }
01425         return table;
01426     }
01427 
01428 
01429 // *************** Region ***************
01430 // *
01431 
01432     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
01433         // Initialization
01434         Dimensions = 0;
01435         for (int i = 0; i < 256; i++) {
01436             pDimensionRegions[i] = NULL;
01437         }
01438         Layers = 1;
01439         File* file = (File*) GetParent()->GetParent();
01440         int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
01441 
01442         // Actual Loading
01443 
01444         LoadDimensionRegions(rgnList);
01445 
01446         RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
01447         if (_3lnk) {
01448             DimensionRegions = _3lnk->ReadUint32();
01449             for (int i = 0; i < dimensionBits; i++) {
01450                 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
01451                 uint8_t     bits      = _3lnk->ReadUint8();
01452                 if (dimension == dimension_none) { // inactive dimension
01453                     pDimensionDefinitions[i].dimension  = dimension_none;
01454                     pDimensionDefinitions[i].bits       = 0;
01455                     pDimensionDefinitions[i].zones      = 0;
01456                     pDimensionDefinitions[i].split_type = split_type_bit;
01457                     pDimensionDefinitions[i].ranges     = NULL;
01458                     pDimensionDefinitions[i].zone_size  = 0;
01459                 }
01460                 else { // active dimension
01461                     pDimensionDefinitions[i].dimension = dimension;
01462                     pDimensionDefinitions[i].bits      = bits;
01463                     pDimensionDefinitions[i].zones     = 0x01 << bits; // = pow(2,bits)
01464                     pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
01465                                                            dimension == dimension_samplechannel ||
01466                                                            dimension == dimension_releasetrigger ||
01467                                                            dimension == dimension_roundrobin ||
01468                                                            dimension == dimension_random) ? split_type_bit
01469                                                                                           : split_type_normal;
01470                     pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
01471                     pDimensionDefinitions[i].zone_size  =
01472                         (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
01473                                                                                    : 0;
01474                     Dimensions++;
01475 
01476                     // if this is a layer dimension, remember the amount of layers
01477                     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
01478                 }
01479                 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
01480             }
01481 
01482             // check velocity dimension (if there is one) for custom defined zone ranges
01483             for (uint i = 0; i < Dimensions; i++) {
01484                 dimension_def_t* pDimDef = pDimensionDefinitions + i;
01485                 if (pDimDef->dimension == dimension_velocity) {
01486                     if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
01487                         // no custom defined ranges
01488                         pDimDef->split_type = split_type_normal;
01489                         pDimDef->ranges     = NULL;
01490                     }
01491                     else { // custom defined ranges
01492                         pDimDef->split_type = split_type_customvelocity;
01493                         pDimDef->ranges     = new range_t[pDimDef->zones];
01494                         uint8_t bits[8] = { 0 };
01495                         int previousUpperLimit = -1;
01496                         for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
01497                             bits[i] = velocityZone;
01498                             DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits);
01499 
01500                             pDimDef->ranges[velocityZone].low  = previousUpperLimit + 1;
01501                             pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
01502                             previousUpperLimit = pDimDef->ranges[velocityZone].high;
01503                             // fill velocity table
01504                             for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
01505                                 VelocityTable[i] = velocityZone;
01506                             }
01507                         }
01508                     }
01509                 }
01510             }
01511 
01512             // jump to start of the wave pool indices (if not already there)
01513             File* file = (File*) GetParent()->GetParent();
01514             if (file->pVersion && file->pVersion->major == 3)
01515                 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
01516             else
01517                 _3lnk->SetPos(44);
01518 
01519             // load sample references
01520             for (uint i = 0; i < DimensionRegions; i++) {
01521                 uint32_t wavepoolindex = _3lnk->ReadUint32();
01522                 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
01523             }
01524         }
01525         else throw gig::Exception("Mandatory <3lnk> chunk not found.");
01526     }
01527 
01528     void Region::LoadDimensionRegions(RIFF::List* rgn) {
01529         RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
01530         if (_3prg) {
01531             int dimensionRegionNr = 0;
01532             RIFF::List* _3ewl = _3prg->GetFirstSubList();
01533             while (_3ewl) {
01534                 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
01535                     pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
01536                     dimensionRegionNr++;
01537                 }
01538                 _3ewl = _3prg->GetNextSubList();
01539             }
01540             if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
01541         }
01542     }
01543 
01544     Region::~Region() {
01545         for (uint i = 0; i < Dimensions; i++) {
01546             if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
01547         }
01548         for (int i = 0; i < 256; i++) {
01549             if (pDimensionRegions[i]) delete pDimensionRegions[i];
01550         }
01551     }
01552 
01571     DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
01572         uint8_t bits[8] = { 0 };
01573         for (uint i = 0; i < Dimensions; i++) {
01574             bits[i] = DimValues[i];
01575             switch (pDimensionDefinitions[i].split_type) {
01576                 case split_type_normal:
01577                     bits[i] /= pDimensionDefinitions[i].zone_size;
01578                     break;
01579                 case split_type_customvelocity:
01580                     bits[i] = VelocityTable[bits[i]];
01581                     break;
01582                 case split_type_bit: // the value is already the sought dimension bit number
01583                     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
01584                     bits[i] = bits[i] & limiter_mask; // just make sure the value don't uses more bits than allowed
01585                     break;
01586             }
01587         }
01588         return GetDimensionRegionByBit(bits);
01589     }
01590 
01601     DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
01602         return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
01603                                                   << pDimensionDefinitions[5].bits | DimBits[5])
01604                                                   << pDimensionDefinitions[4].bits | DimBits[4])
01605                                                   << pDimensionDefinitions[3].bits | DimBits[3])
01606                                                   << pDimensionDefinitions[2].bits | DimBits[2])
01607                                                   << pDimensionDefinitions[1].bits | DimBits[1])
01608                                                   << pDimensionDefinitions[0].bits | DimBits[0]];
01609     }
01610 
01620     Sample* Region::GetSample() {
01621         if (pSample) return static_cast<gig::Sample*>(pSample);
01622         else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
01623     }
01624 
01625     Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
01626         if ((int32_t)WavePoolTableIndex == -1) return NULL;
01627         File* file = (File*) GetParent()->GetParent();
01628         unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
01629         unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
01630         Sample* sample = file->GetFirstSample(pProgress);
01631         while (sample) {
01632             if (sample->ulWavePoolOffset == soughtoffset &&
01633                 sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(pSample = sample);
01634             sample = file->GetNextSample();
01635         }
01636         return NULL;
01637     }
01638 
01639 
01640 
01641 // *************** Instrument ***************
01642 // *
01643 
01644     Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
01645         // Initialization
01646         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
01647         RegionIndex = -1;
01648 
01649         // Loading
01650         RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
01651         if (lart) {
01652             RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
01653             if (_3ewg) {
01654                 EffectSend             = _3ewg->ReadUint16();
01655                 Attenuation            = _3ewg->ReadInt32();
01656                 FineTune               = _3ewg->ReadInt16();
01657                 PitchbendRange         = _3ewg->ReadInt16();
01658                 uint8_t dimkeystart    = _3ewg->ReadUint8();
01659                 PianoReleaseMode       = dimkeystart & 0x01;
01660                 DimensionKeyRange.low  = dimkeystart >> 1;
01661                 DimensionKeyRange.high = _3ewg->ReadUint8();
01662             }
01663             else throw gig::Exception("Mandatory <3ewg> chunk not found.");
01664         }
01665         else throw gig::Exception("Mandatory <lart> list chunk not found.");
01666 
01667         RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
01668         if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
01669         pRegions = new Region*[Regions];
01670         for (uint i = 0; i < Regions; i++) pRegions[i] = NULL;
01671         RIFF::List* rgn = lrgn->GetFirstSubList();
01672         unsigned int iRegion = 0;
01673         while (rgn) {
01674             if (rgn->GetListType() == LIST_TYPE_RGN) {
01675                 __notify_progress(pProgress, (float) iRegion / (float) Regions);
01676                 pRegions[iRegion] = new Region(this, rgn);
01677                 iRegion++;
01678             }
01679             rgn = lrgn->GetNextSubList();
01680         }
01681 
01682         // Creating Region Key Table for fast lookup
01683         for (uint iReg = 0; iReg < Regions; iReg++) {
01684             for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
01685                 RegionKeyTable[iKey] = pRegions[iReg];
01686             }
01687         }
01688 
01689         __notify_progress(pProgress, 1.0f); // notify done
01690     }
01691 
01692     Instrument::~Instrument() {
01693         for (uint i = 0; i < Regions; i++) {
01694             if (pRegions) {
01695                 if (pRegions[i]) delete (pRegions[i]);
01696             }
01697         }
01698         if (pRegions) delete[] pRegions;
01699     }
01700 
01708     Region* Instrument::GetRegion(unsigned int Key) {
01709         if (!pRegions || Key > 127) return NULL;
01710         return RegionKeyTable[Key];
01711         /*for (int i = 0; i < Regions; i++) {
01712             if (Key <= pRegions[i]->KeyRange.high &&
01713                 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
01714         }
01715         return NULL;*/
01716     }
01717 
01725     Region* Instrument::GetFirstRegion() {
01726         if (!Regions) return NULL;
01727         RegionIndex = 1;
01728         return pRegions[0];
01729     }
01730 
01739     Region* Instrument::GetNextRegion() {
01740         if (RegionIndex < 0 || uint32_t(RegionIndex) >= Regions) return NULL;
01741         return pRegions[RegionIndex++];
01742     }
01743 
01744 
01745 
01746 // *************** File ***************
01747 // *
01748 
01749     File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
01750         pSamples     = NULL;
01751         pInstruments = NULL;
01752     }
01753 
01754     File::~File() {
01755         // free samples
01756         if (pSamples) {
01757             SamplesIterator = pSamples->begin();
01758             while (SamplesIterator != pSamples->end() ) {
01759                 delete (*SamplesIterator);
01760                 SamplesIterator++;
01761             }
01762             pSamples->clear();
01763             delete pSamples;
01764 
01765         }
01766         // free instruments
01767         if (pInstruments) {
01768             InstrumentsIterator = pInstruments->begin();
01769             while (InstrumentsIterator != pInstruments->end() ) {
01770                 delete (*InstrumentsIterator);
01771                 InstrumentsIterator++;
01772             }
01773             pInstruments->clear();
01774             delete pInstruments;
01775         }
01776         // free extension files
01777         for (std::list<RIFF::File*>::iterator i = ExtensionFiles.begin() ; i != ExtensionFiles.end() ; i++)
01778             delete *i;
01779     }
01780 
01781     Sample* File::GetFirstSample(progress_t* pProgress) {
01782         if (!pSamples) LoadSamples(pProgress);
01783         if (!pSamples) return NULL;
01784         SamplesIterator = pSamples->begin();
01785         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01786     }
01787 
01788     Sample* File::GetNextSample() {
01789         if (!pSamples) return NULL;
01790         SamplesIterator++;
01791         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01792     }
01793 
01794     void File::LoadSamples(progress_t* pProgress) {
01795         RIFF::File* file = pRIFF;
01796 
01797         // just for progress calculation
01798         int iSampleIndex  = 0;
01799         int iTotalSamples = WavePoolCount;
01800 
01801         // check if samples should be loaded from extension files
01802         int lastFileNo = 0;
01803         for (int i = 0 ; i < WavePoolCount ; i++) {
01804             if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
01805         }
01806         String name(pRIFF->Filename);
01807         int nameLen = pRIFF->Filename.length();
01808         char suffix[6];
01809         if (nameLen > 4 && pRIFF->Filename.substr(nameLen - 4) == ".gig") nameLen -= 4;
01810 
01811         for (int fileNo = 0 ; ; ) {
01812             RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
01813             if (wvpl) {
01814                 unsigned long wvplFileOffset = wvpl->GetFilePos();
01815                 RIFF::List* wave = wvpl->GetFirstSubList();
01816                 while (wave) {
01817                     if (wave->GetListType() == LIST_TYPE_WAVE) {
01818                         // notify current progress
01819                         const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
01820                         __notify_progress(pProgress, subprogress);
01821 
01822                         if (!pSamples) pSamples = new SampleList;
01823                         unsigned long waveFileOffset = wave->GetFilePos();
01824                         pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
01825 
01826                         iSampleIndex++;
01827                     }
01828                     wave = wvpl->GetNextSubList();
01829                 }
01830 
01831                 if (fileNo == lastFileNo) break;
01832 
01833                 // open extension file (*.gx01, *.gx02, ...)
01834                 fileNo++;
01835                 sprintf(suffix, ".gx%02d", fileNo);
01836                 name.replace(nameLen, 5, suffix);
01837                 file = new RIFF::File(name);
01838                 ExtensionFiles.push_back(file);
01839             }
01840             else throw gig::Exception("Mandatory <wvpl> chunk not found.");
01841         }
01842 
01843         __notify_progress(pProgress, 1.0); // notify done
01844     }
01845 
01846     Instrument* File::GetFirstInstrument() {
01847         if (!pInstruments) LoadInstruments();
01848         if (!pInstruments) return NULL;
01849         InstrumentsIterator = pInstruments->begin();
01850         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01851     }
01852 
01853     Instrument* File::GetNextInstrument() {
01854         if (!pInstruments) return NULL;
01855         InstrumentsIterator++;
01856         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01857     }
01858 
01866     Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
01867         if (!pInstruments) {
01868             // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
01869 
01870             // sample loading subtask
01871             progress_t subprogress;
01872             __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
01873             __notify_progress(&subprogress, 0.0f);
01874             GetFirstSample(&subprogress); // now force all samples to be loaded
01875             __notify_progress(&subprogress, 1.0f);
01876 
01877             // instrument loading subtask
01878             if (pProgress && pProgress->callback) {
01879                 subprogress.__range_min = subprogress.__range_max;
01880                 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
01881             }
01882             __notify_progress(&subprogress, 0.0f);
01883             LoadInstruments(&subprogress);
01884             __notify_progress(&subprogress, 1.0f);
01885         }
01886         if (!pInstruments) return NULL;
01887         InstrumentsIterator = pInstruments->begin();
01888         for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
01889             if (i == index) return *InstrumentsIterator;
01890             InstrumentsIterator++;
01891         }
01892         return NULL;
01893     }
01894 
01895     void File::LoadInstruments(progress_t* pProgress) {
01896         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
01897         if (lstInstruments) {
01898             int iInstrumentIndex = 0;
01899             RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
01900             while (lstInstr) {
01901                 if (lstInstr->GetListType() == LIST_TYPE_INS) {
01902                     // notify current progress
01903                     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
01904                     __notify_progress(pProgress, localProgress);
01905 
01906                     // divide local progress into subprogress for loading current Instrument
01907                     progress_t subprogress;
01908                     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
01909 
01910                     if (!pInstruments) pInstruments = new InstrumentList;
01911                     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
01912 
01913                     iInstrumentIndex++;
01914                 }
01915                 lstInstr = lstInstruments->GetNextSubList();
01916             }
01917             __notify_progress(pProgress, 1.0); // notify done
01918         }
01919         else throw gig::Exception("Mandatory <lins> list chunk not found.");
01920     }
01921 
01922 
01923 
01924 // *************** Exception ***************
01925 // *
01926 
01927     Exception::Exception(String Message) : DLS::Exception(Message) {
01928     }
01929 
01930     void Exception::PrintMessage() {
01931         std::cout << "gig::Exception: " << Message << std::endl;
01932     }
01933 
01934 
01935 // *************** functions ***************
01936 // *
01937 
01943     String libraryName() {
01944         return PACKAGE;
01945     }
01946 
01951     String libraryVersion() {
01952         return VERSION;
01953     }
01954 
01955 } // namespace gig

Generated on Wed Nov 23 17:03:42 2005 for libgig by  doxygen 1.4.5