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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (show annotations) (download)
Fri Dec 26 16:15:31 2003 UTC (15 years, 10 months ago) by schoenebeck
File size: 64310 byte(s)
* src/gig.cpp, src/gig.h: added ReadAndLoop() method to class 'Sample'
  which is an extension to the normal Read() method to honor the sample's
  looping information while streaming from disk
* src/RIFF.cpp: minor fix in Chunk::Read() method (only a minor efficiency
  issue)
* src/gigdump.cpp: added printout of samples' looping informations

1 /***************************************************************************
2 * *
3 * libgig - C++ cross-platform Gigasampler format file loader library *
4 * *
5 * Copyright (C) 2003 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 {
27
28 // *************** Sample ***************
29 // *
30
31 unsigned int Sample::Instances = 0;
32 void* Sample::pDecompressionBuffer = NULL;
33 unsigned long Sample::DecompressionBufferSize = 0;
34
35 Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
36 Instances++;
37
38 RIFF::Chunk* _3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
39 if (!_3gix) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
40 SampleGroup = _3gix->ReadInt16();
41
42 RIFF::Chunk* smpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
43 if (!smpl) throw gig::Exception("Mandatory chunks in <wave> list chunk not found.");
44 Manufacturer = smpl->ReadInt32();
45 Product = smpl->ReadInt32();
46 SamplePeriod = smpl->ReadInt32();
47 MIDIUnityNote = smpl->ReadInt32();
48 FineTune = smpl->ReadInt32();
49 smpl->Read(&SMPTEFormat, 1, 4);
50 SMPTEOffset = smpl->ReadInt32();
51 Loops = smpl->ReadInt32();
52 uint32_t manufByt = smpl->ReadInt32();
53 LoopID = smpl->ReadInt32();
54 smpl->Read(&LoopType, 1, 4);
55 LoopStart = smpl->ReadInt32();
56 LoopEnd = smpl->ReadInt32();
57 LoopFraction = smpl->ReadInt32();
58 LoopPlayCount = smpl->ReadInt32();
59
60 FrameTable = NULL;
61 SamplePos = 0;
62 RAMCache.Size = 0;
63 RAMCache.pStart = NULL;
64 RAMCache.NullExtensionSize = 0;
65
66 Compressed = (waveList->GetSubChunk(CHUNK_ID_EWAV));
67 if (Compressed) {
68 ScanCompressedSample();
69 if (!pDecompressionBuffer) {
70 pDecompressionBuffer = new int8_t[INITIAL_SAMPLE_BUFFER_SIZE];
71 DecompressionBufferSize = INITIAL_SAMPLE_BUFFER_SIZE;
72 }
73 }
74 FrameOffset = 0; // just for streaming compressed samples
75
76 LoopStart /= FrameSize; // convert to sample points
77 LoopEnd /= FrameSize; // convert to sample points
78 LoopSize = LoopEnd - LoopStart;
79 }
80
81 /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
82 void Sample::ScanCompressedSample() {
83 //TODO: we have to add some more scans here (e.g. determine compression rate)
84 this->SamplesTotal = 0;
85 std::list<unsigned long> frameOffsets;
86
87 // Scanning
88 pCkData->SetPos(0);
89 while (pCkData->GetState() == RIFF::stream_ready) {
90 frameOffsets.push_back(pCkData->GetPos());
91 int16_t compressionmode = pCkData->ReadInt16();
92 this->SamplesTotal += 2048;
93 switch (compressionmode) {
94 case 1: // left channel compressed
95 case 256: // right channel compressed
96 pCkData->SetPos(6148, RIFF::stream_curpos);
97 break;
98 case 257: // both channels compressed
99 pCkData->SetPos(4104, RIFF::stream_curpos);
100 break;
101 default: // both channels uncompressed
102 pCkData->SetPos(8192, RIFF::stream_curpos);
103 }
104 }
105 pCkData->SetPos(0);
106
107 //FIXME: only seen compressed samples with 16 bit stereo so far
108 this->FrameSize = 4;
109 this->BitDepth = 16;
110
111 // Build the frames table (which is used for fast resolving of a frame's chunk offset)
112 if (FrameTable) delete[] FrameTable;
113 FrameTable = new unsigned long[frameOffsets.size()];
114 std::list<unsigned long>::iterator end = frameOffsets.end();
115 std::list<unsigned long>::iterator iter = frameOffsets.begin();
116 for (int i = 0; iter != end; i++, iter++) {
117 FrameTable[i] = *iter;
118 }
119 }
120
121 /**
122 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
123 * ReleaseSampleData() to free the memory if you don't need the cached
124 * sample data anymore.
125 *
126 * @returns buffer_t structure with start address and size of the buffer
127 * in bytes
128 * @see ReleaseSampleData(), Read(), SetPos()
129 */
130 buffer_t Sample::LoadSampleData() {
131 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
132 }
133
134 /**
135 * Reads (uncompresses if needed) and caches the first \a SampleCount
136 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
137 * memory space if you don't need the cached samples anymore. There is no
138 * guarantee that exactly \a SampleCount samples will be cached; this is
139 * not an error. The size will be eventually truncated e.g. to the
140 * beginning of a frame of a compressed sample. This is done for
141 * efficiency reasons while streaming the wave by your sampler engine
142 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
143 * that will be returned to determine the actual cached samples, but note
144 * that the size is given in bytes! You get the number of actually cached
145 * samples by dividing it by the frame size of the sample:
146 *
147 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
148 * long cachedsamples = buf.Size / pSample->FrameSize;
149 *
150 * @param SampleCount - number of sample points to load into RAM
151 * @returns buffer_t structure with start address and size of
152 * the cached sample data in bytes
153 * @see ReleaseSampleData(), Read(), SetPos()
154 */
155 buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
156 return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
157 }
158
159 /**
160 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
161 * ReleaseSampleData() to free the memory if you don't need the cached
162 * sample data anymore.
163 * The method will add \a NullSamplesCount silence samples past the
164 * official buffer end (this won't affect the 'Size' member of the
165 * buffer_t structure, that means 'Size' always reflects the size of the
166 * actual sample data, the buffer might be bigger though). Silence
167 * samples past the official buffer are needed for differential
168 * algorithms that always have to take subsequent samples into account
169 * (resampling/interpolation would be an important example) and avoids
170 * memory access faults in such cases.
171 *
172 * @param NullSamplesCount - number of silence samples the buffer should
173 * be extended past it's data end
174 * @returns buffer_t structure with start address and
175 * size of the buffer in bytes
176 * @see ReleaseSampleData(), Read(), SetPos()
177 */
178 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
179 return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
180 }
181
182 /**
183 * Reads (uncompresses if needed) and caches the first \a SampleCount
184 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
185 * memory space if you don't need the cached samples anymore. There is no
186 * guarantee that exactly \a SampleCount samples will be cached; this is
187 * not an error. The size will be eventually truncated e.g. to the
188 * beginning of a frame of a compressed sample. This is done for
189 * efficiency reasons while streaming the wave by your sampler engine
190 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
191 * that will be returned to determine the actual cached samples, but note
192 * that the size is given in bytes! You get the number of actually cached
193 * samples by dividing it by the frame size of the sample:
194 *
195 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
196 * long cachedsamples = buf.Size / pSample->FrameSize;
197 *
198 * The method will add \a NullSamplesCount silence samples past the
199 * official buffer end (this won't affect the 'Size' member of the
200 * buffer_t structure, that means 'Size' always reflects the size of the
201 * actual sample data, the buffer might be bigger though). Silence
202 * samples past the official buffer are needed for differential
203 * algorithms that always have to take subsequent samples into account
204 * (resampling/interpolation would be an important example) and avoids
205 * memory access faults in such cases.
206 *
207 * @param SampleCount - number of sample points to load into RAM
208 * @param NullSamplesCount - number of silence samples the buffer should
209 * be extended past it's data end
210 * @returns buffer_t structure with start address and
211 * size of the cached sample data in bytes
212 * @see ReleaseSampleData(), Read(), SetPos()
213 */
214 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
215 if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
216 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
217 unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
218 RAMCache.pStart = new int8_t[allocationsize];
219 RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
220 RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
221 // fill the remaining buffer space with silence samples
222 memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
223 return GetCache();
224 }
225
226 /**
227 * Returns current cached sample points. A buffer_t structure will be
228 * returned which contains address pointer to the begin of the cache and
229 * the size of the cached sample data in bytes. Use
230 * <i>LoadSampleData()</i> to cache a specific amount of sample points in
231 * RAM.
232 *
233 * @returns buffer_t structure with current cached sample points
234 * @see LoadSampleData();
235 */
236 buffer_t Sample::GetCache() {
237 // return a copy of the buffer_t structure
238 buffer_t result;
239 result.Size = this->RAMCache.Size;
240 result.pStart = this->RAMCache.pStart;
241 result.NullExtensionSize = this->RAMCache.NullExtensionSize;
242 return result;
243 }
244
245 /**
246 * Frees the cached sample from RAM if loaded with
247 * <i>LoadSampleData()</i> previously.
248 *
249 * @see LoadSampleData();
250 */
251 void Sample::ReleaseSampleData() {
252 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
253 RAMCache.pStart = NULL;
254 RAMCache.Size = 0;
255 }
256
257 /**
258 * Sets the position within the sample (in sample points, not in
259 * bytes). Use this method and <i>Read()</i> if you don't want to load
260 * the sample into RAM, thus for disk streaming.
261 *
262 * Although the original Gigasampler engine doesn't allow positioning
263 * within compressed samples, I decided to implement it. Even though
264 * the Gigasampler format doesn't allow to define loops for compressed
265 * samples at the moment, positioning within compressed samples might be
266 * interesting for some sampler engines though. The only drawback about
267 * my decision is that it takes longer to load compressed gig Files on
268 * startup, because it's neccessary to scan the samples for some
269 * mandatory informations. But I think as it doesn't affect the runtime
270 * efficiency, nobody will have a problem with that.
271 *
272 * @param SampleCount number of sample points to jump
273 * @param Whence optional: to which relation \a SampleCount refers
274 * to, if omited <i>RIFF::stream_start</i> is assumed
275 * @returns the new sample position
276 * @see Read()
277 */
278 unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
279 if (Compressed) {
280 switch (Whence) {
281 case RIFF::stream_curpos:
282 this->SamplePos += SampleCount;
283 break;
284 case RIFF::stream_end:
285 this->SamplePos = this->SamplesTotal - 1 - SampleCount;
286 break;
287 case RIFF::stream_backward:
288 this->SamplePos -= SampleCount;
289 break;
290 case RIFF::stream_start: default:
291 this->SamplePos = SampleCount;
292 break;
293 }
294 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
295
296 unsigned long frame = this->SamplePos / 2048; // to which frame to jump
297 this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
298 pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
299 return this->SamplePos;
300 }
301 else { // not compressed
302 unsigned long orderedBytes = SampleCount * this->FrameSize;
303 unsigned long result = pCkData->SetPos(orderedBytes, Whence);
304 return (result == orderedBytes) ? SampleCount
305 : result / this->FrameSize;
306 }
307 }
308
309 /**
310 * Returns the current position in the sample (in sample points).
311 */
312 unsigned long Sample::GetPos() {
313 if (Compressed) return SamplePos;
314 else return pCkData->GetPos() / FrameSize;
315 }
316
317 /**
318 * Reads \a SampleCount number of sample points from the position stored
319 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
320 * the position within the sample respectively, this method honors the
321 * looping informations of the sample (if any). The sample wave stream
322 * will be decompressed on the fly if using a compressed sample. Use this
323 * method if you don't want to load the sample into RAM, thus for disk
324 * streaming. All this methods needs to know to proceed with streaming
325 * for the next time you call this method is stored in \a pPlaybackState.
326 * You have to allocate and initialize the playback_state_t structure by
327 * yourself before you use it to stream a sample:
328 *
329 * <i>
330 * gig::playback_state_t playbackstate; <br>
331 * playbackstate.position = 0; <br>
332 * playbackstate.reverse = false; <br>
333 * playbackstate.loop_cycles_left = pSample->LoopPlayCount; <br>
334 * </i>
335 *
336 * You don't have to take care of things like if there is actually a loop
337 * defined or if the current read position is located within a loop area.
338 * The method already handles such cases by itself.
339 *
340 * @param pBuffer destination buffer
341 * @param SampleCount number of sample points to read
342 * @param pPlaybackState will be used to store and reload the playback
343 * state for the next ReadAndLoop() call
344 * @returns number of successfully read sample points
345 */
346 unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState) {
347 unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
348 uint8_t* pDst = (uint8_t*) pBuffer;
349
350 SetPos(pPlaybackState->position); // recover position from the last time
351
352 if (this->Loops && GetPos() <= this->LoopEnd) { // honor looping if there are loop points defined
353
354 switch (this->LoopType) {
355
356 case loop_type_bidirectional: { //TODO: not tested yet!
357 do {
358 // if not endless loop check if max. number of loop cycles have been passed
359 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
360
361 if (!pPlaybackState->reverse) { // forward playback
362 do {
363 samplestoloopend = this->LoopEnd - GetPos();
364 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
365 samplestoread -= readsamples;
366 totalreadsamples += readsamples;
367 if (readsamples == samplestoloopend) {
368 pPlaybackState->reverse = true;
369 break;
370 }
371 } while (samplestoread && readsamples);
372 }
373 else { // backward playback
374
375 // as we can only read forward from disk, we have to
376 // determine the end position within the loop first,
377 // read forward from that 'end' and finally after
378 // reading, swap all sample frames so it reflects
379 // backward playback
380
381 unsigned long swapareastart = totalreadsamples;
382 unsigned long loopoffset = GetPos() - this->LoopStart;
383 unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
384 unsigned long reverseplaybackend = GetPos() - samplestoreadinloop;
385
386 SetPos(reverseplaybackend);
387
388 // read samples for backward playback
389 do {
390 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop);
391 samplestoreadinloop -= readsamples;
392 samplestoread -= readsamples;
393 totalreadsamples += readsamples;
394 } while (samplestoreadinloop && readsamples);
395
396 SetPos(reverseplaybackend); // pretend we really read backwards
397
398 if (reverseplaybackend == this->LoopStart) {
399 pPlaybackState->loop_cycles_left--;
400 pPlaybackState->reverse = false;
401 }
402
403 // reverse the sample frames for backward playback
404 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
405 }
406 } while (samplestoread && readsamples);
407 break;
408 }
409
410 case loop_type_backward: { // TODO: not tested yet!
411 // forward playback (not entered the loop yet)
412 if (!pPlaybackState->reverse) do {
413 samplestoloopend = this->LoopEnd - GetPos();
414 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
415 samplestoread -= readsamples;
416 totalreadsamples += readsamples;
417 if (readsamples == samplestoloopend) {
418 pPlaybackState->reverse = true;
419 break;
420 }
421 } while (samplestoread && readsamples);
422
423 if (!samplestoread) break;
424
425 // as we can only read forward from disk, we have to
426 // determine the end position within the loop first,
427 // read forward from that 'end' and finally after
428 // reading, swap all sample frames so it reflects
429 // backward playback
430
431 unsigned long swapareastart = totalreadsamples;
432 unsigned long loopoffset = GetPos() - this->LoopStart;
433 unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * LoopSize - loopoffset)
434 : samplestoread;
435 unsigned long reverseplaybackend = this->LoopStart + Abs((loopoffset - samplestoreadinloop) % this->LoopSize);
436
437 SetPos(reverseplaybackend);
438
439 // read samples for backward playback
440 do {
441 // if not endless loop check if max. number of loop cycles have been passed
442 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
443 samplestoloopend = this->LoopEnd - GetPos();
444 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend));
445 samplestoreadinloop -= readsamples;
446 samplestoread -= readsamples;
447 totalreadsamples += readsamples;
448 if (readsamples == samplestoloopend) {
449 pPlaybackState->loop_cycles_left--;
450 SetPos(this->LoopStart);
451 }
452 } while (samplestoreadinloop && readsamples);
453
454 SetPos(reverseplaybackend); // pretend we really read backwards
455
456 // reverse the sample frames for backward playback
457 SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
458 break;
459 }
460
461 default: case loop_type_normal: {
462 do {
463 // if not endless loop check if max. number of loop cycles have been passed
464 if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
465 samplestoloopend = this->LoopEnd - GetPos();
466 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend));
467 samplestoread -= readsamples;
468 totalreadsamples += readsamples;
469 if (readsamples == samplestoloopend) {
470 pPlaybackState->loop_cycles_left--;
471 SetPos(this->LoopStart);
472 }
473 } while (samplestoread && readsamples);
474 break;
475 }
476 }
477 }
478
479 // read on without looping
480 if (samplestoread) do {
481 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread);
482 samplestoread -= readsamples;
483 totalreadsamples += readsamples;
484 } while (readsamples && samplestoread);
485
486 // store current position
487 pPlaybackState->position = GetPos();
488
489 return totalreadsamples;
490 }
491
492 /**
493 * Reads \a SampleCount number of sample points from the current
494 * position into the buffer pointed by \a pBuffer and increments the
495 * position within the sample. The sample wave stream will be
496 * decompressed on the fly if using a compressed sample. Use this method
497 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
498 * thus for disk streaming.
499 *
500 * @param pBuffer destination buffer
501 * @param SampleCount number of sample points to read
502 * @returns number of successfully read sample points
503 * @see SetPos()
504 */
505 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
506 if (SampleCount == 0) return 0;
507 if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize); //FIXME: channel inversion due to endian correction?
508 else { //FIXME: no support for mono compressed samples yet, are there any?
509 if (this->SamplePos >= this->SamplesTotal) return 0;
510 //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate
511 // best case needed buffer size (all frames compressed)
512 unsigned long assumedsize = (SampleCount << 1) + // *2 (16 Bit, stereo, but assume all frames compressed)
513 (SampleCount >> 10) + // 10 bytes header per 2048 sample points
514 8194, // at least one worst case sample frame
515 remainingbytes = 0, // remaining bytes in the local buffer
516 remainingsamples = SampleCount,
517 copysamples;
518 int currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
519 this->FrameOffset = 0;
520
521 if (assumedsize > this->DecompressionBufferSize) {
522 // local buffer reallocation - hope this won't happen
523 if (this->pDecompressionBuffer) delete[] (int8_t*) this->pDecompressionBuffer;
524 this->pDecompressionBuffer = new int8_t[assumedsize << 1]; // double of current needed size
525 this->DecompressionBufferSize = assumedsize;
526 }
527
528 int16_t compressionmode, left, dleft, right, dright;
529 int8_t* pSrc = (int8_t*) this->pDecompressionBuffer;
530 int16_t* pDst = (int16_t*) pBuffer;
531 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
532
533 while (remainingsamples) {
534
535 // reload from disk to local buffer if needed
536 if (remainingbytes < 8194) {
537 if (pCkData->GetState() != RIFF::stream_ready) {
538 this->SamplePos = this->SamplesTotal;
539 return (SampleCount - remainingsamples);
540 }
541 assumedsize = remainingsamples;
542 assumedsize = (assumedsize << 1) + // *2 (16 Bit, stereo, but assume all frames compressed)
543 (assumedsize >> 10) + // 10 bytes header per 2048 sample points
544 8194; // at least one worst case sample frame
545 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
546 if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
547 remainingbytes = pCkData->Read(this->pDecompressionBuffer, assumedsize, 1);
548 pSrc = (int8_t*) this->pDecompressionBuffer;
549 }
550
551 // determine how many samples in this frame to skip and read
552 if (remainingsamples >= 2048) {
553 copysamples = 2048 - currentframeoffset;
554 remainingsamples -= copysamples;
555 }
556 else {
557 copysamples = remainingsamples;
558 if (currentframeoffset + copysamples > 2048) {
559 copysamples = 2048 - currentframeoffset;
560 remainingsamples -= copysamples;
561 }
562 else {
563 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
564 remainingsamples = 0;
565 this->FrameOffset = currentframeoffset + copysamples;
566 }
567 }
568
569 // decompress and copy current frame from local buffer to destination buffer
570 compressionmode = *(int16_t*)pSrc; pSrc+=2;
571 switch (compressionmode) {
572 case 1: // left channel compressed
573 remainingbytes -= 6150; // (left 8 bit, right 16 bit, +6 byte header)
574 if (!remainingsamples && copysamples == 2048)
575 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
576
577 left = *(int16_t*)pSrc; pSrc+=2;
578 dleft = *(int16_t*)pSrc; pSrc+=2;
579 while (currentframeoffset) {
580 dleft -= *pSrc;
581 left -= dleft;
582 pSrc+=3; // 8 bit left channel, skip uncompressed right channel (16 bit)
583 currentframeoffset--;
584 }
585 while (copysamples) {
586 dleft -= *pSrc; pSrc++;
587 left -= dleft;
588 *pDst = left; pDst++;
589 *pDst = *(int16_t*)pSrc; pDst++; pSrc+=2;
590 copysamples--;
591 }
592 break;
593 case 256: // right channel compressed
594 remainingbytes -= 6150; // (left 16 bit, right 8 bit, +6 byte header)
595 if (!remainingsamples && copysamples == 2048)
596 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
597
598 right = *(int16_t*)pSrc; pSrc+=2;
599 dright = *(int16_t*)pSrc; pSrc+=2;
600 if (currentframeoffset) {
601 pSrc+=2; // skip uncompressed left channel, now we can increment by 3
602 while (currentframeoffset) {
603 dright -= *pSrc;
604 right -= dright;
605 pSrc+=3; // 8 bit right channel, skip uncompressed left channel (16 bit)
606 currentframeoffset--;
607 }
608 pSrc-=2; // back aligned to left channel
609 }
610 while (copysamples) {
611 *pDst = *(int16_t*)pSrc; pDst++; pSrc+=2;
612 dright -= *pSrc; pSrc++;
613 right -= dright;
614 *pDst = right; pDst++;
615 copysamples--;
616 }
617 break;
618 case 257: // both channels compressed
619 remainingbytes -= 4106; // (left 8 bit, right 8 bit, +10 byte header)
620 if (!remainingsamples && copysamples == 2048)
621 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
622
623 left = *(int16_t*)pSrc; pSrc+=2;
624 dleft = *(int16_t*)pSrc; pSrc+=2;
625 right = *(int16_t*)pSrc; pSrc+=2;
626 dright = *(int16_t*)pSrc; pSrc+=2;
627 while (currentframeoffset) {
628 dleft -= *pSrc; pSrc++;
629 left -= dleft;
630 dright -= *pSrc; pSrc++;
631 right -= dright;
632 currentframeoffset--;
633 }
634 while (copysamples) {
635 dleft -= *pSrc; pSrc++;
636 left -= dleft;
637 dright -= *pSrc; pSrc++;
638 right -= dright;
639 *pDst = left; pDst++;
640 *pDst = right; pDst++;
641 copysamples--;
642 }
643 break;
644 default: // both channels uncompressed
645 remainingbytes -= 8194; // (left 16 bit, right 16 bit, +2 byte header)
646 if (!remainingsamples && copysamples == 2048)
647 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
648
649 pSrc += currentframeoffset << 2;
650 currentframeoffset = 0;
651 memcpy(pDst, pSrc, copysamples << 2);
652 pDst += copysamples << 1;
653 pSrc += copysamples << 2;
654 break;
655 }
656 }
657 this->SamplePos += (SampleCount - remainingsamples);
658 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
659 return (SampleCount - remainingsamples);
660 }
661 }
662
663 Sample::~Sample() {
664 Instances--;
665 if (!Instances && pDecompressionBuffer) delete[] (int8_t*) pDecompressionBuffer;
666 if (FrameTable) delete[] FrameTable;
667 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
668 }
669
670
671
672 // *************** DimensionRegion ***************
673 // *
674
675 uint DimensionRegion::Instances = 0;
676 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
677
678 DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
679 Instances++;
680
681 memcpy(&Crossfade, &SamplerOptions, 4);
682 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
683
684 RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
685 _3ewa->ReadInt32(); // unknown, allways 0x0000008C ?
686 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
687 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
688 _3ewa->ReadInt16(); // unknown
689 LFO1InternalDepth = _3ewa->ReadUint16();
690 _3ewa->ReadInt16(); // unknown
691 LFO3InternalDepth = _3ewa->ReadInt16();
692 _3ewa->ReadInt16(); // unknown
693 LFO1ControlDepth = _3ewa->ReadUint16();
694 _3ewa->ReadInt16(); // unknown
695 LFO3ControlDepth = _3ewa->ReadInt16();
696 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
697 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
698 _3ewa->ReadInt16(); // unknown
699 EG1Sustain = _3ewa->ReadUint16();
700 EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
701 EG1Controller = static_cast<eg1_ctrl_t>(_3ewa->ReadUint8());
702 uint8_t eg1ctrloptions = _3ewa->ReadUint8();
703 EG1ControllerInvert = eg1ctrloptions & 0x01;
704 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
705 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
706 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
707 EG2Controller = static_cast<eg2_ctrl_t>(_3ewa->ReadUint8());
708 uint8_t eg2ctrloptions = _3ewa->ReadUint8();
709 EG2ControllerInvert = eg2ctrloptions & 0x01;
710 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
711 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
712 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
713 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
714 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
715 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
716 _3ewa->ReadInt16(); // unknown
717 EG2Sustain = _3ewa->ReadUint16();
718 EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
719 _3ewa->ReadInt16(); // unknown
720 LFO2ControlDepth = _3ewa->ReadUint16();
721 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
722 _3ewa->ReadInt16(); // unknown
723 LFO2InternalDepth = _3ewa->ReadUint16();
724 int32_t eg1decay2 = _3ewa->ReadInt32();
725 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
726 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
727 _3ewa->ReadInt16(); // unknown
728 EG1PreAttack = _3ewa->ReadUint16();
729 int32_t eg2decay2 = _3ewa->ReadInt32();
730 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
731 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
732 _3ewa->ReadInt16(); // unknown
733 EG2PreAttack = _3ewa->ReadUint16();
734 uint8_t velocityresponse = _3ewa->ReadUint8();
735 if (velocityresponse < 5) {
736 VelocityResponseCurve = curve_type_nonlinear;
737 VelocityResponseDepth = velocityresponse;
738 }
739 else if (velocityresponse < 10) {
740 VelocityResponseCurve = curve_type_linear;
741 VelocityResponseDepth = velocityresponse - 5;
742 }
743 else if (velocityresponse < 15) {
744 VelocityResponseCurve = curve_type_special;
745 VelocityResponseDepth = velocityresponse - 10;
746 }
747 else {
748 VelocityResponseCurve = curve_type_unknown;
749 VelocityResponseDepth = 0;
750 }
751 uint8_t releasevelocityresponse = _3ewa->ReadUint8();
752 if (releasevelocityresponse < 5) {
753 ReleaseVelocityResponseCurve = curve_type_nonlinear;
754 ReleaseVelocityResponseDepth = releasevelocityresponse;
755 }
756 else if (releasevelocityresponse < 10) {
757 ReleaseVelocityResponseCurve = curve_type_linear;
758 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
759 }
760 else if (releasevelocityresponse < 15) {
761 ReleaseVelocityResponseCurve = curve_type_special;
762 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
763 }
764 else {
765 ReleaseVelocityResponseCurve = curve_type_unknown;
766 ReleaseVelocityResponseDepth = 0;
767 }
768 VelocityResponseCurveScaling = _3ewa->ReadUint8();
769 AttenuationControlTreshold = _3ewa->ReadInt8();
770 _3ewa->ReadInt32(); // unknown
771 SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
772 _3ewa->ReadInt16(); // unknown
773 uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
774 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
775 if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
776 else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
777 else DimensionBypass = dim_bypass_ctrl_none;
778 uint8_t pan = _3ewa->ReadUint8();
779 Pan = (pan < 64) ? pan : (-1) * (int8_t)pan - 63;
780 SelfMask = _3ewa->ReadInt8() & 0x01;
781 _3ewa->ReadInt8(); // unknown
782 uint8_t lfo3ctrl = _3ewa->ReadUint8();
783 LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
784 LFO3Sync = lfo3ctrl & 0x20; // bit 5
785 InvertAttenuationControl = lfo3ctrl & 0x80; // bit 7
786 if (VCFType == vcf_type_lowpass) {
787 if (lfo3ctrl & 0x40) // bit 6
788 VCFType = vcf_type_lowpassturbo;
789 }
790 AttenuationControl = static_cast<attenuation_ctrl_t>(_3ewa->ReadUint8());
791 uint8_t lfo2ctrl = _3ewa->ReadUint8();
792 LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
793 LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
794 LFO2Sync = lfo2ctrl & 0x20; // bit 5
795 bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
796 uint8_t lfo1ctrl = _3ewa->ReadUint8();
797 LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
798 LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
799 LFO1Sync = lfo1ctrl & 0x40; // bit 6
800 VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
801 : vcf_res_ctrl_none;
802 uint16_t eg3depth = _3ewa->ReadUint16();
803 EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
804 : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
805 _3ewa->ReadInt16(); // unknown
806 ChannelOffset = _3ewa->ReadUint8() / 4;
807 uint8_t regoptions = _3ewa->ReadUint8();
808 MSDecode = regoptions & 0x01; // bit 0
809 SustainDefeat = regoptions & 0x02; // bit 1
810 _3ewa->ReadInt16(); // unknown
811 VelocityUpperLimit = _3ewa->ReadInt8();
812 _3ewa->ReadInt8(); // unknown
813 _3ewa->ReadInt16(); // unknown
814 ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
815 _3ewa->ReadInt8(); // unknown
816 _3ewa->ReadInt8(); // unknown
817 EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
818 uint8_t vcfcutoff = _3ewa->ReadUint8();
819 VCFEnabled = vcfcutoff & 0x80; // bit 7
820 VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
821 VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
822 VCFVelocityScale = _3ewa->ReadUint8();
823 _3ewa->ReadInt8(); // unknown
824 uint8_t vcfresonance = _3ewa->ReadUint8();
825 VCFResonance = vcfresonance & 0x7f; // lower 7 bits
826 VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
827 uint8_t vcfbreakpoint = _3ewa->ReadUint8();
828 VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
829 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
830 uint8_t vcfvelocity = _3ewa->ReadUint8();
831 VCFVelocityDynamicRange = vcfvelocity % 5;
832 VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
833 VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
834
835 // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
836 uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
837 if (pVelocityTables->count(tableKey)) { // if key exists
838 pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
839 }
840 else {
841 pVelocityAttenuationTable = new double[128];
842 switch (VelocityResponseCurve) { // calculate the new table
843 case curve_type_nonlinear:
844 for (int velocity = 0; velocity < 128; velocity++) {
845 pVelocityAttenuationTable[velocity] =
846 GIG_VELOCITY_TRANSFORM_NONLINEAR((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
847 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
848 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
849 }
850 break;
851 case curve_type_linear:
852 for (int velocity = 0; velocity < 128; velocity++) {
853 pVelocityAttenuationTable[velocity] =
854 GIG_VELOCITY_TRANSFORM_LINEAR((double)velocity,(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
855 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
856 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
857 }
858 break;
859 case curve_type_special:
860 for (int velocity = 0; velocity < 128; velocity++) {
861 pVelocityAttenuationTable[velocity] =
862 GIG_VELOCITY_TRANSFORM_SPECIAL((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
863 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
864 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
865 }
866 break;
867 case curve_type_unknown:
868 default:
869 throw gig::Exception("Unknown transform curve type.");
870 }
871 (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
872 }
873 }
874
875 DimensionRegion::~DimensionRegion() {
876 Instances--;
877 if (!Instances) {
878 // delete the velocity->volume tables
879 VelocityTableMap::iterator iter;
880 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
881 double* pTable = iter->second;
882 if (pTable) delete[] pTable;
883 }
884 pVelocityTables->clear();
885 delete pVelocityTables;
886 pVelocityTables = NULL;
887 }
888 }
889
890 /**
891 * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
892 * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
893 * and VelocityResponseCurveScaling) involved are taken into account to
894 * calculate the amplitude factor. Use this method when a key was
895 * triggered to get the volume with which the sample should be played
896 * back.
897 *
898 * @param MIDI velocity value of the triggered key (between 0 and 127)
899 * @returns amplitude factor (between 0.0 and 1.0)
900 */
901 double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
902 return pVelocityAttenuationTable[MIDIKeyVelocity];
903 }
904
905
906
907 // *************** Region ***************
908 // *
909
910 Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
911 // Initialization
912 Dimensions = 0;
913 for (int i = 0; i < 32; i++) {
914 pDimensionRegions[i] = NULL;
915 }
916
917 // Actual Loading
918
919 LoadDimensionRegions(rgnList);
920
921 RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
922 if (_3lnk) {
923 DimensionRegions = _3lnk->ReadUint32();
924 for (int i = 0; i < 5; i++) {
925 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
926 uint8_t bits = _3lnk->ReadUint8();
927 if (dimension == dimension_none) { // inactive dimension
928 pDimensionDefinitions[i].dimension = dimension_none;
929 pDimensionDefinitions[i].bits = 0;
930 pDimensionDefinitions[i].zones = 0;
931 pDimensionDefinitions[i].split_type = split_type_bit;
932 pDimensionDefinitions[i].ranges = NULL;
933 pDimensionDefinitions[i].zone_size = 0;
934 }
935 else { // active dimension
936 pDimensionDefinitions[i].dimension = dimension;
937 pDimensionDefinitions[i].bits = bits;
938 pDimensionDefinitions[i].zones = 0x01 << bits; // = pow(2,bits)
939 pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
940 dimension == dimension_samplechannel) ? split_type_bit
941 : split_type_normal;
942 pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
943 pDimensionDefinitions[i].zone_size =
944 (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
945 : 0;
946 Dimensions++;
947 }
948 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
949 }
950
951 // check velocity dimension (if there is one) for custom defined zone ranges
952 for (uint i = 0; i < Dimensions; i++) {
953 dimension_def_t* pDimDef = pDimensionDefinitions + i;
954 if (pDimDef->dimension == dimension_velocity) {
955 if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
956 // no custom defined ranges
957 pDimDef->split_type = split_type_normal;
958 pDimDef->ranges = NULL;
959 }
960 else { // custom defined ranges
961 pDimDef->split_type = split_type_customvelocity;
962 pDimDef->ranges = new range_t[pDimDef->zones];
963 unsigned int bits[5] = {0,0,0,0,0};
964 int previousUpperLimit = -1;
965 for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
966 bits[i] = velocityZone;
967 DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);
968
969 pDimDef->ranges[velocityZone].low = previousUpperLimit + 1;
970 pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
971 previousUpperLimit = pDimDef->ranges[velocityZone].high;
972 // fill velocity table
973 for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
974 VelocityTable[i] = velocityZone;
975 }
976 }
977 }
978 }
979 }
980
981 // load sample references
982 _3lnk->SetPos(44); // jump to start of the wave pool indices (if not already there)
983 for (uint i = 0; i < DimensionRegions; i++) {
984 uint32_t wavepoolindex = _3lnk->ReadUint32();
985 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
986 }
987 }
988 else throw gig::Exception("Mandatory <3lnk> chunk not found.");
989 }
990
991 void Region::LoadDimensionRegions(RIFF::List* rgn) {
992 RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
993 if (_3prg) {
994 int dimensionRegionNr = 0;
995 RIFF::List* _3ewl = _3prg->GetFirstSubList();
996 while (_3ewl) {
997 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
998 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
999 dimensionRegionNr++;
1000 }
1001 _3ewl = _3prg->GetNextSubList();
1002 }
1003 if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
1004 }
1005 }
1006
1007 Region::~Region() {
1008 for (uint i = 0; i < Dimensions; i++) {
1009 if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
1010 }
1011 for (int i = 0; i < 32; i++) {
1012 if (pDimensionRegions[i]) delete pDimensionRegions[i];
1013 }
1014 }
1015
1016 /**
1017 * Use this method in your audio engine to get the appropriate dimension
1018 * region with it's articulation data for the current situation. Just
1019 * call the method with the current MIDI controller values and you'll get
1020 * the DimensionRegion with the appropriate articulation data for the
1021 * current situation (for this Region of course only). To do that you'll
1022 * first have to look which dimensions with which controllers and in
1023 * which order are defined for this Region when you load the .gig file.
1024 * Special cases are e.g. layer or channel dimensions where you just put
1025 * in the index numbers instead of a MIDI controller value (means 0 for
1026 * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
1027 * etc.).
1028 *
1029 * @param Dim4Val MIDI controller value (0-127) for dimension 4
1030 * @param Dim3Val MIDI controller value (0-127) for dimension 3
1031 * @param Dim2Val MIDI controller value (0-127) for dimension 2
1032 * @param Dim1Val MIDI controller value (0-127) for dimension 1
1033 * @param Dim0Val MIDI controller value (0-127) for dimension 0
1034 * @returns adress to the DimensionRegion for the given situation
1035 * @see pDimensionDefinitions
1036 * @see Dimensions
1037 */
1038 DimensionRegion* Region::GetDimensionRegionByValue(uint Dim4Val, uint Dim3Val, uint Dim2Val, uint Dim1Val, uint Dim0Val) {
1039 unsigned int bits[5] = {Dim0Val,Dim1Val,Dim2Val,Dim3Val,Dim4Val};
1040 for (uint i = 0; i < Dimensions; i++) {
1041 switch (pDimensionDefinitions[i].split_type) {
1042 case split_type_normal:
1043 bits[i] /= pDimensionDefinitions[i].zone_size;
1044 break;
1045 case split_type_customvelocity:
1046 bits[i] = VelocityTable[bits[i]];
1047 break;
1048 // else the value is already the sought dimension bit number
1049 }
1050 }
1051 return GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);
1052 }
1053
1054 /**
1055 * Returns the appropriate DimensionRegion for the given dimension bit
1056 * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
1057 * instead of calling this method directly!
1058 *
1059 * @param Dim4Bit Bit number for dimension 4
1060 * @param Dim3Bit Bit number for dimension 3
1061 * @param Dim2Bit Bit number for dimension 2
1062 * @param Dim1Bit Bit number for dimension 1
1063 * @param Dim0Bit Bit number for dimension 0
1064 * @returns adress to the DimensionRegion for the given dimension
1065 * bit numbers
1066 * @see GetDimensionRegionByValue()
1067 */
1068 DimensionRegion* Region::GetDimensionRegionByBit(uint8_t Dim4Bit, uint8_t Dim3Bit, uint8_t Dim2Bit, uint8_t Dim1Bit, uint8_t Dim0Bit) {
1069 return *(pDimensionRegions + ((((((((Dim4Bit << pDimensionDefinitions[3].bits) | Dim3Bit)
1070 << pDimensionDefinitions[2].bits) | Dim2Bit)
1071 << pDimensionDefinitions[1].bits) | Dim1Bit)
1072 << pDimensionDefinitions[0].bits) | Dim0Bit) );
1073 }
1074
1075 /**
1076 * Returns pointer address to the Sample referenced with this region.
1077 * This is the global Sample for the entire Region (not sure if this is
1078 * actually used by the Gigasampler engine - I would only use the Sample
1079 * referenced by the appropriate DimensionRegion instead of this sample).
1080 *
1081 * @returns address to Sample or NULL if there is no reference to a
1082 * sample saved in the .gig file
1083 */
1084 Sample* Region::GetSample() {
1085 if (pSample) return static_cast<gig::Sample*>(pSample);
1086 else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
1087 }
1088
1089 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex) {
1090 File* file = (File*) GetParent()->GetParent();
1091 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
1092 Sample* sample = file->GetFirstSample();
1093 while (sample) {
1094 if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
1095 sample = file->GetNextSample();
1096 }
1097 return NULL;
1098 }
1099
1100
1101
1102 // *************** Instrument ***************
1103 // *
1104
1105 Instrument::Instrument(File* pFile, RIFF::List* insList) : DLS::Instrument((DLS::File*)pFile, insList) {
1106 // Initialization
1107 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
1108 RegionIndex = -1;
1109
1110 // Loading
1111 RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
1112 if (lart) {
1113 RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
1114 if (_3ewg) {
1115 EffectSend = _3ewg->ReadUint16();
1116 Attenuation = _3ewg->ReadInt32();
1117 FineTune = _3ewg->ReadInt16();
1118 PitchbendRange = _3ewg->ReadInt16();
1119 uint8_t dimkeystart = _3ewg->ReadUint8();
1120 PianoReleaseMode = dimkeystart & 0x01;
1121 DimensionKeyRange.low = dimkeystart >> 1;
1122 DimensionKeyRange.high = _3ewg->ReadUint8();
1123 }
1124 else throw gig::Exception("Mandatory <3ewg> chunk not found.");
1125 }
1126 else throw gig::Exception("Mandatory <lart> list chunk not found.");
1127
1128 RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
1129 if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
1130 pRegions = new Region*[Regions];
1131 RIFF::List* rgn = lrgn->GetFirstSubList();
1132 unsigned int iRegion = 0;
1133 while (rgn) {
1134 if (rgn->GetListType() == LIST_TYPE_RGN) {
1135 pRegions[iRegion] = new Region(this, rgn);
1136 iRegion++;
1137 }
1138 rgn = lrgn->GetNextSubList();
1139 }
1140
1141 // Creating Region Key Table for fast lookup
1142 for (uint iReg = 0; iReg < Regions; iReg++) {
1143 for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
1144 RegionKeyTable[iKey] = pRegions[iReg];
1145 }
1146 }
1147 }
1148
1149 Instrument::~Instrument() {
1150 for (uint i = 0; i < Regions; i++) {
1151 if (pRegions) {
1152 if (pRegions[i]) delete (pRegions[i]);
1153 }
1154 delete[] pRegions;
1155 }
1156 }
1157
1158 /**
1159 * Returns the appropriate Region for a triggered note.
1160 *
1161 * @param Key MIDI Key number of triggered note / key (0 - 127)
1162 * @returns pointer adress to the appropriate Region or NULL if there
1163 * there is no Region defined for the given \a Key
1164 */
1165 Region* Instrument::GetRegion(unsigned int Key) {
1166 if (!pRegions || Key > 127) return NULL;
1167 return RegionKeyTable[Key];
1168 /*for (int i = 0; i < Regions; i++) {
1169 if (Key <= pRegions[i]->KeyRange.high &&
1170 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
1171 }
1172 return NULL;*/
1173 }
1174
1175 /**
1176 * Returns the first Region of the instrument. You have to call this
1177 * method once before you use GetNextRegion().
1178 *
1179 * @returns pointer address to first region or NULL if there is none
1180 * @see GetNextRegion()
1181 */
1182 Region* Instrument::GetFirstRegion() {
1183 if (!Regions) return NULL;
1184 RegionIndex = 1;
1185 return pRegions[0];
1186 }
1187
1188 /**
1189 * Returns the next Region of the instrument. You have to call
1190 * GetFirstRegion() once before you can use this method. By calling this
1191 * method multiple times it iterates through the available Regions.
1192 *
1193 * @returns pointer address to the next region or NULL if end reached
1194 * @see GetFirstRegion()
1195 */
1196 Region* Instrument::GetNextRegion() {
1197 if (RegionIndex < 0 || RegionIndex >= Regions) return NULL;
1198 return pRegions[RegionIndex++];
1199 }
1200
1201
1202
1203 // *************** File ***************
1204 // *
1205
1206 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
1207 pSamples = NULL;
1208 pInstruments = NULL;
1209 }
1210
1211 Sample* File::GetFirstSample() {
1212 if (!pSamples) LoadSamples();
1213 if (!pSamples) return NULL;
1214 SamplesIterator = pSamples->begin();
1215 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1216 }
1217
1218 Sample* File::GetNextSample() {
1219 if (!pSamples) return NULL;
1220 SamplesIterator++;
1221 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1222 }
1223
1224 void File::LoadSamples() {
1225 RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
1226 if (wvpl) {
1227 unsigned long wvplFileOffset = wvpl->GetFilePos();
1228 RIFF::List* wave = wvpl->GetFirstSubList();
1229 while (wave) {
1230 if (wave->GetListType() == LIST_TYPE_WAVE) {
1231 if (!pSamples) pSamples = new SampleList;
1232 unsigned long waveFileOffset = wave->GetFilePos();
1233 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
1234 }
1235 wave = wvpl->GetNextSubList();
1236 }
1237 }
1238 else throw gig::Exception("Mandatory <wvpl> chunk not found.");
1239 }
1240
1241 Instrument* File::GetFirstInstrument() {
1242 if (!pInstruments) LoadInstruments();
1243 if (!pInstruments) return NULL;
1244 InstrumentsIterator = pInstruments->begin();
1245 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1246 }
1247
1248 Instrument* File::GetNextInstrument() {
1249 if (!pInstruments) return NULL;
1250 InstrumentsIterator++;
1251 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1252 }
1253
1254 /**
1255 * Returns the instrument with the given index.
1256 *
1257 * @returns sought instrument or NULL if there's no such instrument
1258 */
1259 Instrument* File::GetInstrument(uint index) {
1260 if (!pInstruments) LoadInstruments();
1261 if (!pInstruments) return NULL;
1262 InstrumentsIterator = pInstruments->begin();
1263 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
1264 if (i == index) return *InstrumentsIterator;
1265 InstrumentsIterator++;
1266 }
1267 return NULL;
1268 }
1269
1270 void File::LoadInstruments() {
1271 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1272 if (lstInstruments) {
1273 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
1274 while (lstInstr) {
1275 if (lstInstr->GetListType() == LIST_TYPE_INS) {
1276 if (!pInstruments) pInstruments = new InstrumentList;
1277 pInstruments->push_back(new Instrument(this, lstInstr));
1278 }
1279 lstInstr = lstInstruments->GetNextSubList();
1280 }
1281 }
1282 else throw gig::Exception("Mandatory <lins> list chunk not found.");
1283 }
1284
1285
1286
1287 // *************** Exception ***************
1288 // *
1289
1290 Exception::Exception(String Message) : DLS::Exception(Message) {
1291 }
1292
1293 void Exception::PrintMessage() {
1294 std::cout << "gig::Exception: " << Message << std::endl;
1295 }
1296
1297 } // namespace gig

  ViewVC Help
Powered by ViewVC