Main Page | Namespace List | Class Hierarchy | Class List | 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         pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
01165                                                      VelocityResponseDepth,
01166                                                      VelocityResponseCurveScaling);
01167 
01168         curve_type_t curveType = ReleaseVelocityResponseCurve;
01169         uint8_t depth = ReleaseVelocityResponseDepth;
01170 
01171         // this models a strange behaviour or bug in GSt: two of the
01172         // velocity response curves for release time are not used even
01173         // if specified, instead another curve is chosen.
01174 
01175         if ((curveType == curve_type_nonlinear && depth == 0) ||
01176             (curveType == curve_type_special   && depth == 4)) {
01177             curveType = curve_type_nonlinear;
01178             depth = 3;
01179         }
01180         pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);
01181 
01182         SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
01183     }
01184 
01185     // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
01186     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
01187     {
01188         double* table;
01189         uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
01190         if (pVelocityTables->count(tableKey)) { // if key exists
01191             table = (*pVelocityTables)[tableKey];
01192         }
01193         else {
01194             table = CreateVelocityTable(curveType, depth, scaling);
01195             (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
01196         }
01197         return table;
01198     }
01199 
01200     leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
01201         leverage_ctrl_t decodedcontroller;
01202         switch (EncodedController) {
01203             // special controller
01204             case _lev_ctrl_none:
01205                 decodedcontroller.type = leverage_ctrl_t::type_none;
01206                 decodedcontroller.controller_number = 0;
01207                 break;
01208             case _lev_ctrl_velocity:
01209                 decodedcontroller.type = leverage_ctrl_t::type_velocity;
01210                 decodedcontroller.controller_number = 0;
01211                 break;
01212             case _lev_ctrl_channelaftertouch:
01213                 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
01214                 decodedcontroller.controller_number = 0;
01215                 break;
01216 
01217             // ordinary MIDI control change controller
01218             case _lev_ctrl_modwheel:
01219                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01220                 decodedcontroller.controller_number = 1;
01221                 break;
01222             case _lev_ctrl_breath:
01223                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01224                 decodedcontroller.controller_number = 2;
01225                 break;
01226             case _lev_ctrl_foot:
01227                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01228                 decodedcontroller.controller_number = 4;
01229                 break;
01230             case _lev_ctrl_effect1:
01231                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01232                 decodedcontroller.controller_number = 12;
01233                 break;
01234             case _lev_ctrl_effect2:
01235                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01236                 decodedcontroller.controller_number = 13;
01237                 break;
01238             case _lev_ctrl_genpurpose1:
01239                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01240                 decodedcontroller.controller_number = 16;
01241                 break;
01242             case _lev_ctrl_genpurpose2:
01243                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01244                 decodedcontroller.controller_number = 17;
01245                 break;
01246             case _lev_ctrl_genpurpose3:
01247                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01248                 decodedcontroller.controller_number = 18;
01249                 break;
01250             case _lev_ctrl_genpurpose4:
01251                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01252                 decodedcontroller.controller_number = 19;
01253                 break;
01254             case _lev_ctrl_portamentotime:
01255                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01256                 decodedcontroller.controller_number = 5;
01257                 break;
01258             case _lev_ctrl_sustainpedal:
01259                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01260                 decodedcontroller.controller_number = 64;
01261                 break;
01262             case _lev_ctrl_portamento:
01263                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01264                 decodedcontroller.controller_number = 65;
01265                 break;
01266             case _lev_ctrl_sostenutopedal:
01267                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01268                 decodedcontroller.controller_number = 66;
01269                 break;
01270             case _lev_ctrl_softpedal:
01271                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01272                 decodedcontroller.controller_number = 67;
01273                 break;
01274             case _lev_ctrl_genpurpose5:
01275                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01276                 decodedcontroller.controller_number = 80;
01277                 break;
01278             case _lev_ctrl_genpurpose6:
01279                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01280                 decodedcontroller.controller_number = 81;
01281                 break;
01282             case _lev_ctrl_genpurpose7:
01283                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01284                 decodedcontroller.controller_number = 82;
01285                 break;
01286             case _lev_ctrl_genpurpose8:
01287                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01288                 decodedcontroller.controller_number = 83;
01289                 break;
01290             case _lev_ctrl_effect1depth:
01291                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01292                 decodedcontroller.controller_number = 91;
01293                 break;
01294             case _lev_ctrl_effect2depth:
01295                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01296                 decodedcontroller.controller_number = 92;
01297                 break;
01298             case _lev_ctrl_effect3depth:
01299                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01300                 decodedcontroller.controller_number = 93;
01301                 break;
01302             case _lev_ctrl_effect4depth:
01303                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01304                 decodedcontroller.controller_number = 94;
01305                 break;
01306             case _lev_ctrl_effect5depth:
01307                 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
01308                 decodedcontroller.controller_number = 95;
01309                 break;
01310 
01311             // unknown controller type
01312             default:
01313                 throw gig::Exception("Unknown leverage controller type.");
01314         }
01315         return decodedcontroller;
01316     }
01317 
01318     DimensionRegion::~DimensionRegion() {
01319         Instances--;
01320         if (!Instances) {
01321             // delete the velocity->volume tables
01322             VelocityTableMap::iterator iter;
01323             for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
01324                 double* pTable = iter->second;
01325                 if (pTable) delete[] pTable;
01326             }
01327             pVelocityTables->clear();
01328             delete pVelocityTables;
01329             pVelocityTables = NULL;
01330         }
01331     }
01332 
01344     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
01345         return pVelocityAttenuationTable[MIDIKeyVelocity];
01346     }
01347 
01348     double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
01349         return pVelocityReleaseTable[MIDIKeyVelocity];
01350     }
01351 
01352     double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
01353 
01354         // line-segment approximations of the 15 velocity curves
01355 
01356         // linear
01357         const int lin0[] = { 1, 1, 127, 127 };
01358         const int lin1[] = { 1, 21, 127, 127 };
01359         const int lin2[] = { 1, 45, 127, 127 };
01360         const int lin3[] = { 1, 74, 127, 127 };
01361         const int lin4[] = { 1, 127, 127, 127 };
01362 
01363         // non-linear
01364         const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
01365         const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
01366                              127, 127 };
01367         const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
01368                              127, 127 };
01369         const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
01370                              127, 127 };
01371         const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
01372 
01373         // special
01374         const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
01375                              113, 127, 127, 127 };
01376         const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
01377                              118, 127, 127, 127 };
01378         const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
01379                              85, 90, 91, 127, 127, 127 };
01380         const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
01381                              117, 127, 127, 127 };
01382         const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
01383                              127, 127 };
01384 
01385         const int* const curves[] = { non0, non1, non2, non3, non4,
01386                                       lin0, lin1, lin2, lin3, lin4,
01387                                       spe0, spe1, spe2, spe3, spe4 };
01388 
01389         double* const table = new double[128];
01390 
01391         const int* curve = curves[curveType * 5 + depth];
01392         const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
01393 
01394         table[0] = 0;
01395         for (int x = 1 ; x < 128 ; x++) {
01396 
01397             if (x > curve[2]) curve += 2;
01398             double y = curve[1] + (x - curve[0]) *
01399                 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
01400             y = y / 127;
01401 
01402             // Scale up for s > 20, down for s < 20. When
01403             // down-scaling, the curve still ends at 1.0.
01404             if (s < 20 && y >= 0.5)
01405                 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
01406             else
01407                 y = y * (s / 20.0);
01408             if (y > 1) y = 1;
01409 
01410             table[x] = y;
01411         }
01412         return table;
01413     }
01414 
01415 
01416 // *************** Region ***************
01417 // *
01418 
01419     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
01420         // Initialization
01421         Dimensions = 0;
01422         for (int i = 0; i < 256; i++) {
01423             pDimensionRegions[i] = NULL;
01424         }
01425         Layers = 1;
01426         File* file = (File*) GetParent()->GetParent();
01427         int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
01428 
01429         // Actual Loading
01430 
01431         LoadDimensionRegions(rgnList);
01432 
01433         RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
01434         if (_3lnk) {
01435             DimensionRegions = _3lnk->ReadUint32();
01436             for (int i = 0; i < dimensionBits; i++) {
01437                 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
01438                 uint8_t     bits      = _3lnk->ReadUint8();
01439                 if (dimension == dimension_none) { // inactive dimension
01440                     pDimensionDefinitions[i].dimension  = dimension_none;
01441                     pDimensionDefinitions[i].bits       = 0;
01442                     pDimensionDefinitions[i].zones      = 0;
01443                     pDimensionDefinitions[i].split_type = split_type_bit;
01444                     pDimensionDefinitions[i].ranges     = NULL;
01445                     pDimensionDefinitions[i].zone_size  = 0;
01446                 }
01447                 else { // active dimension
01448                     pDimensionDefinitions[i].dimension = dimension;
01449                     pDimensionDefinitions[i].bits      = bits;
01450                     pDimensionDefinitions[i].zones     = 0x01 << bits; // = pow(2,bits)
01451                     pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
01452                                                            dimension == dimension_samplechannel ||
01453                                                            dimension == dimension_releasetrigger ||
01454                                                            dimension == dimension_roundrobin ||
01455                                                            dimension == dimension_random) ? split_type_bit
01456                                                                                           : split_type_normal;
01457                     pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
01458                     pDimensionDefinitions[i].zone_size  =
01459                         (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
01460                                                                                    : 0;
01461                     Dimensions++;
01462 
01463                     // if this is a layer dimension, remember the amount of layers
01464                     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
01465                 }
01466                 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
01467             }
01468 
01469             // check velocity dimension (if there is one) for custom defined zone ranges
01470             for (uint i = 0; i < Dimensions; i++) {
01471                 dimension_def_t* pDimDef = pDimensionDefinitions + i;
01472                 if (pDimDef->dimension == dimension_velocity) {
01473                     if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
01474                         // no custom defined ranges
01475                         pDimDef->split_type = split_type_normal;
01476                         pDimDef->ranges     = NULL;
01477                     }
01478                     else { // custom defined ranges
01479                         pDimDef->split_type = split_type_customvelocity;
01480                         pDimDef->ranges     = new range_t[pDimDef->zones];
01481                         uint8_t bits[8] = { 0 };
01482                         int previousUpperLimit = -1;
01483                         for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
01484                             bits[i] = velocityZone;
01485                             DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits);
01486 
01487                             pDimDef->ranges[velocityZone].low  = previousUpperLimit + 1;
01488                             pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
01489                             previousUpperLimit = pDimDef->ranges[velocityZone].high;
01490                             // fill velocity table
01491                             for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
01492                                 VelocityTable[i] = velocityZone;
01493                             }
01494                         }
01495                     }
01496                 }
01497             }
01498 
01499             // jump to start of the wave pool indices (if not already there)
01500             File* file = (File*) GetParent()->GetParent();
01501             if (file->pVersion && file->pVersion->major == 3)
01502                 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
01503             else
01504                 _3lnk->SetPos(44);
01505 
01506             // load sample references
01507             for (uint i = 0; i < DimensionRegions; i++) {
01508                 uint32_t wavepoolindex = _3lnk->ReadUint32();
01509                 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
01510             }
01511         }
01512         else throw gig::Exception("Mandatory <3lnk> chunk not found.");
01513     }
01514 
01515     void Region::LoadDimensionRegions(RIFF::List* rgn) {
01516         RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
01517         if (_3prg) {
01518             int dimensionRegionNr = 0;
01519             RIFF::List* _3ewl = _3prg->GetFirstSubList();
01520             while (_3ewl) {
01521                 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
01522                     pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
01523                     dimensionRegionNr++;
01524                 }
01525                 _3ewl = _3prg->GetNextSubList();
01526             }
01527             if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
01528         }
01529     }
01530 
01531     Region::~Region() {
01532         for (uint i = 0; i < Dimensions; i++) {
01533             if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
01534         }
01535         for (int i = 0; i < 256; i++) {
01536             if (pDimensionRegions[i]) delete pDimensionRegions[i];
01537         }
01538     }
01539 
01558     DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
01559         uint8_t bits[8] = { 0 };
01560         for (uint i = 0; i < Dimensions; i++) {
01561             bits[i] = DimValues[i];
01562             switch (pDimensionDefinitions[i].split_type) {
01563                 case split_type_normal:
01564                     bits[i] /= pDimensionDefinitions[i].zone_size;
01565                     break;
01566                 case split_type_customvelocity:
01567                     bits[i] = VelocityTable[bits[i]];
01568                     break;
01569                 case split_type_bit: // the value is already the sought dimension bit number
01570                     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
01571                     bits[i] = bits[i] & limiter_mask; // just make sure the value don't uses more bits than allowed
01572                     break;
01573             }
01574         }
01575         return GetDimensionRegionByBit(bits);
01576     }
01577 
01588     DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
01589         return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
01590                                                   << pDimensionDefinitions[5].bits | DimBits[5])
01591                                                   << pDimensionDefinitions[4].bits | DimBits[4])
01592                                                   << pDimensionDefinitions[3].bits | DimBits[3])
01593                                                   << pDimensionDefinitions[2].bits | DimBits[2])
01594                                                   << pDimensionDefinitions[1].bits | DimBits[1])
01595                                                   << pDimensionDefinitions[0].bits | DimBits[0]];
01596     }
01597 
01607     Sample* Region::GetSample() {
01608         if (pSample) return static_cast<gig::Sample*>(pSample);
01609         else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
01610     }
01611 
01612     Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
01613         if ((int32_t)WavePoolTableIndex == -1) return NULL;
01614         File* file = (File*) GetParent()->GetParent();
01615         unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
01616         Sample* sample = file->GetFirstSample(pProgress);
01617         while (sample) {
01618             if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
01619             sample = file->GetNextSample();
01620         }
01621         return NULL;
01622     }
01623 
01624 
01625 
01626 // *************** Instrument ***************
01627 // *
01628 
01629     Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
01630         // Initialization
01631         for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
01632         RegionIndex = -1;
01633 
01634         // Loading
01635         RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
01636         if (lart) {
01637             RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
01638             if (_3ewg) {
01639                 EffectSend             = _3ewg->ReadUint16();
01640                 Attenuation            = _3ewg->ReadInt32();
01641                 FineTune               = _3ewg->ReadInt16();
01642                 PitchbendRange         = _3ewg->ReadInt16();
01643                 uint8_t dimkeystart    = _3ewg->ReadUint8();
01644                 PianoReleaseMode       = dimkeystart & 0x01;
01645                 DimensionKeyRange.low  = dimkeystart >> 1;
01646                 DimensionKeyRange.high = _3ewg->ReadUint8();
01647             }
01648             else throw gig::Exception("Mandatory <3ewg> chunk not found.");
01649         }
01650         else throw gig::Exception("Mandatory <lart> list chunk not found.");
01651 
01652         RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
01653         if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
01654         pRegions = new Region*[Regions];
01655         for (uint i = 0; i < Regions; i++) pRegions[i] = NULL;
01656         RIFF::List* rgn = lrgn->GetFirstSubList();
01657         unsigned int iRegion = 0;
01658         while (rgn) {
01659             if (rgn->GetListType() == LIST_TYPE_RGN) {
01660                 __notify_progress(pProgress, (float) iRegion / (float) Regions);
01661                 pRegions[iRegion] = new Region(this, rgn);
01662                 iRegion++;
01663             }
01664             rgn = lrgn->GetNextSubList();
01665         }
01666 
01667         // Creating Region Key Table for fast lookup
01668         for (uint iReg = 0; iReg < Regions; iReg++) {
01669             for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
01670                 RegionKeyTable[iKey] = pRegions[iReg];
01671             }
01672         }
01673 
01674         __notify_progress(pProgress, 1.0f); // notify done
01675     }
01676 
01677     Instrument::~Instrument() {
01678         for (uint i = 0; i < Regions; i++) {
01679             if (pRegions) {
01680                 if (pRegions[i]) delete (pRegions[i]);
01681             }
01682         }
01683         if (pRegions) delete[] pRegions;
01684     }
01685 
01693     Region* Instrument::GetRegion(unsigned int Key) {
01694         if (!pRegions || Key > 127) return NULL;
01695         return RegionKeyTable[Key];
01696         /*for (int i = 0; i < Regions; i++) {
01697             if (Key <= pRegions[i]->KeyRange.high &&
01698                 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
01699         }
01700         return NULL;*/
01701     }
01702 
01710     Region* Instrument::GetFirstRegion() {
01711         if (!Regions) return NULL;
01712         RegionIndex = 1;
01713         return pRegions[0];
01714     }
01715 
01724     Region* Instrument::GetNextRegion() {
01725         if (RegionIndex < 0 || uint32_t(RegionIndex) >= Regions) return NULL;
01726         return pRegions[RegionIndex++];
01727     }
01728 
01729 
01730 
01731 // *************** File ***************
01732 // *
01733 
01734     File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
01735         pSamples     = NULL;
01736         pInstruments = NULL;
01737     }
01738 
01739     File::~File() {
01740         // free samples
01741         if (pSamples) {
01742             SamplesIterator = pSamples->begin();
01743             while (SamplesIterator != pSamples->end() ) {
01744                 delete (*SamplesIterator);
01745                 SamplesIterator++;
01746             }
01747             pSamples->clear();
01748             delete pSamples;
01749 
01750         }
01751         // free instruments
01752         if (pInstruments) {
01753             InstrumentsIterator = pInstruments->begin();
01754             while (InstrumentsIterator != pInstruments->end() ) {
01755                 delete (*InstrumentsIterator);
01756                 InstrumentsIterator++;
01757             }
01758             pInstruments->clear();
01759             delete pInstruments;
01760         }
01761     }
01762 
01763     Sample* File::GetFirstSample(progress_t* pProgress) {
01764         if (!pSamples) LoadSamples(pProgress);
01765         if (!pSamples) return NULL;
01766         SamplesIterator = pSamples->begin();
01767         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01768     }
01769 
01770     Sample* File::GetNextSample() {
01771         if (!pSamples) return NULL;
01772         SamplesIterator++;
01773         return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
01774     }
01775 
01776     void File::LoadSamples(progress_t* pProgress) {
01777         RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
01778         if (wvpl) {
01779             // just for progress calculation
01780             int iSampleIndex  = 0;
01781             int iTotalSamples = wvpl->CountSubLists(LIST_TYPE_WAVE);
01782 
01783             unsigned long wvplFileOffset = wvpl->GetFilePos();
01784             RIFF::List* wave = wvpl->GetFirstSubList();
01785             while (wave) {
01786                 if (wave->GetListType() == LIST_TYPE_WAVE) {
01787                     // notify current progress
01788                     const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
01789                     __notify_progress(pProgress, subprogress);
01790 
01791                     if (!pSamples) pSamples = new SampleList;
01792                     unsigned long waveFileOffset = wave->GetFilePos();
01793                     pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
01794 
01795                     iSampleIndex++;
01796                 }
01797                 wave = wvpl->GetNextSubList();
01798             }
01799             __notify_progress(pProgress, 1.0); // notify done
01800         }
01801         else throw gig::Exception("Mandatory <wvpl> chunk not found.");
01802     }
01803 
01804     Instrument* File::GetFirstInstrument() {
01805         if (!pInstruments) LoadInstruments();
01806         if (!pInstruments) return NULL;
01807         InstrumentsIterator = pInstruments->begin();
01808         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01809     }
01810 
01811     Instrument* File::GetNextInstrument() {
01812         if (!pInstruments) return NULL;
01813         InstrumentsIterator++;
01814         return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
01815     }
01816 
01824     Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
01825         if (!pInstruments) {
01826             // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
01827 
01828             // sample loading subtask
01829             progress_t subprogress;
01830             __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
01831             __notify_progress(&subprogress, 0.0f);
01832             GetFirstSample(&subprogress); // now force all samples to be loaded
01833             __notify_progress(&subprogress, 1.0f);
01834 
01835             // instrument loading subtask
01836             if (pProgress && pProgress->callback) {
01837                 subprogress.__range_min = subprogress.__range_max;
01838                 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
01839             }
01840             __notify_progress(&subprogress, 0.0f);
01841             LoadInstruments(&subprogress);
01842             __notify_progress(&subprogress, 1.0f);
01843         }
01844         if (!pInstruments) return NULL;
01845         InstrumentsIterator = pInstruments->begin();
01846         for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
01847             if (i == index) return *InstrumentsIterator;
01848             InstrumentsIterator++;
01849         }
01850         return NULL;
01851     }
01852 
01853     void File::LoadInstruments(progress_t* pProgress) {
01854         RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
01855         if (lstInstruments) {
01856             int iInstrumentIndex = 0;
01857             RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
01858             while (lstInstr) {
01859                 if (lstInstr->GetListType() == LIST_TYPE_INS) {
01860                     // notify current progress
01861                     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
01862                     __notify_progress(pProgress, localProgress);
01863 
01864                     // divide local progress into subprogress for loading current Instrument
01865                     progress_t subprogress;
01866                     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
01867 
01868                     if (!pInstruments) pInstruments = new InstrumentList;
01869                     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
01870 
01871                     iInstrumentIndex++;
01872                 }
01873                 lstInstr = lstInstruments->GetNextSubList();
01874             }
01875             __notify_progress(pProgress, 1.0); // notify done
01876         }
01877         else throw gig::Exception("Mandatory <lins> list chunk not found.");
01878     }
01879 
01880 
01881 
01882 // *************** Exception ***************
01883 // *
01884 
01885     Exception::Exception(String Message) : DLS::Exception(Message) {
01886     }
01887 
01888     void Exception::PrintMessage() {
01889         std::cout << "gig::Exception: " << Message << std::endl;
01890     }
01891 
01892 
01893 // *************** functions ***************
01894 // *
01895 
01901     String libraryName() {
01902         return PACKAGE;
01903     }
01904 
01909     String libraryVersion() {
01910         return VERSION;
01911     }
01912 
01913 } // namespace gig

Generated on Fri Jul 29 22:09:29 2005 for libgig by doxygen 1.3.4