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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show annotations) (download)
Thu Dec 25 01:09:08 2003 UTC (17 years, 2 months ago) by schoenebeck
File size: 54728 byte(s)
* gig.h, gig.cpp:
  changes in class 'Sample':
  - fixed loop attributes which reflected wrong values
  - attributes 'LoopStart' and 'LoopEnd' are now measured in sample points
    instead of byte offset
  - renamed misleading attribute name 'MIDIPitchFraction' to 'FineTune'
  - added attribute 'LoopSize'
  changes in class 'File':
  - added method GetInstrument(uint index)

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 current
319 * position into the buffer pointed by \a pBuffer and increments the
320 * position within the sample. The sample wave stream will be
321 * decompressed on the fly if using a compressed sample. Use this method
322 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
323 * thus for disk streaming.
324 *
325 * @param pBuffer destination buffer
326 * @param SampleCount number of sample points to read
327 * @returns number of successfully read sample points
328 * @see SetPos()
329 */
330 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
331 if (SampleCount == 0) return 0;
332 if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize); //FIXME: channel inversion due to endian correction?
333 else { //FIXME: no support for mono compressed samples yet, are there any?
334 if (this->SamplePos >= this->SamplesTotal) return 0;
335 //TODO: efficiency: we simply assume here that all frames are compressed, maybe we should test for an average compression rate
336 // best case needed buffer size (all frames compressed)
337 unsigned long assumedsize = (SampleCount << 1) + // *2 (16 Bit, stereo, but assume all frames compressed)
338 (SampleCount >> 10) + // 10 bytes header per 2048 sample points
339 8194, // at least one worst case sample frame
340 remainingbytes = 0, // remaining bytes in the local buffer
341 remainingsamples = SampleCount,
342 copysamples;
343 int currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
344 this->FrameOffset = 0;
345
346 if (assumedsize > this->DecompressionBufferSize) {
347 // local buffer reallocation - hope this won't happen
348 if (this->pDecompressionBuffer) delete[] (int8_t*) this->pDecompressionBuffer;
349 this->pDecompressionBuffer = new int8_t[assumedsize << 1]; // double of current needed size
350 this->DecompressionBufferSize = assumedsize;
351 }
352
353 int16_t compressionmode, left, dleft, right, dright;
354 int8_t* pSrc = (int8_t*) this->pDecompressionBuffer;
355 int16_t* pDst = (int16_t*) pBuffer;
356 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
357
358 while (remainingsamples) {
359
360 // reload from disk to local buffer if needed
361 if (remainingbytes < 8194) {
362 if (pCkData->GetState() != RIFF::stream_ready) {
363 this->SamplePos = this->SamplesTotal;
364 return (SampleCount - remainingsamples);
365 }
366 assumedsize = remainingsamples;
367 assumedsize = (assumedsize << 1) + // *2 (16 Bit, stereo, but assume all frames compressed)
368 (assumedsize >> 10) + // 10 bytes header per 2048 sample points
369 8194; // at least one worst case sample frame
370 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
371 if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
372 remainingbytes = pCkData->Read(this->pDecompressionBuffer, assumedsize, 1);
373 pSrc = (int8_t*) this->pDecompressionBuffer;
374 }
375
376 // determine how many samples in this frame to skip and read
377 if (remainingsamples >= 2048) {
378 copysamples = 2048 - currentframeoffset;
379 remainingsamples -= copysamples;
380 }
381 else {
382 copysamples = remainingsamples;
383 if (currentframeoffset + copysamples > 2048) {
384 copysamples = 2048 - currentframeoffset;
385 remainingsamples -= copysamples;
386 }
387 else {
388 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
389 remainingsamples = 0;
390 this->FrameOffset = currentframeoffset + copysamples;
391 }
392 }
393
394 // decompress and copy current frame from local buffer to destination buffer
395 compressionmode = *(int16_t*)pSrc; pSrc+=2;
396 switch (compressionmode) {
397 case 1: // left channel compressed
398 remainingbytes -= 6150; // (left 8 bit, right 16 bit, +6 byte header)
399 if (!remainingsamples && copysamples == 2048)
400 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
401
402 left = *(int16_t*)pSrc; pSrc+=2;
403 dleft = *(int16_t*)pSrc; pSrc+=2;
404 while (currentframeoffset) {
405 dleft -= *pSrc;
406 left -= dleft;
407 pSrc+=3; // 8 bit left channel, skip uncompressed right channel (16 bit)
408 currentframeoffset--;
409 }
410 while (copysamples) {
411 dleft -= *pSrc; pSrc++;
412 left -= dleft;
413 *pDst = left; pDst++;
414 *pDst = *(int16_t*)pSrc; pDst++; pSrc+=2;
415 copysamples--;
416 }
417 break;
418 case 256: // right channel compressed
419 remainingbytes -= 6150; // (left 16 bit, right 8 bit, +6 byte header)
420 if (!remainingsamples && copysamples == 2048)
421 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
422
423 right = *(int16_t*)pSrc; pSrc+=2;
424 dright = *(int16_t*)pSrc; pSrc+=2;
425 if (currentframeoffset) {
426 pSrc+=2; // skip uncompressed left channel, now we can increment by 3
427 while (currentframeoffset) {
428 dright -= *pSrc;
429 right -= dright;
430 pSrc+=3; // 8 bit right channel, skip uncompressed left channel (16 bit)
431 currentframeoffset--;
432 }
433 pSrc-=2; // back aligned to left channel
434 }
435 while (copysamples) {
436 *pDst = *(int16_t*)pSrc; pDst++; pSrc+=2;
437 dright -= *pSrc; pSrc++;
438 right -= dright;
439 *pDst = right; pDst++;
440 copysamples--;
441 }
442 break;
443 case 257: // both channels compressed
444 remainingbytes -= 4106; // (left 8 bit, right 8 bit, +10 byte header)
445 if (!remainingsamples && copysamples == 2048)
446 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
447
448 left = *(int16_t*)pSrc; pSrc+=2;
449 dleft = *(int16_t*)pSrc; pSrc+=2;
450 right = *(int16_t*)pSrc; pSrc+=2;
451 dright = *(int16_t*)pSrc; pSrc+=2;
452 while (currentframeoffset) {
453 dleft -= *pSrc; pSrc++;
454 left -= dleft;
455 dright -= *pSrc; pSrc++;
456 right -= dright;
457 currentframeoffset--;
458 }
459 while (copysamples) {
460 dleft -= *pSrc; pSrc++;
461 left -= dleft;
462 dright -= *pSrc; pSrc++;
463 right -= dright;
464 *pDst = left; pDst++;
465 *pDst = right; pDst++;
466 copysamples--;
467 }
468 break;
469 default: // both channels uncompressed
470 remainingbytes -= 8194; // (left 16 bit, right 16 bit, +2 byte header)
471 if (!remainingsamples && copysamples == 2048)
472 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
473
474 pSrc += currentframeoffset << 2;
475 currentframeoffset = 0;
476 memcpy(pDst, pSrc, copysamples << 2);
477 pDst += copysamples << 1;
478 pSrc += copysamples << 2;
479 break;
480 }
481 }
482 this->SamplePos += (SampleCount - remainingsamples);
483 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
484 return (SampleCount - remainingsamples);
485 }
486 }
487
488 Sample::~Sample() {
489 Instances--;
490 if (!Instances && pDecompressionBuffer) delete[] (int8_t*) pDecompressionBuffer;
491 if (FrameTable) delete[] FrameTable;
492 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
493 }
494
495
496
497 // *************** DimensionRegion ***************
498 // *
499
500 uint DimensionRegion::Instances = 0;
501 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
502
503 DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
504 Instances++;
505
506 memcpy(&Crossfade, &SamplerOptions, 4);
507 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
508
509 RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
510 _3ewa->ReadInt32(); // unknown, allways 0x0000008C ?
511 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
512 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
513 _3ewa->ReadInt16(); // unknown
514 LFO1InternalDepth = _3ewa->ReadUint16();
515 _3ewa->ReadInt16(); // unknown
516 LFO3InternalDepth = _3ewa->ReadInt16();
517 _3ewa->ReadInt16(); // unknown
518 LFO1ControlDepth = _3ewa->ReadUint16();
519 _3ewa->ReadInt16(); // unknown
520 LFO3ControlDepth = _3ewa->ReadInt16();
521 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
522 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
523 _3ewa->ReadInt16(); // unknown
524 EG1Sustain = _3ewa->ReadUint16();
525 EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
526 EG1Controller = static_cast<eg1_ctrl_t>(_3ewa->ReadUint8());
527 uint8_t eg1ctrloptions = _3ewa->ReadUint8();
528 EG1ControllerInvert = eg1ctrloptions & 0x01;
529 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
530 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
531 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
532 EG2Controller = static_cast<eg2_ctrl_t>(_3ewa->ReadUint8());
533 uint8_t eg2ctrloptions = _3ewa->ReadUint8();
534 EG2ControllerInvert = eg2ctrloptions & 0x01;
535 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
536 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
537 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
538 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
539 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
540 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
541 _3ewa->ReadInt16(); // unknown
542 EG2Sustain = _3ewa->ReadUint16();
543 EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
544 _3ewa->ReadInt16(); // unknown
545 LFO2ControlDepth = _3ewa->ReadUint16();
546 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
547 _3ewa->ReadInt16(); // unknown
548 LFO2InternalDepth = _3ewa->ReadUint16();
549 int32_t eg1decay2 = _3ewa->ReadInt32();
550 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
551 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
552 _3ewa->ReadInt16(); // unknown
553 EG1PreAttack = _3ewa->ReadUint16();
554 int32_t eg2decay2 = _3ewa->ReadInt32();
555 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
556 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
557 _3ewa->ReadInt16(); // unknown
558 EG2PreAttack = _3ewa->ReadUint16();
559 uint8_t velocityresponse = _3ewa->ReadUint8();
560 if (velocityresponse < 5) {
561 VelocityResponseCurve = curve_type_nonlinear;
562 VelocityResponseDepth = velocityresponse;
563 }
564 else if (velocityresponse < 10) {
565 VelocityResponseCurve = curve_type_linear;
566 VelocityResponseDepth = velocityresponse - 5;
567 }
568 else if (velocityresponse < 15) {
569 VelocityResponseCurve = curve_type_special;
570 VelocityResponseDepth = velocityresponse - 10;
571 }
572 else {
573 VelocityResponseCurve = curve_type_unknown;
574 VelocityResponseDepth = 0;
575 }
576 uint8_t releasevelocityresponse = _3ewa->ReadUint8();
577 if (releasevelocityresponse < 5) {
578 ReleaseVelocityResponseCurve = curve_type_nonlinear;
579 ReleaseVelocityResponseDepth = releasevelocityresponse;
580 }
581 else if (releasevelocityresponse < 10) {
582 ReleaseVelocityResponseCurve = curve_type_linear;
583 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
584 }
585 else if (releasevelocityresponse < 15) {
586 ReleaseVelocityResponseCurve = curve_type_special;
587 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
588 }
589 else {
590 ReleaseVelocityResponseCurve = curve_type_unknown;
591 ReleaseVelocityResponseDepth = 0;
592 }
593 VelocityResponseCurveScaling = _3ewa->ReadUint8();
594 AttenuationControlTreshold = _3ewa->ReadInt8();
595 _3ewa->ReadInt32(); // unknown
596 SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
597 _3ewa->ReadInt16(); // unknown
598 uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
599 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
600 if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
601 else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
602 else DimensionBypass = dim_bypass_ctrl_none;
603 uint8_t pan = _3ewa->ReadUint8();
604 Pan = (pan < 64) ? pan : (-1) * (int8_t)pan - 63;
605 SelfMask = _3ewa->ReadInt8() & 0x01;
606 _3ewa->ReadInt8(); // unknown
607 uint8_t lfo3ctrl = _3ewa->ReadUint8();
608 LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
609 LFO3Sync = lfo3ctrl & 0x20; // bit 5
610 InvertAttenuationControl = lfo3ctrl & 0x80; // bit 7
611 if (VCFType == vcf_type_lowpass) {
612 if (lfo3ctrl & 0x40) // bit 6
613 VCFType = vcf_type_lowpassturbo;
614 }
615 AttenuationControl = static_cast<attenuation_ctrl_t>(_3ewa->ReadUint8());
616 uint8_t lfo2ctrl = _3ewa->ReadUint8();
617 LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
618 LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
619 LFO2Sync = lfo2ctrl & 0x20; // bit 5
620 bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
621 uint8_t lfo1ctrl = _3ewa->ReadUint8();
622 LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
623 LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
624 LFO1Sync = lfo1ctrl & 0x40; // bit 6
625 VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
626 : vcf_res_ctrl_none;
627 uint16_t eg3depth = _3ewa->ReadUint16();
628 EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
629 : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
630 _3ewa->ReadInt16(); // unknown
631 ChannelOffset = _3ewa->ReadUint8() / 4;
632 uint8_t regoptions = _3ewa->ReadUint8();
633 MSDecode = regoptions & 0x01; // bit 0
634 SustainDefeat = regoptions & 0x02; // bit 1
635 _3ewa->ReadInt16(); // unknown
636 VelocityUpperLimit = _3ewa->ReadInt8();
637 _3ewa->ReadInt8(); // unknown
638 _3ewa->ReadInt16(); // unknown
639 ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
640 _3ewa->ReadInt8(); // unknown
641 _3ewa->ReadInt8(); // unknown
642 EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
643 uint8_t vcfcutoff = _3ewa->ReadUint8();
644 VCFEnabled = vcfcutoff & 0x80; // bit 7
645 VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
646 VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
647 VCFVelocityScale = _3ewa->ReadUint8();
648 _3ewa->ReadInt8(); // unknown
649 uint8_t vcfresonance = _3ewa->ReadUint8();
650 VCFResonance = vcfresonance & 0x7f; // lower 7 bits
651 VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
652 uint8_t vcfbreakpoint = _3ewa->ReadUint8();
653 VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
654 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
655 uint8_t vcfvelocity = _3ewa->ReadUint8();
656 VCFVelocityDynamicRange = vcfvelocity % 5;
657 VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
658 VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
659
660 // get the corresponding velocity->volume table from the table map or create & calculate that table if it doesn't exist yet
661 uint32_t tableKey = (VelocityResponseCurve<<16) | (VelocityResponseDepth<<8) | VelocityResponseCurveScaling;
662 if (pVelocityTables->count(tableKey)) { // if key exists
663 pVelocityAttenuationTable = (*pVelocityTables)[tableKey];
664 }
665 else {
666 pVelocityAttenuationTable = new double[128];
667 switch (VelocityResponseCurve) { // calculate the new table
668 case curve_type_nonlinear:
669 for (int velocity = 0; velocity < 128; velocity++) {
670 pVelocityAttenuationTable[velocity] =
671 GIG_VELOCITY_TRANSFORM_NONLINEAR((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
672 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
673 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
674 }
675 break;
676 case curve_type_linear:
677 for (int velocity = 0; velocity < 128; velocity++) {
678 pVelocityAttenuationTable[velocity] =
679 GIG_VELOCITY_TRANSFORM_LINEAR((double)velocity,(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
680 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
681 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
682 }
683 break;
684 case curve_type_special:
685 for (int velocity = 0; velocity < 128; velocity++) {
686 pVelocityAttenuationTable[velocity] =
687 GIG_VELOCITY_TRANSFORM_SPECIAL((double)(velocity+1),(double)(VelocityResponseDepth+1),(double)VelocityResponseCurveScaling);
688 if (pVelocityAttenuationTable[velocity] > 1.0) pVelocityAttenuationTable[velocity] = 1.0;
689 else if (pVelocityAttenuationTable[velocity] < 0.0) pVelocityAttenuationTable[velocity] = 0.0;
690 }
691 break;
692 case curve_type_unknown:
693 default:
694 throw gig::Exception("Unknown transform curve type.");
695 }
696 (*pVelocityTables)[tableKey] = pVelocityAttenuationTable; // put the new table into the tables map
697 }
698 }
699
700 DimensionRegion::~DimensionRegion() {
701 Instances--;
702 if (!Instances) {
703 // delete the velocity->volume tables
704 VelocityTableMap::iterator iter;
705 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
706 double* pTable = iter->second;
707 if (pTable) delete[] pTable;
708 }
709 pVelocityTables->clear();
710 delete pVelocityTables;
711 pVelocityTables = NULL;
712 }
713 }
714
715 /**
716 * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
717 * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
718 * and VelocityResponseCurveScaling) involved are taken into account to
719 * calculate the amplitude factor. Use this method when a key was
720 * triggered to get the volume with which the sample should be played
721 * back.
722 *
723 * @param MIDI velocity value of the triggered key (between 0 and 127)
724 * @returns amplitude factor (between 0.0 and 1.0)
725 */
726 double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
727 return pVelocityAttenuationTable[MIDIKeyVelocity];
728 }
729
730
731
732 // *************** Region ***************
733 // *
734
735 Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
736 // Initialization
737 Dimensions = 0;
738 for (int i = 0; i < 32; i++) {
739 pDimensionRegions[i] = NULL;
740 }
741
742 // Actual Loading
743
744 LoadDimensionRegions(rgnList);
745
746 RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
747 if (_3lnk) {
748 DimensionRegions = _3lnk->ReadUint32();
749 for (int i = 0; i < 5; i++) {
750 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
751 uint8_t bits = _3lnk->ReadUint8();
752 if (dimension == dimension_none) { // inactive dimension
753 pDimensionDefinitions[i].dimension = dimension_none;
754 pDimensionDefinitions[i].bits = 0;
755 pDimensionDefinitions[i].zones = 0;
756 pDimensionDefinitions[i].split_type = split_type_bit;
757 pDimensionDefinitions[i].ranges = NULL;
758 pDimensionDefinitions[i].zone_size = 0;
759 }
760 else { // active dimension
761 pDimensionDefinitions[i].dimension = dimension;
762 pDimensionDefinitions[i].bits = bits;
763 pDimensionDefinitions[i].zones = 0x01 << bits; // = pow(2,bits)
764 pDimensionDefinitions[i].split_type = (dimension == dimension_layer ||
765 dimension == dimension_samplechannel) ? split_type_bit
766 : split_type_normal;
767 pDimensionDefinitions[i].ranges = NULL; // it's not possible to check velocity dimensions for custom defined ranges at this point
768 pDimensionDefinitions[i].zone_size =
769 (pDimensionDefinitions[i].split_type == split_type_normal) ? 128 / pDimensionDefinitions[i].zones
770 : 0;
771 Dimensions++;
772 }
773 _3lnk->SetPos(6, RIFF::stream_curpos); // jump forward to next dimension definition
774 }
775
776 // check velocity dimension (if there is one) for custom defined zone ranges
777 for (uint i = 0; i < Dimensions; i++) {
778 dimension_def_t* pDimDef = pDimensionDefinitions + i;
779 if (pDimDef->dimension == dimension_velocity) {
780 if (pDimensionRegions[0]->VelocityUpperLimit == 0) {
781 // no custom defined ranges
782 pDimDef->split_type = split_type_normal;
783 pDimDef->ranges = NULL;
784 }
785 else { // custom defined ranges
786 pDimDef->split_type = split_type_customvelocity;
787 pDimDef->ranges = new range_t[pDimDef->zones];
788 unsigned int bits[5] = {0,0,0,0,0};
789 int previousUpperLimit = -1;
790 for (int velocityZone = 0; velocityZone < pDimDef->zones; velocityZone++) {
791 bits[i] = velocityZone;
792 DimensionRegion* pDimRegion = GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);
793
794 pDimDef->ranges[velocityZone].low = previousUpperLimit + 1;
795 pDimDef->ranges[velocityZone].high = pDimRegion->VelocityUpperLimit;
796 previousUpperLimit = pDimDef->ranges[velocityZone].high;
797 // fill velocity table
798 for (int i = pDimDef->ranges[velocityZone].low; i <= pDimDef->ranges[velocityZone].high; i++) {
799 VelocityTable[i] = velocityZone;
800 }
801 }
802 }
803 }
804 }
805
806 // load sample references
807 _3lnk->SetPos(44); // jump to start of the wave pool indices (if not already there)
808 for (uint i = 0; i < DimensionRegions; i++) {
809 uint32_t wavepoolindex = _3lnk->ReadUint32();
810 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
811 }
812 }
813 else throw gig::Exception("Mandatory <3lnk> chunk not found.");
814 }
815
816 void Region::LoadDimensionRegions(RIFF::List* rgn) {
817 RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
818 if (_3prg) {
819 int dimensionRegionNr = 0;
820 RIFF::List* _3ewl = _3prg->GetFirstSubList();
821 while (_3ewl) {
822 if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
823 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(_3ewl);
824 dimensionRegionNr++;
825 }
826 _3ewl = _3prg->GetNextSubList();
827 }
828 if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
829 }
830 }
831
832 Region::~Region() {
833 for (uint i = 0; i < Dimensions; i++) {
834 if (pDimensionDefinitions[i].ranges) delete[] pDimensionDefinitions[i].ranges;
835 }
836 for (int i = 0; i < 32; i++) {
837 if (pDimensionRegions[i]) delete pDimensionRegions[i];
838 }
839 }
840
841 /**
842 * Use this method in your audio engine to get the appropriate dimension
843 * region with it's articulation data for the current situation. Just
844 * call the method with the current MIDI controller values and you'll get
845 * the DimensionRegion with the appropriate articulation data for the
846 * current situation (for this Region of course only). To do that you'll
847 * first have to look which dimensions with which controllers and in
848 * which order are defined for this Region when you load the .gig file.
849 * Special cases are e.g. layer or channel dimensions where you just put
850 * in the index numbers instead of a MIDI controller value (means 0 for
851 * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
852 * etc.).
853 *
854 * @param Dim4Val MIDI controller value (0-127) for dimension 4
855 * @param Dim3Val MIDI controller value (0-127) for dimension 3
856 * @param Dim2Val MIDI controller value (0-127) for dimension 2
857 * @param Dim1Val MIDI controller value (0-127) for dimension 1
858 * @param Dim0Val MIDI controller value (0-127) for dimension 0
859 * @returns adress to the DimensionRegion for the given situation
860 * @see pDimensionDefinitions
861 * @see Dimensions
862 */
863 DimensionRegion* Region::GetDimensionRegionByValue(uint Dim4Val, uint Dim3Val, uint Dim2Val, uint Dim1Val, uint Dim0Val) {
864 unsigned int bits[5] = {Dim0Val,Dim1Val,Dim2Val,Dim3Val,Dim4Val};
865 for (uint i = 0; i < Dimensions; i++) {
866 switch (pDimensionDefinitions[i].split_type) {
867 case split_type_normal:
868 bits[i] /= pDimensionDefinitions[i].zone_size;
869 break;
870 case split_type_customvelocity:
871 bits[i] = VelocityTable[bits[i]];
872 break;
873 // else the value is already the sought dimension bit number
874 }
875 }
876 return GetDimensionRegionByBit(bits[4],bits[3],bits[2],bits[1],bits[0]);
877 }
878
879 /**
880 * Returns the appropriate DimensionRegion for the given dimension bit
881 * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
882 * instead of calling this method directly!
883 *
884 * @param Dim4Bit Bit number for dimension 4
885 * @param Dim3Bit Bit number for dimension 3
886 * @param Dim2Bit Bit number for dimension 2
887 * @param Dim1Bit Bit number for dimension 1
888 * @param Dim0Bit Bit number for dimension 0
889 * @returns adress to the DimensionRegion for the given dimension
890 * bit numbers
891 * @see GetDimensionRegionByValue()
892 */
893 DimensionRegion* Region::GetDimensionRegionByBit(uint8_t Dim4Bit, uint8_t Dim3Bit, uint8_t Dim2Bit, uint8_t Dim1Bit, uint8_t Dim0Bit) {
894 return *(pDimensionRegions + ((((((((Dim4Bit << pDimensionDefinitions[3].bits) | Dim3Bit)
895 << pDimensionDefinitions[2].bits) | Dim2Bit)
896 << pDimensionDefinitions[1].bits) | Dim1Bit)
897 << pDimensionDefinitions[0].bits) | Dim0Bit) );
898 }
899
900 /**
901 * Returns pointer address to the Sample referenced with this region.
902 * This is the global Sample for the entire Region (not sure if this is
903 * actually used by the Gigasampler engine - I would only use the Sample
904 * referenced by the appropriate DimensionRegion instead of this sample).
905 *
906 * @returns address to Sample or NULL if there is no reference to a
907 * sample saved in the .gig file
908 */
909 Sample* Region::GetSample() {
910 if (pSample) return static_cast<gig::Sample*>(pSample);
911 else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
912 }
913
914 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex) {
915 File* file = (File*) GetParent()->GetParent();
916 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
917 Sample* sample = file->GetFirstSample();
918 while (sample) {
919 if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
920 sample = file->GetNextSample();
921 }
922 return NULL;
923 }
924
925
926
927 // *************** Instrument ***************
928 // *
929
930 Instrument::Instrument(File* pFile, RIFF::List* insList) : DLS::Instrument((DLS::File*)pFile, insList) {
931 // Initialization
932 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
933 RegionIndex = -1;
934
935 // Loading
936 RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
937 if (lart) {
938 RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
939 if (_3ewg) {
940 EffectSend = _3ewg->ReadUint16();
941 Attenuation = _3ewg->ReadInt32();
942 FineTune = _3ewg->ReadInt16();
943 PitchbendRange = _3ewg->ReadInt16();
944 uint8_t dimkeystart = _3ewg->ReadUint8();
945 PianoReleaseMode = dimkeystart & 0x01;
946 DimensionKeyRange.low = dimkeystart >> 1;
947 DimensionKeyRange.high = _3ewg->ReadUint8();
948 }
949 else throw gig::Exception("Mandatory <3ewg> chunk not found.");
950 }
951 else throw gig::Exception("Mandatory <lart> list chunk not found.");
952
953 RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
954 if (!lrgn) throw gig::Exception("Mandatory chunks in <ins > chunk not found.");
955 pRegions = new Region*[Regions];
956 RIFF::List* rgn = lrgn->GetFirstSubList();
957 unsigned int iRegion = 0;
958 while (rgn) {
959 if (rgn->GetListType() == LIST_TYPE_RGN) {
960 pRegions[iRegion] = new Region(this, rgn);
961 iRegion++;
962 }
963 rgn = lrgn->GetNextSubList();
964 }
965
966 // Creating Region Key Table for fast lookup
967 for (uint iReg = 0; iReg < Regions; iReg++) {
968 for (int iKey = pRegions[iReg]->KeyRange.low; iKey <= pRegions[iReg]->KeyRange.high; iKey++) {
969 RegionKeyTable[iKey] = pRegions[iReg];
970 }
971 }
972 }
973
974 Instrument::~Instrument() {
975 for (uint i = 0; i < Regions; i++) {
976 if (pRegions) {
977 if (pRegions[i]) delete (pRegions[i]);
978 }
979 delete[] pRegions;
980 }
981 }
982
983 /**
984 * Returns the appropriate Region for a triggered note.
985 *
986 * @param Key MIDI Key number of triggered note / key (0 - 127)
987 * @returns pointer adress to the appropriate Region or NULL if there
988 * there is no Region defined for the given \a Key
989 */
990 Region* Instrument::GetRegion(unsigned int Key) {
991 if (!pRegions || Key > 127) return NULL;
992 return RegionKeyTable[Key];
993 /*for (int i = 0; i < Regions; i++) {
994 if (Key <= pRegions[i]->KeyRange.high &&
995 Key >= pRegions[i]->KeyRange.low) return pRegions[i];
996 }
997 return NULL;*/
998 }
999
1000 /**
1001 * Returns the first Region of the instrument. You have to call this
1002 * method once before you use GetNextRegion().
1003 *
1004 * @returns pointer address to first region or NULL if there is none
1005 * @see GetNextRegion()
1006 */
1007 Region* Instrument::GetFirstRegion() {
1008 if (!Regions) return NULL;
1009 RegionIndex = 1;
1010 return pRegions[0];
1011 }
1012
1013 /**
1014 * Returns the next Region of the instrument. You have to call
1015 * GetFirstRegion() once before you can use this method. By calling this
1016 * method multiple times it iterates through the available Regions.
1017 *
1018 * @returns pointer address to the next region or NULL if end reached
1019 * @see GetFirstRegion()
1020 */
1021 Region* Instrument::GetNextRegion() {
1022 if (RegionIndex < 0 || RegionIndex >= Regions) return NULL;
1023 return pRegions[RegionIndex++];
1024 }
1025
1026
1027
1028 // *************** File ***************
1029 // *
1030
1031 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
1032 pSamples = NULL;
1033 pInstruments = NULL;
1034 }
1035
1036 Sample* File::GetFirstSample() {
1037 if (!pSamples) LoadSamples();
1038 if (!pSamples) return NULL;
1039 SamplesIterator = pSamples->begin();
1040 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1041 }
1042
1043 Sample* File::GetNextSample() {
1044 if (!pSamples) return NULL;
1045 SamplesIterator++;
1046 return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1047 }
1048
1049 void File::LoadSamples() {
1050 RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
1051 if (wvpl) {
1052 unsigned long wvplFileOffset = wvpl->GetFilePos();
1053 RIFF::List* wave = wvpl->GetFirstSubList();
1054 while (wave) {
1055 if (wave->GetListType() == LIST_TYPE_WAVE) {
1056 if (!pSamples) pSamples = new SampleList;
1057 unsigned long waveFileOffset = wave->GetFilePos();
1058 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
1059 }
1060 wave = wvpl->GetNextSubList();
1061 }
1062 }
1063 else throw gig::Exception("Mandatory <wvpl> chunk not found.");
1064 }
1065
1066 Instrument* File::GetFirstInstrument() {
1067 if (!pInstruments) LoadInstruments();
1068 if (!pInstruments) return NULL;
1069 InstrumentsIterator = pInstruments->begin();
1070 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1071 }
1072
1073 Instrument* File::GetNextInstrument() {
1074 if (!pInstruments) return NULL;
1075 InstrumentsIterator++;
1076 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1077 }
1078
1079 /**
1080 * Returns the instrument with the given index.
1081 *
1082 * @returns sought instrument or NULL if there's no such instrument
1083 */
1084 Instrument* File::GetInstrument(uint index) {
1085 if (!pInstruments) LoadInstruments();
1086 if (!pInstruments) return NULL;
1087 InstrumentsIterator = pInstruments->begin();
1088 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
1089 if (i == index) return *InstrumentsIterator;
1090 InstrumentsIterator++;
1091 }
1092 return NULL;
1093 }
1094
1095 void File::LoadInstruments() {
1096 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1097 if (lstInstruments) {
1098 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
1099 while (lstInstr) {
1100 if (lstInstr->GetListType() == LIST_TYPE_INS) {
1101 if (!pInstruments) pInstruments = new InstrumentList;
1102 pInstruments->push_back(new Instrument(this, lstInstr));
1103 }
1104 lstInstr = lstInstruments->GetNextSubList();
1105 }
1106 }
1107 else throw gig::Exception("Mandatory <lins> list chunk not found.");
1108 }
1109
1110
1111
1112 // *************** Exception ***************
1113 // *
1114
1115 Exception::Exception(String Message) : DLS::Exception(Message) {
1116 }
1117
1118 void Exception::PrintMessage() {
1119 std::cout << "gig::Exception: " << Message << std::endl;
1120 }
1121
1122 } // namespace gig

  ViewVC Help
Powered by ViewVC