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