/[svn]/libgig/trunk/src/gig.cpp
ViewVC logotype

Contents of /libgig/trunk/src/gig.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1335 - (show annotations) (download)
Sun Sep 9 21:22:58 2007 UTC (16 years, 6 months ago) by schoenebeck
File size: 164818 byte(s)
* added virtual method SetKeyRange() to the gig and DLS Region classes,
  which automatically take care that the "resized" Region is at the
  correct position and that the lookup table for
  gig::Instrument::GetRegion() is updated (moved code from gigedit)
* MoveRegion() method of DLS::Region class is now private
* bugfix: gig::Instrument::UpdateRegionKeyTable() did not reset unused
  areas

1 /***************************************************************************
2 * *
3 * libgig - C++ cross-platform Gigasampler format file access library *
4 * *
5 * Copyright (C) 2003-2007 by Christian Schoenebeck *
6 * <cuse@users.sourceforge.net> *
7 * *
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "gig.h"
25
26 #include "helper.h"
27
28 #include <math.h>
29 #include <iostream>
30
31 /// Initial size of the sample buffer which is used for decompression of
32 /// compressed sample wave streams - this value should always be bigger than
33 /// the biggest sample piece expected to be read by the sampler engine,
34 /// otherwise the buffer size will be raised at runtime and thus the buffer
35 /// reallocated which is time consuming and unefficient.
36 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
37
38 /** (so far) every exponential paramater in the gig format has a basis of 1.000000008813822 */
39 #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x))
40 #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822))
41 #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01))
42 #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01)
43 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03)
44 #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4)
45 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03)
46 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03)
47 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
48 #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1)
49 #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3)
50 #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5)
51
52 namespace gig {
53
54 // *************** progress_t ***************
55 // *
56
57 progress_t::progress_t() {
58 callback = NULL;
59 custom = NULL;
60 __range_min = 0.0f;
61 __range_max = 1.0f;
62 }
63
64 // private helper function to convert progress of a subprocess into the global progress
65 static void __notify_progress(progress_t* pProgress, float subprogress) {
66 if (pProgress && pProgress->callback) {
67 const float totalrange = pProgress->__range_max - pProgress->__range_min;
68 const float totalprogress = pProgress->__range_min + subprogress * totalrange;
69 pProgress->factor = totalprogress;
70 pProgress->callback(pProgress); // now actually notify about the progress
71 }
72 }
73
74 // private helper function to divide a progress into subprogresses
75 static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) {
76 if (pParentProgress && pParentProgress->callback) {
77 const float totalrange = pParentProgress->__range_max - pParentProgress->__range_min;
78 pSubProgress->callback = pParentProgress->callback;
79 pSubProgress->custom = pParentProgress->custom;
80 pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks;
81 pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks;
82 }
83 }
84
85
86 // *************** Internal functions for sample decompression ***************
87 // *
88
89 namespace {
90
91 inline int get12lo(const unsigned char* pSrc)
92 {
93 const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
94 return x & 0x800 ? x - 0x1000 : x;
95 }
96
97 inline int get12hi(const unsigned char* pSrc)
98 {
99 const int x = pSrc[1] >> 4 | pSrc[2] << 4;
100 return x & 0x800 ? x - 0x1000 : x;
101 }
102
103 inline int16_t get16(const unsigned char* pSrc)
104 {
105 return int16_t(pSrc[0] | pSrc[1] << 8);
106 }
107
108 inline int get24(const unsigned char* pSrc)
109 {
110 const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
111 return x & 0x800000 ? x - 0x1000000 : x;
112 }
113
114 inline void store24(unsigned char* pDst, int x)
115 {
116 pDst[0] = x;
117 pDst[1] = x >> 8;
118 pDst[2] = x >> 16;
119 }
120
121 void Decompress16(int compressionmode, const unsigned char* params,
122 int srcStep, int dstStep,
123 const unsigned char* pSrc, int16_t* pDst,
124 unsigned long currentframeoffset,
125 unsigned long copysamples)
126 {
127 switch (compressionmode) {
128 case 0: // 16 bit uncompressed
129 pSrc += currentframeoffset * srcStep;
130 while (copysamples) {
131 *pDst = get16(pSrc);
132 pDst += dstStep;
133 pSrc += srcStep;
134 copysamples--;
135 }
136 break;
137
138 case 1: // 16 bit compressed to 8 bit
139 int y = get16(params);
140 int dy = get16(params + 2);
141 while (currentframeoffset) {
142 dy -= int8_t(*pSrc);
143 y -= dy;
144 pSrc += srcStep;
145 currentframeoffset--;
146 }
147 while (copysamples) {
148 dy -= int8_t(*pSrc);
149 y -= dy;
150 *pDst = y;
151 pDst += dstStep;
152 pSrc += srcStep;
153 copysamples--;
154 }
155 break;
156 }
157 }
158
159 void Decompress24(int compressionmode, const unsigned char* params,
160 int dstStep, const unsigned char* pSrc, uint8_t* pDst,
161 unsigned long currentframeoffset,
162 unsigned long copysamples, int truncatedBits)
163 {
164 int y, dy, ddy, dddy;
165
166 #define GET_PARAMS(params) \
167 y = get24(params); \
168 dy = y - get24((params) + 3); \
169 ddy = get24((params) + 6); \
170 dddy = get24((params) + 9)
171
172 #define SKIP_ONE(x) \
173 dddy -= (x); \
174 ddy -= dddy; \
175 dy = -dy - ddy; \
176 y += dy
177
178 #define COPY_ONE(x) \
179 SKIP_ONE(x); \
180 store24(pDst, y << truncatedBits); \
181 pDst += dstStep
182
183 switch (compressionmode) {
184 case 2: // 24 bit uncompressed
185 pSrc += currentframeoffset * 3;
186 while (copysamples) {
187 store24(pDst, get24(pSrc) << truncatedBits);
188 pDst += dstStep;
189 pSrc += 3;
190 copysamples--;
191 }
192 break;
193
194 case 3: // 24 bit compressed to 16 bit
195 GET_PARAMS(params);
196 while (currentframeoffset) {
197 SKIP_ONE(get16(pSrc));
198 pSrc += 2;
199 currentframeoffset--;
200 }
201 while (copysamples) {
202 COPY_ONE(get16(pSrc));
203 pSrc += 2;
204 copysamples--;
205 }
206 break;
207
208 case 4: // 24 bit compressed to 12 bit
209 GET_PARAMS(params);
210 while (currentframeoffset > 1) {
211 SKIP_ONE(get12lo(pSrc));
212 SKIP_ONE(get12hi(pSrc));
213 pSrc += 3;
214 currentframeoffset -= 2;
215 }
216 if (currentframeoffset) {
217 SKIP_ONE(get12lo(pSrc));
218 currentframeoffset--;
219 if (copysamples) {
220 COPY_ONE(get12hi(pSrc));
221 pSrc += 3;
222 copysamples--;
223 }
224 }
225 while (copysamples > 1) {
226 COPY_ONE(get12lo(pSrc));
227 COPY_ONE(get12hi(pSrc));
228 pSrc += 3;
229 copysamples -= 2;
230 }
231 if (copysamples) {
232 COPY_ONE(get12lo(pSrc));
233 }
234 break;
235
236 case 5: // 24 bit compressed to 8 bit
237 GET_PARAMS(params);
238 while (currentframeoffset) {
239 SKIP_ONE(int8_t(*pSrc++));
240 currentframeoffset--;
241 }
242 while (copysamples) {
243 COPY_ONE(int8_t(*pSrc++));
244 copysamples--;
245 }
246 break;
247 }
248 }
249
250 const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
251 const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
252 const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
253 const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
254 }
255
256
257
258 // *************** Other Internal functions ***************
259 // *
260
261 static split_type_t __resolveSplitType(dimension_t dimension) {
262 return (
263 dimension == dimension_layer ||
264 dimension == dimension_samplechannel ||
265 dimension == dimension_releasetrigger ||
266 dimension == dimension_keyboard ||
267 dimension == dimension_roundrobin ||
268 dimension == dimension_random ||
269 dimension == dimension_smartmidi ||
270 dimension == dimension_roundrobinkeyboard
271 ) ? split_type_bit : split_type_normal;
272 }
273
274 static int __resolveZoneSize(dimension_def_t& dimension_definition) {
275 return (dimension_definition.split_type == split_type_normal)
276 ? int(128.0 / dimension_definition.zones) : 0;
277 }
278
279
280
281 // *************** CRC ***************
282 // *
283
284 const uint32_t* CRC::table(initTable());
285
286 uint32_t* CRC::initTable() {
287 uint32_t* res = new uint32_t[256];
288
289 for (int i = 0 ; i < 256 ; i++) {
290 uint32_t c = i;
291 for (int j = 0 ; j < 8 ; j++) {
292 c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
293 }
294 res[i] = c;
295 }
296 return res;
297 }
298
299
300
301 // *************** Sample ***************
302 // *
303
304 unsigned int Sample::Instances = 0;
305 buffer_t Sample::InternalDecompressionBuffer;
306
307 /** @brief Constructor.
308 *
309 * Load an existing sample or create a new one. A 'wave' list chunk must
310 * be given to this constructor. In case the given 'wave' list chunk
311 * contains a 'fmt', 'data' (and optionally a '3gix', 'smpl') chunk, the
312 * format and sample data will be loaded from there, otherwise default
313 * values will be used and those chunks will be created when
314 * File::Save() will be called later on.
315 *
316 * @param pFile - pointer to gig::File where this sample is
317 * located (or will be located)
318 * @param waveList - pointer to 'wave' list chunk which is (or
319 * will be) associated with this sample
320 * @param WavePoolOffset - offset of this sample data from wave pool
321 * ('wvpl') list chunk
322 * @param fileNo - number of an extension file where this sample
323 * is located, 0 otherwise
324 */
325 Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
326 static const DLS::Info::FixedStringLength fixedStringLengths[] = {
327 { CHUNK_ID_INAM, 64 },
328 { 0, 0 }
329 };
330 pInfo->FixedStringLengths = fixedStringLengths;
331 Instances++;
332 FileNo = fileNo;
333
334 pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
335 if (pCk3gix) {
336 uint16_t iSampleGroup = pCk3gix->ReadInt16();
337 pGroup = pFile->GetGroup(iSampleGroup);
338 } else { // '3gix' chunk missing
339 // by default assigned to that mandatory "Default Group"
340 pGroup = pFile->GetGroup(0);
341 }
342
343 pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
344 if (pCkSmpl) {
345 Manufacturer = pCkSmpl->ReadInt32();
346 Product = pCkSmpl->ReadInt32();
347 SamplePeriod = pCkSmpl->ReadInt32();
348 MIDIUnityNote = pCkSmpl->ReadInt32();
349 FineTune = pCkSmpl->ReadInt32();
350 pCkSmpl->Read(&SMPTEFormat, 1, 4);
351 SMPTEOffset = pCkSmpl->ReadInt32();
352 Loops = pCkSmpl->ReadInt32();
353 pCkSmpl->ReadInt32(); // manufByt
354 LoopID = pCkSmpl->ReadInt32();
355 pCkSmpl->Read(&LoopType, 1, 4);
356 LoopStart = pCkSmpl->ReadInt32();
357 LoopEnd = pCkSmpl->ReadInt32();
358 LoopFraction = pCkSmpl->ReadInt32();
359 LoopPlayCount = pCkSmpl->ReadInt32();
360 } else { // 'smpl' chunk missing
361 // use default values
362 Manufacturer = 0;
363 Product = 0;
364 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
365 MIDIUnityNote = 60;
366 FineTune = 0;
367 SMPTEFormat = smpte_format_no_offset;
368 SMPTEOffset = 0;
369 Loops = 0;
370 LoopID = 0;
371 LoopType = loop_type_normal;
372 LoopStart = 0;
373 LoopEnd = 0;
374 LoopFraction = 0;
375 LoopPlayCount = 0;
376 }
377
378 FrameTable = NULL;
379 SamplePos = 0;
380 RAMCache.Size = 0;
381 RAMCache.pStart = NULL;
382 RAMCache.NullExtensionSize = 0;
383
384 if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
385
386 RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
387 Compressed = ewav;
388 Dithered = false;
389 TruncatedBits = 0;
390 if (Compressed) {
391 uint32_t version = ewav->ReadInt32();
392 if (version == 3 && BitDepth == 24) {
393 Dithered = ewav->ReadInt32();
394 ewav->SetPos(Channels == 2 ? 84 : 64);
395 TruncatedBits = ewav->ReadInt32();
396 }
397 ScanCompressedSample();
398 }
399
400 // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
401 if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
402 InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
403 InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE;
404 }
405 FrameOffset = 0; // just for streaming compressed samples
406
407 LoopSize = LoopEnd - LoopStart + 1;
408 }
409
410 /**
411 * Apply sample and its settings to the respective RIFF chunks. You have
412 * to call File::Save() to make changes persistent.
413 *
414 * Usually there is absolutely no need to call this method explicitly.
415 * It will be called automatically when File::Save() was called.
416 *
417 * @throws DLS::Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data
418 * was provided yet
419 * @throws gig::Exception if there is any invalid sample setting
420 */
421 void Sample::UpdateChunks() {
422 // first update base class's chunks
423 DLS::Sample::UpdateChunks();
424
425 // make sure 'smpl' chunk exists
426 pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
427 if (!pCkSmpl) {
428 pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
429 memset(pCkSmpl->LoadChunkData(), 0, 60);
430 }
431 // update 'smpl' chunk
432 uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
433 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
434 store32(&pData[0], Manufacturer);
435 store32(&pData[4], Product);
436 store32(&pData[8], SamplePeriod);
437 store32(&pData[12], MIDIUnityNote);
438 store32(&pData[16], FineTune);
439 store32(&pData[20], SMPTEFormat);
440 store32(&pData[24], SMPTEOffset);
441 store32(&pData[28], Loops);
442
443 // we skip 'manufByt' for now (4 bytes)
444
445 store32(&pData[36], LoopID);
446 store32(&pData[40], LoopType);
447 store32(&pData[44], LoopStart);
448 store32(&pData[48], LoopEnd);
449 store32(&pData[52], LoopFraction);
450 store32(&pData[56], LoopPlayCount);
451
452 // make sure '3gix' chunk exists
453 pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
454 if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
455 // determine appropriate sample group index (to be stored in chunk)
456 uint16_t iSampleGroup = 0; // 0 refers to default sample group
457 File* pFile = static_cast<File*>(pParent);
458 if (pFile->pGroups) {
459 std::list<Group*>::iterator iter = pFile->pGroups->begin();
460 std::list<Group*>::iterator end = pFile->pGroups->end();
461 for (int i = 0; iter != end; i++, iter++) {
462 if (*iter == pGroup) {
463 iSampleGroup = i;
464 break; // found
465 }
466 }
467 }
468 // update '3gix' chunk
469 pData = (uint8_t*) pCk3gix->LoadChunkData();
470 store16(&pData[0], iSampleGroup);
471 }
472
473 /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
474 void Sample::ScanCompressedSample() {
475 //TODO: we have to add some more scans here (e.g. determine compression rate)
476 this->SamplesTotal = 0;
477 std::list<unsigned long> frameOffsets;
478
479 SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
480 WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
481
482 // Scanning
483 pCkData->SetPos(0);
484 if (Channels == 2) { // Stereo
485 for (int i = 0 ; ; i++) {
486 // for 24 bit samples every 8:th frame offset is
487 // stored, to save some memory
488 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
489
490 const int mode_l = pCkData->ReadUint8();
491 const int mode_r = pCkData->ReadUint8();
492 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
493 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
494
495 if (pCkData->RemainingBytes() <= frameSize) {
496 SamplesInLastFrame =
497 ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
498 (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
499 SamplesTotal += SamplesInLastFrame;
500 break;
501 }
502 SamplesTotal += SamplesPerFrame;
503 pCkData->SetPos(frameSize, RIFF::stream_curpos);
504 }
505 }
506 else { // Mono
507 for (int i = 0 ; ; i++) {
508 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
509
510 const int mode = pCkData->ReadUint8();
511 if (mode > 5) throw gig::Exception("Unknown compression mode");
512 const unsigned long frameSize = bytesPerFrame[mode];
513
514 if (pCkData->RemainingBytes() <= frameSize) {
515 SamplesInLastFrame =
516 ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
517 SamplesTotal += SamplesInLastFrame;
518 break;
519 }
520 SamplesTotal += SamplesPerFrame;
521 pCkData->SetPos(frameSize, RIFF::stream_curpos);
522 }
523 }
524 pCkData->SetPos(0);
525
526 // Build the frames table (which is used for fast resolving of a frame's chunk offset)
527 if (FrameTable) delete[] FrameTable;
528 FrameTable = new unsigned long[frameOffsets.size()];
529 std::list<unsigned long>::iterator end = frameOffsets.end();
530 std::list<unsigned long>::iterator iter = frameOffsets.begin();
531 for (int i = 0; iter != end; i++, iter++) {
532 FrameTable[i] = *iter;
533 }
534 }
535
536 /**
537 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
538 * ReleaseSampleData() to free the memory if you don't need the cached
539 * sample data anymore.
540 *
541 * @returns buffer_t structure with start address and size of the buffer
542 * in bytes
543 * @see ReleaseSampleData(), Read(), SetPos()
544 */
545 buffer_t Sample::LoadSampleData() {
546 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
547 }
548
549 /**
550 * Reads (uncompresses if needed) and caches the first \a SampleCount
551 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
552 * memory space if you don't need the cached samples anymore. There is no
553 * guarantee that exactly \a SampleCount samples will be cached; this is
554 * not an error. The size will be eventually truncated e.g. to the
555 * beginning of a frame of a compressed sample. This is done for
556 * efficiency reasons while streaming the wave by your sampler engine
557 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
558 * that will be returned to determine the actual cached samples, but note
559 * that the size is given in bytes! You get the number of actually cached
560 * samples by dividing it by the frame size of the sample:
561 * @code
562 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
563 * long cachedsamples = buf.Size / pSample->FrameSize;
564 * @endcode
565 *
566 * @param SampleCount - number of sample points to load into RAM
567 * @returns buffer_t structure with start address and size of
568 * the cached sample data in bytes
569 * @see ReleaseSampleData(), Read(), SetPos()
570 */
571 buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
572 return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
573 }
574
575 /**
576 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
577 * ReleaseSampleData() to free the memory if you don't need the cached
578 * sample data anymore.
579 * The method will add \a NullSamplesCount silence samples past the
580 * official buffer end (this won't affect the 'Size' member of the
581 * buffer_t structure, that means 'Size' always reflects the size of the
582 * actual sample data, the buffer might be bigger though). Silence
583 * samples past the official buffer are needed for differential
584 * algorithms that always have to take subsequent samples into account
585 * (resampling/interpolation would be an important example) and avoids
586 * memory access faults in such cases.
587 *
588 * @param NullSamplesCount - number of silence samples the buffer should
589 * be extended past it's data end
590 * @returns buffer_t structure with start address and
591 * size of the buffer in bytes
592 * @see ReleaseSampleData(), Read(), SetPos()
593 */
594 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
595 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
596 }
597
598 /**
599 * Reads (uncompresses if needed) and caches the first \a SampleCount
600 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
601 * memory space if you don't need the cached samples anymore. There is no
602 * guarantee that exactly \a SampleCount samples will be cached; this is
603 * not an error. The size will be eventually truncated e.g. to the
604 * beginning of a frame of a compressed sample. This is done for
605 * efficiency reasons while streaming the wave by your sampler engine
606 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
607 * that will be returned to determine the actual cached samples, but note
608 * that the size is given in bytes! You get the number of actually cached
609 * samples by dividing it by the frame size of the sample:
610 * @code
611 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
612 * long cachedsamples = buf.Size / pSample->FrameSize;
613 * @endcode
614 * The method will add \a NullSamplesCount silence samples past the
615 * official buffer end (this won't affect the 'Size' member of the
616 * buffer_t structure, that means 'Size' always reflects the size of the
617 * actual sample data, the buffer might be bigger though). Silence
618 * samples past the official buffer are needed for differential
619 * algorithms that always have to take subsequent samples into account
620 * (resampling/interpolation would be an important example) and avoids
621 * memory access faults in such cases.
622 *
623 * @param SampleCount - number of sample points to load into RAM
624 * @param NullSamplesCount - number of silence samples the buffer should
625 * be extended past it's data end
626 * @returns buffer_t structure with start address and
627 * size of the cached sample data in bytes
628 * @see ReleaseSampleData(), Read(), SetPos()
629 */
630 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
631 if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
632 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
633 unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
634 RAMCache.pStart = new int8_t[allocationsize];
635 RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
636 RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
637 // fill the remaining buffer space with silence samples
638 memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
639 return GetCache();
640 }
641
642 /**
643 * Returns current cached sample points. A buffer_t structure will be
644 * returned which contains address pointer to the begin of the cache and
645 * the size of the cached sample data in bytes. Use
646 * <i>LoadSampleData()</i> to cache a specific amount of sample points in
647 * RAM.
648 *
649 * @returns buffer_t structure with current cached sample points
650 * @see LoadSampleData();
651 */
652 buffer_t Sample::GetCache() {
653 // return a copy of the buffer_t structure
654 buffer_t result;
655 result.Size = this->RAMCache.Size;
656 result.pStart = this->RAMCache.pStart;
657 result.NullExtensionSize = this->RAMCache.NullExtensionSize;
658 return result;
659 }
660
661 /**
662 * Frees the cached sample from RAM if loaded with
663 * <i>LoadSampleData()</i> previously.
664 *
665 * @see LoadSampleData();
666 */
667 void Sample::ReleaseSampleData() {
668 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
669 RAMCache.pStart = NULL;
670 RAMCache.Size = 0;
671 }
672
673 /** @brief Resize sample.
674 *
675 * Resizes the sample's wave form data, that is the actual size of
676 * sample wave data possible to be written for this sample. This call
677 * will return immediately and just schedule the resize operation. You
678 * should call File::Save() to actually perform the resize operation(s)
679 * "physically" to the file. As this can take a while on large files, it
680 * is recommended to call Resize() first on all samples which have to be
681 * resized and finally to call File::Save() to perform all those resize
682 * operations in one rush.
683 *
684 * The actual size (in bytes) is dependant to the current FrameSize
685 * value. You may want to set FrameSize before calling Resize().
686 *
687 * <b>Caution:</b> You cannot directly write (i.e. with Write()) to
688 * enlarged samples before calling File::Save() as this might exceed the
689 * current sample's boundary!
690 *
691 * Also note: only DLS_WAVE_FORMAT_PCM is currently supported, that is
692 * FormatTag must be DLS_WAVE_FORMAT_PCM. Trying to resize samples with
693 * other formats will fail!
694 *
695 * @param iNewSize - new sample wave data size in sample points (must be
696 * greater than zero)
697 * @throws DLS::Excecption if FormatTag != DLS_WAVE_FORMAT_PCM
698 * or if \a iNewSize is less than 1
699 * @throws gig::Exception if existing sample is compressed
700 * @see DLS::Sample::GetSize(), DLS::Sample::FrameSize,
701 * DLS::Sample::FormatTag, File::Save()
702 */
703 void Sample::Resize(int iNewSize) {
704 if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
705 DLS::Sample::Resize(iNewSize);
706 }
707
708 /**
709 * Sets the position within the sample (in sample points, not in
710 * bytes). Use this method and <i>Read()</i> if you don't want to load
711 * the sample into RAM, thus for disk streaming.
712 *
713 * Although the original Gigasampler engine doesn't allow positioning
714 * within compressed samples, I decided to implement it. Even though
715 * the Gigasampler format doesn't allow to define loops for compressed
716 * samples at the moment, positioning within compressed samples might be
717 * interesting for some sampler engines though. The only drawback about
718 * my decision is that it takes longer to load compressed gig Files on
719 * startup, because it's neccessary to scan the samples for some
720 * mandatory informations. But I think as it doesn't affect the runtime
721 * efficiency, nobody will have a problem with that.
722 *
723 * @param SampleCount number of sample points to jump
724 * @param Whence optional: to which relation \a SampleCount refers
725 * to, if omited <i>RIFF::stream_start</i> is assumed
726 * @returns the new sample position
727 * @see Read()
728 */
729 unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
730 if (Compressed) {
731 switch (Whence) {
732 case RIFF::stream_curpos:
733 this->SamplePos += SampleCount;
734 break;
735 case RIFF::stream_end:
736 this->SamplePos = this->SamplesTotal - 1 - SampleCount;
737 break;
738 case RIFF::stream_backward:
739 this->SamplePos -= SampleCount;
740 break;
741 case RIFF::stream_start: default:
742 this->SamplePos = SampleCount;
743 break;
744 }
745 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
746
747 unsigned long frame = this->SamplePos / 2048; // to which frame to jump
748 this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
749 pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
750 return this->SamplePos;
751 }
752 else { // not compressed
753 unsigned long orderedBytes = SampleCount * this->FrameSize;
754 unsigned long result = pCkData->SetPos(orderedBytes, Whence);
755 return (result == orderedBytes) ? SampleCount
756 : result / this->FrameSize;
757 }
758 }
759
760 /**
761 * Returns the current position in the sample (in sample points).
762 */
763 unsigned long Sample::GetPos() {
764 if (Compressed) return SamplePos;
765 else return pCkData->GetPos() / FrameSize;
766 }
767
768 /**
769 * Reads \a SampleCount number of sample points from the position stored
770 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
771 * the position within the sample respectively, this method honors the
772 * looping informations of the sample (if any). The sample wave stream
773 * will be decompressed on the fly if using a compressed sample. Use this
774 * method if you don't want to load the sample into RAM, thus for disk
775 * streaming. All this methods needs to know to proceed with streaming
776 * for the next time you call this method is stored in \a pPlaybackState.
777 * You have to allocate and initialize the playback_state_t structure by
778 * yourself before you use it to stream a sample:
779 * @code
780 * gig::playback_state_t playbackstate;
781 * playbackstate.position = 0;
782 * playbackstate.reverse = false;
783 * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
784 * @endcode
785 * You don't have to take care of things like if there is actually a loop
786 * defined or if the current read position is located within a loop area.
787 * The method already handles such cases by itself.
788 *
789 * <b>Caution:</b> If you are using more than one streaming thread, you
790 * have to use an external decompression buffer for <b>EACH</b>
791 * streaming thread to avoid race conditions and crashes!
792 *
793 * @param pBuffer destination buffer
794 * @param SampleCount number of sample points to read
795 * @param pPlaybackState will be used to store and reload the playback
796 * state for the next ReadAndLoop() call
797 * @param pDimRgn dimension region with looping information
798 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
799 * @returns number of successfully read sample points
800 * @see CreateDecompressionBuffer()
801 */
802 unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState,
803 DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
804 unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
805 uint8_t* pDst = (uint8_t*) pBuffer;
806
807 SetPos(pPlaybackState->position); // recover position from the last time
808
809 if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
810
811 const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
812 const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
813
814 if (GetPos() <= loopEnd) {
815 switch (loop.LoopType) {
816
817 case loop_type_bidirectional: { //TODO: not tested yet!
818 do {
819 // if not endless loop check if max. number of loop cycles have been passed
820 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
821
822 if (!pPlaybackState->reverse) { // forward playback
823 do {
824 samplestoloopend = loopEnd - GetPos();
825 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
826 samplestoread -= readsamples;
827 totalreadsamples += readsamples;
828 if (readsamples == samplestoloopend) {
829 pPlaybackState->reverse = true;
830 break;
831 }
832 } while (samplestoread && readsamples);
833 }
834 else { // backward playback
835
836 // as we can only read forward from disk, we have to
837 // determine the end position within the loop first,
838 // read forward from that 'end' and finally after
839 // reading, swap all sample frames so it reflects
840 // backward playback
841
842 unsigned long swapareastart = totalreadsamples;
843 unsigned long loopoffset = GetPos() - loop.LoopStart;
844 unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
845 unsigned long reverseplaybackend = GetPos() - samplestoreadinloop;
846
847 SetPos(reverseplaybackend);
848
849 // read samples for backward playback
850 do {
851 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
852 samplestoreadinloop -= readsamples;
853 samplestoread -= readsamples;
854 totalreadsamples += readsamples;
855 } while (samplestoreadinloop && readsamples);
856
857 SetPos(reverseplaybackend); // pretend we really read backwards
858
859 if (reverseplaybackend == loop.LoopStart) {
860 pPlaybackState->loop_cycles_left--;
861 pPlaybackState->reverse = false;
862 }
863
864 // reverse the sample frames for backward playback
865 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
866 }
867 } while (samplestoread && readsamples);
868 break;
869 }
870
871 case loop_type_backward: { // TODO: not tested yet!
872 // forward playback (not entered the loop yet)
873 if (!pPlaybackState->reverse) do {
874 samplestoloopend = loopEnd - GetPos();
875 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
876 samplestoread -= readsamples;
877 totalreadsamples += readsamples;
878 if (readsamples == samplestoloopend) {
879 pPlaybackState->reverse = true;
880 break;
881 }
882 } while (samplestoread && readsamples);
883
884 if (!samplestoread) break;
885
886 // as we can only read forward from disk, we have to
887 // determine the end position within the loop first,
888 // read forward from that 'end' and finally after
889 // reading, swap all sample frames so it reflects
890 // backward playback
891
892 unsigned long swapareastart = totalreadsamples;
893 unsigned long loopoffset = GetPos() - loop.LoopStart;
894 unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
895 : samplestoread;
896 unsigned long reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
897
898 SetPos(reverseplaybackend);
899
900 // read samples for backward playback
901 do {
902 // if not endless loop check if max. number of loop cycles have been passed
903 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
904 samplestoloopend = loopEnd - GetPos();
905 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
906 samplestoreadinloop -= readsamples;
907 samplestoread -= readsamples;
908 totalreadsamples += readsamples;
909 if (readsamples == samplestoloopend) {
910 pPlaybackState->loop_cycles_left--;
911 SetPos(loop.LoopStart);
912 }
913 } while (samplestoreadinloop && readsamples);
914
915 SetPos(reverseplaybackend); // pretend we really read backwards
916
917 // reverse the sample frames for backward playback
918 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
919 break;
920 }
921
922 default: case loop_type_normal: {
923 do {
924 // if not endless loop check if max. number of loop cycles have been passed
925 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
926 samplestoloopend = loopEnd - GetPos();
927 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
928 samplestoread -= readsamples;
929 totalreadsamples += readsamples;
930 if (readsamples == samplestoloopend) {
931 pPlaybackState->loop_cycles_left--;
932 SetPos(loop.LoopStart);
933 }
934 } while (samplestoread && readsamples);
935 break;
936 }
937 }
938 }
939 }
940
941 // read on without looping
942 if (samplestoread) do {
943 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
944 samplestoread -= readsamples;
945 totalreadsamples += readsamples;
946 } while (readsamples && samplestoread);
947
948 // store current position
949 pPlaybackState->position = GetPos();
950
951 return totalreadsamples;
952 }
953
954 /**
955 * Reads \a SampleCount number of sample points from the current
956 * position into the buffer pointed by \a pBuffer and increments the
957 * position within the sample. The sample wave stream will be
958 * decompressed on the fly if using a compressed sample. Use this method
959 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
960 * thus for disk streaming.
961 *
962 * <b>Caution:</b> If you are using more than one streaming thread, you
963 * have to use an external decompression buffer for <b>EACH</b>
964 * streaming thread to avoid race conditions and crashes!
965 *
966 * For 16 bit samples, the data in the buffer will be int16_t
967 * (using native endianness). For 24 bit, the buffer will
968 * contain three bytes per sample, little-endian.
969 *
970 * @param pBuffer destination buffer
971 * @param SampleCount number of sample points to read
972 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
973 * @returns number of successfully read sample points
974 * @see SetPos(), CreateDecompressionBuffer()
975 */
976 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
977 if (SampleCount == 0) return 0;
978 if (!Compressed) {
979 if (BitDepth == 24) {
980 return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
981 }
982 else { // 16 bit
983 // (pCkData->Read does endian correction)
984 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
985 : pCkData->Read(pBuffer, SampleCount, 2);
986 }
987 }
988 else {
989 if (this->SamplePos >= this->SamplesTotal) return 0;
990 //TODO: efficiency: maybe we should test for an average compression rate
991 unsigned long assumedsize = GuessSize(SampleCount),
992 remainingbytes = 0, // remaining bytes in the local buffer
993 remainingsamples = SampleCount,
994 copysamples, skipsamples,
995 currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
996 this->FrameOffset = 0;
997
998 buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
999
1000 // if decompression buffer too small, then reduce amount of samples to read
1001 if (pDecompressionBuffer->Size < assumedsize) {
1002 std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1003 SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1004 remainingsamples = SampleCount;
1005 assumedsize = GuessSize(SampleCount);
1006 }
1007
1008 unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1009 int16_t* pDst = static_cast<int16_t*>(pBuffer);
1010 uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1011 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1012
1013 while (remainingsamples && remainingbytes) {
1014 unsigned long framesamples = SamplesPerFrame;
1015 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
1016
1017 int mode_l = *pSrc++, mode_r = 0;
1018
1019 if (Channels == 2) {
1020 mode_r = *pSrc++;
1021 framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1022 rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1023 nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1024 if (remainingbytes < framebytes) { // last frame in sample
1025 framesamples = SamplesInLastFrame;
1026 if (mode_l == 4 && (framesamples & 1)) {
1027 rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1028 }
1029 else {
1030 rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1031 }
1032 }
1033 }
1034 else {
1035 framebytes = bytesPerFrame[mode_l] + 1;
1036 nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1037 if (remainingbytes < framebytes) {
1038 framesamples = SamplesInLastFrame;
1039 }
1040 }
1041
1042 // determine how many samples in this frame to skip and read
1043 if (currentframeoffset + remainingsamples >= framesamples) {
1044 if (currentframeoffset <= framesamples) {
1045 copysamples = framesamples - currentframeoffset;
1046 skipsamples = currentframeoffset;
1047 }
1048 else {
1049 copysamples = 0;
1050 skipsamples = framesamples;
1051 }
1052 }
1053 else {
1054 // This frame has enough data for pBuffer, but not
1055 // all of the frame is needed. Set file position
1056 // to start of this frame for next call to Read.
1057 copysamples = remainingsamples;
1058 skipsamples = currentframeoffset;
1059 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1060 this->FrameOffset = currentframeoffset + copysamples;
1061 }
1062 remainingsamples -= copysamples;
1063
1064 if (remainingbytes > framebytes) {
1065 remainingbytes -= framebytes;
1066 if (remainingsamples == 0 &&
1067 currentframeoffset + copysamples == framesamples) {
1068 // This frame has enough data for pBuffer, and
1069 // all of the frame is needed. Set file
1070 // position to start of next frame for next
1071 // call to Read. FrameOffset is 0.
1072 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1073 }
1074 }
1075 else remainingbytes = 0;
1076
1077 currentframeoffset -= skipsamples;
1078
1079 if (copysamples == 0) {
1080 // skip this frame
1081 pSrc += framebytes - Channels;
1082 }
1083 else {
1084 const unsigned char* const param_l = pSrc;
1085 if (BitDepth == 24) {
1086 if (mode_l != 2) pSrc += 12;
1087
1088 if (Channels == 2) { // Stereo
1089 const unsigned char* const param_r = pSrc;
1090 if (mode_r != 2) pSrc += 12;
1091
1092 Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1093 skipsamples, copysamples, TruncatedBits);
1094 Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1095 skipsamples, copysamples, TruncatedBits);
1096 pDst24 += copysamples * 6;
1097 }
1098 else { // Mono
1099 Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1100 skipsamples, copysamples, TruncatedBits);
1101 pDst24 += copysamples * 3;
1102 }
1103 }
1104 else { // 16 bit
1105 if (mode_l) pSrc += 4;
1106
1107 int step;
1108 if (Channels == 2) { // Stereo
1109 const unsigned char* const param_r = pSrc;
1110 if (mode_r) pSrc += 4;
1111
1112 step = (2 - mode_l) + (2 - mode_r);
1113 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1114 Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1115 skipsamples, copysamples);
1116 pDst += copysamples << 1;
1117 }
1118 else { // Mono
1119 step = 2 - mode_l;
1120 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1121 pDst += copysamples;
1122 }
1123 }
1124 pSrc += nextFrameOffset;
1125 }
1126
1127 // reload from disk to local buffer if needed
1128 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1129 assumedsize = GuessSize(remainingsamples);
1130 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1131 if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1132 remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1133 pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1134 }
1135 } // while
1136
1137 this->SamplePos += (SampleCount - remainingsamples);
1138 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1139 return (SampleCount - remainingsamples);
1140 }
1141 }
1142
1143 /** @brief Write sample wave data.
1144 *
1145 * Writes \a SampleCount number of sample points from the buffer pointed
1146 * by \a pBuffer and increments the position within the sample. Use this
1147 * method to directly write the sample data to disk, i.e. if you don't
1148 * want or cannot load the whole sample data into RAM.
1149 *
1150 * You have to Resize() the sample to the desired size and call
1151 * File::Save() <b>before</b> using Write().
1152 *
1153 * Note: there is currently no support for writing compressed samples.
1154 *
1155 * For 16 bit samples, the data in the source buffer should be
1156 * int16_t (using native endianness). For 24 bit, the buffer
1157 * should contain three bytes per sample, little-endian.
1158 *
1159 * @param pBuffer - source buffer
1160 * @param SampleCount - number of sample points to write
1161 * @throws DLS::Exception if current sample size is too small
1162 * @throws gig::Exception if sample is compressed
1163 * @see DLS::LoadSampleData()
1164 */
1165 unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
1166 if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1167
1168 // if this is the first write in this sample, reset the
1169 // checksum calculator
1170 if (pCkData->GetPos() == 0) {
1171 crc.reset();
1172 }
1173 if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1174 unsigned long res;
1175 if (BitDepth == 24) {
1176 res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1177 } else { // 16 bit
1178 res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1179 : pCkData->Write(pBuffer, SampleCount, 2);
1180 }
1181 crc.update((unsigned char *)pBuffer, SampleCount * FrameSize);
1182
1183 // if this is the last write, update the checksum chunk in the
1184 // file
1185 if (pCkData->GetPos() == pCkData->GetSize()) {
1186 File* pFile = static_cast<File*>(GetParent());
1187 pFile->SetSampleChecksum(this, crc.getValue());
1188 }
1189 return res;
1190 }
1191
1192 /**
1193 * Allocates a decompression buffer for streaming (compressed) samples
1194 * with Sample::Read(). If you are using more than one streaming thread
1195 * in your application you <b>HAVE</b> to create a decompression buffer
1196 * for <b>EACH</b> of your streaming threads and provide it with the
1197 * Sample::Read() call in order to avoid race conditions and crashes.
1198 *
1199 * You should free the memory occupied by the allocated buffer(s) once
1200 * you don't need one of your streaming threads anymore by calling
1201 * DestroyDecompressionBuffer().
1202 *
1203 * @param MaxReadSize - the maximum size (in sample points) you ever
1204 * expect to read with one Read() call
1205 * @returns allocated decompression buffer
1206 * @see DestroyDecompressionBuffer()
1207 */
1208 buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
1209 buffer_t result;
1210 const double worstCaseHeaderOverhead =
1211 (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1212 result.Size = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1213 result.pStart = new int8_t[result.Size];
1214 result.NullExtensionSize = 0;
1215 return result;
1216 }
1217
1218 /**
1219 * Free decompression buffer, previously created with
1220 * CreateDecompressionBuffer().
1221 *
1222 * @param DecompressionBuffer - previously allocated decompression
1223 * buffer to free
1224 */
1225 void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1226 if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1227 delete[] (int8_t*) DecompressionBuffer.pStart;
1228 DecompressionBuffer.pStart = NULL;
1229 DecompressionBuffer.Size = 0;
1230 DecompressionBuffer.NullExtensionSize = 0;
1231 }
1232 }
1233
1234 /**
1235 * Returns pointer to the Group this Sample belongs to. In the .gig
1236 * format a sample always belongs to one group. If it wasn't explicitly
1237 * assigned to a certain group, it will be automatically assigned to a
1238 * default group.
1239 *
1240 * @returns Sample's Group (never NULL)
1241 */
1242 Group* Sample::GetGroup() const {
1243 return pGroup;
1244 }
1245
1246 Sample::~Sample() {
1247 Instances--;
1248 if (!Instances && InternalDecompressionBuffer.Size) {
1249 delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1250 InternalDecompressionBuffer.pStart = NULL;
1251 InternalDecompressionBuffer.Size = 0;
1252 }
1253 if (FrameTable) delete[] FrameTable;
1254 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1255 }
1256
1257
1258
1259 // *************** DimensionRegion ***************
1260 // *
1261
1262 uint DimensionRegion::Instances = 0;
1263 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1264
1265 DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1266 Instances++;
1267
1268 pSample = NULL;
1269 pRegion = pParent;
1270
1271 if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1272 else memset(&Crossfade, 0, 4);
1273
1274 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1275
1276 RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1277 if (_3ewa) { // if '3ewa' chunk exists
1278 _3ewa->ReadInt32(); // unknown, always == chunk size ?
1279 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1280 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1281 _3ewa->ReadInt16(); // unknown
1282 LFO1InternalDepth = _3ewa->ReadUint16();
1283 _3ewa->ReadInt16(); // unknown
1284 LFO3InternalDepth = _3ewa->ReadInt16();
1285 _3ewa->ReadInt16(); // unknown
1286 LFO1ControlDepth = _3ewa->ReadUint16();
1287 _3ewa->ReadInt16(); // unknown
1288 LFO3ControlDepth = _3ewa->ReadInt16();
1289 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1290 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1291 _3ewa->ReadInt16(); // unknown
1292 EG1Sustain = _3ewa->ReadUint16();
1293 EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1294 EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1295 uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1296 EG1ControllerInvert = eg1ctrloptions & 0x01;
1297 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1298 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1299 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1300 EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1301 uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1302 EG2ControllerInvert = eg2ctrloptions & 0x01;
1303 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1304 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1305 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1306 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1307 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1308 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1309 _3ewa->ReadInt16(); // unknown
1310 EG2Sustain = _3ewa->ReadUint16();
1311 EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1312 _3ewa->ReadInt16(); // unknown
1313 LFO2ControlDepth = _3ewa->ReadUint16();
1314 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1315 _3ewa->ReadInt16(); // unknown
1316 LFO2InternalDepth = _3ewa->ReadUint16();
1317 int32_t eg1decay2 = _3ewa->ReadInt32();
1318 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1319 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1320 _3ewa->ReadInt16(); // unknown
1321 EG1PreAttack = _3ewa->ReadUint16();
1322 int32_t eg2decay2 = _3ewa->ReadInt32();
1323 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1324 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1325 _3ewa->ReadInt16(); // unknown
1326 EG2PreAttack = _3ewa->ReadUint16();
1327 uint8_t velocityresponse = _3ewa->ReadUint8();
1328 if (velocityresponse < 5) {
1329 VelocityResponseCurve = curve_type_nonlinear;
1330 VelocityResponseDepth = velocityresponse;
1331 } else if (velocityresponse < 10) {
1332 VelocityResponseCurve = curve_type_linear;
1333 VelocityResponseDepth = velocityresponse - 5;
1334 } else if (velocityresponse < 15) {
1335 VelocityResponseCurve = curve_type_special;
1336 VelocityResponseDepth = velocityresponse - 10;
1337 } else {
1338 VelocityResponseCurve = curve_type_unknown;
1339 VelocityResponseDepth = 0;
1340 }
1341 uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1342 if (releasevelocityresponse < 5) {
1343 ReleaseVelocityResponseCurve = curve_type_nonlinear;
1344 ReleaseVelocityResponseDepth = releasevelocityresponse;
1345 } else if (releasevelocityresponse < 10) {
1346 ReleaseVelocityResponseCurve = curve_type_linear;
1347 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1348 } else if (releasevelocityresponse < 15) {
1349 ReleaseVelocityResponseCurve = curve_type_special;
1350 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1351 } else {
1352 ReleaseVelocityResponseCurve = curve_type_unknown;
1353 ReleaseVelocityResponseDepth = 0;
1354 }
1355 VelocityResponseCurveScaling = _3ewa->ReadUint8();
1356 AttenuationControllerThreshold = _3ewa->ReadInt8();
1357 _3ewa->ReadInt32(); // unknown
1358 SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1359 _3ewa->ReadInt16(); // unknown
1360 uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1361 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1362 if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1363 else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1364 else DimensionBypass = dim_bypass_ctrl_none;
1365 uint8_t pan = _3ewa->ReadUint8();
1366 Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1367 SelfMask = _3ewa->ReadInt8() & 0x01;
1368 _3ewa->ReadInt8(); // unknown
1369 uint8_t lfo3ctrl = _3ewa->ReadUint8();
1370 LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1371 LFO3Sync = lfo3ctrl & 0x20; // bit 5
1372 InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1373 AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1374 uint8_t lfo2ctrl = _3ewa->ReadUint8();
1375 LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1376 LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1377 LFO2Sync = lfo2ctrl & 0x20; // bit 5
1378 bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1379 uint8_t lfo1ctrl = _3ewa->ReadUint8();
1380 LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1381 LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1382 LFO1Sync = lfo1ctrl & 0x40; // bit 6
1383 VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1384 : vcf_res_ctrl_none;
1385 uint16_t eg3depth = _3ewa->ReadUint16();
1386 EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1387 : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
1388 _3ewa->ReadInt16(); // unknown
1389 ChannelOffset = _3ewa->ReadUint8() / 4;
1390 uint8_t regoptions = _3ewa->ReadUint8();
1391 MSDecode = regoptions & 0x01; // bit 0
1392 SustainDefeat = regoptions & 0x02; // bit 1
1393 _3ewa->ReadInt16(); // unknown
1394 VelocityUpperLimit = _3ewa->ReadInt8();
1395 _3ewa->ReadInt8(); // unknown
1396 _3ewa->ReadInt16(); // unknown
1397 ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1398 _3ewa->ReadInt8(); // unknown
1399 _3ewa->ReadInt8(); // unknown
1400 EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1401 uint8_t vcfcutoff = _3ewa->ReadUint8();
1402 VCFEnabled = vcfcutoff & 0x80; // bit 7
1403 VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1404 VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1405 uint8_t vcfvelscale = _3ewa->ReadUint8();
1406 VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1407 VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1408 _3ewa->ReadInt8(); // unknown
1409 uint8_t vcfresonance = _3ewa->ReadUint8();
1410 VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1411 VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1412 uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1413 VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1414 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1415 uint8_t vcfvelocity = _3ewa->ReadUint8();
1416 VCFVelocityDynamicRange = vcfvelocity % 5;
1417 VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1418 VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1419 if (VCFType == vcf_type_lowpass) {
1420 if (lfo3ctrl & 0x40) // bit 6
1421 VCFType = vcf_type_lowpassturbo;
1422 }
1423 if (_3ewa->RemainingBytes() >= 8) {
1424 _3ewa->Read(DimensionUpperLimits, 1, 8);
1425 } else {
1426 memset(DimensionUpperLimits, 0, 8);
1427 }
1428 } else { // '3ewa' chunk does not exist yet
1429 // use default values
1430 LFO3Frequency = 1.0;
1431 EG3Attack = 0.0;
1432 LFO1InternalDepth = 0;
1433 LFO3InternalDepth = 0;
1434 LFO1ControlDepth = 0;
1435 LFO3ControlDepth = 0;
1436 EG1Attack = 0.0;
1437 EG1Decay1 = 0.005;
1438 EG1Sustain = 1000;
1439 EG1Release = 0.3;
1440 EG1Controller.type = eg1_ctrl_t::type_none;
1441 EG1Controller.controller_number = 0;
1442 EG1ControllerInvert = false;
1443 EG1ControllerAttackInfluence = 0;
1444 EG1ControllerDecayInfluence = 0;
1445 EG1ControllerReleaseInfluence = 0;
1446 EG2Controller.type = eg2_ctrl_t::type_none;
1447 EG2Controller.controller_number = 0;
1448 EG2ControllerInvert = false;
1449 EG2ControllerAttackInfluence = 0;
1450 EG2ControllerDecayInfluence = 0;
1451 EG2ControllerReleaseInfluence = 0;
1452 LFO1Frequency = 1.0;
1453 EG2Attack = 0.0;
1454 EG2Decay1 = 0.005;
1455 EG2Sustain = 1000;
1456 EG2Release = 0.3;
1457 LFO2ControlDepth = 0;
1458 LFO2Frequency = 1.0;
1459 LFO2InternalDepth = 0;
1460 EG1Decay2 = 0.0;
1461 EG1InfiniteSustain = true;
1462 EG1PreAttack = 0;
1463 EG2Decay2 = 0.0;
1464 EG2InfiniteSustain = true;
1465 EG2PreAttack = 0;
1466 VelocityResponseCurve = curve_type_nonlinear;
1467 VelocityResponseDepth = 3;
1468 ReleaseVelocityResponseCurve = curve_type_nonlinear;
1469 ReleaseVelocityResponseDepth = 3;
1470 VelocityResponseCurveScaling = 32;
1471 AttenuationControllerThreshold = 0;
1472 SampleStartOffset = 0;
1473 PitchTrack = true;
1474 DimensionBypass = dim_bypass_ctrl_none;
1475 Pan = 0;
1476 SelfMask = true;
1477 LFO3Controller = lfo3_ctrl_modwheel;
1478 LFO3Sync = false;
1479 InvertAttenuationController = false;
1480 AttenuationController.type = attenuation_ctrl_t::type_none;
1481 AttenuationController.controller_number = 0;
1482 LFO2Controller = lfo2_ctrl_internal;
1483 LFO2FlipPhase = false;
1484 LFO2Sync = false;
1485 LFO1Controller = lfo1_ctrl_internal;
1486 LFO1FlipPhase = false;
1487 LFO1Sync = false;
1488 VCFResonanceController = vcf_res_ctrl_none;
1489 EG3Depth = 0;
1490 ChannelOffset = 0;
1491 MSDecode = false;
1492 SustainDefeat = false;
1493 VelocityUpperLimit = 0;
1494 ReleaseTriggerDecay = 0;
1495 EG1Hold = false;
1496 VCFEnabled = false;
1497 VCFCutoff = 0;
1498 VCFCutoffController = vcf_cutoff_ctrl_none;
1499 VCFCutoffControllerInvert = false;
1500 VCFVelocityScale = 0;
1501 VCFResonance = 0;
1502 VCFResonanceDynamic = false;
1503 VCFKeyboardTracking = false;
1504 VCFKeyboardTrackingBreakpoint = 0;
1505 VCFVelocityDynamicRange = 0x04;
1506 VCFVelocityCurve = curve_type_linear;
1507 VCFType = vcf_type_lowpass;
1508 memset(DimensionUpperLimits, 127, 8);
1509 }
1510
1511 pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1512 VelocityResponseDepth,
1513 VelocityResponseCurveScaling);
1514
1515 curve_type_t curveType = ReleaseVelocityResponseCurve;
1516 uint8_t depth = ReleaseVelocityResponseDepth;
1517
1518 // this models a strange behaviour or bug in GSt: two of the
1519 // velocity response curves for release time are not used even
1520 // if specified, instead another curve is chosen.
1521 if ((curveType == curve_type_nonlinear && depth == 0) ||
1522 (curveType == curve_type_special && depth == 4)) {
1523 curveType = curve_type_nonlinear;
1524 depth = 3;
1525 }
1526 pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);
1527
1528 curveType = VCFVelocityCurve;
1529 depth = VCFVelocityDynamicRange;
1530
1531 // even stranger GSt: two of the velocity response curves for
1532 // filter cutoff are not used, instead another special curve
1533 // is chosen. This curve is not used anywhere else.
1534 if ((curveType == curve_type_nonlinear && depth == 0) ||
1535 (curveType == curve_type_special && depth == 4)) {
1536 curveType = curve_type_special;
1537 depth = 5;
1538 }
1539 pVelocityCutoffTable = GetVelocityTable(curveType, depth,
1540 VCFCutoffController <= vcf_cutoff_ctrl_none2 ? VCFVelocityScale : 0);
1541
1542 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1543 VelocityTable = 0;
1544 }
1545
1546 /*
1547 * Constructs a DimensionRegion by copying all parameters from
1548 * another DimensionRegion
1549 */
1550 DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1551 Instances++;
1552 *this = src; // default memberwise shallow copy of all parameters
1553 pParentList = _3ewl; // restore the chunk pointer
1554
1555 // deep copy of owned structures
1556 if (src.VelocityTable) {
1557 VelocityTable = new uint8_t[128];
1558 for (int k = 0 ; k < 128 ; k++)
1559 VelocityTable[k] = src.VelocityTable[k];
1560 }
1561 if (src.pSampleLoops) {
1562 pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1563 for (int k = 0 ; k < src.SampleLoops ; k++)
1564 pSampleLoops[k] = src.pSampleLoops[k];
1565 }
1566 }
1567
1568 /**
1569 * Apply dimension region settings to the respective RIFF chunks. You
1570 * have to call File::Save() to make changes persistent.
1571 *
1572 * Usually there is absolutely no need to call this method explicitly.
1573 * It will be called automatically when File::Save() was called.
1574 */
1575 void DimensionRegion::UpdateChunks() {
1576 // first update base class's chunk
1577 DLS::Sampler::UpdateChunks();
1578
1579 RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1580 uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1581 pData[12] = Crossfade.in_start;
1582 pData[13] = Crossfade.in_end;
1583 pData[14] = Crossfade.out_start;
1584 pData[15] = Crossfade.out_end;
1585
1586 // make sure '3ewa' chunk exists
1587 RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1588 if (!_3ewa) {
1589 File* pFile = (File*) GetParent()->GetParent()->GetParent();
1590 bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1591 _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1592 }
1593 pData = (uint8_t*) _3ewa->LoadChunkData();
1594
1595 // update '3ewa' chunk with DimensionRegion's current settings
1596
1597 const uint32_t chunksize = _3ewa->GetNewSize();
1598 store32(&pData[0], chunksize); // unknown, always chunk size?
1599
1600 const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1601 store32(&pData[4], lfo3freq);
1602
1603 const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1604 store32(&pData[8], eg3attack);
1605
1606 // next 2 bytes unknown
1607
1608 store16(&pData[14], LFO1InternalDepth);
1609
1610 // next 2 bytes unknown
1611
1612 store16(&pData[18], LFO3InternalDepth);
1613
1614 // next 2 bytes unknown
1615
1616 store16(&pData[22], LFO1ControlDepth);
1617
1618 // next 2 bytes unknown
1619
1620 store16(&pData[26], LFO3ControlDepth);
1621
1622 const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
1623 store32(&pData[28], eg1attack);
1624
1625 const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
1626 store32(&pData[32], eg1decay1);
1627
1628 // next 2 bytes unknown
1629
1630 store16(&pData[38], EG1Sustain);
1631
1632 const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
1633 store32(&pData[40], eg1release);
1634
1635 const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
1636 pData[44] = eg1ctl;
1637
1638 const uint8_t eg1ctrloptions =
1639 (EG1ControllerInvert ? 0x01 : 0x00) |
1640 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
1641 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
1642 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
1643 pData[45] = eg1ctrloptions;
1644
1645 const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
1646 pData[46] = eg2ctl;
1647
1648 const uint8_t eg2ctrloptions =
1649 (EG2ControllerInvert ? 0x01 : 0x00) |
1650 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
1651 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
1652 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
1653 pData[47] = eg2ctrloptions;
1654
1655 const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
1656 store32(&pData[48], lfo1freq);
1657
1658 const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
1659 store32(&pData[52], eg2attack);
1660
1661 const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
1662 store32(&pData[56], eg2decay1);
1663
1664 // next 2 bytes unknown
1665
1666 store16(&pData[62], EG2Sustain);
1667
1668 const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
1669 store32(&pData[64], eg2release);
1670
1671 // next 2 bytes unknown
1672
1673 store16(&pData[70], LFO2ControlDepth);
1674
1675 const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
1676 store32(&pData[72], lfo2freq);
1677
1678 // next 2 bytes unknown
1679
1680 store16(&pData[78], LFO2InternalDepth);
1681
1682 const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
1683 store32(&pData[80], eg1decay2);
1684
1685 // next 2 bytes unknown
1686
1687 store16(&pData[86], EG1PreAttack);
1688
1689 const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
1690 store32(&pData[88], eg2decay2);
1691
1692 // next 2 bytes unknown
1693
1694 store16(&pData[94], EG2PreAttack);
1695
1696 {
1697 if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
1698 uint8_t velocityresponse = VelocityResponseDepth;
1699 switch (VelocityResponseCurve) {
1700 case curve_type_nonlinear:
1701 break;
1702 case curve_type_linear:
1703 velocityresponse += 5;
1704 break;
1705 case curve_type_special:
1706 velocityresponse += 10;
1707 break;
1708 case curve_type_unknown:
1709 default:
1710 throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
1711 }
1712 pData[96] = velocityresponse;
1713 }
1714
1715 {
1716 if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
1717 uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
1718 switch (ReleaseVelocityResponseCurve) {
1719 case curve_type_nonlinear:
1720 break;
1721 case curve_type_linear:
1722 releasevelocityresponse += 5;
1723 break;
1724 case curve_type_special:
1725 releasevelocityresponse += 10;
1726 break;
1727 case curve_type_unknown:
1728 default:
1729 throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
1730 }
1731 pData[97] = releasevelocityresponse;
1732 }
1733
1734 pData[98] = VelocityResponseCurveScaling;
1735
1736 pData[99] = AttenuationControllerThreshold;
1737
1738 // next 4 bytes unknown
1739
1740 store16(&pData[104], SampleStartOffset);
1741
1742 // next 2 bytes unknown
1743
1744 {
1745 uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
1746 switch (DimensionBypass) {
1747 case dim_bypass_ctrl_94:
1748 pitchTrackDimensionBypass |= 0x10;
1749 break;
1750 case dim_bypass_ctrl_95:
1751 pitchTrackDimensionBypass |= 0x20;
1752 break;
1753 case dim_bypass_ctrl_none:
1754 //FIXME: should we set anything here?
1755 break;
1756 default:
1757 throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
1758 }
1759 pData[108] = pitchTrackDimensionBypass;
1760 }
1761
1762 const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
1763 pData[109] = pan;
1764
1765 const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
1766 pData[110] = selfmask;
1767
1768 // next byte unknown
1769
1770 {
1771 uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
1772 if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
1773 if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
1774 if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
1775 pData[112] = lfo3ctrl;
1776 }
1777
1778 const uint8_t attenctl = EncodeLeverageController(AttenuationController);
1779 pData[113] = attenctl;
1780
1781 {
1782 uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
1783 if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
1784 if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
1785 if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
1786 pData[114] = lfo2ctrl;
1787 }
1788
1789 {
1790 uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
1791 if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
1792 if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
1793 if (VCFResonanceController != vcf_res_ctrl_none)
1794 lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
1795 pData[115] = lfo1ctrl;
1796 }
1797
1798 const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1799 : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
1800 pData[116] = eg3depth;
1801
1802 // next 2 bytes unknown
1803
1804 const uint8_t channeloffset = ChannelOffset * 4;
1805 pData[120] = channeloffset;
1806
1807 {
1808 uint8_t regoptions = 0;
1809 if (MSDecode) regoptions |= 0x01; // bit 0
1810 if (SustainDefeat) regoptions |= 0x02; // bit 1
1811 pData[121] = regoptions;
1812 }
1813
1814 // next 2 bytes unknown
1815
1816 pData[124] = VelocityUpperLimit;
1817
1818 // next 3 bytes unknown
1819
1820 pData[128] = ReleaseTriggerDecay;
1821
1822 // next 2 bytes unknown
1823
1824 const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
1825 pData[131] = eg1hold;
1826
1827 const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
1828 (VCFCutoff & 0x7f); /* lower 7 bits */
1829 pData[132] = vcfcutoff;
1830
1831 pData[133] = VCFCutoffController;
1832
1833 const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
1834 (VCFVelocityScale & 0x7f); /* lower 7 bits */
1835 pData[134] = vcfvelscale;
1836
1837 // next byte unknown
1838
1839 const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
1840 (VCFResonance & 0x7f); /* lower 7 bits */
1841 pData[136] = vcfresonance;
1842
1843 const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
1844 (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
1845 pData[137] = vcfbreakpoint;
1846
1847 const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |
1848 VCFVelocityCurve * 5;
1849 pData[138] = vcfvelocity;
1850
1851 const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
1852 pData[139] = vcftype;
1853
1854 if (chunksize >= 148) {
1855 memcpy(&pData[140], DimensionUpperLimits, 8);
1856 }
1857 }
1858
1859 // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
1860 double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
1861 {
1862 double* table;
1863 uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
1864 if (pVelocityTables->count(tableKey)) { // if key exists
1865 table = (*pVelocityTables)[tableKey];
1866 }
1867 else {
1868 table = CreateVelocityTable(curveType, depth, scaling);
1869 (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
1870 }
1871 return table;
1872 }
1873
1874 Region* DimensionRegion::GetParent() const {
1875 return pRegion;
1876 }
1877
1878 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
1879 leverage_ctrl_t decodedcontroller;
1880 switch (EncodedController) {
1881 // special controller
1882 case _lev_ctrl_none:
1883 decodedcontroller.type = leverage_ctrl_t::type_none;
1884 decodedcontroller.controller_number = 0;
1885 break;
1886 case _lev_ctrl_velocity:
1887 decodedcontroller.type = leverage_ctrl_t::type_velocity;
1888 decodedcontroller.controller_number = 0;
1889 break;
1890 case _lev_ctrl_channelaftertouch:
1891 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
1892 decodedcontroller.controller_number = 0;
1893 break;
1894
1895 // ordinary MIDI control change controller
1896 case _lev_ctrl_modwheel:
1897 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1898 decodedcontroller.controller_number = 1;
1899 break;
1900 case _lev_ctrl_breath:
1901 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1902 decodedcontroller.controller_number = 2;
1903 break;
1904 case _lev_ctrl_foot:
1905 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1906 decodedcontroller.controller_number = 4;
1907 break;
1908 case _lev_ctrl_effect1:
1909 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1910 decodedcontroller.controller_number = 12;
1911 break;
1912 case _lev_ctrl_effect2:
1913 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1914 decodedcontroller.controller_number = 13;
1915 break;
1916 case _lev_ctrl_genpurpose1:
1917 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1918 decodedcontroller.controller_number = 16;
1919 break;
1920 case _lev_ctrl_genpurpose2:
1921 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1922 decodedcontroller.controller_number = 17;
1923 break;
1924 case _lev_ctrl_genpurpose3:
1925 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1926 decodedcontroller.controller_number = 18;
1927 break;
1928 case _lev_ctrl_genpurpose4:
1929 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1930 decodedcontroller.controller_number = 19;
1931 break;
1932 case _lev_ctrl_portamentotime:
1933 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1934 decodedcontroller.controller_number = 5;
1935 break;
1936 case _lev_ctrl_sustainpedal:
1937 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1938 decodedcontroller.controller_number = 64;
1939 break;
1940 case _lev_ctrl_portamento:
1941 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1942 decodedcontroller.controller_number = 65;
1943 break;
1944 case _lev_ctrl_sostenutopedal:
1945 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1946 decodedcontroller.controller_number = 66;
1947 break;
1948 case _lev_ctrl_softpedal:
1949 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1950 decodedcontroller.controller_number = 67;
1951 break;
1952 case _lev_ctrl_genpurpose5:
1953 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1954 decodedcontroller.controller_number = 80;
1955 break;
1956 case _lev_ctrl_genpurpose6:
1957 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1958 decodedcontroller.controller_number = 81;
1959 break;
1960 case _lev_ctrl_genpurpose7:
1961 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1962 decodedcontroller.controller_number = 82;
1963 break;
1964 case _lev_ctrl_genpurpose8:
1965 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1966 decodedcontroller.controller_number = 83;
1967 break;
1968 case _lev_ctrl_effect1depth:
1969 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1970 decodedcontroller.controller_number = 91;
1971 break;
1972 case _lev_ctrl_effect2depth:
1973 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1974 decodedcontroller.controller_number = 92;
1975 break;
1976 case _lev_ctrl_effect3depth:
1977 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1978 decodedcontroller.controller_number = 93;
1979 break;
1980 case _lev_ctrl_effect4depth:
1981 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1982 decodedcontroller.controller_number = 94;
1983 break;
1984 case _lev_ctrl_effect5depth:
1985 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1986 decodedcontroller.controller_number = 95;
1987 break;
1988
1989 // unknown controller type
1990 default:
1991 throw gig::Exception("Unknown leverage controller type.");
1992 }
1993 return decodedcontroller;
1994 }
1995
1996 DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
1997 _lev_ctrl_t encodedcontroller;
1998 switch (DecodedController.type) {
1999 // special controller
2000 case leverage_ctrl_t::type_none:
2001 encodedcontroller = _lev_ctrl_none;
2002 break;
2003 case leverage_ctrl_t::type_velocity:
2004 encodedcontroller = _lev_ctrl_velocity;
2005 break;
2006 case leverage_ctrl_t::type_channelaftertouch:
2007 encodedcontroller = _lev_ctrl_channelaftertouch;
2008 break;
2009
2010 // ordinary MIDI control change controller
2011 case leverage_ctrl_t::type_controlchange:
2012 switch (DecodedController.controller_number) {
2013 case 1:
2014 encodedcontroller = _lev_ctrl_modwheel;
2015 break;
2016 case 2:
2017 encodedcontroller = _lev_ctrl_breath;
2018 break;
2019 case 4:
2020 encodedcontroller = _lev_ctrl_foot;
2021 break;
2022 case 12:
2023 encodedcontroller = _lev_ctrl_effect1;
2024 break;
2025 case 13:
2026 encodedcontroller = _lev_ctrl_effect2;
2027 break;
2028 case 16:
2029 encodedcontroller = _lev_ctrl_genpurpose1;
2030 break;
2031 case 17:
2032 encodedcontroller = _lev_ctrl_genpurpose2;
2033 break;
2034 case 18:
2035 encodedcontroller = _lev_ctrl_genpurpose3;
2036 break;
2037 case 19:
2038 encodedcontroller = _lev_ctrl_genpurpose4;
2039 break;
2040 case 5:
2041 encodedcontroller = _lev_ctrl_portamentotime;
2042 break;
2043 case 64:
2044 encodedcontroller = _lev_ctrl_sustainpedal;
2045 break;
2046 case 65:
2047 encodedcontroller = _lev_ctrl_portamento;
2048 break;
2049 case 66:
2050 encodedcontroller = _lev_ctrl_sostenutopedal;
2051 break;
2052 case 67:
2053 encodedcontroller = _lev_ctrl_softpedal;
2054 break;
2055 case 80:
2056 encodedcontroller = _lev_ctrl_genpurpose5;
2057 break;
2058 case 81:
2059 encodedcontroller = _lev_ctrl_genpurpose6;
2060 break;
2061 case 82:
2062 encodedcontroller = _lev_ctrl_genpurpose7;
2063 break;
2064 case 83:
2065 encodedcontroller = _lev_ctrl_genpurpose8;
2066 break;
2067 case 91:
2068 encodedcontroller = _lev_ctrl_effect1depth;
2069 break;
2070 case 92:
2071 encodedcontroller = _lev_ctrl_effect2depth;
2072 break;
2073 case 93:
2074 encodedcontroller = _lev_ctrl_effect3depth;
2075 break;
2076 case 94:
2077 encodedcontroller = _lev_ctrl_effect4depth;
2078 break;
2079 case 95:
2080 encodedcontroller = _lev_ctrl_effect5depth;
2081 break;
2082 default:
2083 throw gig::Exception("leverage controller number is not supported by the gig format");
2084 }
2085 break;
2086 default:
2087 throw gig::Exception("Unknown leverage controller type.");
2088 }
2089 return encodedcontroller;
2090 }
2091
2092 DimensionRegion::~DimensionRegion() {
2093 Instances--;
2094 if (!Instances) {
2095 // delete the velocity->volume tables
2096 VelocityTableMap::iterator iter;
2097 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
2098 double* pTable = iter->second;
2099 if (pTable) delete[] pTable;
2100 }
2101 pVelocityTables->clear();
2102 delete pVelocityTables;
2103 pVelocityTables = NULL;
2104 }
2105 if (VelocityTable) delete[] VelocityTable;
2106 }
2107
2108 /**
2109 * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
2110 * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
2111 * and VelocityResponseCurveScaling) involved are taken into account to
2112 * calculate the amplitude factor. Use this method when a key was
2113 * triggered to get the volume with which the sample should be played
2114 * back.
2115 *
2116 * @param MIDIKeyVelocity MIDI velocity value of the triggered key (between 0 and 127)
2117 * @returns amplitude factor (between 0.0 and 1.0)
2118 */
2119 double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
2120 return pVelocityAttenuationTable[MIDIKeyVelocity];
2121 }
2122
2123 double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
2124 return pVelocityReleaseTable[MIDIKeyVelocity];
2125 }
2126
2127 double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
2128 return pVelocityCutoffTable[MIDIKeyVelocity];
2129 }
2130
2131 double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
2132
2133 // line-segment approximations of the 15 velocity curves
2134
2135 // linear
2136 const int lin0[] = { 1, 1, 127, 127 };
2137 const int lin1[] = { 1, 21, 127, 127 };
2138 const int lin2[] = { 1, 45, 127, 127 };
2139 const int lin3[] = { 1, 74, 127, 127 };
2140 const int lin4[] = { 1, 127, 127, 127 };
2141
2142 // non-linear
2143 const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
2144 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
2145 127, 127 };
2146 const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
2147 127, 127 };
2148 const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
2149 127, 127 };
2150 const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
2151
2152 // special
2153 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
2154 113, 127, 127, 127 };
2155 const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
2156 118, 127, 127, 127 };
2157 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
2158 85, 90, 91, 127, 127, 127 };
2159 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
2160 117, 127, 127, 127 };
2161 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
2162 127, 127 };
2163
2164 // this is only used by the VCF velocity curve
2165 const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
2166 91, 127, 127, 127 };
2167
2168 const int* const curves[] = { non0, non1, non2, non3, non4,
2169 lin0, lin1, lin2, lin3, lin4,
2170 spe0, spe1, spe2, spe3, spe4, spe5 };
2171
2172 double* const table = new double[128];
2173
2174 const int* curve = curves[curveType * 5 + depth];
2175 const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
2176
2177 table[0] = 0;
2178 for (int x = 1 ; x < 128 ; x++) {
2179
2180 if (x > curve[2]) curve += 2;
2181 double y = curve[1] + (x - curve[0]) *
2182 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
2183 y = y / 127;
2184
2185 // Scale up for s > 20, down for s < 20. When
2186 // down-scaling, the curve still ends at 1.0.
2187 if (s < 20 && y >= 0.5)
2188 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
2189 else
2190 y = y * (s / 20.0);
2191 if (y > 1) y = 1;
2192
2193 table[x] = y;
2194 }
2195 return table;
2196 }
2197
2198
2199 // *************** Region ***************
2200 // *
2201
2202 Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
2203 // Initialization
2204 Dimensions = 0;
2205 for (int i = 0; i < 256; i++) {
2206 pDimensionRegions[i] = NULL;
2207 }
2208 Layers = 1;
2209 File* file = (File*) GetParent()->GetParent();
2210 int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
2211
2212 // Actual Loading
2213
2214 LoadDimensionRegions(rgnList);
2215
2216 RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
2217 if (_3lnk) {
2218 DimensionRegions = _3lnk->ReadUint32();
2219 for (int i = 0; i < dimensionBits; i++) {
2220 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
2221 uint8_t bits = _3lnk->ReadUint8();
2222 _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
2223 _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
2224 uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
2225 if (dimension == dimension_none) { // inactive dimension
2226 pDimensionDefinitions[i].dimension = dimension_none;
2227 pDimensionDefinitions[i].bits = 0;
2228 pDimensionDefinitions[i].zones = 0;
2229 pDimensionDefinitions[i].split_type = split_type_bit;
2230 pDimensionDefinitions[i].zone_size = 0;
2231 }
2232 else { // active dimension
2233 pDimensionDefinitions[i].dimension = dimension;
2234 pDimensionDefinitions[i].bits = bits;
2235 pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
2236 pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
2237 pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
2238 Dimensions++;
2239
2240 // if this is a layer dimension, remember the amount of layers
2241 if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
2242 }
2243 _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
2244 }
2245 for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
2246
2247 // if there's a velocity dimension and custom velocity zone splits are used,
2248 // update the VelocityTables in the dimension regions
2249 UpdateVelocityTable();
2250
2251 // jump to start of the wave pool indices (if not already there)
2252 if (file->pVersion && file->pVersion->major == 3)
2253 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
2254 else
2255 _3lnk->SetPos(44);
2256
2257 // load sample references
2258 for (uint i = 0; i < DimensionRegions; i++) {
2259 uint32_t wavepoolindex = _3lnk->ReadUint32();
2260 if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
2261 }
2262 GetSample(); // load global region sample reference
2263 } else {
2264 DimensionRegions = 0;
2265 for (int i = 0 ; i < 8 ; i++) {
2266 pDimensionDefinitions[i].dimension = dimension_none;
2267 pDimensionDefinitions[i].bits = 0;
2268 pDimensionDefinitions[i].zones = 0;
2269 }
2270 }
2271
2272 // make sure there is at least one dimension region
2273 if (!DimensionRegions) {
2274 RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
2275 if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
2276 RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
2277 pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
2278 DimensionRegions = 1;
2279 }
2280 }
2281
2282 /**
2283 * Apply Region settings and all its DimensionRegions to the respective
2284 * RIFF chunks. You have to call File::Save() to make changes persistent.
2285 *
2286 * Usually there is absolutely no need to call this method explicitly.
2287 * It will be called automatically when File::Save() was called.
2288 *
2289 * @throws gig::Exception if samples cannot be dereferenced
2290 */
2291 void Region::UpdateChunks() {
2292 // in the gig format we don't care about the Region's sample reference
2293 // but we still have to provide some existing one to not corrupt the
2294 // file, so to avoid the latter we simply always assign the sample of
2295 // the first dimension region of this region
2296 pSample = pDimensionRegions[0]->pSample;
2297
2298 // first update base class's chunks
2299 DLS::Region::UpdateChunks();
2300
2301 // update dimension region's chunks
2302 for (int i = 0; i < DimensionRegions; i++) {
2303 pDimensionRegions[i]->UpdateChunks();
2304 }
2305
2306 File* pFile = (File*) GetParent()->GetParent();
2307 bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
2308 const int iMaxDimensions = version3 ? 8 : 5;
2309 const int iMaxDimensionRegions = version3 ? 256 : 32;
2310
2311 // make sure '3lnk' chunk exists
2312 RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
2313 if (!_3lnk) {
2314 const int _3lnkChunkSize = version3 ? 1092 : 172;
2315 _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
2316 memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
2317
2318 // move 3prg to last position
2319 pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), 0);
2320 }
2321
2322 // update dimension definitions in '3lnk' chunk
2323 uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
2324 store32(&pData[0], DimensionRegions);
2325 int shift = 0;
2326 for (int i = 0; i < iMaxDimensions; i++) {
2327 pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
2328 pData[5 + i * 8] = pDimensionDefinitions[i].bits;
2329 pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
2330 pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
2331 pData[8 + i * 8] = pDimensionDefinitions[i].zones;
2332 // next 3 bytes unknown, always zero?
2333
2334 shift += pDimensionDefinitions[i].bits;
2335 }
2336
2337 // update wave pool table in '3lnk' chunk
2338 const int iWavePoolOffset = version3 ? 68 : 44;
2339 for (uint i = 0; i < iMaxDimensionRegions; i++) {
2340 int iWaveIndex = -1;
2341 if (i < DimensionRegions) {
2342 if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
2343 File::SampleList::iterator iter = pFile->pSamples->begin();
2344 File::SampleList::iterator end = pFile->pSamples->end();
2345 for (int index = 0; iter != end; ++iter, ++index) {
2346 if (*iter == pDimensionRegions[i]->pSample) {
2347 iWaveIndex = index;
2348 break;
2349 }
2350 }
2351 }
2352 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
2353 }
2354 }
2355
2356 void Region::LoadDimensionRegions(RIFF::List* rgn) {
2357 RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
2358 if (_3prg) {
2359 int dimensionRegionNr = 0;
2360 RIFF::List* _3ewl = _3prg->GetFirstSubList();
2361 while (_3ewl) {
2362 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
2363 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
2364 dimensionRegionNr++;
2365 }
2366 _3ewl = _3prg->GetNextSubList();
2367 }
2368 if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
2369 }
2370 }
2371
2372 void Region::SetKeyRange(uint16_t Low, uint16_t High) {
2373 // update KeyRange struct and make sure regions are in correct order
2374 DLS::Region::SetKeyRange(Low, High);
2375 // update Region key table for fast lookup
2376 ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
2377 }
2378
2379 void Region::UpdateVelocityTable() {
2380 // get velocity dimension's index
2381 int veldim = -1;
2382 for (int i = 0 ; i < Dimensions ; i++) {
2383 if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
2384 veldim = i;
2385 break;
2386 }
2387 }
2388 if (veldim == -1) return;
2389
2390 int step = 1;
2391 for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
2392 int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
2393 int end = step * pDimensionDefinitions[veldim].zones;
2394
2395 // loop through all dimension regions for all dimensions except the velocity dimension
2396 int dim[8] = { 0 };
2397 for (int i = 0 ; i < DimensionRegions ; i++) {
2398
2399 if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
2400 pDimensionRegions[i]->VelocityUpperLimit) {
2401 // create the velocity table
2402 uint8_t* table = pDimensionRegions[i]->VelocityTable;
2403 if (!table) {
2404 table = new uint8_t[128];
2405 pDimensionRegions[i]->VelocityTable = table;
2406 }
2407 int tableidx = 0;
2408 int velocityZone = 0;
2409 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
2410 for (int k = i ; k < end ; k += step) {
2411 DimensionRegion *d = pDimensionRegions[k];
2412 for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
2413 velocityZone++;
2414 }
2415 } else { // gig2
2416 for (int k = i ; k < end ; k += step) {
2417 DimensionRegion *d = pDimensionRegions[k];
2418 for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
2419 velocityZone++;
2420 }
2421 }
2422 } else {
2423 if (pDimensionRegions[i]->VelocityTable) {
2424 delete[] pDimensionRegions[i]->VelocityTable;
2425 pDimensionRegions[i]->VelocityTable = 0;
2426 }
2427 }
2428
2429 int j;
2430 int shift = 0;
2431 for (j = 0 ; j < Dimensions ; j++) {
2432 if (j == veldim) i += skipveldim; // skip velocity dimension
2433 else {
2434 dim[j]++;
2435 if (dim[j] < pDimensionDefinitions[j].zones) break;
2436 else {
2437 // skip unused dimension regions
2438 dim[j] = 0;
2439 i += ((1 << pDimensionDefinitions[j].bits) -
2440 pDimensionDefinitions[j].zones) << shift;
2441 }
2442 }
2443 shift += pDimensionDefinitions[j].bits;
2444 }
2445 if (j == Dimensions) break;
2446 }
2447 }
2448
2449 /** @brief Einstein would have dreamed of it - create a new dimension.
2450 *
2451 * Creates a new dimension with the dimension definition given by
2452 * \a pDimDef. The appropriate amount of DimensionRegions will be created.
2453 * There is a hard limit of dimensions and total amount of "bits" all
2454 * dimensions can have. This limit is dependant to what gig file format
2455 * version this file refers to. The gig v2 (and lower) format has a
2456 * dimension limit and total amount of bits limit of 5, whereas the gig v3
2457 * format has a limit of 8.
2458 *
2459 * @param pDimDef - defintion of the new dimension
2460 * @throws gig::Exception if dimension of the same type exists already
2461 * @throws gig::Exception if amount of dimensions or total amount of
2462 * dimension bits limit is violated
2463 */
2464 void Region::AddDimension(dimension_def_t* pDimDef) {
2465 // check if max. amount of dimensions reached
2466 File* file = (File*) GetParent()->GetParent();
2467 const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
2468 if (Dimensions >= iMaxDimensions)
2469 throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
2470 // check if max. amount of dimension bits reached
2471 int iCurrentBits = 0;
2472 for (int i = 0; i < Dimensions; i++)
2473 iCurrentBits += pDimensionDefinitions[i].bits;
2474 if (iCurrentBits >= iMaxDimensions)
2475 throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
2476 const int iNewBits = iCurrentBits + pDimDef->bits;
2477 if (iNewBits > iMaxDimensions)
2478 throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
2479 // check if there's already a dimensions of the same type
2480 for (int i = 0; i < Dimensions; i++)
2481 if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
2482 throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
2483
2484 // pos is where the new dimension should be placed, normally
2485 // last in list, except for the samplechannel dimension which
2486 // has to be first in list
2487 int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
2488 int bitpos = 0;
2489 for (int i = 0 ; i < pos ; i++)
2490 bitpos += pDimensionDefinitions[i].bits;
2491
2492 // make room for the new dimension
2493 for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
2494 for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
2495 for (int j = Dimensions ; j > pos ; j--) {
2496 pDimensionRegions[i]->DimensionUpperLimits[j] =
2497 pDimensionRegions[i]->DimensionUpperLimits[j - 1];
2498 }
2499 }
2500
2501 // assign definition of new dimension
2502 pDimensionDefinitions[pos] = *pDimDef;
2503
2504 // auto correct certain dimension definition fields (where possible)
2505 pDimensionDefinitions[pos].split_type =
2506 __resolveSplitType(pDimensionDefinitions[pos].dimension);
2507 pDimensionDefinitions[pos].zone_size =
2508 __resolveZoneSize(pDimensionDefinitions[pos]);
2509
2510 // create new dimension region(s) for this new dimension, and make
2511 // sure that the dimension regions are placed correctly in both the
2512 // RIFF list and the pDimensionRegions array
2513 RIFF::Chunk* moveTo = NULL;
2514 RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
2515 for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
2516 for (int k = 0 ; k < (1 << bitpos) ; k++) {
2517 pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
2518 }
2519 for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
2520 for (int k = 0 ; k < (1 << bitpos) ; k++) {
2521 RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
2522 if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
2523 // create a new dimension region and copy all parameter values from
2524 // an existing dimension region
2525 pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
2526 new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
2527
2528 DimensionRegions++;
2529 }
2530 }
2531 moveTo = pDimensionRegions[i]->pParentList;
2532 }
2533
2534 // initialize the upper limits for this dimension
2535 int mask = (1 << bitpos) - 1;
2536 for (int z = 0 ; z < pDimDef->zones ; z++) {
2537 uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
2538 for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
2539 pDimensionRegions[((i & ~mask) << pDimDef->bits) |
2540 (z << bitpos) |
2541 (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
2542 }
2543 }
2544
2545 Dimensions++;
2546
2547 // if this is a layer dimension, update 'Layers' attribute
2548 if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
2549
2550 UpdateVelocityTable();
2551 }
2552
2553 /** @brief Delete an existing dimension.
2554 *
2555 * Deletes the dimension given by \a pDimDef and deletes all respective
2556 * dimension regions, that is all dimension regions where the dimension's
2557 * bit(s) part is greater than 0. In case of a 'sustain pedal' dimension
2558 * for example this would delete all dimension regions for the case(s)
2559 * where the sustain pedal is pressed down.
2560 *
2561 * @param pDimDef - dimension to delete
2562 * @throws gig::Exception if given dimension cannot be found
2563 */
2564 void Region::DeleteDimension(dimension_def_t* pDimDef) {
2565 // get dimension's index
2566 int iDimensionNr = -1;
2567 for (int i = 0; i < Dimensions; i++) {
2568 if (&pDimensionDefinitions[i] == pDimDef) {
2569 iDimensionNr = i;
2570 break;
2571 }
2572 }
2573 if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
2574
2575 // get amount of bits below the dimension to delete
2576 int iLowerBits = 0;
2577 for (int i = 0; i < iDimensionNr; i++)
2578 iLowerBits += pDimensionDefinitions[i].bits;
2579
2580 // get amount ot bits above the dimension to delete
2581 int iUpperBits = 0;
2582 for (int i = iDimensionNr + 1; i < Dimensions; i++)
2583 iUpperBits += pDimensionDefinitions[i].bits;
2584
2585 RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
2586
2587 // delete dimension regions which belong to the given dimension
2588 // (that is where the dimension's bit > 0)
2589 for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
2590 for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
2591 for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
2592 int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
2593 iObsoleteBit << iLowerBits |
2594 iLowerBit;
2595
2596 _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
2597 delete pDimensionRegions[iToDelete];
2598 pDimensionRegions[iToDelete] = NULL;
2599 DimensionRegions--;
2600 }
2601 }
2602 }
2603
2604 // defrag pDimensionRegions array
2605 // (that is remove the NULL spaces within the pDimensionRegions array)
2606 for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
2607 if (!pDimensionRegions[iTo]) {
2608 if (iFrom <= iTo) iFrom = iTo + 1;
2609 while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
2610 if (iFrom < 256 && pDimensionRegions[iFrom]) {
2611 pDimensionRegions[iTo] = pDimensionRegions[iFrom];
2612 pDimensionRegions[iFrom] = NULL;
2613 }
2614 }
2615 }
2616
2617 // remove the this dimension from the upper limits arrays
2618 for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
2619 DimensionRegion* d = pDimensionRegions[j];
2620 for (int i = iDimensionNr + 1; i < Dimensions; i++) {
2621 d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
2622 }
2623 d->DimensionUpperLimits[Dimensions - 1] = 127;
2624 }
2625
2626 // 'remove' dimension definition
2627 for (int i = iDimensionNr + 1; i < Dimensions; i++) {
2628 pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
2629 }
2630 pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
2631 pDimensionDefinitions[Dimensions - 1].bits = 0;
2632 pDimensionDefinitions[Dimensions - 1].zones = 0;
2633
2634 Dimensions--;
2635
2636 // if this was a layer dimension, update 'Layers' attribute
2637 if (pDimDef->dimension == dimension_layer) Layers = 1;
2638 }
2639
2640 Region::~Region() {
2641 for (int i = 0; i < 256; i++) {
2642 if (pDimensionRegions[i]) delete pDimensionRegions[i];
2643 }
2644 }
2645
2646 /**
2647 * Use this method in your audio engine to get the appropriate dimension
2648 * region with it's articulation data for the current situation. Just
2649 * call the method with the current MIDI controller values and you'll get
2650 * the DimensionRegion with the appropriate articulation data for the
2651 * current situation (for this Region of course only). To do that you'll
2652 * first have to look which dimensions with which controllers and in
2653 * which order are defined for this Region when you load the .gig file.
2654 * Special cases are e.g. layer or channel dimensions where you just put
2655 * in the index numbers instead of a MIDI controller value (means 0 for
2656 * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
2657 * etc.).
2658 *
2659 * @param DimValues MIDI controller values (0-127) for dimension 0 to 7
2660 * @returns adress to the DimensionRegion for the given situation
2661 * @see pDimensionDefinitions
2662 * @see Dimensions
2663 */
2664 DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
2665 uint8_t bits;
2666 int veldim = -1;
2667 int velbitpos;
2668 int bitpos = 0;
2669 int dimregidx = 0;
2670 for (uint i = 0; i < Dimensions; i++) {
2671 if (pDimensionDefinitions[i].dimension == dimension_velocity) {
2672 // the velocity dimension must be handled after the other dimensions
2673 veldim = i;
2674 velbitpos = bitpos;
2675 } else {
2676 switch (pDimensionDefinitions[i].split_type) {
2677 case split_type_normal:
2678 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
2679 // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
2680 for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
2681 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
2682 }
2683 } else {
2684 // gig2: evenly sized zones
2685 bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
2686 }
2687 break;
2688 case split_type_bit: // the value is already the sought dimension bit number
2689 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
2690 bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
2691 break;
2692 }
2693 dimregidx |= bits << bitpos;
2694 }
2695 bitpos += pDimensionDefinitions[i].bits;
2696 }
2697 DimensionRegion* dimreg = pDimensionRegions[dimregidx];
2698 if (veldim != -1) {
2699 // (dimreg is now the dimension region for the lowest velocity)
2700 if (dimreg->VelocityTable) // custom defined zone ranges
2701 bits = dimreg->VelocityTable[DimValues[veldim]];
2702 else // normal split type
2703 bits = uint8_t(DimValues[veldim] / pDimensionDefinitions[veldim].zone_size);
2704
2705 dimregidx |= bits << velbitpos;
2706 dimreg = pDimensionRegions[dimregidx];
2707 }
2708 return dimreg;
2709 }
2710
2711 /**
2712 * Returns the appropriate DimensionRegion for the given dimension bit
2713 * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
2714 * instead of calling this method directly!
2715 *
2716 * @param DimBits Bit numbers for dimension 0 to 7
2717 * @returns adress to the DimensionRegion for the given dimension
2718 * bit numbers
2719 * @see GetDimensionRegionByValue()
2720 */
2721 DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
2722 return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
2723 << pDimensionDefinitions[5].bits | DimBits[5])
2724 << pDimensionDefinitions[4].bits | DimBits[4])
2725 << pDimensionDefinitions[3].bits | DimBits[3])
2726 << pDimensionDefinitions[2].bits | DimBits[2])
2727 << pDimensionDefinitions[1].bits | DimBits[1])
2728 << pDimensionDefinitions[0].bits | DimBits[0]];
2729 }
2730
2731 /**
2732 * Returns pointer address to the Sample referenced with this region.
2733 * This is the global Sample for the entire Region (not sure if this is
2734 * actually used by the Gigasampler engine - I would only use the Sample
2735 * referenced by the appropriate DimensionRegion instead of this sample).
2736 *
2737 * @returns address to Sample or NULL if there is no reference to a
2738 * sample saved in the .gig file
2739 */
2740 Sample* Region::GetSample() {
2741 if (pSample) return static_cast<gig::Sample*>(pSample);
2742 else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
2743 }
2744
2745 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
2746 if ((int32_t)WavePoolTableIndex == -1) return NULL;
2747 File* file = (File*) GetParent()->GetParent();
2748 if (!file->pWavePoolTable) return NULL;
2749 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
2750 unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
2751 Sample* sample = file->GetFirstSample(pProgress);
2752 while (sample) {
2753 if (sample->ulWavePoolOffset == soughtoffset &&
2754 sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
2755 sample = file->GetNextSample();
2756 }
2757 return NULL;
2758 }
2759
2760
2761
2762 // *************** Instrument ***************
2763 // *
2764
2765 Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
2766 static const DLS::Info::FixedStringLength fixedStringLengths[] = {
2767 { CHUNK_ID_INAM, 64 },
2768 { CHUNK_ID_ISFT, 12 },
2769 { 0, 0 }
2770 };
2771 pInfo->FixedStringLengths = fixedStringLengths;
2772
2773 // Initialization
2774 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
2775 EffectSend = 0;
2776 Attenuation = 0;
2777 FineTune = 0;
2778 PitchbendRange = 0;
2779 PianoReleaseMode = false;
2780 DimensionKeyRange.low = 0;
2781 DimensionKeyRange.high = 0;
2782
2783 // Loading
2784 RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
2785 if (lart) {
2786 RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
2787 if (_3ewg) {
2788 EffectSend = _3ewg->ReadUint16();
2789 Attenuation = _3ewg->ReadInt32();
2790 FineTune = _3ewg->ReadInt16();
2791 PitchbendRange = _3ewg->ReadInt16();
2792 uint8_t dimkeystart = _3ewg->ReadUint8();
2793 PianoReleaseMode = dimkeystart & 0x01;
2794 DimensionKeyRange.low = dimkeystart >> 1;
2795 DimensionKeyRange.high = _3ewg->ReadUint8();
2796 }
2797 }
2798
2799 if (!pRegions) pRegions = new RegionList;
2800 RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
2801 if (lrgn) {
2802 RIFF::List* rgn = lrgn->GetFirstSubList();
2803 while (rgn) {
2804 if (rgn->GetListType() == LIST_TYPE_RGN) {
2805 __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
2806 pRegions->push_back(new Region(this, rgn));
2807 }
2808 rgn = lrgn->GetNextSubList();
2809 }
2810 // Creating Region Key Table for fast lookup
2811 UpdateRegionKeyTable();
2812 }
2813
2814 __notify_progress(pProgress, 1.0f); // notify done
2815 }
2816
2817 void Instrument::UpdateRegionKeyTable() {
2818 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
2819 RegionList::iterator iter = pRegions->begin();
2820 RegionList::iterator end = pRegions->end();
2821 for (; iter != end; ++iter) {
2822 gig::Region* pRegion = static_cast<gig::Region*>(*iter);
2823 for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
2824 RegionKeyTable[iKey] = pRegion;
2825 }
2826 }
2827 }
2828
2829 Instrument::~Instrument() {
2830 }
2831
2832 /**
2833 * Apply Instrument with all its Regions to the respective RIFF chunks.
2834 * You have to call File::Save() to make changes persistent.
2835 *
2836 * Usually there is absolutely no need to call this method explicitly.
2837 * It will be called automatically when File::Save() was called.
2838 *
2839 * @throws gig::Exception if samples cannot be dereferenced
2840 */
2841 void Instrument::UpdateChunks() {
2842 // first update base classes' chunks
2843 DLS::Instrument::UpdateChunks();
2844
2845 // update Regions' chunks
2846 {
2847 RegionList::iterator iter = pRegions->begin();
2848 RegionList::iterator end = pRegions->end();
2849 for (; iter != end; ++iter)
2850 (*iter)->UpdateChunks();
2851 }
2852
2853 // make sure 'lart' RIFF list chunk exists
2854 RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
2855 if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
2856 // make sure '3ewg' RIFF chunk exists
2857 RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
2858 if (!_3ewg) {
2859 File* pFile = (File*) GetParent();
2860
2861 // 3ewg is bigger in gig3, as it includes the iMIDI rules
2862 int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
2863 _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
2864 memset(_3ewg->LoadChunkData(), 0, size);
2865 }
2866 // update '3ewg' RIFF chunk
2867 uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
2868 store16(&pData[0], EffectSend);
2869 store32(&pData[2], Attenuation);
2870 store16(&pData[6], FineTune);
2871 store16(&pData[8], PitchbendRange);
2872 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
2873 DimensionKeyRange.low << 1;
2874 pData[10] = dimkeystart;
2875 pData[11] = DimensionKeyRange.high;
2876 }
2877
2878 /**
2879 * Returns the appropriate Region for a triggered note.
2880 *
2881 * @param Key MIDI Key number of triggered note / key (0 - 127)
2882 * @returns pointer adress to the appropriate Region or NULL if there
2883 * there is no Region defined for the given \a Key
2884 */
2885 Region* Instrument::GetRegion(unsigned int Key) {
2886 if (!pRegions || pRegions->empty() || Key > 127) return NULL;
2887 return RegionKeyTable[Key];
2888
2889 /*for (int i = 0; i < Regions; i++) {
2890 if (Key <= pRegions[i]->KeyRange.high &&
2891 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
2892 }
2893 return NULL;*/
2894 }
2895
2896 /**
2897 * Returns the first Region of the instrument. You have to call this
2898 * method once before you use GetNextRegion().
2899 *
2900 * @returns pointer address to first region or NULL if there is none
2901 * @see GetNextRegion()
2902 */
2903 Region* Instrument::GetFirstRegion() {
2904 if (!pRegions) return NULL;
2905 RegionsIterator = pRegions->begin();
2906 return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
2907 }
2908
2909 /**
2910 * Returns the next Region of the instrument. You have to call
2911 * GetFirstRegion() once before you can use this method. By calling this
2912 * method multiple times it iterates through the available Regions.
2913 *
2914 * @returns pointer address to the next region or NULL if end reached
2915 * @see GetFirstRegion()
2916 */
2917 Region* Instrument::GetNextRegion() {
2918 if (!pRegions) return NULL;
2919 RegionsIterator++;
2920 return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
2921 }
2922
2923 Region* Instrument::AddRegion() {
2924 // create new Region object (and its RIFF chunks)
2925 RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
2926 if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
2927 RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
2928 Region* pNewRegion = new Region(this, rgn);
2929 pRegions->push_back(pNewRegion);
2930 Regions = pRegions->size();
2931 // update Region key table for fast lookup
2932 UpdateRegionKeyTable();
2933 // done
2934 return pNewRegion;
2935 }
2936
2937 void Instrument::DeleteRegion(Region* pRegion) {
2938 if (!pRegions) return;
2939 DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
2940 // update Region key table for fast lookup
2941 UpdateRegionKeyTable();
2942 }
2943
2944
2945
2946 // *************** Group ***************
2947 // *
2948
2949 /** @brief Constructor.
2950 *
2951 * @param file - pointer to the gig::File object
2952 * @param ck3gnm - pointer to 3gnm chunk associated with this group or
2953 * NULL if this is a new Group
2954 */
2955 Group::Group(File* file, RIFF::Chunk* ck3gnm) {
2956 pFile = file;
2957 pNameChunk = ck3gnm;
2958 ::LoadString(pNameChunk, Name);
2959 }
2960
2961 Group::~Group() {
2962 // remove the chunk associated with this group (if any)
2963 if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
2964 }
2965
2966 /** @brief Update chunks with current group settings.
2967 *
2968 * Apply current Group field values to the respective chunks. You have
2969 * to call File::Save() to make changes persistent.
2970 *
2971 * Usually there is absolutely no need to call this method explicitly.
2972 * It will be called automatically when File::Save() was called.
2973 */
2974 void Group::UpdateChunks() {
2975 // make sure <3gri> and <3gnl> list chunks exist
2976 RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
2977 if (!_3gri) {
2978 _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
2979 pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
2980 }
2981 RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
2982 if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
2983
2984 if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
2985 // v3 has a fixed list of 128 strings, find a free one
2986 for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
2987 if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
2988 pNameChunk = ck;
2989 break;
2990 }
2991 }
2992 }
2993
2994 // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
2995 ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
2996 }
2997
2998 /**
2999 * Returns the first Sample of this Group. You have to call this method
3000 * once before you use GetNextSample().
3001 *
3002 * <b>Notice:</b> this method might block for a long time, in case the
3003 * samples of this .gig file were not scanned yet
3004 *
3005 * @returns pointer address to first Sample or NULL if there is none
3006 * applied to this Group
3007 * @see GetNextSample()
3008 */
3009 Sample* Group::GetFirstSample() {
3010 // FIXME: lazy und unsafe implementation, should be an autonomous iterator
3011 for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
3012 if (pSample->GetGroup() == this) return pSample;
3013 }
3014 return NULL;
3015 }
3016
3017 /**
3018 * Returns the next Sample of the Group. You have to call
3019 * GetFirstSample() once before you can use this method. By calling this
3020 * method multiple times it iterates through the Samples assigned to
3021 * this Group.
3022 *
3023 * @returns pointer address to the next Sample of this Group or NULL if
3024 * end reached
3025 * @see GetFirstSample()
3026 */
3027 Sample* Group::GetNextSample() {
3028 // FIXME: lazy und unsafe implementation, should be an autonomous iterator
3029 for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
3030 if (pSample->GetGroup() == this) return pSample;
3031 }
3032 return NULL;
3033 }
3034
3035 /**
3036 * Move Sample given by \a pSample from another Group to this Group.
3037 */
3038 void Group::AddSample(Sample* pSample) {
3039 pSample->pGroup = this;
3040 }
3041
3042 /**
3043 * Move all members of this group to another group (preferably the 1st
3044 * one except this). This method is called explicitly by
3045 * File::DeleteGroup() thus when a Group was deleted. This code was
3046 * intentionally not placed in the destructor!
3047 */
3048 void Group::MoveAll() {
3049 // get "that" other group first
3050 Group* pOtherGroup = NULL;
3051 for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
3052 if (pOtherGroup != this) break;
3053 }
3054 if (!pOtherGroup) throw Exception(
3055 "Could not move samples to another group, since there is no "
3056 "other Group. This is a bug, report it!"
3057 );
3058 // now move all samples of this group to the other group
3059 for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
3060 pOtherGroup->AddSample(pSample);
3061 }
3062 }
3063
3064
3065
3066 // *************** File ***************
3067 // *
3068
3069 // File version 2.0, 1998-06-28
3070 const DLS::version_t File::VERSION_2 = {
3071 0, 2, 19980628 & 0xffff, 19980628 >> 16
3072 };
3073
3074 // File version 3.0, 2003-03-31
3075 const DLS::version_t File::VERSION_3 = {
3076 0, 3, 20030331 & 0xffff, 20030331 >> 16
3077 };
3078
3079 const DLS::Info::FixedStringLength File::FixedStringLengths[] = {
3080 { CHUNK_ID_IARL, 256 },
3081 { CHUNK_ID_IART, 128 },
3082 { CHUNK_ID_ICMS, 128 },
3083 { CHUNK_ID_ICMT, 1024 },
3084 { CHUNK_ID_ICOP, 128 },
3085 { CHUNK_ID_ICRD, 128 },
3086 { CHUNK_ID_IENG, 128 },
3087 { CHUNK_ID_IGNR, 128 },
3088 { CHUNK_ID_IKEY, 128 },
3089 { CHUNK_ID_IMED, 128 },
3090 { CHUNK_ID_INAM, 128 },
3091 { CHUNK_ID_IPRD, 128 },
3092 { CHUNK_ID_ISBJ, 128 },
3093 { CHUNK_ID_ISFT, 128 },
3094 { CHUNK_ID_ISRC, 128 },
3095 { CHUNK_ID_ISRF, 128 },
3096 { CHUNK_ID_ITCH, 128 },
3097 { 0, 0 }
3098 };
3099
3100 File::File() : DLS::File() {
3101 *pVersion = VERSION_3;
3102 pGroups = NULL;
3103 pInfo->FixedStringLengths = FixedStringLengths;
3104 pInfo->ArchivalLocation = String(256, ' ');
3105
3106 // add some mandatory chunks to get the file chunks in right
3107 // order (INFO chunk will be moved to first position later)
3108 pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
3109 pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
3110 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
3111
3112 GenerateDLSID();
3113 }
3114
3115 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
3116 pGroups = NULL;
3117 pInfo->FixedStringLengths = FixedStringLengths;
3118 }
3119
3120 File::~File() {
3121 if (pGroups) {
3122 std::list<Group*>::iterator iter = pGroups->begin();
3123 std::list<Group*>::iterator end = pGroups->end();
3124 while (iter != end) {
3125 delete *iter;
3126 ++iter;
3127 }
3128 delete pGroups;
3129 }
3130 }
3131
3132 Sample* File::GetFirstSample(progress_t* pProgress) {
3133 if (!pSamples) LoadSamples(pProgress);
3134 if (!pSamples) return NULL;
3135 SamplesIterator = pSamples->begin();
3136 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
3137 }
3138
3139 Sample* File::GetNextSample() {
3140 if (!pSamples) return NULL;
3141 SamplesIterator++;
3142 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
3143 }
3144
3145 /** @brief Add a new sample.
3146 *
3147 * This will create a new Sample object for the gig file. You have to
3148 * call Save() to make this persistent to the file.
3149 *
3150 * @returns pointer to new Sample object
3151 */
3152 Sample* File::AddSample() {
3153 if (!pSamples) LoadSamples();
3154 __ensureMandatoryChunksExist();
3155 RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
3156 // create new Sample object and its respective 'wave' list chunk
3157 RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
3158 Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
3159
3160 // add mandatory chunks to get the chunks in right order
3161 wave->AddSubChunk(CHUNK_ID_FMT, 16);
3162 wave->AddSubList(LIST_TYPE_INFO);
3163
3164 pSamples->push_back(pSample);
3165 return pSample;
3166 }
3167
3168 /** @brief Delete a sample.
3169 *
3170 * This will delete the given Sample object from the gig file. Any
3171 * references to this sample from Regions and DimensionRegions will be
3172 * removed. You have to call Save() to make this persistent to the file.
3173 *
3174 * @param pSample - sample to delete
3175 * @throws gig::Exception if given sample could not be found
3176 */
3177 void File::DeleteSample(Sample* pSample) {
3178 if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
3179 SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
3180 if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
3181 if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
3182 pSamples->erase(iter);
3183 delete pSample;
3184
3185 // remove all references to the sample
3186 for (Instrument* instrument = GetFirstInstrument() ; instrument ;
3187 instrument = GetNextInstrument()) {
3188 for (Region* region = instrument->GetFirstRegion() ; region ;
3189 region = instrument->GetNextRegion()) {
3190
3191 if (region->GetSample() == pSample) region->SetSample(NULL);
3192
3193 for (int i = 0 ; i < region->DimensionRegions ; i++) {
3194 gig::DimensionRegion *d = region->pDimensionRegions[i];
3195 if (d->pSample == pSample) d->pSample = NULL;
3196 }
3197 }
3198 }
3199 }
3200
3201 void File::LoadSamples() {
3202 LoadSamples(NULL);
3203 }
3204
3205 void File::LoadSamples(progress_t* pProgress) {
3206 // Groups must be loaded before samples, because samples will try
3207 // to resolve the group they belong to
3208 if (!pGroups) LoadGroups();
3209
3210 if (!pSamples) pSamples = new SampleList;
3211
3212 RIFF::File* file = pRIFF;
3213
3214 // just for progress calculation
3215 int iSampleIndex = 0;
3216 int iTotalSamples = WavePoolCount;
3217
3218 // check if samples should be loaded from extension files
3219 int lastFileNo = 0;
3220 for (int i = 0 ; i < WavePoolCount ; i++) {
3221 if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
3222 }
3223 String name(pRIFF->GetFileName());
3224 int nameLen = name.length();
3225 char suffix[6];
3226 if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
3227
3228 for (int fileNo = 0 ; ; ) {
3229 RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
3230 if (wvpl) {
3231 unsigned long wvplFileOffset = wvpl->GetFilePos();
3232 RIFF::List* wave = wvpl->GetFirstSubList();
3233 while (wave) {
3234 if (wave->GetListType() == LIST_TYPE_WAVE) {
3235 // notify current progress
3236 const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
3237 __notify_progress(pProgress, subprogress);
3238
3239 unsigned long waveFileOffset = wave->GetFilePos();
3240 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
3241
3242 iSampleIndex++;
3243 }
3244 wave = wvpl->GetNextSubList();
3245 }
3246
3247 if (fileNo == lastFileNo) break;
3248
3249 // open extension file (*.gx01, *.gx02, ...)
3250 fileNo++;
3251 sprintf(suffix, ".gx%02d", fileNo);
3252 name.replace(nameLen, 5, suffix);
3253 file = new RIFF::File(name);
3254 ExtensionFiles.push_back(file);
3255 } else break;
3256 }
3257
3258 __notify_progress(pProgress, 1.0); // notify done
3259 }
3260
3261 Instrument* File::GetFirstInstrument() {
3262 if (!pInstruments) LoadInstruments();
3263 if (!pInstruments) return NULL;
3264 InstrumentsIterator = pInstruments->begin();
3265 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
3266 }
3267
3268 Instrument* File::GetNextInstrument() {
3269 if (!pInstruments) return NULL;
3270 InstrumentsIterator++;
3271 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
3272 }
3273
3274 /**
3275 * Returns the instrument with the given index.
3276 *
3277 * @param index - number of the sought instrument (0..n)
3278 * @param pProgress - optional: callback function for progress notification
3279 * @returns sought instrument or NULL if there's no such instrument
3280 */
3281 Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
3282 if (!pInstruments) {
3283 // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
3284
3285 // sample loading subtask
3286 progress_t subprogress;
3287 __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
3288 __notify_progress(&subprogress, 0.0f);
3289 GetFirstSample(&subprogress); // now force all samples to be loaded
3290 __notify_progress(&subprogress, 1.0f);
3291
3292 // instrument loading subtask
3293 if (pProgress && pProgress->callback) {
3294 subprogress.__range_min = subprogress.__range_max;
3295 subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
3296 }
3297 __notify_progress(&subprogress, 0.0f);
3298 LoadInstruments(&subprogress);
3299 __notify_progress(&subprogress, 1.0f);
3300 }
3301 if (!pInstruments) return NULL;
3302 InstrumentsIterator = pInstruments->begin();
3303 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
3304 if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
3305 InstrumentsIterator++;
3306 }
3307 return NULL;
3308 }
3309
3310 /** @brief Add a new instrument definition.
3311 *
3312 * This will create a new Instrument object for the gig file. You have
3313 * to call Save() to make this persistent to the file.
3314 *
3315 * @returns pointer to new Instrument object
3316 */
3317 Instrument* File::AddInstrument() {
3318 if (!pInstruments) LoadInstruments();
3319 __ensureMandatoryChunksExist();
3320 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
3321 RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
3322
3323 // add mandatory chunks to get the chunks in right order
3324 lstInstr->AddSubList(LIST_TYPE_INFO);
3325 lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
3326
3327 Instrument* pInstrument = new Instrument(this, lstInstr);
3328 pInstrument->GenerateDLSID();
3329
3330 lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
3331
3332 // this string is needed for the gig to be loadable in GSt:
3333 pInstrument->pInfo->Software = "Endless Wave";
3334
3335 pInstruments->push_back(pInstrument);
3336 return pInstrument;
3337 }
3338
3339 /** @brief Delete an instrument.
3340 *
3341 * This will delete the given Instrument object from the gig file. You
3342 * have to call Save() to make this persistent to the file.
3343 *
3344 * @param pInstrument - instrument to delete
3345 * @throws gig::Exception if given instrument could not be found
3346 */
3347 void File::DeleteInstrument(Instrument* pInstrument) {
3348 if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
3349 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
3350 if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
3351 pInstruments->erase(iter);
3352 delete pInstrument;
3353 }
3354
3355 void File::LoadInstruments() {
3356 LoadInstruments(NULL);
3357 }
3358
3359 void File::LoadInstruments(progress_t* pProgress) {
3360 if (!pInstruments) pInstruments = new InstrumentList;
3361 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
3362 if (lstInstruments) {
3363 int iInstrumentIndex = 0;
3364 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
3365 while (lstInstr) {
3366 if (lstInstr->GetListType() == LIST_TYPE_INS) {
3367 // notify current progress
3368 const float localProgress = (float) iInstrumentIndex / (float) Instruments;
3369 __notify_progress(pProgress, localProgress);
3370
3371 // divide local progress into subprogress for loading current Instrument
3372 progress_t subprogress;
3373 __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
3374
3375 pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
3376
3377 iInstrumentIndex++;
3378 }
3379 lstInstr = lstInstruments->GetNextSubList();
3380 }
3381 __notify_progress(pProgress, 1.0); // notify done
3382 }
3383 }
3384
3385 /// Updates the 3crc chunk with the checksum of a sample. The
3386 /// update is done directly to disk, as this method is called
3387 /// after File::Save()
3388 void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
3389 RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
3390 if (!_3crc) return;
3391
3392 // get the index of the sample
3393 int iWaveIndex = -1;
3394 File::SampleList::iterator iter = pSamples->begin();
3395 File::SampleList::iterator end = pSamples->end();
3396 for (int index = 0; iter != end; ++iter, ++index) {
3397 if (*iter == pSample) {
3398 iWaveIndex = index;
3399 break;
3400 }
3401 }
3402 if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
3403
3404 // write the CRC-32 checksum to disk
3405 _3crc->SetPos(iWaveIndex * 8);
3406 uint32_t tmp = 1;
3407 _3crc->WriteUint32(&tmp); // unknown, always 1?
3408 _3crc->WriteUint32(&crc);
3409 }
3410
3411 Group* File::GetFirstGroup() {
3412 if (!pGroups) LoadGroups();
3413 // there must always be at least one group
3414 GroupsIterator = pGroups->begin();
3415 return *GroupsIterator;
3416 }
3417
3418 Group* File::GetNextGroup() {
3419 if (!pGroups) return NULL;
3420 ++GroupsIterator;
3421 return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
3422 }
3423
3424 /**
3425 * Returns the group with the given index.
3426 *
3427 * @param index - number of the sought group (0..n)
3428 * @returns sought group or NULL if there's no such group
3429 */
3430 Group* File::GetGroup(uint index) {
3431 if (!pGroups) LoadGroups();
3432 GroupsIterator = pGroups->begin();
3433 for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
3434 if (i == index) return *GroupsIterator;
3435 ++GroupsIterator;
3436 }
3437 return NULL;
3438 }
3439
3440 Group* File::AddGroup() {
3441 if (!pGroups) LoadGroups();
3442 // there must always be at least one group
3443 __ensureMandatoryChunksExist();
3444 Group* pGroup = new Group(this, NULL);
3445 pGroups->push_back(pGroup);
3446 return pGroup;
3447 }
3448
3449 /** @brief Delete a group and its samples.
3450 *
3451 * This will delete the given Group object and all the samples that
3452 * belong to this group from the gig file. You have to call Save() to
3453 * make this persistent to the file.
3454 *
3455 * @param pGroup - group to delete
3456 * @throws gig::Exception if given group could not be found
3457 */
3458 void File::DeleteGroup(Group* pGroup) {
3459 if (!pGroups) LoadGroups();
3460 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
3461 if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
3462 if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
3463 // delete all members of this group
3464 for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
3465 DeleteSample(pSample);
3466 }
3467 // now delete this group object
3468 pGroups->erase(iter);
3469 delete pGroup;
3470 }
3471
3472 /** @brief Delete a group.
3473 *
3474 * This will delete the given Group object from the gig file. All the
3475 * samples that belong to this group will not be deleted, but instead
3476 * be moved to another group. You have to call Save() to make this
3477 * persistent to the file.
3478 *
3479 * @param pGroup - group to delete
3480 * @throws gig::Exception if given group could not be found
3481 */
3482 void File::DeleteGroupOnly(Group* pGroup) {
3483 if (!pGroups) LoadGroups();
3484 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
3485 if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
3486 if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
3487 // move all members of this group to another group
3488 pGroup->MoveAll();
3489 pGroups->erase(iter);
3490 delete pGroup;
3491 }
3492
3493 void File::LoadGroups() {
3494 if (!pGroups) pGroups = new std::list<Group*>;
3495 // try to read defined groups from file
3496 RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
3497 if (lst3gri) {
3498 RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
3499 if (lst3gnl) {
3500 RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
3501 while (ck) {
3502 if (ck->GetChunkID() == CHUNK_ID_3GNM) {
3503 if (pVersion && pVersion->major == 3 &&
3504 strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
3505
3506 pGroups->push_back(new Group(this, ck));
3507 }
3508 ck = lst3gnl->GetNextSubChunk();
3509 }
3510 }
3511 }
3512 // if there were no group(s), create at least the mandatory default group
3513 if (!pGroups->size()) {
3514 Group* pGroup = new Group(this, NULL);
3515 pGroup->Name = "Default Group";
3516 pGroups->push_back(pGroup);
3517 }
3518 }
3519
3520 /**
3521 * Apply all the gig file's current instruments, samples, groups and settings
3522 * to the respective RIFF chunks. You have to call Save() to make changes
3523 * persistent.
3524 *
3525 * Usually there is absolutely no need to call this method explicitly.
3526 * It will be called automatically when File::Save() was called.
3527 *
3528 * @throws Exception - on errors
3529 */
3530 void File::UpdateChunks() {
3531 bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
3532
3533 b64BitWavePoolOffsets = pVersion && pVersion->major == 3;
3534
3535 // first update base class's chunks
3536 DLS::File::UpdateChunks();
3537
3538 if (newFile) {
3539 // INFO was added by Resource::UpdateChunks - make sure it
3540 // is placed first in file
3541 RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
3542 RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
3543 if (first != info) {
3544 pRIFF->MoveSubChunk(info, first);
3545 }
3546 }
3547
3548 // update group's chunks
3549 if (pGroups) {
3550 std::list<Group*>::iterator iter = pGroups->begin();
3551 std::list<Group*>::iterator end = pGroups->end();
3552 for (; iter != end; ++iter) {
3553 (*iter)->UpdateChunks();
3554 }
3555
3556 // v3: make sure the file has 128 3gnm chunks
3557 if (pVersion && pVersion->major == 3) {
3558 RIFF::List* _3gnl = pRIFF->GetSubList(LIST_TYPE_3GRI)->GetSubList(LIST_TYPE_3GNL);
3559 RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
3560 for (int i = 0 ; i < 128 ; i++) {
3561 if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
3562 if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
3563 }
3564 }
3565 }
3566
3567 // update einf chunk
3568
3569 // The einf chunk contains statistics about the gig file, such
3570 // as the number of regions and samples used by each
3571 // instrument. It is divided in equally sized parts, where the
3572 // first part contains information about the whole gig file,
3573 // and the rest of the parts map to each instrument in the
3574 // file.
3575 //
3576 // At the end of each part there is a bit map of each sample
3577 // in the file, where a set bit means that the sample is used
3578 // by the file/instrument.
3579 //
3580 // Note that there are several fields with unknown use. These
3581 // are set to zero.
3582
3583 int sublen = pSamples->size() / 8 + 49;
3584 int einfSize = (Instruments + 1) * sublen;
3585
3586 RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
3587 if (einf) {
3588 if (einf->GetSize() != einfSize) {
3589 einf->Resize(einfSize);
3590 memset(einf->LoadChunkData(), 0, einfSize);
3591 }
3592 } else if (newFile) {
3593 einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
3594 }
3595 if (einf) {
3596 uint8_t* pData = (uint8_t*) einf->LoadChunkData();
3597
3598 std::map<gig::Sample*,int> sampleMap;
3599 int sampleIdx = 0;
3600 for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
3601 sampleMap[pSample] = sampleIdx++;
3602 }
3603
3604 int totnbusedsamples = 0;
3605 int totnbusedchannels = 0;
3606 int totnbregions = 0;
3607 int totnbdimregions = 0;
3608 int totnbloops = 0;
3609 int instrumentIdx = 0;
3610
3611 memset(&pData[48], 0, sublen - 48);
3612
3613 for (Instrument* instrument = GetFirstInstrument() ; instrument ;
3614 instrument = GetNextInstrument()) {
3615 int nbusedsamples = 0;
3616 int nbusedchannels = 0;
3617 int nbdimregions = 0;
3618 int nbloops = 0;
3619
3620 memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
3621
3622 for (Region* region = instrument->GetFirstRegion() ; region ;
3623 region = instrument->GetNextRegion()) {
3624 for (int i = 0 ; i < region->DimensionRegions ; i++) {
3625 gig::DimensionRegion *d = region->pDimensionRegions[i];
3626 if (d->pSample) {
3627 int sampleIdx = sampleMap[d->pSample];
3628 int byte = 48 + sampleIdx / 8;
3629 int bit = 1 << (sampleIdx & 7);
3630 if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
3631 pData[(instrumentIdx + 1) * sublen + byte] |= bit;
3632 nbusedsamples++;
3633 nbusedchannels += d->pSample->Channels;
3634
3635 if ((pData[byte] & bit) == 0) {
3636 pData[byte] |= bit;
3637 totnbusedsamples++;
3638 totnbusedchannels += d->pSample->Channels;
3639 }
3640 }
3641 }
3642 if (d->SampleLoops) nbloops++;
3643 }
3644 nbdimregions += region->DimensionRegions;
3645 }
3646 // first 4 bytes unknown - sometimes 0, sometimes length of einf part
3647 // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
3648 store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
3649 store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
3650 store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
3651 store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
3652 store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
3653 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
3654 // next 8 bytes unknown
3655 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
3656 store32(&pData[(instrumentIdx + 1) * sublen + 40], pSamples->size());
3657 // next 4 bytes unknown
3658
3659 totnbregions += instrument->Regions;
3660 totnbdimregions += nbdimregions;
3661 totnbloops += nbloops;
3662 instrumentIdx++;
3663 }
3664 // first 4 bytes unknown - sometimes 0, sometimes length of einf part
3665 // store32(&pData[0], sublen);
3666 store32(&pData[4], totnbusedchannels);
3667 store32(&pData[8], totnbusedsamples);
3668 store32(&pData[12], Instruments);
3669 store32(&pData[16], totnbregions);
3670 store32(&pData[20], totnbdimregions);
3671 store32(&pData[24], totnbloops);
3672 // next 8 bytes unknown
3673 // next 4 bytes unknown, not always 0
3674 store32(&pData[40], pSamples->size());
3675 // next 4 bytes unknown
3676 }
3677
3678 // update 3crc chunk
3679
3680 // The 3crc chunk contains CRC-32 checksums for the
3681 // samples. The actual checksum values will be filled in
3682 // later, by Sample::Write.
3683
3684 RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
3685 if (_3crc) {
3686 _3crc->Resize(pSamples->size() * 8);
3687 } else if (newFile) {
3688 _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
3689 _3crc->LoadChunkData();
3690
3691 // the order of einf and 3crc is not the same in v2 and v3
3692 if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
3693 }
3694 }
3695
3696
3697
3698 // *************** Exception ***************
3699 // *
3700
3701 Exception::Exception(String Message) : DLS::Exception(Message) {
3702 }
3703
3704 void Exception::PrintMessage() {
3705 std::cout << "gig::Exception: " << Message << std::endl;
3706 }
3707
3708
3709 // *************** functions ***************
3710 // *
3711
3712 /**
3713 * Returns the name of this C++ library. This is usually "libgig" of
3714 * course. This call is equivalent to RIFF::libraryName() and
3715 * DLS::libraryName().
3716 */
3717 String libraryName() {
3718 return PACKAGE;
3719 }
3720
3721 /**
3722 * Returns version of this C++ library. This call is equivalent to
3723 * RIFF::libraryVersion() and DLS::libraryVersion().
3724 */
3725 String libraryVersion() {
3726 return VERSION;
3727 }
3728
3729 } // namespace gig

  ViewVC Help
Powered by ViewVC