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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 372 - (show annotations) (download)
Fri Feb 11 18:58:07 2005 UTC (14 years, 9 months ago) by persson
File size: 79612 byte(s)
* src/gig.cpp: Fixed mono decompression.

1 /***************************************************************************
2 * *
3 * libgig - C++ cross-platform Gigasampler format file loader library *
4 * *
5 * Copyright (C) 2003, 2004 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 namespace gig { namespace {
27
28 // *************** Internal functions for sample decopmression ***************
29 // *
30
31 inline int get12lo(const unsigned char* pSrc)
32 {
33 const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
34 return x & 0x800 ? x - 0x1000 : x;
35 }
36
37 inline int get12hi(const unsigned char* pSrc)
38 {
39 const int x = pSrc[1] >> 4 | pSrc[2] << 4;
40 return x & 0x800 ? x - 0x1000 : x;
41 }
42
43 inline int16_t get16(const unsigned char* pSrc)
44 {
45 return int16_t(pSrc[0] | pSrc[1] << 8);
46 }
47
48 inline int get24(const unsigned char* pSrc)
49 {
50 const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
51 return x & 0x800000 ? x - 0x1000000 : x;
52 }
53
54 void Decompress16(int compressionmode, const unsigned char* params,
55 int srcStep, int dstStep,
56 const unsigned char* pSrc, int16_t* pDst,
57 unsigned long currentframeoffset,
58 unsigned long copysamples)
59 {
60 switch (compressionmode) {
61 case 0: // 16 bit uncompressed
62 pSrc += currentframeoffset * srcStep;
63 while (copysamples) {
64 *pDst = get16(pSrc);
65 pDst += dstStep;
66 pSrc += srcStep;
67 copysamples--;
68 }
69 break;
70
71 case 1: // 16 bit compressed to 8 bit
72 int y = get16(params);
73 int dy = get16(params + 2);
74 while (currentframeoffset) {
75 dy -= int8_t(*pSrc);
76 y -= dy;
77 pSrc += srcStep;
78 currentframeoffset--;
79 }
80 while (copysamples) {
81 dy -= int8_t(*pSrc);
82 y -= dy;
83 *pDst = y;
84 pDst += dstStep;
85 pSrc += srcStep;
86 copysamples--;
87 }
88 break;
89 }
90 }
91
92 void Decompress24(int compressionmode, const unsigned char* params,
93 int dstStep, const unsigned char* pSrc, int16_t* pDst,
94 unsigned long currentframeoffset,
95 unsigned long copysamples)
96 {
97 // Note: The 24 bits are truncated to 16 bits for now.
98
99 // Note: The calculation of the initial value of y is strange
100 // and not 100% correct. What should the first two parameters
101 // really be used for? Why are they two? The correct value for
102 // y seems to lie somewhere between the values of the first
103 // two parameters.
104 //
105 // Strange thing #2: The formula in SKIP_ONE gives values for
106 // y that are twice as high as they should be. That's why
107 // COPY_ONE shifts 9 steps instead of 8, and also why y is
108 // initialized with a sum instead of a mean value.
109
110 int y, dy, ddy;
111
112 #define GET_PARAMS(params) \
113 y = (get24(params) + get24((params) + 3)); \
114 dy = get24((params) + 6); \
115 ddy = get24((params) + 9)
116
117 #define SKIP_ONE(x) \
118 ddy -= (x); \
119 dy -= ddy; \
120 y -= dy
121
122 #define COPY_ONE(x) \
123 SKIP_ONE(x); \
124 *pDst = y >> 9; \
125 pDst += dstStep
126
127 switch (compressionmode) {
128 case 2: // 24 bit uncompressed
129 pSrc += currentframeoffset * 3;
130 while (copysamples) {
131 *pDst = get24(pSrc) >> 8;
132 pDst += dstStep;
133 pSrc += 3;
134 copysamples--;
135 }
136 break;
137
138 case 3: // 24 bit compressed to 16 bit
139 GET_PARAMS(params);
140 while (currentframeoffset) {
141 SKIP_ONE(get16(pSrc));
142 pSrc += 2;
143 currentframeoffset--;
144 }
145 while (copysamples) {
146 COPY_ONE(get16(pSrc));
147 pSrc += 2;
148 copysamples--;
149 }
150 break;
151
152 case 4: // 24 bit compressed to 12 bit
153 GET_PARAMS(params);
154 while (currentframeoffset > 1) {
155 SKIP_ONE(get12lo(pSrc));
156 SKIP_ONE(get12hi(pSrc));
157 pSrc += 3;
158 currentframeoffset -= 2;
159 }
160 if (currentframeoffset) {
161 SKIP_ONE(get12lo(pSrc));
162 currentframeoffset--;
163 if (copysamples) {
164 COPY_ONE(get12hi(pSrc));
165 pSrc += 3;
166 copysamples--;
167 }
168 }
169 while (copysamples > 1) {
170 COPY_ONE(get12lo(pSrc));
171 COPY_ONE(get12hi(pSrc));
172 pSrc += 3;
173 copysamples -= 2;
174 }
175 if (copysamples) {
176 COPY_ONE(get12lo(pSrc));
177 }
178 break;
179
180 case 5: // 24 bit compressed to 8 bit
181 GET_PARAMS(params);
182 while (currentframeoffset) {
183 SKIP_ONE(int8_t(*pSrc++));
184 currentframeoffset--;
185 }
186 while (copysamples) {
187 COPY_ONE(int8_t(*pSrc++));
188 copysamples--;
189 }
190 break;
191 }
192 }
193
194 const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
195 const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
196 const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
197 const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
198 }
199
200
201 // *************** Sample ***************
202 // *
203
204 unsigned int Sample::Instances = 0;
205 unsigned char* Sample::pDecompressionBuffer = NULL;
206 unsigned long Sample::DecompressionBufferSize = 0;
207
208 Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
209 Instances++;
210
211 RIFF::Chunk* _3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
212 if (!_3gix) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
213 SampleGroup = _3gix->ReadInt16();
214
215 RIFF::Chunk* smpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
216 if (!smpl) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
217 Manufacturer = smpl->ReadInt32();
218 Product = smpl->ReadInt32();
219 SamplePeriod = smpl->ReadInt32();
220 MIDIUnityNote = smpl->ReadInt32();
221 FineTune = smpl->ReadInt32();
222 smpl->Read(&SMPTEFormat, 1, 4);
223 SMPTEOffset = smpl->ReadInt32();
224 Loops = smpl->ReadInt32();
225 smpl->ReadInt32(); // manufByt
226 LoopID = smpl->ReadInt32();
227 smpl->Read(&LoopType, 1, 4);
228 LoopStart = smpl->ReadInt32();
229 LoopEnd = smpl->ReadInt32();
230 LoopFraction = smpl->ReadInt32();
231 LoopPlayCount = smpl->ReadInt32();
232
233 FrameTable = NULL;
234 SamplePos = 0;
235 RAMCache.Size = 0;
236 RAMCache.pStart = NULL;
237 RAMCache.NullExtensionSize = 0;
238
239 if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
240
241 Compressed = (waveList->GetSubChunk(CHUNK_ID_EWAV));
242 if (Compressed) {
243 ScanCompressedSample();
244 }
245
246 // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
247 if ((Compressed || BitDepth == 24) && !pDecompressionBuffer) {
248 pDecompressionBuffer = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
249 DecompressionBufferSize = INITIAL_SAMPLE_BUFFER_SIZE;
250 }
251 FrameOffset = 0; // just for streaming compressed samples
252
253 LoopSize = LoopEnd - LoopStart;
254 }
255
256 /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
257 void Sample::ScanCompressedSample() {
258 //TODO: we have to add some more scans here (e.g. determine compression rate)
259 this->SamplesTotal = 0;
260 std::list<unsigned long> frameOffsets;
261
262 SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
263 WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels;
264
265 // Scanning
266 pCkData->SetPos(0);
267 if (Channels == 2) { // Stereo
268 for (int i = 0 ; ; i++) {
269 // for 24 bit samples every 8:th frame offset is
270 // stored, to save some memory
271 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
272
273 const int mode_l = pCkData->ReadUint8();
274 const int mode_r = pCkData->ReadUint8();
275 if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
276 const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
277
278 if (pCkData->RemainingBytes() <= frameSize) {
279 SamplesInLastFrame =
280 ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
281 (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
282 SamplesTotal += SamplesInLastFrame;
283 break;
284 }
285 SamplesTotal += SamplesPerFrame;
286 pCkData->SetPos(frameSize, RIFF::stream_curpos);
287 }
288 }
289 else { // Mono
290 for (int i = 0 ; ; i++) {
291 if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
292
293 const int mode = pCkData->ReadUint8();
294 if (mode > 5) throw gig::Exception("Unknown compression mode");
295 const unsigned long frameSize = bytesPerFrame[mode];
296
297 if (pCkData->RemainingBytes() <= frameSize) {
298 SamplesInLastFrame =
299 ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
300 SamplesTotal += SamplesInLastFrame;
301 break;
302 }
303 SamplesTotal += SamplesPerFrame;
304 pCkData->SetPos(frameSize, RIFF::stream_curpos);
305 }
306 }
307 pCkData->SetPos(0);
308
309 // Build the frames table (which is used for fast resolving of a frame's chunk offset)
310 if (FrameTable) delete[] FrameTable;
311 FrameTable = new unsigned long[frameOffsets.size()];
312 std::list<unsigned long>::iterator end = frameOffsets.end();
313 std::list<unsigned long>::iterator iter = frameOffsets.begin();
314 for (int i = 0; iter != end; i++, iter++) {
315 FrameTable[i] = *iter;
316 }
317 }
318
319 /**
320 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
321 * ReleaseSampleData() to free the memory if you don't need the cached
322 * sample data anymore.
323 *
324 * @returns buffer_t structure with start address and size of the buffer
325 * in bytes
326 * @see ReleaseSampleData(), Read(), SetPos()
327 */
328 buffer_t Sample::LoadSampleData() {
329 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
330 }
331
332 /**
333 * Reads (uncompresses if needed) and caches the first \a SampleCount
334 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
335 * memory space if you don't need the cached samples anymore. There is no
336 * guarantee that exactly \a SampleCount samples will be cached; this is
337 * not an error. The size will be eventually truncated e.g. to the
338 * beginning of a frame of a compressed sample. This is done for
339 * efficiency reasons while streaming the wave by your sampler engine
340 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
341 * that will be returned to determine the actual cached samples, but note
342 * that the size is given in bytes! You get the number of actually cached
343 * samples by dividing it by the frame size of the sample:
344 *
345 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
346 * long cachedsamples = buf.Size / pSample->FrameSize;
347 *
348 * @param SampleCount - number of sample points to load into RAM
349 * @returns buffer_t structure with start address and size of
350 * the cached sample data in bytes
351 * @see ReleaseSampleData(), Read(), SetPos()
352 */
353 buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
354 return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
355 }
356
357 /**
358 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
359 * ReleaseSampleData() to free the memory if you don't need the cached
360 * sample data anymore.
361 * The method will add \a NullSamplesCount silence samples past the
362 * official buffer end (this won't affect the 'Size' member of the
363 * buffer_t structure, that means 'Size' always reflects the size of the
364 * actual sample data, the buffer might be bigger though). Silence
365 * samples past the official buffer are needed for differential
366 * algorithms that always have to take subsequent samples into account
367 * (resampling/interpolation would be an important example) and avoids
368 * memory access faults in such cases.
369 *
370 * @param NullSamplesCount - number of silence samples the buffer should
371 * be extended past it's data end
372 * @returns buffer_t structure with start address and
373 * size of the buffer in bytes
374 * @see ReleaseSampleData(), Read(), SetPos()
375 */
376 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
377 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
378 }
379
380 /**
381 * Reads (uncompresses if needed) and caches the first \a SampleCount
382 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
383 * memory space if you don't need the cached samples anymore. There is no
384 * guarantee that exactly \a SampleCount samples will be cached; this is
385 * not an error. The size will be eventually truncated e.g. to the
386 * beginning of a frame of a compressed sample. This is done for
387 * efficiency reasons while streaming the wave by your sampler engine
388 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
389 * that will be returned to determine the actual cached samples, but note
390 * that the size is given in bytes! You get the number of actually cached
391 * samples by dividing it by the frame size of the sample:
392 *
393 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
394 * long cachedsamples = buf.Size / pSample->FrameSize;
395 *
396 * The method will add \a NullSamplesCount silence samples past the
397 * official buffer end (this won't affect the 'Size' member of the
398 * buffer_t structure, that means 'Size' always reflects the size of the
399 * actual sample data, the buffer might be bigger though). Silence
400 * samples past the official buffer are needed for differential
401 * algorithms that always have to take subsequent samples into account
402 * (resampling/interpolation would be an important example) and avoids
403 * memory access faults in such cases.
404 *
405 * @param SampleCount - number of sample points to load into RAM
406 * @param NullSamplesCount - number of silence samples the buffer should
407 * be extended past it's data end
408 * @returns buffer_t structure with start address and
409 * size of the cached sample data in bytes
410 * @see ReleaseSampleData(), Read(), SetPos()
411 */
412 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
413 if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
414 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
415 unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
416 RAMCache.pStart = new int8_t[allocationsize];
417 RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
418 RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
419 // fill the remaining buffer space with silence samples
420 memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
421 return GetCache();
422 }
423
424 /**
425 * Returns current cached sample points. A buffer_t structure will be
426 * returned which contains address pointer to the begin of the cache and
427 * the size of the cached sample data in bytes. Use
428 * <i>LoadSampleData()</i> to cache a specific amount of sample points in
429 * RAM.
430 *
431 * @returns buffer_t structure with current cached sample points
432 * @see LoadSampleData();
433 */
434 buffer_t Sample::GetCache() {
435 // return a copy of the buffer_t structure
436 buffer_t result;
437 result.Size = this->RAMCache.Size;
438 result.pStart = this->RAMCache.pStart;
439 result.NullExtensionSize = this->RAMCache.NullExtensionSize;
440 return result;
441 }
442
443 /**
444 * Frees the cached sample from RAM if loaded with
445 * <i>LoadSampleData()</i> previously.
446 *
447 * @see LoadSampleData();
448 */
449 void Sample::ReleaseSampleData() {
450 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
451 RAMCache.pStart = NULL;
452 RAMCache.Size = 0;
453 }
454
455 /**
456 * Sets the position within the sample (in sample points, not in
457 * bytes). Use this method and <i>Read()</i> if you don't want to load
458 * the sample into RAM, thus for disk streaming.
459 *
460 * Although the original Gigasampler engine doesn't allow positioning
461 * within compressed samples, I decided to implement it. Even though
462 * the Gigasampler format doesn't allow to define loops for compressed
463 * samples at the moment, positioning within compressed samples might be
464 * interesting for some sampler engines though. The only drawback about
465 * my decision is that it takes longer to load compressed gig Files on
466 * startup, because it's neccessary to scan the samples for some
467 * mandatory informations. But I think as it doesn't affect the runtime
468 * efficiency, nobody will have a problem with that.
469 *
470 * @param SampleCount number of sample points to jump
471 * @param Whence optional: to which relation \a SampleCount refers
472 * to, if omited <i>RIFF::stream_start</i> is assumed
473 * @returns the new sample position
474 * @see Read()
475 */
476 unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
477 if (Compressed) {
478 switch (Whence) {
479 case RIFF::stream_curpos:
480 this->SamplePos += SampleCount;
481 break;
482 case RIFF::stream_end:
483 this->SamplePos = this->SamplesTotal - 1 - SampleCount;
484 break;
485 case RIFF::stream_backward:
486 this->SamplePos -= SampleCount;
487 break;
488 case RIFF::stream_start: default:
489 this->SamplePos = SampleCount;
490 break;
491 }
492 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
493
494 unsigned long frame = this->SamplePos / 2048; // to which frame to jump
495 this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
496 pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
497 return this->SamplePos;
498 }
499 else { // not compressed
500 unsigned long orderedBytes = SampleCount * this->FrameSize;
501 unsigned long result = pCkData->SetPos(orderedBytes, Whence);
502 return (result == orderedBytes) ? SampleCount
503 : result / this->FrameSize;
504 }
505 }
506
507 /**
508 * Returns the current position in the sample (in sample points).
509 */
510 unsigned long Sample::GetPos() {
511 if (Compressed) return SamplePos;
512 else return pCkData->GetPos() / FrameSize;
513 }
514
515 /**
516 * Reads \a SampleCount number of sample points from the position stored
517 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
518 * the position within the sample respectively, this method honors the
519 * looping informations of the sample (if any). The sample wave stream
520 * will be decompressed on the fly if using a compressed sample. Use this
521 * method if you don't want to load the sample into RAM, thus for disk
522 * streaming. All this methods needs to know to proceed with streaming
523 * for the next time you call this method is stored in \a pPlaybackState.
524 * You have to allocate and initialize the playback_state_t structure by
525 * yourself before you use it to stream a sample:
526 *
527 * <i>
528 * gig::playback_state_t playbackstate; <br>
529 * playbackstate.position = 0; <br>
530 * playbackstate.reverse = false; <br>
531 * playbackstate.loop_cycles_left = pSample->LoopPlayCount; <br>
532 * </i>
533 *
534 * You don't have to take care of things like if there is actually a loop
535 * defined or if the current read position is located within a loop area.
536 * The method already handles such cases by itself.
537 *
538 * @param pBuffer destination buffer
539 * @param SampleCount number of sample points to read
540 * @param pPlaybackState will be used to store and reload the playback
541 * state for the next ReadAndLoop() call
542 * @returns number of successfully read sample points
543 */
544 unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState) {
545 unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
546 uint8_t* pDst = (uint8_t*) pBuffer;
547
548 SetPos(pPlaybackState->position); // recover position from the last time
549
550 if (this->Loops && GetPos() <= this->LoopEnd) { // honor looping if there are loop points defined
551
552 switch (this->LoopType) {
553
554 case loop_type_bidirectional: { //TODO: not tested yet!
555 do {
556 // if not endless loop check if max. number of loop cycles have been passed
557 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
558
559 if (!pPlaybackState->reverse) { // forward playback
560 do {
561 samplestoloopend = this->LoopEnd - GetPos();
562 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
563 samplestoread -= readsamples;
564 totalreadsamples += readsamples;
565 if (readsamples == samplestoloopend) {
566 pPlaybackState->reverse = true;
567 break;
568 }
569 } while (samplestoread && readsamples);
570 }
571 else { // backward playback
572
573 // as we can only read forward from disk, we have to
574 // determine the end position within the loop first,
575 // read forward from that 'end' and finally after
576 // reading, swap all sample frames so it reflects
577 // backward playback
578
579 unsigned long swapareastart = totalreadsamples;
580 unsigned long loopoffset = GetPos() - this->LoopStart;
581 unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
582 unsigned long reverseplaybackend = GetPos() - samplestoreadinloop;
583
584 SetPos(reverseplaybackend);
585
586 // read samples for backward playback
587 do {
588 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop);
589 samplestoreadinloop -= readsamples;
590 samplestoread -= readsamples;
591 totalreadsamples += readsamples;
592 } while (samplestoreadinloop && readsamples);
593
594 SetPos(reverseplaybackend); // pretend we really read backwards
595
596 if (reverseplaybackend == this->LoopStart) {
597 pPlaybackState->loop_cycles_left--;
598 pPlaybackState->reverse = false;
599 }
600
601 // reverse the sample frames for backward playback
602 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
603 }
604 } while (samplestoread && readsamples);
605 break;
606 }
607
608 case loop_type_backward: { // TODO: not tested yet!
609 // forward playback (not entered the loop yet)
610 if (!pPlaybackState->reverse) do {
611 samplestoloopend = this->LoopEnd - GetPos();
612 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
613 samplestoread -= readsamples;
614 totalreadsamples += readsamples;
615 if (readsamples == samplestoloopend) {
616 pPlaybackState->reverse = true;
617 break;
618 }
619 } while (samplestoread && readsamples);
620
621 if (!samplestoread) break;
622
623 // as we can only read forward from disk, we have to
624 // determine the end position within the loop first,
625 // read forward from that 'end' and finally after
626 // reading, swap all sample frames so it reflects
627 // backward playback
628
629 unsigned long swapareastart = totalreadsamples;
630 unsigned long loopoffset = GetPos() - this->LoopStart;
631 unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * LoopSize - loopoffset)
632 : samplestoread;
633 unsigned long reverseplaybackend = this->LoopStart + Abs((loopoffset - samplestoreadinloop) % this->LoopSize);
634
635 SetPos(reverseplaybackend);
636
637 // read samples for backward playback
638 do {
639 // if not endless loop check if max. number of loop cycles have been passed
640 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
641 samplestoloopend = this->LoopEnd - GetPos();
642 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend));
643 samplestoreadinloop -= readsamples;
644 samplestoread -= readsamples;
645 totalreadsamples += readsamples;
646 if (readsamples == samplestoloopend) {
647 pPlaybackState->loop_cycles_left--;
648 SetPos(this->LoopStart);
649 }
650 } while (samplestoreadinloop && readsamples);
651
652 SetPos(reverseplaybackend); // pretend we really read backwards
653
654 // reverse the sample frames for backward playback
655 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
656 break;
657 }
658
659 default: case loop_type_normal: {
660 do {
661 // if not endless loop check if max. number of loop cycles have been passed
662 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
663 samplestoloopend = this->LoopEnd - GetPos();
664 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
665 samplestoread -= readsamples;
666 totalreadsamples += readsamples;
667 if (readsamples == samplestoloopend) {
668 pPlaybackState->loop_cycles_left--;
669 SetPos(this->LoopStart);
670 }
671 } while (samplestoread && readsamples);
672 break;
673 }
674 }
675 }
676
677 // read on without looping
678 if (samplestoread) do {
679 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread);
680 samplestoread -= readsamples;
681 totalreadsamples += readsamples;
682 } while (readsamples && samplestoread);
683
684 // store current position
685 pPlaybackState->position = GetPos();
686
687 return totalreadsamples;
688 }
689
690 /**
691 * Reads \a SampleCount number of sample points from the current
692 * position into the buffer pointed by \a pBuffer and increments the
693 * position within the sample. The sample wave stream will be
694 * decompressed on the fly if using a compressed sample. Use this method
695 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
696 * thus for disk streaming.
697 *
698 * @param pBuffer destination buffer
699 * @param SampleCount number of sample points to read
700 * @returns number of successfully read sample points
701 * @see SetPos()
702 */
703 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
704 if (SampleCount == 0) return 0;
705 if (!Compressed) {
706 if (BitDepth == 24) {
707 // 24 bit sample. For now just truncate to 16 bit.
708 unsigned char* pSrc = this->pDecompressionBuffer;
709 int16_t* pDst = static_cast<int16_t*>(pBuffer);
710 if (Channels == 2) { // Stereo
711 unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 6, 1);
712 pSrc++;
713 for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
714 *pDst++ = get16(pSrc);
715 pSrc += 3;
716 }
717 return (pDst - static_cast<int16_t*>(pBuffer)) >> 1;
718 }
719 else { // Mono
720 unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 3, 1);
721 pSrc++;
722 for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
723 *pDst++ = get16(pSrc);
724 pSrc += 3;
725 }
726 return pDst - static_cast<int16_t*>(pBuffer);
727 }
728 }
729 else { // 16 bit
730 // (pCkData->Read does endian correction)
731 return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
732 : pCkData->Read(pBuffer, SampleCount, 2);
733 }
734 }
735 else {
736 if (this->SamplePos >= this->SamplesTotal) return 0;
737 //TODO: efficiency: maybe we should test for an average compression rate
738 unsigned long assumedsize = GuessSize(SampleCount),
739 remainingbytes = 0, // remaining bytes in the local buffer
740 remainingsamples = SampleCount,
741 copysamples, skipsamples,
742 currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
743 this->FrameOffset = 0;
744
745 if (assumedsize > this->DecompressionBufferSize) {
746 // local buffer reallocation - hope this won't happen
747 if (this->pDecompressionBuffer) delete[] this->pDecompressionBuffer;
748 this->pDecompressionBuffer = new unsigned char[assumedsize << 1]; // double of current needed size
749 this->DecompressionBufferSize = assumedsize << 1;
750 }
751
752 unsigned char* pSrc = this->pDecompressionBuffer;
753 int16_t* pDst = static_cast<int16_t*>(pBuffer);
754 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
755
756 while (remainingsamples && remainingbytes) {
757 unsigned long framesamples = SamplesPerFrame;
758 unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
759
760 int mode_l = *pSrc++, mode_r = 0;
761
762 if (Channels == 2) {
763 mode_r = *pSrc++;
764 framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
765 rightChannelOffset = bytesPerFrameNoHdr[mode_l];
766 nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
767 if (remainingbytes < framebytes) { // last frame in sample
768 framesamples = SamplesInLastFrame;
769 if (mode_l == 4 && (framesamples & 1)) {
770 rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
771 }
772 else {
773 rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
774 }
775 }
776 }
777 else {
778 framebytes = bytesPerFrame[mode_l] + 1;
779 nextFrameOffset = bytesPerFrameNoHdr[mode_l];
780 if (remainingbytes < framebytes) {
781 framesamples = SamplesInLastFrame;
782 }
783 }
784
785 // determine how many samples in this frame to skip and read
786 if (currentframeoffset + remainingsamples >= framesamples) {
787 if (currentframeoffset <= framesamples) {
788 copysamples = framesamples - currentframeoffset;
789 skipsamples = currentframeoffset;
790 }
791 else {
792 copysamples = 0;
793 skipsamples = framesamples;
794 }
795 }
796 else {
797 // This frame has enough data for pBuffer, but not
798 // all of the frame is needed. Set file position
799 // to start of this frame for next call to Read.
800 copysamples = remainingsamples;
801 skipsamples = currentframeoffset;
802 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
803 this->FrameOffset = currentframeoffset + copysamples;
804 }
805 remainingsamples -= copysamples;
806
807 if (remainingbytes > framebytes) {
808 remainingbytes -= framebytes;
809 if (remainingsamples == 0 &&
810 currentframeoffset + copysamples == framesamples) {
811 // This frame has enough data for pBuffer, and
812 // all of the frame is needed. Set file
813 // position to start of next frame for next
814 // call to Read. FrameOffset is 0.
815 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
816 }
817 }
818 else remainingbytes = 0;
819
820 currentframeoffset -= skipsamples;
821
822 if (copysamples == 0) {
823 // skip this frame
824 pSrc += framebytes - Channels;
825 }
826 else {
827 const unsigned char* const param_l = pSrc;
828 if (BitDepth == 24) {
829 if (mode_l != 2) pSrc += 12;
830
831 if (Channels == 2) { // Stereo
832 const unsigned char* const param_r = pSrc;
833 if (mode_r != 2) pSrc += 12;
834
835 Decompress24(mode_l, param_l, 2, pSrc, pDst, skipsamples, copysamples);
836 Decompress24(mode_r, param_r, 2, pSrc + rightChannelOffset, pDst + 1,
837 skipsamples, copysamples);
838 pDst += copysamples << 1;
839 }
840 else { // Mono
841 Decompress24(mode_l, param_l, 1, pSrc, pDst, skipsamples, copysamples);
842 pDst += copysamples;
843 }
844 }
845 else { // 16 bit
846 if (mode_l) pSrc += 4;
847
848 int step;
849 if (Channels == 2) { // Stereo
850 const unsigned char* const param_r = pSrc;
851 if (mode_r) pSrc += 4;
852
853 step = (2 - mode_l) + (2 - mode_r);
854 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
855 Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
856 skipsamples, copysamples);
857 pDst += copysamples << 1;
858 }
859 else { // Mono
860 step = 2 - mode_l;
861 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
862 pDst += copysamples;
863 }
864 }
865 pSrc += nextFrameOffset;
866 }
867
868 // reload from disk to local buffer if needed
869 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
870 assumedsize = GuessSize(remainingsamples);
871 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
872 if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
873 remainingbytes = pCkData->Read(this->pDecompressionBuffer, assumedsize, 1);
874 pSrc = this->pDecompressionBuffer;
875 }
876 } // while
877
878 this->SamplePos += (SampleCount - remainingsamples);
879 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
880 return (SampleCount - remainingsamples);
881 }
882 }
883
884 Sample::~Sample() {
885 Instances--;
886 if (!Instances && pDecompressionBuffer) {
887 delete[] pDecompressionBuffer;
888 pDecompressionBuffer = NULL;
889 }
890 if (FrameTable) delete[] FrameTable;
891 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
892 }
893
894
895
896 // *************** DimensionRegion ***************
897 // *
898
899 uint DimensionRegion::Instances = 0;
900 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
901
902 DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
903 Instances++;
904
905 memcpy(&Crossfade, &SamplerOptions, 4);
906 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
907
908 RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
909 _3ewa->ReadInt32(); // unknown, always 0x0000008C ?
910 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
911 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
912 _3ewa->ReadInt16(); // unknown
913 LFO1InternalDepth = _3ewa->ReadUint16();
914 _3ewa->ReadInt16(); // unknown
915 LFO3InternalDepth = _3ewa->ReadInt16();
916 _3ewa->ReadInt16(); // unknown
917 LFO1ControlDepth = _3ewa->ReadUint16();
918 _3ewa->ReadInt16(); // unknown
919 LFO3ControlDepth = _3ewa->ReadInt16();
920 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
921 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
922 _3ewa->ReadInt16(); // unknown
923 EG1Sustain = _3ewa->ReadUint16();
924 EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
925 EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
926 uint8_t eg1ctrloptions = _3ewa->ReadUint8();
927 EG1ControllerInvert = eg1ctrloptions & 0x01;
928 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
929 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
930 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
931 EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
932 uint8_t eg2ctrloptions = _3ewa->ReadUint8();
933 EG2ControllerInvert = eg2ctrloptions & 0x01;
934 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
935 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
936 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
937 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
938 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
939 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
940 _3ewa->ReadInt16(); // unknown
941 EG2Sustain = _3ewa->ReadUint16();
942 EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
943 _3ewa->ReadInt16(); // unknown
944 LFO2ControlDepth = _3ewa->ReadUint16();
945 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
946 _3ewa->ReadInt16(); // unknown
947 LFO2InternalDepth = _3ewa->ReadUint16();
948 int32_t eg1decay2 = _3ewa->ReadInt32();
949 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
950 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
951 _3ewa->ReadInt16(); // unknown
952 EG1PreAttack = _3ewa->ReadUint16();
953 int32_t eg2decay2 = _3ewa->ReadInt32();
954 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
955 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
956 _3ewa->ReadInt16(); // unknown
957 EG2PreAttack = _3ewa->ReadUint16();
958 uint8_t velocityresponse = _3ewa->ReadUint8();
959 if (velocityresponse < 5) {
960 VelocityResponseCurve = curve_type_nonlinear;
961 VelocityResponseDepth = velocityresponse;
962 }
963 else if (velocityresponse < 10) {
964 VelocityResponseCurve = curve_type_linear;
965 VelocityResponseDepth = velocityresponse - 5;
966 }
967 else if (velocityresponse < 15) {
968 VelocityResponseCurve = curve_type_special;
969 VelocityResponseDepth = velocityresponse - 10;
970 }
971 else {
972 VelocityResponseCurve = curve_type_unknown;
973 VelocityResponseDepth = 0;
974 }
975 uint8_t releasevelocityresponse = _3ewa->ReadUint8();
976 if (releasevelocityresponse < 5) {
977 ReleaseVelocityResponseCurve = curve_type_nonlinear;
978 ReleaseVelocityResponseDepth = releasevelocityresponse;
979 }
980 else if (releasevelocityresponse < 10) {
981 ReleaseVelocityResponseCurve = curve_type_linear;
982 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
983 }
984 else if (releasevelocityresponse < 15) {
985 ReleaseVelocityResponseCurve = curve_type_special;
986 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
987 }
988 else {
989 ReleaseVelocityResponseCurve = curve_type_unknown;
990 ReleaseVelocityResponseDepth = 0;
991 }
992 VelocityResponseCurveScaling = _3ewa->ReadUint8();
993 AttenuationControllerThreshold = _3ewa->ReadInt8();
994 _3ewa->ReadInt32(); // unknown
995 SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
996 _3ewa->ReadInt16(); // unknown
997 uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
998 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
999 if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1000 else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1001 else DimensionBypass = dim_bypass_ctrl_none;
1002 uint8_t pan = _3ewa->ReadUint8();
1003 Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1004 SelfMask = _3ewa->ReadInt8() & 0x01;
1005 _3ewa->ReadInt8(); // unknown
1006 uint8_t lfo3ctrl = _3ewa->ReadUint8();
1007 LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1008 LFO3Sync = lfo3ctrl & 0x20; // bit 5
1009 InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1010 AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1011 uint8_t lfo2ctrl = _3ewa->ReadUint8();
1012 LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1013 LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1014 LFO2Sync = lfo2ctrl & 0x20; // bit 5
1015 bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1016 uint8_t lfo1ctrl = _3ewa->ReadUint8();
1017 LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1018 LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1019 LFO1Sync = lfo1ctrl & 0x40; // bit 6
1020 VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1021 : vcf_res_ctrl_none;
1022 uint16_t eg3depth = _3ewa->ReadUint16();
1023 EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1024 : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
1025 _3ewa->ReadInt16(); // unknown
1026 ChannelOffset = _3ewa->ReadUint8() / 4;
1027 uint8_t regoptions = _3ewa->ReadUint8();
1028 MSDecode = regoptions & 0x01; // bit 0
1029 SustainDefeat = regoptions & 0x02; // bit 1
1030 _3ewa->ReadInt16(); // unknown
1031 VelocityUpperLimit = _3ewa->ReadInt8();
1032 _3ewa->ReadInt8(); // unknown
1033 _3ewa->ReadInt16(); // unknown
1034 ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1035 _3ewa->ReadInt8(); // unknown
1036 _3ewa->ReadInt8(); // unknown
1037 EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1038 uint8_t vcfcutoff = _3ewa->ReadUint8();
1039 VCFEnabled = vcfcutoff & 0x80; // bit 7
1040 VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1041 VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1042 VCFVelocityScale = _3ewa->ReadUint8();
1043 _3ewa->ReadInt8(); // unknown
1044 uint8_t vcfresonance = _3ewa->ReadUint8();
1045 VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1046 VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1047 uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1048 VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1049 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1050 uint8_t vcfvelocity = _3ewa->ReadUint8();
1051 VCFVelocityDynamicRange = vcfvelocity % 5;
1052 VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1053 VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1054 if (VCFType == vcf_type_lowpass) {
1055 if (lfo3ctrl & 0x40) // bit 6
1056 VCFType = vcf_type_lowpassturbo;
1057 }
1058
1059 // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
1060 uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
1061 if (pVelocityTables->count(tableKey)) { // if key exists
1062 pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
1063 }
1064 else {
1065 pVelocityAttenuationTable =
1066 CreateVelocityTable(VelocityResponseCurve,
1067 VelocityResponseDepth,
1068 VelocityResponseCurveScaling);
1069 (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
1070 }
1071 }
1072
1073 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
1074 leverage_ctrl_t decodedcontroller;
1075 switch (EncodedController) {
1076 // special controller
1077 case _lev_ctrl_none:
1078 decodedcontroller.type = leverage_ctrl_t::type_none;
1079 decodedcontroller.controller_number = 0;
1080 break;
1081 case _lev_ctrl_velocity:
1082 decodedcontroller.type = leverage_ctrl_t::type_velocity;
1083 decodedcontroller.controller_number = 0;
1084 break;
1085 case _lev_ctrl_channelaftertouch:
1086 decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
1087 decodedcontroller.controller_number = 0;
1088 break;
1089
1090 // ordinary MIDI control change controller
1091 case _lev_ctrl_modwheel:
1092 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1093 decodedcontroller.controller_number = 1;
1094 break;
1095 case _lev_ctrl_breath:
1096 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1097 decodedcontroller.controller_number = 2;
1098 break;
1099 case _lev_ctrl_foot:
1100 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1101 decodedcontroller.controller_number = 4;
1102 break;
1103 case _lev_ctrl_effect1:
1104 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1105 decodedcontroller.controller_number = 12;
1106 break;
1107 case _lev_ctrl_effect2:
1108 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1109 decodedcontroller.controller_number = 13;
1110 break;
1111 case _lev_ctrl_genpurpose1:
1112 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1113 decodedcontroller.controller_number = 16;
1114 break;
1115 case _lev_ctrl_genpurpose2:
1116 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1117 decodedcontroller.controller_number = 17;
1118 break;
1119 case _lev_ctrl_genpurpose3:
1120 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1121 decodedcontroller.controller_number = 18;
1122 break;
1123 case _lev_ctrl_genpurpose4:
1124 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1125 decodedcontroller.controller_number = 19;
1126 break;
1127 case _lev_ctrl_portamentotime:
1128 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1129 decodedcontroller.controller_number = 5;
1130 break;
1131 case _lev_ctrl_sustainpedal:
1132 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1133 decodedcontroller.controller_number = 64;
1134 break;
1135 case _lev_ctrl_portamento:
1136 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1137 decodedcontroller.controller_number = 65;
1138 break;
1139 case _lev_ctrl_sostenutopedal:
1140 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1141 decodedcontroller.controller_number = 66;
1142 break;
1143 case _lev_ctrl_softpedal:
1144 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1145 decodedcontroller.controller_number = 67;
1146 break;
1147 case _lev_ctrl_genpurpose5:
1148 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1149 decodedcontroller.controller_number = 80;
1150 break;
1151 case _lev_ctrl_genpurpose6:
1152 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1153 decodedcontroller.controller_number = 81;
1154 break;
1155 case _lev_ctrl_genpurpose7:
1156 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1157 decodedcontroller.controller_number = 82;
1158 break;
1159 case _lev_ctrl_genpurpose8:
1160 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1161 decodedcontroller.controller_number = 83;
1162 break;
1163 case _lev_ctrl_effect1depth:
1164 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1165 decodedcontroller.controller_number = 91;
1166 break;
1167 case _lev_ctrl_effect2depth:
1168 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1169 decodedcontroller.controller_number = 92;
1170 break;
1171 case _lev_ctrl_effect3depth:
1172 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1173 decodedcontroller.controller_number = 93;
1174 break;
1175 case _lev_ctrl_effect4depth:
1176 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1177 decodedcontroller.controller_number = 94;
1178 break;
1179 case _lev_ctrl_effect5depth:
1180 decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1181 decodedcontroller.controller_number = 95;
1182 break;
1183
1184 // unknown controller type
1185 default:
1186 throw gig::Exception("Unknown leverage controller type.");
1187 }
1188 return decodedcontroller;
1189 }
1190
1191 DimensionRegion::~DimensionRegion() {
1192 Instances--;
1193 if (!Instances) {
1194 // delete the velocity->volume tables
1195 VelocityTableMap::iterator iter;
1196 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
1197 double* pTable = iter->second;
1198 if (pTable) delete[] pTable;
1199 }
1200 pVelocityTables->clear();
1201 delete pVelocityTables;
1202 pVelocityTables = NULL;
1203 }
1204 }
1205
1206 /**
1207 * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
1208 * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
1209 * and VelocityResponseCurveScaling) involved are taken into account to
1210 * calculate the amplitude factor. Use this method when a key was
1211 * triggered to get the volume with which the sample should be played
1212 * back.
1213 *
1214 * @param MIDIKeyVelocity MIDI velocity value of the triggered key (between 0 and 127)
1215 * @returns amplitude factor (between 0.0 and 1.0)
1216 */
1217 double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
1218 return pVelocityAttenuationTable[MIDIKeyVelocity];
1219 }
1220
1221 double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
1222
1223 // line-segment approximations of the 15 velocity curves
1224
1225 // linear
1226 const int lin0[] = { 1, 1, 127, 127 };
1227 const int lin1[] = { 1, 21, 127, 127 };
1228 const int lin2[] = { 1, 45, 127, 127 };
1229 const int lin3[] = { 1, 74, 127, 127 };
1230 const int lin4[] = { 1, 127, 127, 127 };
1231
1232 // non-linear
1233 const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
1234 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
1235 127, 127 };
1236 const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
1237 127, 127 };
1238 const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
1239 127, 127 };
1240 const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
1241
1242 // special
1243 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
1244 113, 127, 127, 127 };
1245 const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
1246 118, 127, 127, 127 };
1247 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
1248 85, 90, 91, 127, 127, 127 };
1249 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
1250 117, 127, 127, 127 };
1251 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
1252 127, 127 };
1253
1254 const int* const curves[] = { non0, non1, non2, non3, non4,
1255 lin0, lin1, lin2, lin3, lin4,
1256 spe0, spe1, spe2, spe3, spe4 };
1257
1258 double* const table = new double[128];
1259
1260 const int* curve = curves[curveType * 5 + depth];
1261 const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
1262
1263 table[0] = 0;
1264 for (int x = 1 ; x < 128 ; x++) {
1265
1266 if (x > curve[2]) curve += 2;
1267 double y = curve[1] + (x - curve[0]) *
1268 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
1269 y = y / 127;
1270
1271 // Scale up for s > 20, down for s < 20. When
1272 // down-scaling, the curve still ends at 1.0.
1273 if (s < 20 && y >= 0.5)
1274 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
1275 else
1276 y = y * (s / 20.0);
1277 if (y > 1) y = 1;
1278
1279 table[x] = y;
1280 }
1281 return table;
1282 }
1283
1284
1285 // *************** Region ***************
1286 // *
1287
1288 Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
1289 // Initialization
1290 Dimensions = 0;
1291 for (int i = 0; i < 256; i++) {
1292 pDimensionRegions[i] = NULL;
1293 }
1294 Layers = 1;
1295 File* file = (File*) GetParent()->GetParent();
1296 int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
1297
1298 // Actual Loading
1299
1300 LoadDimensionRegions(rgnList);
1301
1302 RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
1303 if (_3lnk) {
1304 DimensionRegions = _3lnk->ReadUint32();
1305 for (int i = 0; i < dimensionBits; i++) {
1306 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
1307 uint8_t bits = _3lnk->ReadUint8();
1308 if (dimension == dimension_none) { // inactive dimension
1309 pDimensionDefinitions[i].dimension = dimension_none;
1310 pDimensionDefinitions[i].bits = 0;
1311 pDimensionDefinitions[i].zones = 0;
1312 pDimensionDefinitions[i].split_type = split_type_bit;
1313 pDimensionDefinitions[i].ranges = NULL;
1314 pDimensionDefinitions[i].zone_size = 0;
1315 }
1316 else { // active dimension
1317 pDimensionDefinitions[i].dimension = dimension;
1318 pDimensionDefinitions[i].bits = bits;
1319 pDimensionDefinitions[i].zones = 0x01 << bits; // = pow(2,bits)
1320 pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
1321 dimension == dimension_samplechannel ||
1322 dimension == dimension_releasetrigger) ? split_type_bit
1323 : split_type_normal;
1324 pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
1325 pDimensionDefinitions[i].zone_size =
1326 (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
1327 : 0;
1328 Dimensions++;
1329
1330 // if this is a layer dimension, remember the amount of layers
1331 if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
1332 }
1333 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
1334 }
1335
1336 // check velocity dimension (if there is one) for custom defined zone ranges
1337 for (uint i = 0; i < Dimensions; i++) {
1338 dimension_def_t* pDimDef = pDimensionDefinitions + i;
1339 if (pDimDef->dimension == dimension_velocity) {
1340 if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
1341 // no custom defined ranges
1342 pDimDef->split_type = split_type_normal;
1343 pDimDef->ranges = NULL;
1344 }
1345 else { // custom defined ranges
1346 pDimDef->split_type = split_type_customvelocity;
1347 pDimDef->ranges = new range_t[pDimDef->zones];
1348 uint8_t bits[8] = { 0 };
1349 int previousUpperLimit = -1;
1350 for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
1351 bits[i] = velocityZone;
1352 DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits);
1353
1354 pDimDef->ranges[velocityZone].low = previousUpperLimit + 1;
1355 pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
1356 previousUpperLimit = pDimDef->ranges[velocityZone].high;
1357 // fill velocity table
1358 for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
1359 VelocityTable[i] = velocityZone;
1360 }
1361 }
1362 }
1363 }
1364 }
1365
1366 // jump to start of the wave pool indices (if not already there)
1367 File* file = (File*) GetParent()->GetParent();
1368 if (file->pVersion && file->pVersion->major == 3)
1369 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
1370 else
1371 _3lnk->SetPos(44);
1372
1373 // load sample references
1374 for (uint i = 0; i < DimensionRegions; i++) {
1375 uint32_t wavepoolindex = _3lnk->ReadUint32();
1376 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
1377 }
1378 }
1379 else throw gig::Exception("Mandatory <3lnk> chunk not found.");
1380 }
1381
1382 void Region::LoadDimensionRegions(RIFF::List* rgn) {
1383 RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
1384 if (_3prg) {
1385 int dimensionRegionNr = 0;
1386 RIFF::List* _3ewl = _3prg->GetFirstSubList();
1387 while (_3ewl) {
1388 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
1389 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
1390 dimensionRegionNr++;
1391 }
1392 _3ewl = _3prg->GetNextSubList();
1393 }
1394 if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
1395 }
1396 }
1397
1398 Region::~Region() {
1399 for (uint i = 0; i < Dimensions; i++) {
1400 if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
1401 }
1402 for (int i = 0; i < 256; i++) {
1403 if (pDimensionRegions[i]) delete pDimensionRegions[i];
1404 }
1405 }
1406
1407 /**
1408 * Use this method in your audio engine to get the appropriate dimension
1409 * region with it's articulation data for the current situation. Just
1410 * call the method with the current MIDI controller values and you'll get
1411 * the DimensionRegion with the appropriate articulation data for the
1412 * current situation (for this Region of course only). To do that you'll
1413 * first have to look which dimensions with which controllers and in
1414 * which order are defined for this Region when you load the .gig file.
1415 * Special cases are e.g. layer or channel dimensions where you just put
1416 * in the index numbers instead of a MIDI controller value (means 0 for
1417 * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
1418 * etc.).
1419 *
1420 * @param DimValues MIDI controller values (0-127) for dimension 0 to 7
1421 * @returns adress to the DimensionRegion for the given situation
1422 * @see pDimensionDefinitions
1423 * @see Dimensions
1424 */
1425 DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
1426 uint8_t bits[8] = { 0 };
1427 for (uint i = 0; i < Dimensions; i++) {
1428 bits[i] = DimValues[i];
1429 switch (pDimensionDefinitions[i].split_type) {
1430 case split_type_normal:
1431 bits[i] /= pDimensionDefinitions[i].zone_size;
1432 break;
1433 case split_type_customvelocity:
1434 bits[i] = VelocityTable[bits[i]];
1435 break;
1436 case split_type_bit: // the value is already the sought dimension bit number
1437 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
1438 bits[i] = bits[i] & limiter_mask; // just make sure the value don't uses more bits than allowed
1439 break;
1440 }
1441 }
1442 return GetDimensionRegionByBit(bits);
1443 }
1444
1445 /**
1446 * Returns the appropriate DimensionRegion for the given dimension bit
1447 * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
1448 * instead of calling this method directly!
1449 *
1450 * @param DimBits Bit numbers for dimension 0 to 7
1451 * @returns adress to the DimensionRegion for the given dimension
1452 * bit numbers
1453 * @see GetDimensionRegionByValue()
1454 */
1455 DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
1456 return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
1457 << pDimensionDefinitions[5].bits | DimBits[5])
1458 << pDimensionDefinitions[4].bits | DimBits[4])
1459 << pDimensionDefinitions[3].bits | DimBits[3])
1460 << pDimensionDefinitions[2].bits | DimBits[2])
1461 << pDimensionDefinitions[1].bits | DimBits[1])
1462 << pDimensionDefinitions[0].bits | DimBits[0]];
1463 }
1464
1465 /**
1466 * Returns pointer address to the Sample referenced with this region.
1467 * This is the global Sample for the entire Region (not sure if this is
1468 * actually used by the Gigasampler engine - I would only use the Sample
1469 * referenced by the appropriate DimensionRegion instead of this sample).
1470 *
1471 * @returns address to Sample or NULL if there is no reference to a
1472 * sample saved in the .gig file
1473 */
1474 Sample* Region::GetSample() {
1475 if (pSample) return static_cast<gig::Sample*>(pSample);
1476 else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
1477 }
1478
1479 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex) {
1480 if ((int32_t)WavePoolTableIndex == -1) return NULL;
1481 File* file = (File*) GetParent()->GetParent();
1482 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
1483 Sample* sample = file->GetFirstSample();
1484 while (sample) {
1485 if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
1486 sample = file->GetNextSample();
1487 }
1488 return NULL;
1489 }
1490
1491
1492
1493 // *************** Instrument ***************
1494 // *
1495
1496 Instrument::Instrument(File* pFile, RIFF::List* insList) : DLS::Instrument((DLS::File*)pFile, insList) {
1497 // Initialization
1498 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
1499 RegionIndex = -1;
1500
1501 // Loading
1502 RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
1503 if (lart) {
1504 RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
1505 if (_3ewg) {
1506 EffectSend = _3ewg->ReadUint16();
1507 Attenuation = _3ewg->ReadInt32();
1508 FineTune = _3ewg->ReadInt16();
1509 PitchbendRange = _3ewg->ReadInt16();
1510 uint8_t dimkeystart = _3ewg->ReadUint8();
1511 PianoReleaseMode = dimkeystart & 0x01;
1512 DimensionKeyRange.low = dimkeystart >> 1;
1513 DimensionKeyRange.high = _3ewg->ReadUint8();
1514 }
1515 else throw gig::Exception("Mandatory <3ewg> chunk not found.");
1516 }
1517 else throw gig::Exception("Mandatory <lart> list chunk not found.");
1518
1519 RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
1520 if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
1521 pRegions = new Region*[Regions];
1522 for (uint i = 0; i < Regions; i++) pRegions[i] = NULL;
1523 RIFF::List* rgn = lrgn->GetFirstSubList();
1524 unsigned int iRegion = 0;
1525 while (rgn) {
1526 if (rgn->GetListType() == LIST_TYPE_RGN) {
1527 pRegions[iRegion] = new Region(this, rgn);
1528 iRegion++;
1529 }
1530 rgn = lrgn->GetNextSubList();
1531 }
1532
1533 // Creating Region Key Table for fast lookup
1534 for (uint iReg = 0; iReg < Regions; iReg++) {
1535 for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
1536 RegionKeyTable[iKey] = pRegions[iReg];
1537 }
1538 }
1539 }
1540
1541 Instrument::~Instrument() {
1542 for (uint i = 0; i < Regions; i++) {
1543 if (pRegions) {
1544 if (pRegions[i]) delete (pRegions[i]);
1545 }
1546 }
1547 if (pRegions) delete[] pRegions;
1548 }
1549
1550 /**
1551 * Returns the appropriate Region for a triggered note.
1552 *
1553 * @param Key MIDI Key number of triggered note / key (0 - 127)
1554 * @returns pointer adress to the appropriate Region or NULL if there
1555 * there is no Region defined for the given \a Key
1556 */
1557 Region* Instrument::GetRegion(unsigned int Key) {
1558 if (!pRegions || Key > 127) return NULL;
1559 return RegionKeyTable[Key];
1560 /*for (int i = 0; i < Regions; i++) {
1561 if (Key <= pRegions[i]->KeyRange.high &&
1562 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
1563 }
1564 return NULL;*/
1565 }
1566
1567 /**
1568 * Returns the first Region of the instrument. You have to call this
1569 * method once before you use GetNextRegion().
1570 *
1571 * @returns pointer address to first region or NULL if there is none
1572 * @see GetNextRegion()
1573 */
1574 Region* Instrument::GetFirstRegion() {
1575 if (!Regions) return NULL;
1576 RegionIndex = 1;
1577 return pRegions[0];
1578 }
1579
1580 /**
1581 * Returns the next Region of the instrument. You have to call
1582 * GetFirstRegion() once before you can use this method. By calling this
1583 * method multiple times it iterates through the available Regions.
1584 *
1585 * @returns pointer address to the next region or NULL if end reached
1586 * @see GetFirstRegion()
1587 */
1588 Region* Instrument::GetNextRegion() {
1589 if (RegionIndex < 0 || uint32_t(RegionIndex) >= Regions) return NULL;
1590 return pRegions[RegionIndex++];
1591 }
1592
1593
1594
1595 // *************** File ***************
1596 // *
1597
1598 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
1599 pSamples = NULL;
1600 pInstruments = NULL;
1601 }
1602
1603 File::~File() {
1604 // free samples
1605 if (pSamples) {
1606 SamplesIterator = pSamples->begin();
1607 while (SamplesIterator != pSamples->end() ) {
1608 delete (*SamplesIterator);
1609 SamplesIterator++;
1610 }
1611 pSamples->clear();
1612 delete pSamples;
1613
1614 }
1615 // free instruments
1616 if (pInstruments) {
1617 InstrumentsIterator = pInstruments->begin();
1618 while (InstrumentsIterator != pInstruments->end() ) {
1619 delete (*InstrumentsIterator);
1620 InstrumentsIterator++;
1621 }
1622 pInstruments->clear();
1623 delete pInstruments;
1624 }
1625 }
1626
1627 Sample* File::GetFirstSample() {
1628 if (!pSamples) LoadSamples();
1629 if (!pSamples) return NULL;
1630 SamplesIterator = pSamples->begin();
1631 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1632 }
1633
1634 Sample* File::GetNextSample() {
1635 if (!pSamples) return NULL;
1636 SamplesIterator++;
1637 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1638 }
1639
1640 void File::LoadSamples() {
1641 RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
1642 if (wvpl) {
1643 unsigned long wvplFileOffset = wvpl->GetFilePos();
1644 RIFF::List* wave = wvpl->GetFirstSubList();
1645 while (wave) {
1646 if (wave->GetListType() == LIST_TYPE_WAVE) {
1647 if (!pSamples) pSamples = new SampleList;
1648 unsigned long waveFileOffset = wave->GetFilePos();
1649 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
1650 }
1651 wave = wvpl->GetNextSubList();
1652 }
1653 }
1654 else throw gig::Exception("Mandatory <wvpl> chunk not found.");
1655 }
1656
1657 Instrument* File::GetFirstInstrument() {
1658 if (!pInstruments) LoadInstruments();
1659 if (!pInstruments) return NULL;
1660 InstrumentsIterator = pInstruments->begin();
1661 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1662 }
1663
1664 Instrument* File::GetNextInstrument() {
1665 if (!pInstruments) return NULL;
1666 InstrumentsIterator++;
1667 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1668 }
1669
1670 /**
1671 * Returns the instrument with the given index.
1672 *
1673 * @returns sought instrument or NULL if there's no such instrument
1674 */
1675 Instrument* File::GetInstrument(uint index) {
1676 if (!pInstruments) LoadInstruments();
1677 if (!pInstruments) return NULL;
1678 InstrumentsIterator = pInstruments->begin();
1679 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
1680 if (i == index) return *InstrumentsIterator;
1681 InstrumentsIterator++;
1682 }
1683 return NULL;
1684 }
1685
1686 void File::LoadInstruments() {
1687 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1688 if (lstInstruments) {
1689 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
1690 while (lstInstr) {
1691 if (lstInstr->GetListType() == LIST_TYPE_INS) {
1692 if (!pInstruments) pInstruments = new InstrumentList;
1693 pInstruments->push_back(new Instrument(this, lstInstr));
1694 }
1695 lstInstr = lstInstruments->GetNextSubList();
1696 }
1697 }
1698 else throw gig::Exception("Mandatory <lins> list chunk not found.");
1699 }
1700
1701
1702
1703 // *************** Exception ***************
1704 // *
1705
1706 Exception::Exception(String Message) : DLS::Exception(Message) {
1707 }
1708
1709 void Exception::PrintMessage() {
1710 std::cout << "gig::Exception: " << Message << std::endl;
1711 }
1712
1713 } // namespace gig

  ViewVC Help
Powered by ViewVC