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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC