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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations) (download)
Thu Dec 25 01:09:08 2003 UTC (20 years, 3 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 schoenebeck 2 /***************************************************************************
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 schoenebeck 21 FineTune = smpl->ReadInt32();
49 schoenebeck 2 smpl->Read(&SMPTEFormat, 1, 4);
50     SMPTEOffset = smpl->ReadInt32();
51     Loops = smpl->ReadInt32();
52 schoenebeck 21 uint32_t manufByt = smpl->ReadInt32();
53 schoenebeck 2 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 schoenebeck 21
76     LoopStart /= FrameSize; // convert to sample points
77     LoopEnd /= FrameSize; // convert to sample points
78     LoopSize = LoopEnd - LoopStart;
79 schoenebeck 2 }
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 schoenebeck 21 if (SampleCount == 0) return 0;
332 schoenebeck 11 if (!Compressed) return pCkData->Read(pBuffer, SampleCount, FrameSize); //FIXME: channel inversion due to endian correction?
333 schoenebeck 2 else { //FIXME: no support for mono compressed samples yet, are there any?
334 schoenebeck 11 if (this->SamplePos >= this->SamplesTotal) return 0;
335 schoenebeck 2 //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 schoenebeck 11 this->SamplePos = this->SamplesTotal;
364 schoenebeck 2 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 schoenebeck 11 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
484 schoenebeck 2 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 schoenebeck 16 uint DimensionRegion::Instances = 0;
501     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
502    
503 schoenebeck 2 DimensionRegion::DimensionRegion(RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
504 schoenebeck 16 Instances++;
505    
506 schoenebeck 2 memcpy(&Crossfade, &SamplerOptions, 4);
507 schoenebeck 16 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
508 schoenebeck 2
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 schoenebeck 16
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 schoenebeck 2 }
699    
700 schoenebeck 16 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 schoenebeck 2
715 schoenebeck 16 /**
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 schoenebeck 2
730 schoenebeck 16
731    
732 schoenebeck 2 // *************** 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 schoenebeck 21 /**
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 schoenebeck 2 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