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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1335 - (hide annotations) (download)
Sun Sep 9 21:22:58 2007 UTC (16 years, 6 months ago) by schoenebeck
File size: 164818 byte(s)
* added virtual method SetKeyRange() to the gig and DLS Region classes,
  which automatically take care that the "resized" Region is at the
  correct position and that the lookup table for
  gig::Instrument::GetRegion() is updated (moved code from gigedit)
* MoveRegion() method of DLS::Region class is now private
* bugfix: gig::Instrument::UpdateRegionKeyTable() did not reset unused
  areas

1 schoenebeck 2 /***************************************************************************
2     * *
3 schoenebeck 933 * libgig - C++ cross-platform Gigasampler format file access library *
4 schoenebeck 2 * *
5 schoenebeck 1050 * Copyright (C) 2003-2007 by Christian Schoenebeck *
6 schoenebeck 384 * <cuse@users.sourceforge.net> *
7 schoenebeck 2 * *
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 schoenebeck 809 #include "helper.h"
27    
28     #include <math.h>
29 schoenebeck 384 #include <iostream>
30    
31 schoenebeck 809 /// Initial size of the sample buffer which is used for decompression of
32     /// compressed sample wave streams - this value should always be bigger than
33     /// the biggest sample piece expected to be read by the sampler engine,
34     /// otherwise the buffer size will be raised at runtime and thus the buffer
35     /// reallocated which is time consuming and unefficient.
36     #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
37    
38     /** (so far) every exponential paramater in the gig format has a basis of 1.000000008813822 */
39     #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x))
40     #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822))
41     #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01))
42     #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01)
43     #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03)
44     #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4)
45     #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03)
46     #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03)
47     #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
48     #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1)
49     #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3)
50     #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5)
51    
52 schoenebeck 515 namespace gig {
53 schoenebeck 2
54 schoenebeck 515 // *************** progress_t ***************
55     // *
56    
57     progress_t::progress_t() {
58     callback = NULL;
59 schoenebeck 516 custom = NULL;
60 schoenebeck 515 __range_min = 0.0f;
61     __range_max = 1.0f;
62     }
63    
64     // private helper function to convert progress of a subprocess into the global progress
65     static void __notify_progress(progress_t* pProgress, float subprogress) {
66     if (pProgress && pProgress->callback) {
67     const float totalrange = pProgress->__range_max - pProgress->__range_min;
68     const float totalprogress = pProgress->__range_min + subprogress * totalrange;
69 schoenebeck 516 pProgress->factor = totalprogress;
70     pProgress->callback(pProgress); // now actually notify about the progress
71 schoenebeck 515 }
72     }
73    
74     // private helper function to divide a progress into subprogresses
75     static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) {
76     if (pParentProgress && pParentProgress->callback) {
77     const float totalrange = pParentProgress->__range_max - pParentProgress->__range_min;
78     pSubProgress->callback = pParentProgress->callback;
79 schoenebeck 516 pSubProgress->custom = pParentProgress->custom;
80 schoenebeck 515 pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks;
81     pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks;
82     }
83     }
84    
85    
86 schoenebeck 809 // *************** Internal functions for sample decompression ***************
87 persson 365 // *
88    
89 schoenebeck 515 namespace {
90    
91 persson 365 inline int get12lo(const unsigned char* pSrc)
92     {
93     const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
94     return x & 0x800 ? x - 0x1000 : x;
95     }
96    
97     inline int get12hi(const unsigned char* pSrc)
98     {
99     const int x = pSrc[1] >> 4 | pSrc[2] << 4;
100     return x & 0x800 ? x - 0x1000 : x;
101     }
102    
103     inline int16_t get16(const unsigned char* pSrc)
104     {
105     return int16_t(pSrc[0] | pSrc[1] << 8);
106     }
107    
108     inline int get24(const unsigned char* pSrc)
109     {
110     const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
111     return x & 0x800000 ? x - 0x1000000 : x;
112     }
113    
114 persson 902 inline void store24(unsigned char* pDst, int x)
115     {
116     pDst[0] = x;
117     pDst[1] = x >> 8;
118     pDst[2] = x >> 16;
119     }
120    
121 persson 365 void Decompress16(int compressionmode, const unsigned char* params,
122 persson 372 int srcStep, int dstStep,
123     const unsigned char* pSrc, int16_t* pDst,
124 persson 365 unsigned long currentframeoffset,
125     unsigned long copysamples)
126     {
127     switch (compressionmode) {
128     case 0: // 16 bit uncompressed
129     pSrc += currentframeoffset * srcStep;
130     while (copysamples) {
131     *pDst = get16(pSrc);
132 persson 372 pDst += dstStep;
133 persson 365 pSrc += srcStep;
134     copysamples--;
135     }
136     break;
137    
138     case 1: // 16 bit compressed to 8 bit
139     int y = get16(params);
140     int dy = get16(params + 2);
141     while (currentframeoffset) {
142     dy -= int8_t(*pSrc);
143     y -= dy;
144     pSrc += srcStep;
145     currentframeoffset--;
146     }
147     while (copysamples) {
148     dy -= int8_t(*pSrc);
149     y -= dy;
150     *pDst = y;
151 persson 372 pDst += dstStep;
152 persson 365 pSrc += srcStep;
153     copysamples--;
154     }
155     break;
156     }
157     }
158    
159     void Decompress24(int compressionmode, const unsigned char* params,
160 persson 902 int dstStep, const unsigned char* pSrc, uint8_t* pDst,
161 persson 365 unsigned long currentframeoffset,
162 persson 437 unsigned long copysamples, int truncatedBits)
163 persson 365 {
164 persson 695 int y, dy, ddy, dddy;
165 persson 437
166 persson 695 #define GET_PARAMS(params) \
167     y = get24(params); \
168     dy = y - get24((params) + 3); \
169     ddy = get24((params) + 6); \
170     dddy = get24((params) + 9)
171 persson 365
172     #define SKIP_ONE(x) \
173 persson 695 dddy -= (x); \
174     ddy -= dddy; \
175     dy = -dy - ddy; \
176     y += dy
177 persson 365
178     #define COPY_ONE(x) \
179     SKIP_ONE(x); \
180 persson 902 store24(pDst, y << truncatedBits); \
181 persson 372 pDst += dstStep
182 persson 365
183     switch (compressionmode) {
184     case 2: // 24 bit uncompressed
185     pSrc += currentframeoffset * 3;
186     while (copysamples) {
187 persson 902 store24(pDst, get24(pSrc) << truncatedBits);
188 persson 372 pDst += dstStep;
189 persson 365 pSrc += 3;
190     copysamples--;
191     }
192     break;
193    
194     case 3: // 24 bit compressed to 16 bit
195     GET_PARAMS(params);
196     while (currentframeoffset) {
197     SKIP_ONE(get16(pSrc));
198     pSrc += 2;
199     currentframeoffset--;
200     }
201     while (copysamples) {
202     COPY_ONE(get16(pSrc));
203     pSrc += 2;
204     copysamples--;
205     }
206     break;
207    
208     case 4: // 24 bit compressed to 12 bit
209     GET_PARAMS(params);
210     while (currentframeoffset > 1) {
211     SKIP_ONE(get12lo(pSrc));
212     SKIP_ONE(get12hi(pSrc));
213     pSrc += 3;
214     currentframeoffset -= 2;
215     }
216     if (currentframeoffset) {
217     SKIP_ONE(get12lo(pSrc));
218     currentframeoffset--;
219     if (copysamples) {
220     COPY_ONE(get12hi(pSrc));
221     pSrc += 3;
222     copysamples--;
223     }
224     }
225     while (copysamples > 1) {
226     COPY_ONE(get12lo(pSrc));
227     COPY_ONE(get12hi(pSrc));
228     pSrc += 3;
229     copysamples -= 2;
230     }
231     if (copysamples) {
232     COPY_ONE(get12lo(pSrc));
233     }
234     break;
235    
236     case 5: // 24 bit compressed to 8 bit
237     GET_PARAMS(params);
238     while (currentframeoffset) {
239     SKIP_ONE(int8_t(*pSrc++));
240     currentframeoffset--;
241     }
242     while (copysamples) {
243     COPY_ONE(int8_t(*pSrc++));
244     copysamples--;
245     }
246     break;
247     }
248     }
249    
250     const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
251     const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
252     const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
253     const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
254     }
255    
256    
257 schoenebeck 1113
258     // *************** Other Internal functions ***************
259     // *
260    
261     static split_type_t __resolveSplitType(dimension_t dimension) {
262     return (
263     dimension == dimension_layer ||
264     dimension == dimension_samplechannel ||
265     dimension == dimension_releasetrigger ||
266     dimension == dimension_keyboard ||
267     dimension == dimension_roundrobin ||
268     dimension == dimension_random ||
269     dimension == dimension_smartmidi ||
270     dimension == dimension_roundrobinkeyboard
271     ) ? split_type_bit : split_type_normal;
272     }
273    
274     static int __resolveZoneSize(dimension_def_t& dimension_definition) {
275     return (dimension_definition.split_type == split_type_normal)
276     ? int(128.0 / dimension_definition.zones) : 0;
277     }
278    
279    
280    
281 persson 1199 // *************** CRC ***************
282     // *
283    
284     const uint32_t* CRC::table(initTable());
285    
286     uint32_t* CRC::initTable() {
287     uint32_t* res = new uint32_t[256];
288    
289     for (int i = 0 ; i < 256 ; i++) {
290     uint32_t c = i;
291     for (int j = 0 ; j < 8 ; j++) {
292     c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
293     }
294     res[i] = c;
295     }
296     return res;
297     }
298    
299    
300    
301 schoenebeck 2 // *************** Sample ***************
302     // *
303    
304 schoenebeck 384 unsigned int Sample::Instances = 0;
305     buffer_t Sample::InternalDecompressionBuffer;
306 schoenebeck 2
307 schoenebeck 809 /** @brief Constructor.
308     *
309     * Load an existing sample or create a new one. A 'wave' list chunk must
310     * be given to this constructor. In case the given 'wave' list chunk
311     * contains a 'fmt', 'data' (and optionally a '3gix', 'smpl') chunk, the
312     * format and sample data will be loaded from there, otherwise default
313     * values will be used and those chunks will be created when
314     * File::Save() will be called later on.
315     *
316     * @param pFile - pointer to gig::File where this sample is
317     * located (or will be located)
318     * @param waveList - pointer to 'wave' list chunk which is (or
319     * will be) associated with this sample
320     * @param WavePoolOffset - offset of this sample data from wave pool
321     * ('wvpl') list chunk
322     * @param fileNo - number of an extension file where this sample
323     * is located, 0 otherwise
324     */
325 persson 666 Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
326 persson 1180 static const DLS::Info::FixedStringLength fixedStringLengths[] = {
327     { CHUNK_ID_INAM, 64 },
328     { 0, 0 }
329     };
330     pInfo->FixedStringLengths = fixedStringLengths;
331 schoenebeck 2 Instances++;
332 persson 666 FileNo = fileNo;
333 schoenebeck 2
334 schoenebeck 809 pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
335     if (pCk3gix) {
336 schoenebeck 929 uint16_t iSampleGroup = pCk3gix->ReadInt16();
337 schoenebeck 930 pGroup = pFile->GetGroup(iSampleGroup);
338 schoenebeck 809 } else { // '3gix' chunk missing
339 schoenebeck 930 // by default assigned to that mandatory "Default Group"
340     pGroup = pFile->GetGroup(0);
341 schoenebeck 809 }
342 schoenebeck 2
343 schoenebeck 809 pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
344     if (pCkSmpl) {
345     Manufacturer = pCkSmpl->ReadInt32();
346     Product = pCkSmpl->ReadInt32();
347     SamplePeriod = pCkSmpl->ReadInt32();
348     MIDIUnityNote = pCkSmpl->ReadInt32();
349     FineTune = pCkSmpl->ReadInt32();
350     pCkSmpl->Read(&SMPTEFormat, 1, 4);
351     SMPTEOffset = pCkSmpl->ReadInt32();
352     Loops = pCkSmpl->ReadInt32();
353     pCkSmpl->ReadInt32(); // manufByt
354     LoopID = pCkSmpl->ReadInt32();
355     pCkSmpl->Read(&LoopType, 1, 4);
356     LoopStart = pCkSmpl->ReadInt32();
357     LoopEnd = pCkSmpl->ReadInt32();
358     LoopFraction = pCkSmpl->ReadInt32();
359     LoopPlayCount = pCkSmpl->ReadInt32();
360     } else { // 'smpl' chunk missing
361     // use default values
362     Manufacturer = 0;
363     Product = 0;
364 persson 928 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
365 persson 1218 MIDIUnityNote = 60;
366 schoenebeck 809 FineTune = 0;
367 persson 1182 SMPTEFormat = smpte_format_no_offset;
368 schoenebeck 809 SMPTEOffset = 0;
369     Loops = 0;
370     LoopID = 0;
371 persson 1182 LoopType = loop_type_normal;
372 schoenebeck 809 LoopStart = 0;
373     LoopEnd = 0;
374     LoopFraction = 0;
375     LoopPlayCount = 0;
376     }
377 schoenebeck 2
378     FrameTable = NULL;
379     SamplePos = 0;
380     RAMCache.Size = 0;
381     RAMCache.pStart = NULL;
382     RAMCache.NullExtensionSize = 0;
383    
384 persson 365 if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
385    
386 persson 437 RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
387     Compressed = ewav;
388     Dithered = false;
389     TruncatedBits = 0;
390 schoenebeck 2 if (Compressed) {
391 persson 437 uint32_t version = ewav->ReadInt32();
392     if (version == 3 && BitDepth == 24) {
393     Dithered = ewav->ReadInt32();
394     ewav->SetPos(Channels == 2 ? 84 : 64);
395     TruncatedBits = ewav->ReadInt32();
396     }
397 schoenebeck 2 ScanCompressedSample();
398     }
399 schoenebeck 317
400     // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
401 schoenebeck 384 if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
402     InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
403     InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE;
404 schoenebeck 317 }
405 persson 437 FrameOffset = 0; // just for streaming compressed samples
406 schoenebeck 21
407 persson 864 LoopSize = LoopEnd - LoopStart + 1;
408 schoenebeck 2 }
409    
410 schoenebeck 809 /**
411     * Apply sample and its settings to the respective RIFF chunks. You have
412     * to call File::Save() to make changes persistent.
413     *
414     * Usually there is absolutely no need to call this method explicitly.
415     * It will be called automatically when File::Save() was called.
416     *
417 schoenebeck 1050 * @throws DLS::Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data
418 schoenebeck 809 * was provided yet
419     * @throws gig::Exception if there is any invalid sample setting
420     */
421     void Sample::UpdateChunks() {
422     // first update base class's chunks
423     DLS::Sample::UpdateChunks();
424    
425     // make sure 'smpl' chunk exists
426     pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
427 persson 1182 if (!pCkSmpl) {
428     pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
429     memset(pCkSmpl->LoadChunkData(), 0, 60);
430     }
431 schoenebeck 809 // update 'smpl' chunk
432     uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
433 persson 918 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
434 persson 1179 store32(&pData[0], Manufacturer);
435     store32(&pData[4], Product);
436     store32(&pData[8], SamplePeriod);
437     store32(&pData[12], MIDIUnityNote);
438     store32(&pData[16], FineTune);
439     store32(&pData[20], SMPTEFormat);
440     store32(&pData[24], SMPTEOffset);
441     store32(&pData[28], Loops);
442 schoenebeck 809
443     // we skip 'manufByt' for now (4 bytes)
444    
445 persson 1179 store32(&pData[36], LoopID);
446     store32(&pData[40], LoopType);
447     store32(&pData[44], LoopStart);
448     store32(&pData[48], LoopEnd);
449     store32(&pData[52], LoopFraction);
450     store32(&pData[56], LoopPlayCount);
451 schoenebeck 809
452     // make sure '3gix' chunk exists
453     pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
454     if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
455 schoenebeck 929 // determine appropriate sample group index (to be stored in chunk)
456 schoenebeck 930 uint16_t iSampleGroup = 0; // 0 refers to default sample group
457 schoenebeck 929 File* pFile = static_cast<File*>(pParent);
458     if (pFile->pGroups) {
459     std::list<Group*>::iterator iter = pFile->pGroups->begin();
460     std::list<Group*>::iterator end = pFile->pGroups->end();
461 schoenebeck 930 for (int i = 0; iter != end; i++, iter++) {
462 schoenebeck 929 if (*iter == pGroup) {
463     iSampleGroup = i;
464     break; // found
465     }
466     }
467     }
468 schoenebeck 809 // update '3gix' chunk
469     pData = (uint8_t*) pCk3gix->LoadChunkData();
470 persson 1179 store16(&pData[0], iSampleGroup);
471 schoenebeck 809 }
472    
473 schoenebeck 2 /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
474     void Sample::ScanCompressedSample() {
475     //TODO: we have to add some more scans here (e.g. determine compression rate)
476     this->SamplesTotal = 0;
477     std::list<unsigned long> frameOffsets;
478    
479 persson 365 SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
480 schoenebeck 384 WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
481 persson 365
482 schoenebeck 2 // Scanning
483     pCkData->SetPos(0);
484 persson 365 if (Channels == 2) { // Stereo
485     for (int i = 0 ; ; i++) {
486     // for 24 bit samples every 8:th frame offset is
487     // stored, to save some memory
488     if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
489    
490     const int mode_l = pCkData->ReadUint8();
491     const int mode_r = pCkData->ReadUint8();
492     if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
493     const unsigned long frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
494    
495     if (pCkData->RemainingBytes() <= frameSize) {
496     SamplesInLastFrame =
497     ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
498     (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
499     SamplesTotal += SamplesInLastFrame;
500 schoenebeck 2 break;
501 persson 365 }
502     SamplesTotal += SamplesPerFrame;
503     pCkData->SetPos(frameSize, RIFF::stream_curpos);
504     }
505     }
506     else { // Mono
507     for (int i = 0 ; ; i++) {
508     if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
509    
510     const int mode = pCkData->ReadUint8();
511     if (mode > 5) throw gig::Exception("Unknown compression mode");
512     const unsigned long frameSize = bytesPerFrame[mode];
513    
514     if (pCkData->RemainingBytes() <= frameSize) {
515     SamplesInLastFrame =
516     ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
517     SamplesTotal += SamplesInLastFrame;
518 schoenebeck 2 break;
519 persson 365 }
520     SamplesTotal += SamplesPerFrame;
521     pCkData->SetPos(frameSize, RIFF::stream_curpos);
522 schoenebeck 2 }
523     }
524     pCkData->SetPos(0);
525    
526     // Build the frames table (which is used for fast resolving of a frame's chunk offset)
527     if (FrameTable) delete[] FrameTable;
528     FrameTable = new unsigned long[frameOffsets.size()];
529     std::list<unsigned long>::iterator end = frameOffsets.end();
530     std::list<unsigned long>::iterator iter = frameOffsets.begin();
531     for (int i = 0; iter != end; i++, iter++) {
532     FrameTable[i] = *iter;
533     }
534     }
535    
536     /**
537     * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
538     * ReleaseSampleData() to free the memory if you don't need the cached
539     * sample data anymore.
540     *
541     * @returns buffer_t structure with start address and size of the buffer
542     * in bytes
543     * @see ReleaseSampleData(), Read(), SetPos()
544     */
545     buffer_t Sample::LoadSampleData() {
546     return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
547     }
548    
549     /**
550     * Reads (uncompresses if needed) and caches the first \a SampleCount
551     * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
552     * memory space if you don't need the cached samples anymore. There is no
553     * guarantee that exactly \a SampleCount samples will be cached; this is
554     * not an error. The size will be eventually truncated e.g. to the
555     * beginning of a frame of a compressed sample. This is done for
556     * efficiency reasons while streaming the wave by your sampler engine
557     * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
558     * that will be returned to determine the actual cached samples, but note
559     * that the size is given in bytes! You get the number of actually cached
560     * samples by dividing it by the frame size of the sample:
561 schoenebeck 384 * @code
562 schoenebeck 2 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
563     * long cachedsamples = buf.Size / pSample->FrameSize;
564 schoenebeck 384 * @endcode
565 schoenebeck 2 *
566     * @param SampleCount - number of sample points to load into RAM
567     * @returns buffer_t structure with start address and size of
568     * the cached sample data in bytes
569     * @see ReleaseSampleData(), Read(), SetPos()
570     */
571     buffer_t Sample::LoadSampleData(unsigned long SampleCount) {
572     return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
573     }
574    
575     /**
576     * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
577     * ReleaseSampleData() to free the memory if you don't need the cached
578     * sample data anymore.
579     * The method will add \a NullSamplesCount silence samples past the
580     * official buffer end (this won't affect the 'Size' member of the
581     * buffer_t structure, that means 'Size' always reflects the size of the
582     * actual sample data, the buffer might be bigger though). Silence
583     * samples past the official buffer are needed for differential
584     * algorithms that always have to take subsequent samples into account
585     * (resampling/interpolation would be an important example) and avoids
586     * memory access faults in such cases.
587     *
588     * @param NullSamplesCount - number of silence samples the buffer should
589     * be extended past it's data end
590     * @returns buffer_t structure with start address and
591     * size of the buffer in bytes
592     * @see ReleaseSampleData(), Read(), SetPos()
593     */
594     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
595     return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
596     }
597    
598     /**
599     * Reads (uncompresses if needed) and caches the first \a SampleCount
600     * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
601     * memory space if you don't need the cached samples anymore. There is no
602     * guarantee that exactly \a SampleCount samples will be cached; this is
603     * not an error. The size will be eventually truncated e.g. to the
604     * beginning of a frame of a compressed sample. This is done for
605     * efficiency reasons while streaming the wave by your sampler engine
606     * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
607     * that will be returned to determine the actual cached samples, but note
608     * that the size is given in bytes! You get the number of actually cached
609     * samples by dividing it by the frame size of the sample:
610 schoenebeck 384 * @code
611 schoenebeck 2 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
612     * long cachedsamples = buf.Size / pSample->FrameSize;
613 schoenebeck 384 * @endcode
614 schoenebeck 2 * The method will add \a NullSamplesCount silence samples past the
615     * official buffer end (this won't affect the 'Size' member of the
616     * buffer_t structure, that means 'Size' always reflects the size of the
617     * actual sample data, the buffer might be bigger though). Silence
618     * samples past the official buffer are needed for differential
619     * algorithms that always have to take subsequent samples into account
620     * (resampling/interpolation would be an important example) and avoids
621     * memory access faults in such cases.
622     *
623     * @param SampleCount - number of sample points to load into RAM
624     * @param NullSamplesCount - number of silence samples the buffer should
625     * be extended past it's data end
626     * @returns buffer_t structure with start address and
627     * size of the cached sample data in bytes
628     * @see ReleaseSampleData(), Read(), SetPos()
629     */
630     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount) {
631     if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
632     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
633     unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
634     RAMCache.pStart = new int8_t[allocationsize];
635     RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
636     RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
637     // fill the remaining buffer space with silence samples
638     memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
639     return GetCache();
640     }
641    
642     /**
643     * Returns current cached sample points. A buffer_t structure will be
644     * returned which contains address pointer to the begin of the cache and
645     * the size of the cached sample data in bytes. Use
646     * <i>LoadSampleData()</i> to cache a specific amount of sample points in
647     * RAM.
648     *
649     * @returns buffer_t structure with current cached sample points
650     * @see LoadSampleData();
651     */
652     buffer_t Sample::GetCache() {
653     // return a copy of the buffer_t structure
654     buffer_t result;
655     result.Size = this->RAMCache.Size;
656     result.pStart = this->RAMCache.pStart;
657     result.NullExtensionSize = this->RAMCache.NullExtensionSize;
658     return result;
659     }
660    
661     /**
662     * Frees the cached sample from RAM if loaded with
663     * <i>LoadSampleData()</i> previously.
664     *
665     * @see LoadSampleData();
666     */
667     void Sample::ReleaseSampleData() {
668     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
669     RAMCache.pStart = NULL;
670     RAMCache.Size = 0;
671     }
672    
673 schoenebeck 809 /** @brief Resize sample.
674     *
675     * Resizes the sample's wave form data, that is the actual size of
676     * sample wave data possible to be written for this sample. This call
677     * will return immediately and just schedule the resize operation. You
678     * should call File::Save() to actually perform the resize operation(s)
679     * "physically" to the file. As this can take a while on large files, it
680     * is recommended to call Resize() first on all samples which have to be
681     * resized and finally to call File::Save() to perform all those resize
682     * operations in one rush.
683     *
684     * The actual size (in bytes) is dependant to the current FrameSize
685     * value. You may want to set FrameSize before calling Resize().
686     *
687     * <b>Caution:</b> You cannot directly write (i.e. with Write()) to
688     * enlarged samples before calling File::Save() as this might exceed the
689     * current sample's boundary!
690     *
691 schoenebeck 1050 * Also note: only DLS_WAVE_FORMAT_PCM is currently supported, that is
692     * FormatTag must be DLS_WAVE_FORMAT_PCM. Trying to resize samples with
693 schoenebeck 809 * other formats will fail!
694     *
695     * @param iNewSize - new sample wave data size in sample points (must be
696     * greater than zero)
697 schoenebeck 1050 * @throws DLS::Excecption if FormatTag != DLS_WAVE_FORMAT_PCM
698 schoenebeck 809 * or if \a iNewSize is less than 1
699     * @throws gig::Exception if existing sample is compressed
700     * @see DLS::Sample::GetSize(), DLS::Sample::FrameSize,
701     * DLS::Sample::FormatTag, File::Save()
702     */
703     void Sample::Resize(int iNewSize) {
704     if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
705     DLS::Sample::Resize(iNewSize);
706     }
707    
708 schoenebeck 2 /**
709     * Sets the position within the sample (in sample points, not in
710     * bytes). Use this method and <i>Read()</i> if you don't want to load
711     * the sample into RAM, thus for disk streaming.
712     *
713     * Although the original Gigasampler engine doesn't allow positioning
714     * within compressed samples, I decided to implement it. Even though
715     * the Gigasampler format doesn't allow to define loops for compressed
716     * samples at the moment, positioning within compressed samples might be
717     * interesting for some sampler engines though. The only drawback about
718     * my decision is that it takes longer to load compressed gig Files on
719     * startup, because it's neccessary to scan the samples for some
720     * mandatory informations. But I think as it doesn't affect the runtime
721     * efficiency, nobody will have a problem with that.
722     *
723     * @param SampleCount number of sample points to jump
724     * @param Whence optional: to which relation \a SampleCount refers
725     * to, if omited <i>RIFF::stream_start</i> is assumed
726     * @returns the new sample position
727     * @see Read()
728     */
729     unsigned long Sample::SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence) {
730     if (Compressed) {
731     switch (Whence) {
732     case RIFF::stream_curpos:
733     this->SamplePos += SampleCount;
734     break;
735     case RIFF::stream_end:
736     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
737     break;
738     case RIFF::stream_backward:
739     this->SamplePos -= SampleCount;
740     break;
741     case RIFF::stream_start: default:
742     this->SamplePos = SampleCount;
743     break;
744     }
745     if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
746    
747     unsigned long frame = this->SamplePos / 2048; // to which frame to jump
748     this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
749     pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
750     return this->SamplePos;
751     }
752     else { // not compressed
753     unsigned long orderedBytes = SampleCount * this->FrameSize;
754     unsigned long result = pCkData->SetPos(orderedBytes, Whence);
755     return (result == orderedBytes) ? SampleCount
756     : result / this->FrameSize;
757     }
758     }
759    
760     /**
761     * Returns the current position in the sample (in sample points).
762     */
763     unsigned long Sample::GetPos() {
764     if (Compressed) return SamplePos;
765     else return pCkData->GetPos() / FrameSize;
766     }
767    
768     /**
769 schoenebeck 24 * Reads \a SampleCount number of sample points from the position stored
770     * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
771     * the position within the sample respectively, this method honors the
772     * looping informations of the sample (if any). The sample wave stream
773     * will be decompressed on the fly if using a compressed sample. Use this
774     * method if you don't want to load the sample into RAM, thus for disk
775     * streaming. All this methods needs to know to proceed with streaming
776     * for the next time you call this method is stored in \a pPlaybackState.
777     * You have to allocate and initialize the playback_state_t structure by
778     * yourself before you use it to stream a sample:
779 schoenebeck 384 * @code
780     * gig::playback_state_t playbackstate;
781     * playbackstate.position = 0;
782     * playbackstate.reverse = false;
783     * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
784     * @endcode
785 schoenebeck 24 * You don't have to take care of things like if there is actually a loop
786     * defined or if the current read position is located within a loop area.
787     * The method already handles such cases by itself.
788     *
789 schoenebeck 384 * <b>Caution:</b> If you are using more than one streaming thread, you
790     * have to use an external decompression buffer for <b>EACH</b>
791     * streaming thread to avoid race conditions and crashes!
792     *
793 schoenebeck 24 * @param pBuffer destination buffer
794     * @param SampleCount number of sample points to read
795     * @param pPlaybackState will be used to store and reload the playback
796     * state for the next ReadAndLoop() call
797 persson 864 * @param pDimRgn dimension region with looping information
798 schoenebeck 384 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
799 schoenebeck 24 * @returns number of successfully read sample points
800 schoenebeck 384 * @see CreateDecompressionBuffer()
801 schoenebeck 24 */
802 persson 864 unsigned long Sample::ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState,
803     DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
804 schoenebeck 24 unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
805     uint8_t* pDst = (uint8_t*) pBuffer;
806    
807     SetPos(pPlaybackState->position); // recover position from the last time
808    
809 persson 864 if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
810 schoenebeck 24
811 persson 864 const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
812     const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
813 schoenebeck 24
814 persson 864 if (GetPos() <= loopEnd) {
815     switch (loop.LoopType) {
816 schoenebeck 24
817 persson 864 case loop_type_bidirectional: { //TODO: not tested yet!
818     do {
819     // if not endless loop check if max. number of loop cycles have been passed
820     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
821 schoenebeck 24
822 persson 864 if (!pPlaybackState->reverse) { // forward playback
823     do {
824     samplestoloopend = loopEnd - GetPos();
825     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
826     samplestoread -= readsamples;
827     totalreadsamples += readsamples;
828     if (readsamples == samplestoloopend) {
829     pPlaybackState->reverse = true;
830     break;
831     }
832     } while (samplestoread && readsamples);
833     }
834     else { // backward playback
835 schoenebeck 24
836 persson 864 // as we can only read forward from disk, we have to
837     // determine the end position within the loop first,
838     // read forward from that 'end' and finally after
839     // reading, swap all sample frames so it reflects
840     // backward playback
841 schoenebeck 24
842 persson 864 unsigned long swapareastart = totalreadsamples;
843     unsigned long loopoffset = GetPos() - loop.LoopStart;
844     unsigned long samplestoreadinloop = Min(samplestoread, loopoffset);
845     unsigned long reverseplaybackend = GetPos() - samplestoreadinloop;
846 schoenebeck 24
847 persson 864 SetPos(reverseplaybackend);
848 schoenebeck 24
849 persson 864 // read samples for backward playback
850     do {
851     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
852     samplestoreadinloop -= readsamples;
853     samplestoread -= readsamples;
854     totalreadsamples += readsamples;
855     } while (samplestoreadinloop && readsamples);
856 schoenebeck 24
857 persson 864 SetPos(reverseplaybackend); // pretend we really read backwards
858    
859     if (reverseplaybackend == loop.LoopStart) {
860     pPlaybackState->loop_cycles_left--;
861     pPlaybackState->reverse = false;
862     }
863    
864     // reverse the sample frames for backward playback
865     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
866 schoenebeck 24 }
867 persson 864 } while (samplestoread && readsamples);
868     break;
869     }
870 schoenebeck 24
871 persson 864 case loop_type_backward: { // TODO: not tested yet!
872     // forward playback (not entered the loop yet)
873     if (!pPlaybackState->reverse) do {
874     samplestoloopend = loopEnd - GetPos();
875     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
876     samplestoread -= readsamples;
877     totalreadsamples += readsamples;
878     if (readsamples == samplestoloopend) {
879     pPlaybackState->reverse = true;
880     break;
881     }
882     } while (samplestoread && readsamples);
883 schoenebeck 24
884 persson 864 if (!samplestoread) break;
885 schoenebeck 24
886 persson 864 // as we can only read forward from disk, we have to
887     // determine the end position within the loop first,
888     // read forward from that 'end' and finally after
889     // reading, swap all sample frames so it reflects
890     // backward playback
891 schoenebeck 24
892 persson 864 unsigned long swapareastart = totalreadsamples;
893     unsigned long loopoffset = GetPos() - loop.LoopStart;
894     unsigned long samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
895     : samplestoread;
896     unsigned long reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
897 schoenebeck 24
898 persson 864 SetPos(reverseplaybackend);
899 schoenebeck 24
900 persson 864 // read samples for backward playback
901     do {
902     // if not endless loop check if max. number of loop cycles have been passed
903     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
904     samplestoloopend = loopEnd - GetPos();
905     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
906     samplestoreadinloop -= readsamples;
907     samplestoread -= readsamples;
908     totalreadsamples += readsamples;
909     if (readsamples == samplestoloopend) {
910     pPlaybackState->loop_cycles_left--;
911     SetPos(loop.LoopStart);
912     }
913     } while (samplestoreadinloop && readsamples);
914 schoenebeck 24
915 persson 864 SetPos(reverseplaybackend); // pretend we really read backwards
916 schoenebeck 24
917 persson 864 // reverse the sample frames for backward playback
918     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
919     break;
920     }
921 schoenebeck 24
922 persson 864 default: case loop_type_normal: {
923     do {
924     // if not endless loop check if max. number of loop cycles have been passed
925     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
926     samplestoloopend = loopEnd - GetPos();
927     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
928     samplestoread -= readsamples;
929     totalreadsamples += readsamples;
930     if (readsamples == samplestoloopend) {
931     pPlaybackState->loop_cycles_left--;
932     SetPos(loop.LoopStart);
933     }
934     } while (samplestoread && readsamples);
935     break;
936     }
937 schoenebeck 24 }
938     }
939     }
940    
941     // read on without looping
942     if (samplestoread) do {
943 schoenebeck 384 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
944 schoenebeck 24 samplestoread -= readsamples;
945     totalreadsamples += readsamples;
946     } while (readsamples && samplestoread);
947    
948     // store current position
949     pPlaybackState->position = GetPos();
950    
951     return totalreadsamples;
952     }
953    
954     /**
955 schoenebeck 2 * Reads \a SampleCount number of sample points from the current
956     * position into the buffer pointed by \a pBuffer and increments the
957     * position within the sample. The sample wave stream will be
958     * decompressed on the fly if using a compressed sample. Use this method
959     * and <i>SetPos()</i> if you don't want to load the sample into RAM,
960     * thus for disk streaming.
961     *
962 schoenebeck 384 * <b>Caution:</b> If you are using more than one streaming thread, you
963     * have to use an external decompression buffer for <b>EACH</b>
964     * streaming thread to avoid race conditions and crashes!
965     *
966 persson 902 * For 16 bit samples, the data in the buffer will be int16_t
967     * (using native endianness). For 24 bit, the buffer will
968     * contain three bytes per sample, little-endian.
969     *
970 schoenebeck 2 * @param pBuffer destination buffer
971     * @param SampleCount number of sample points to read
972 schoenebeck 384 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
973 schoenebeck 2 * @returns number of successfully read sample points
974 schoenebeck 384 * @see SetPos(), CreateDecompressionBuffer()
975 schoenebeck 2 */
976 schoenebeck 384 unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer) {
977 schoenebeck 21 if (SampleCount == 0) return 0;
978 schoenebeck 317 if (!Compressed) {
979     if (BitDepth == 24) {
980 persson 902 return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
981 schoenebeck 317 }
982 persson 365 else { // 16 bit
983     // (pCkData->Read does endian correction)
984     return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
985     : pCkData->Read(pBuffer, SampleCount, 2);
986     }
987 schoenebeck 317 }
988 persson 365 else {
989 schoenebeck 11 if (this->SamplePos >= this->SamplesTotal) return 0;
990 persson 365 //TODO: efficiency: maybe we should test for an average compression rate
991     unsigned long assumedsize = GuessSize(SampleCount),
992 schoenebeck 2 remainingbytes = 0, // remaining bytes in the local buffer
993     remainingsamples = SampleCount,
994 persson 365 copysamples, skipsamples,
995     currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
996 schoenebeck 2 this->FrameOffset = 0;
997    
998 schoenebeck 384 buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
999    
1000     // if decompression buffer too small, then reduce amount of samples to read
1001     if (pDecompressionBuffer->Size < assumedsize) {
1002     std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1003     SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1004     remainingsamples = SampleCount;
1005     assumedsize = GuessSize(SampleCount);
1006 schoenebeck 2 }
1007    
1008 schoenebeck 384 unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1009 persson 365 int16_t* pDst = static_cast<int16_t*>(pBuffer);
1010 persson 902 uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1011 schoenebeck 2 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1012    
1013 persson 365 while (remainingsamples && remainingbytes) {
1014     unsigned long framesamples = SamplesPerFrame;
1015     unsigned long framebytes, rightChannelOffset = 0, nextFrameOffset;
1016 schoenebeck 2
1017 persson 365 int mode_l = *pSrc++, mode_r = 0;
1018    
1019     if (Channels == 2) {
1020     mode_r = *pSrc++;
1021     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1022     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1023     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1024     if (remainingbytes < framebytes) { // last frame in sample
1025     framesamples = SamplesInLastFrame;
1026     if (mode_l == 4 && (framesamples & 1)) {
1027     rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1028     }
1029     else {
1030     rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1031     }
1032 schoenebeck 2 }
1033     }
1034 persson 365 else {
1035     framebytes = bytesPerFrame[mode_l] + 1;
1036     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1037     if (remainingbytes < framebytes) {
1038     framesamples = SamplesInLastFrame;
1039     }
1040     }
1041 schoenebeck 2
1042     // determine how many samples in this frame to skip and read
1043 persson 365 if (currentframeoffset + remainingsamples >= framesamples) {
1044     if (currentframeoffset <= framesamples) {
1045     copysamples = framesamples - currentframeoffset;
1046     skipsamples = currentframeoffset;
1047     }
1048     else {
1049     copysamples = 0;
1050     skipsamples = framesamples;
1051     }
1052 schoenebeck 2 }
1053     else {
1054 persson 365 // This frame has enough data for pBuffer, but not
1055     // all of the frame is needed. Set file position
1056     // to start of this frame for next call to Read.
1057 schoenebeck 2 copysamples = remainingsamples;
1058 persson 365 skipsamples = currentframeoffset;
1059     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1060     this->FrameOffset = currentframeoffset + copysamples;
1061     }
1062     remainingsamples -= copysamples;
1063    
1064     if (remainingbytes > framebytes) {
1065     remainingbytes -= framebytes;
1066     if (remainingsamples == 0 &&
1067     currentframeoffset + copysamples == framesamples) {
1068     // This frame has enough data for pBuffer, and
1069     // all of the frame is needed. Set file
1070     // position to start of next frame for next
1071     // call to Read. FrameOffset is 0.
1072 schoenebeck 2 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1073     }
1074     }
1075 persson 365 else remainingbytes = 0;
1076 schoenebeck 2
1077 persson 365 currentframeoffset -= skipsamples;
1078 schoenebeck 2
1079 persson 365 if (copysamples == 0) {
1080     // skip this frame
1081     pSrc += framebytes - Channels;
1082     }
1083     else {
1084     const unsigned char* const param_l = pSrc;
1085     if (BitDepth == 24) {
1086     if (mode_l != 2) pSrc += 12;
1087 schoenebeck 2
1088 persson 365 if (Channels == 2) { // Stereo
1089     const unsigned char* const param_r = pSrc;
1090     if (mode_r != 2) pSrc += 12;
1091    
1092 persson 902 Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1093 persson 437 skipsamples, copysamples, TruncatedBits);
1094 persson 902 Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1095 persson 437 skipsamples, copysamples, TruncatedBits);
1096 persson 902 pDst24 += copysamples * 6;
1097 schoenebeck 2 }
1098 persson 365 else { // Mono
1099 persson 902 Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1100 persson 437 skipsamples, copysamples, TruncatedBits);
1101 persson 902 pDst24 += copysamples * 3;
1102 schoenebeck 2 }
1103 persson 365 }
1104     else { // 16 bit
1105     if (mode_l) pSrc += 4;
1106 schoenebeck 2
1107 persson 365 int step;
1108     if (Channels == 2) { // Stereo
1109     const unsigned char* const param_r = pSrc;
1110     if (mode_r) pSrc += 4;
1111    
1112     step = (2 - mode_l) + (2 - mode_r);
1113 persson 372 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1114     Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1115 persson 365 skipsamples, copysamples);
1116     pDst += copysamples << 1;
1117 schoenebeck 2 }
1118 persson 365 else { // Mono
1119     step = 2 - mode_l;
1120 persson 372 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1121 persson 365 pDst += copysamples;
1122 schoenebeck 2 }
1123 persson 365 }
1124     pSrc += nextFrameOffset;
1125     }
1126 schoenebeck 2
1127 persson 365 // reload from disk to local buffer if needed
1128     if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1129     assumedsize = GuessSize(remainingsamples);
1130     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1131     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1132 schoenebeck 384 remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1133     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1134 schoenebeck 2 }
1135 persson 365 } // while
1136    
1137 schoenebeck 2 this->SamplePos += (SampleCount - remainingsamples);
1138 schoenebeck 11 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1139 schoenebeck 2 return (SampleCount - remainingsamples);
1140     }
1141     }
1142    
1143 schoenebeck 809 /** @brief Write sample wave data.
1144     *
1145     * Writes \a SampleCount number of sample points from the buffer pointed
1146     * by \a pBuffer and increments the position within the sample. Use this
1147     * method to directly write the sample data to disk, i.e. if you don't
1148     * want or cannot load the whole sample data into RAM.
1149     *
1150     * You have to Resize() the sample to the desired size and call
1151     * File::Save() <b>before</b> using Write().
1152     *
1153     * Note: there is currently no support for writing compressed samples.
1154     *
1155 persson 1264 * For 16 bit samples, the data in the source buffer should be
1156     * int16_t (using native endianness). For 24 bit, the buffer
1157     * should contain three bytes per sample, little-endian.
1158     *
1159 schoenebeck 809 * @param pBuffer - source buffer
1160     * @param SampleCount - number of sample points to write
1161     * @throws DLS::Exception if current sample size is too small
1162     * @throws gig::Exception if sample is compressed
1163     * @see DLS::LoadSampleData()
1164     */
1165     unsigned long Sample::Write(void* pBuffer, unsigned long SampleCount) {
1166     if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1167 persson 1207
1168     // if this is the first write in this sample, reset the
1169     // checksum calculator
1170 persson 1199 if (pCkData->GetPos() == 0) {
1171     crc.reset();
1172     }
1173 persson 1264 if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1174     unsigned long res;
1175     if (BitDepth == 24) {
1176     res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1177     } else { // 16 bit
1178     res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1179     : pCkData->Write(pBuffer, SampleCount, 2);
1180     }
1181 persson 1199 crc.update((unsigned char *)pBuffer, SampleCount * FrameSize);
1182    
1183 persson 1207 // if this is the last write, update the checksum chunk in the
1184     // file
1185 persson 1199 if (pCkData->GetPos() == pCkData->GetSize()) {
1186     File* pFile = static_cast<File*>(GetParent());
1187     pFile->SetSampleChecksum(this, crc.getValue());
1188     }
1189     return res;
1190 schoenebeck 809 }
1191    
1192 schoenebeck 384 /**
1193     * Allocates a decompression buffer for streaming (compressed) samples
1194     * with Sample::Read(). If you are using more than one streaming thread
1195     * in your application you <b>HAVE</b> to create a decompression buffer
1196     * for <b>EACH</b> of your streaming threads and provide it with the
1197     * Sample::Read() call in order to avoid race conditions and crashes.
1198     *
1199     * You should free the memory occupied by the allocated buffer(s) once
1200     * you don't need one of your streaming threads anymore by calling
1201     * DestroyDecompressionBuffer().
1202     *
1203     * @param MaxReadSize - the maximum size (in sample points) you ever
1204     * expect to read with one Read() call
1205     * @returns allocated decompression buffer
1206     * @see DestroyDecompressionBuffer()
1207     */
1208     buffer_t Sample::CreateDecompressionBuffer(unsigned long MaxReadSize) {
1209     buffer_t result;
1210     const double worstCaseHeaderOverhead =
1211     (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1212     result.Size = (unsigned long) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1213     result.pStart = new int8_t[result.Size];
1214     result.NullExtensionSize = 0;
1215     return result;
1216     }
1217    
1218     /**
1219     * Free decompression buffer, previously created with
1220     * CreateDecompressionBuffer().
1221     *
1222     * @param DecompressionBuffer - previously allocated decompression
1223     * buffer to free
1224     */
1225     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1226     if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1227     delete[] (int8_t*) DecompressionBuffer.pStart;
1228     DecompressionBuffer.pStart = NULL;
1229     DecompressionBuffer.Size = 0;
1230     DecompressionBuffer.NullExtensionSize = 0;
1231     }
1232     }
1233    
1234 schoenebeck 930 /**
1235     * Returns pointer to the Group this Sample belongs to. In the .gig
1236     * format a sample always belongs to one group. If it wasn't explicitly
1237     * assigned to a certain group, it will be automatically assigned to a
1238     * default group.
1239     *
1240     * @returns Sample's Group (never NULL)
1241     */
1242     Group* Sample::GetGroup() const {
1243     return pGroup;
1244     }
1245    
1246 schoenebeck 2 Sample::~Sample() {
1247     Instances--;
1248 schoenebeck 384 if (!Instances && InternalDecompressionBuffer.Size) {
1249     delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1250     InternalDecompressionBuffer.pStart = NULL;
1251     InternalDecompressionBuffer.Size = 0;
1252 schoenebeck 355 }
1253 schoenebeck 2 if (FrameTable) delete[] FrameTable;
1254     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1255     }
1256    
1257    
1258    
1259     // *************** DimensionRegion ***************
1260     // *
1261    
1262 schoenebeck 16 uint DimensionRegion::Instances = 0;
1263     DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1264    
1265 schoenebeck 1316 DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1266 schoenebeck 16 Instances++;
1267    
1268 schoenebeck 823 pSample = NULL;
1269 schoenebeck 1316 pRegion = pParent;
1270 schoenebeck 823
1271 persson 1247 if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1272     else memset(&Crossfade, 0, 4);
1273    
1274 schoenebeck 16 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1275 schoenebeck 2
1276     RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1277 schoenebeck 809 if (_3ewa) { // if '3ewa' chunk exists
1278 persson 918 _3ewa->ReadInt32(); // unknown, always == chunk size ?
1279 schoenebeck 809 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1280     EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1281     _3ewa->ReadInt16(); // unknown
1282     LFO1InternalDepth = _3ewa->ReadUint16();
1283     _3ewa->ReadInt16(); // unknown
1284     LFO3InternalDepth = _3ewa->ReadInt16();
1285     _3ewa->ReadInt16(); // unknown
1286     LFO1ControlDepth = _3ewa->ReadUint16();
1287     _3ewa->ReadInt16(); // unknown
1288     LFO3ControlDepth = _3ewa->ReadInt16();
1289     EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1290     EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1291     _3ewa->ReadInt16(); // unknown
1292     EG1Sustain = _3ewa->ReadUint16();
1293     EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1294     EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1295     uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1296     EG1ControllerInvert = eg1ctrloptions & 0x01;
1297     EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1298     EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1299     EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1300     EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1301     uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1302     EG2ControllerInvert = eg2ctrloptions & 0x01;
1303     EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1304     EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1305     EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1306     LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1307     EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1308     EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1309     _3ewa->ReadInt16(); // unknown
1310     EG2Sustain = _3ewa->ReadUint16();
1311     EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1312     _3ewa->ReadInt16(); // unknown
1313     LFO2ControlDepth = _3ewa->ReadUint16();
1314     LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1315     _3ewa->ReadInt16(); // unknown
1316     LFO2InternalDepth = _3ewa->ReadUint16();
1317     int32_t eg1decay2 = _3ewa->ReadInt32();
1318     EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1319     EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1320     _3ewa->ReadInt16(); // unknown
1321     EG1PreAttack = _3ewa->ReadUint16();
1322     int32_t eg2decay2 = _3ewa->ReadInt32();
1323     EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1324     EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1325     _3ewa->ReadInt16(); // unknown
1326     EG2PreAttack = _3ewa->ReadUint16();
1327     uint8_t velocityresponse = _3ewa->ReadUint8();
1328     if (velocityresponse < 5) {
1329     VelocityResponseCurve = curve_type_nonlinear;
1330     VelocityResponseDepth = velocityresponse;
1331     } else if (velocityresponse < 10) {
1332     VelocityResponseCurve = curve_type_linear;
1333     VelocityResponseDepth = velocityresponse - 5;
1334     } else if (velocityresponse < 15) {
1335     VelocityResponseCurve = curve_type_special;
1336     VelocityResponseDepth = velocityresponse - 10;
1337     } else {
1338     VelocityResponseCurve = curve_type_unknown;
1339     VelocityResponseDepth = 0;
1340     }
1341     uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1342     if (releasevelocityresponse < 5) {
1343     ReleaseVelocityResponseCurve = curve_type_nonlinear;
1344     ReleaseVelocityResponseDepth = releasevelocityresponse;
1345     } else if (releasevelocityresponse < 10) {
1346     ReleaseVelocityResponseCurve = curve_type_linear;
1347     ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1348     } else if (releasevelocityresponse < 15) {
1349     ReleaseVelocityResponseCurve = curve_type_special;
1350     ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1351     } else {
1352     ReleaseVelocityResponseCurve = curve_type_unknown;
1353     ReleaseVelocityResponseDepth = 0;
1354     }
1355     VelocityResponseCurveScaling = _3ewa->ReadUint8();
1356     AttenuationControllerThreshold = _3ewa->ReadInt8();
1357     _3ewa->ReadInt32(); // unknown
1358     SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1359     _3ewa->ReadInt16(); // unknown
1360     uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1361     PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1362     if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1363     else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1364     else DimensionBypass = dim_bypass_ctrl_none;
1365     uint8_t pan = _3ewa->ReadUint8();
1366     Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1367     SelfMask = _3ewa->ReadInt8() & 0x01;
1368     _3ewa->ReadInt8(); // unknown
1369     uint8_t lfo3ctrl = _3ewa->ReadUint8();
1370     LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1371     LFO3Sync = lfo3ctrl & 0x20; // bit 5
1372     InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1373     AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1374     uint8_t lfo2ctrl = _3ewa->ReadUint8();
1375     LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1376     LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1377     LFO2Sync = lfo2ctrl & 0x20; // bit 5
1378     bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1379     uint8_t lfo1ctrl = _3ewa->ReadUint8();
1380     LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1381     LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1382     LFO1Sync = lfo1ctrl & 0x40; // bit 6
1383     VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1384     : vcf_res_ctrl_none;
1385     uint16_t eg3depth = _3ewa->ReadUint16();
1386     EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1387     : (-1) * (int16_t) ((eg3depth ^ 0xffff) + 1); /* binary complementary for negatives */
1388     _3ewa->ReadInt16(); // unknown
1389     ChannelOffset = _3ewa->ReadUint8() / 4;
1390     uint8_t regoptions = _3ewa->ReadUint8();
1391     MSDecode = regoptions & 0x01; // bit 0
1392     SustainDefeat = regoptions & 0x02; // bit 1
1393     _3ewa->ReadInt16(); // unknown
1394     VelocityUpperLimit = _3ewa->ReadInt8();
1395     _3ewa->ReadInt8(); // unknown
1396     _3ewa->ReadInt16(); // unknown
1397     ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1398     _3ewa->ReadInt8(); // unknown
1399     _3ewa->ReadInt8(); // unknown
1400     EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1401     uint8_t vcfcutoff = _3ewa->ReadUint8();
1402     VCFEnabled = vcfcutoff & 0x80; // bit 7
1403     VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1404     VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1405     uint8_t vcfvelscale = _3ewa->ReadUint8();
1406     VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1407     VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1408     _3ewa->ReadInt8(); // unknown
1409     uint8_t vcfresonance = _3ewa->ReadUint8();
1410     VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1411     VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1412     uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1413     VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1414     VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1415     uint8_t vcfvelocity = _3ewa->ReadUint8();
1416     VCFVelocityDynamicRange = vcfvelocity % 5;
1417     VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1418     VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1419     if (VCFType == vcf_type_lowpass) {
1420     if (lfo3ctrl & 0x40) // bit 6
1421     VCFType = vcf_type_lowpassturbo;
1422     }
1423 persson 1070 if (_3ewa->RemainingBytes() >= 8) {
1424     _3ewa->Read(DimensionUpperLimits, 1, 8);
1425     } else {
1426     memset(DimensionUpperLimits, 0, 8);
1427     }
1428 schoenebeck 809 } else { // '3ewa' chunk does not exist yet
1429     // use default values
1430     LFO3Frequency = 1.0;
1431     EG3Attack = 0.0;
1432     LFO1InternalDepth = 0;
1433     LFO3InternalDepth = 0;
1434     LFO1ControlDepth = 0;
1435     LFO3ControlDepth = 0;
1436     EG1Attack = 0.0;
1437 persson 1218 EG1Decay1 = 0.005;
1438     EG1Sustain = 1000;
1439     EG1Release = 0.3;
1440 schoenebeck 809 EG1Controller.type = eg1_ctrl_t::type_none;
1441     EG1Controller.controller_number = 0;
1442     EG1ControllerInvert = false;
1443     EG1ControllerAttackInfluence = 0;
1444     EG1ControllerDecayInfluence = 0;
1445     EG1ControllerReleaseInfluence = 0;
1446     EG2Controller.type = eg2_ctrl_t::type_none;
1447     EG2Controller.controller_number = 0;
1448     EG2ControllerInvert = false;
1449     EG2ControllerAttackInfluence = 0;
1450     EG2ControllerDecayInfluence = 0;
1451     EG2ControllerReleaseInfluence = 0;
1452     LFO1Frequency = 1.0;
1453     EG2Attack = 0.0;
1454 persson 1218 EG2Decay1 = 0.005;
1455     EG2Sustain = 1000;
1456     EG2Release = 0.3;
1457 schoenebeck 809 LFO2ControlDepth = 0;
1458     LFO2Frequency = 1.0;
1459     LFO2InternalDepth = 0;
1460     EG1Decay2 = 0.0;
1461 persson 1218 EG1InfiniteSustain = true;
1462     EG1PreAttack = 0;
1463 schoenebeck 809 EG2Decay2 = 0.0;
1464 persson 1218 EG2InfiniteSustain = true;
1465     EG2PreAttack = 0;
1466 schoenebeck 809 VelocityResponseCurve = curve_type_nonlinear;
1467     VelocityResponseDepth = 3;
1468     ReleaseVelocityResponseCurve = curve_type_nonlinear;
1469     ReleaseVelocityResponseDepth = 3;
1470     VelocityResponseCurveScaling = 32;
1471     AttenuationControllerThreshold = 0;
1472     SampleStartOffset = 0;
1473     PitchTrack = true;
1474     DimensionBypass = dim_bypass_ctrl_none;
1475     Pan = 0;
1476     SelfMask = true;
1477     LFO3Controller = lfo3_ctrl_modwheel;
1478     LFO3Sync = false;
1479     InvertAttenuationController = false;
1480     AttenuationController.type = attenuation_ctrl_t::type_none;
1481     AttenuationController.controller_number = 0;
1482     LFO2Controller = lfo2_ctrl_internal;
1483     LFO2FlipPhase = false;
1484     LFO2Sync = false;
1485     LFO1Controller = lfo1_ctrl_internal;
1486     LFO1FlipPhase = false;
1487     LFO1Sync = false;
1488     VCFResonanceController = vcf_res_ctrl_none;
1489     EG3Depth = 0;
1490     ChannelOffset = 0;
1491     MSDecode = false;
1492     SustainDefeat = false;
1493     VelocityUpperLimit = 0;
1494     ReleaseTriggerDecay = 0;
1495     EG1Hold = false;
1496     VCFEnabled = false;
1497     VCFCutoff = 0;
1498     VCFCutoffController = vcf_cutoff_ctrl_none;
1499     VCFCutoffControllerInvert = false;
1500     VCFVelocityScale = 0;
1501     VCFResonance = 0;
1502     VCFResonanceDynamic = false;
1503     VCFKeyboardTracking = false;
1504     VCFKeyboardTrackingBreakpoint = 0;
1505     VCFVelocityDynamicRange = 0x04;
1506     VCFVelocityCurve = curve_type_linear;
1507     VCFType = vcf_type_lowpass;
1508 persson 1247 memset(DimensionUpperLimits, 127, 8);
1509 schoenebeck 2 }
1510 schoenebeck 16
1511 persson 613 pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1512     VelocityResponseDepth,
1513     VelocityResponseCurveScaling);
1514    
1515     curve_type_t curveType = ReleaseVelocityResponseCurve;
1516     uint8_t depth = ReleaseVelocityResponseDepth;
1517    
1518     // this models a strange behaviour or bug in GSt: two of the
1519     // velocity response curves for release time are not used even
1520     // if specified, instead another curve is chosen.
1521     if ((curveType == curve_type_nonlinear && depth == 0) ||
1522     (curveType == curve_type_special && depth == 4)) {
1523     curveType = curve_type_nonlinear;
1524     depth = 3;
1525     }
1526     pVelocityReleaseTable = GetVelocityTable(curveType, depth, 0);
1527    
1528 persson 728 curveType = VCFVelocityCurve;
1529     depth = VCFVelocityDynamicRange;
1530    
1531     // even stranger GSt: two of the velocity response curves for
1532     // filter cutoff are not used, instead another special curve
1533     // is chosen. This curve is not used anywhere else.
1534     if ((curveType == curve_type_nonlinear && depth == 0) ||
1535     (curveType == curve_type_special && depth == 4)) {
1536     curveType = curve_type_special;
1537     depth = 5;
1538     }
1539     pVelocityCutoffTable = GetVelocityTable(curveType, depth,
1540 persson 773 VCFCutoffController <= vcf_cutoff_ctrl_none2 ? VCFVelocityScale : 0);
1541 persson 728
1542 persson 613 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1543 persson 858 VelocityTable = 0;
1544 persson 613 }
1545    
1546 persson 1301 /*
1547     * Constructs a DimensionRegion by copying all parameters from
1548     * another DimensionRegion
1549     */
1550     DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1551     Instances++;
1552     *this = src; // default memberwise shallow copy of all parameters
1553     pParentList = _3ewl; // restore the chunk pointer
1554    
1555     // deep copy of owned structures
1556     if (src.VelocityTable) {
1557     VelocityTable = new uint8_t[128];
1558     for (int k = 0 ; k < 128 ; k++)
1559     VelocityTable[k] = src.VelocityTable[k];
1560     }
1561     if (src.pSampleLoops) {
1562     pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1563     for (int k = 0 ; k < src.SampleLoops ; k++)
1564     pSampleLoops[k] = src.pSampleLoops[k];
1565     }
1566     }
1567    
1568 schoenebeck 809 /**
1569     * Apply dimension region settings to the respective RIFF chunks. You
1570     * have to call File::Save() to make changes persistent.
1571     *
1572     * Usually there is absolutely no need to call this method explicitly.
1573     * It will be called automatically when File::Save() was called.
1574     */
1575     void DimensionRegion::UpdateChunks() {
1576     // first update base class's chunk
1577     DLS::Sampler::UpdateChunks();
1578    
1579 persson 1247 RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1580     uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1581     pData[12] = Crossfade.in_start;
1582     pData[13] = Crossfade.in_end;
1583     pData[14] = Crossfade.out_start;
1584     pData[15] = Crossfade.out_end;
1585    
1586 schoenebeck 809 // make sure '3ewa' chunk exists
1587     RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1588 persson 1317 if (!_3ewa) {
1589     File* pFile = (File*) GetParent()->GetParent()->GetParent();
1590     bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1591     _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1592 persson 1264 }
1593 persson 1247 pData = (uint8_t*) _3ewa->LoadChunkData();
1594 schoenebeck 809
1595     // update '3ewa' chunk with DimensionRegion's current settings
1596    
1597 persson 1182 const uint32_t chunksize = _3ewa->GetNewSize();
1598 persson 1179 store32(&pData[0], chunksize); // unknown, always chunk size?
1599 schoenebeck 809
1600     const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1601 persson 1179 store32(&pData[4], lfo3freq);
1602 schoenebeck 809
1603     const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1604 persson 1179 store32(&pData[8], eg3attack);
1605 schoenebeck 809
1606     // next 2 bytes unknown
1607    
1608 persson 1179 store16(&pData[14], LFO1InternalDepth);
1609 schoenebeck 809
1610     // next 2 bytes unknown
1611    
1612 persson 1179 store16(&pData[18], LFO3InternalDepth);
1613 schoenebeck 809
1614     // next 2 bytes unknown
1615    
1616 persson 1179 store16(&pData[22], LFO1ControlDepth);
1617 schoenebeck 809
1618     // next 2 bytes unknown
1619    
1620 persson 1179 store16(&pData[26], LFO3ControlDepth);
1621 schoenebeck 809
1622     const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
1623 persson 1179 store32(&pData[28], eg1attack);
1624 schoenebeck 809
1625     const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
1626 persson 1179 store32(&pData[32], eg1decay1);
1627 schoenebeck 809
1628     // next 2 bytes unknown
1629    
1630 persson 1179 store16(&pData[38], EG1Sustain);
1631 schoenebeck 809
1632     const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
1633 persson 1179 store32(&pData[40], eg1release);
1634 schoenebeck 809
1635     const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
1636 persson 1179 pData[44] = eg1ctl;
1637 schoenebeck 809
1638     const uint8_t eg1ctrloptions =
1639 persson 1266 (EG1ControllerInvert ? 0x01 : 0x00) |
1640 schoenebeck 809 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
1641     GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
1642     GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
1643 persson 1179 pData[45] = eg1ctrloptions;
1644 schoenebeck 809
1645     const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
1646 persson 1179 pData[46] = eg2ctl;
1647 schoenebeck 809
1648     const uint8_t eg2ctrloptions =
1649 persson 1266 (EG2ControllerInvert ? 0x01 : 0x00) |
1650 schoenebeck 809 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
1651     GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
1652     GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
1653 persson 1179 pData[47] = eg2ctrloptions;
1654 schoenebeck 809
1655     const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
1656 persson 1179 store32(&pData[48], lfo1freq);
1657 schoenebeck 809
1658     const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
1659 persson 1179 store32(&pData[52], eg2attack);
1660 schoenebeck 809
1661     const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
1662 persson 1179 store32(&pData[56], eg2decay1);
1663 schoenebeck 809
1664     // next 2 bytes unknown
1665    
1666 persson 1179 store16(&pData[62], EG2Sustain);
1667 schoenebeck 809
1668     const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
1669 persson 1179 store32(&pData[64], eg2release);
1670 schoenebeck 809
1671     // next 2 bytes unknown
1672    
1673 persson 1179 store16(&pData[70], LFO2ControlDepth);
1674 schoenebeck 809
1675     const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
1676 persson 1179 store32(&pData[72], lfo2freq);
1677 schoenebeck 809
1678     // next 2 bytes unknown
1679    
1680 persson 1179 store16(&pData[78], LFO2InternalDepth);
1681 schoenebeck 809
1682     const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
1683 persson 1179 store32(&pData[80], eg1decay2);
1684 schoenebeck 809
1685     // next 2 bytes unknown
1686    
1687 persson 1179 store16(&pData[86], EG1PreAttack);
1688 schoenebeck 809
1689     const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
1690 persson 1179 store32(&pData[88], eg2decay2);
1691 schoenebeck 809
1692     // next 2 bytes unknown
1693    
1694 persson 1179 store16(&pData[94], EG2PreAttack);
1695 schoenebeck 809
1696     {
1697     if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
1698     uint8_t velocityresponse = VelocityResponseDepth;
1699     switch (VelocityResponseCurve) {
1700     case curve_type_nonlinear:
1701     break;
1702     case curve_type_linear:
1703     velocityresponse += 5;
1704     break;
1705     case curve_type_special:
1706     velocityresponse += 10;
1707     break;
1708     case curve_type_unknown:
1709     default:
1710     throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
1711     }
1712 persson 1179 pData[96] = velocityresponse;
1713 schoenebeck 809 }
1714    
1715     {
1716     if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
1717     uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
1718     switch (ReleaseVelocityResponseCurve) {
1719     case curve_type_nonlinear:
1720     break;
1721     case curve_type_linear:
1722     releasevelocityresponse += 5;
1723     break;
1724     case curve_type_special:
1725     releasevelocityresponse += 10;
1726     break;
1727     case curve_type_unknown:
1728     default:
1729     throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
1730     }
1731 persson 1179 pData[97] = releasevelocityresponse;
1732 schoenebeck 809 }
1733    
1734 persson 1179 pData[98] = VelocityResponseCurveScaling;
1735 schoenebeck 809
1736 persson 1179 pData[99] = AttenuationControllerThreshold;
1737 schoenebeck 809
1738     // next 4 bytes unknown
1739    
1740 persson 1179 store16(&pData[104], SampleStartOffset);
1741 schoenebeck 809
1742     // next 2 bytes unknown
1743    
1744     {
1745     uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
1746     switch (DimensionBypass) {
1747     case dim_bypass_ctrl_94:
1748     pitchTrackDimensionBypass |= 0x10;
1749     break;
1750     case dim_bypass_ctrl_95:
1751     pitchTrackDimensionBypass |= 0x20;
1752     break;
1753     case dim_bypass_ctrl_none:
1754     //FIXME: should we set anything here?
1755     break;
1756     default:
1757     throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
1758     }
1759 persson 1179 pData[108] = pitchTrackDimensionBypass;
1760 schoenebeck 809 }
1761    
1762     const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
1763 persson 1179 pData[109] = pan;
1764 schoenebeck 809
1765     const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
1766 persson 1179 pData[110] = selfmask;
1767 schoenebeck 809
1768     // next byte unknown
1769    
1770     {
1771     uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
1772     if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
1773     if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
1774     if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
1775 persson 1179 pData[112] = lfo3ctrl;
1776 schoenebeck 809 }
1777    
1778     const uint8_t attenctl = EncodeLeverageController(AttenuationController);
1779 persson 1179 pData[113] = attenctl;
1780 schoenebeck 809
1781     {
1782     uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
1783     if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
1784     if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
1785     if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
1786 persson 1179 pData[114] = lfo2ctrl;
1787 schoenebeck 809 }
1788    
1789     {
1790     uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
1791     if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
1792     if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
1793     if (VCFResonanceController != vcf_res_ctrl_none)
1794     lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
1795 persson 1179 pData[115] = lfo1ctrl;
1796 schoenebeck 809 }
1797    
1798     const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1799     : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
1800 persson 1179 pData[116] = eg3depth;
1801 schoenebeck 809
1802     // next 2 bytes unknown
1803    
1804     const uint8_t channeloffset = ChannelOffset * 4;
1805 persson 1179 pData[120] = channeloffset;
1806 schoenebeck 809
1807     {
1808     uint8_t regoptions = 0;
1809     if (MSDecode) regoptions |= 0x01; // bit 0
1810     if (SustainDefeat) regoptions |= 0x02; // bit 1
1811 persson 1179 pData[121] = regoptions;
1812 schoenebeck 809 }
1813    
1814     // next 2 bytes unknown
1815    
1816 persson 1179 pData[124] = VelocityUpperLimit;
1817 schoenebeck 809
1818     // next 3 bytes unknown
1819    
1820 persson 1179 pData[128] = ReleaseTriggerDecay;
1821 schoenebeck 809
1822     // next 2 bytes unknown
1823    
1824     const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
1825 persson 1179 pData[131] = eg1hold;
1826 schoenebeck 809
1827 persson 1266 const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
1828 persson 918 (VCFCutoff & 0x7f); /* lower 7 bits */
1829 persson 1179 pData[132] = vcfcutoff;
1830 schoenebeck 809
1831 persson 1179 pData[133] = VCFCutoffController;
1832 schoenebeck 809
1833 persson 1266 const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
1834 persson 918 (VCFVelocityScale & 0x7f); /* lower 7 bits */
1835 persson 1179 pData[134] = vcfvelscale;
1836 schoenebeck 809
1837     // next byte unknown
1838    
1839 persson 1266 const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
1840 persson 918 (VCFResonance & 0x7f); /* lower 7 bits */
1841 persson 1179 pData[136] = vcfresonance;
1842 schoenebeck 809
1843 persson 1266 const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
1844 persson 918 (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
1845 persson 1179 pData[137] = vcfbreakpoint;
1846 schoenebeck 809
1847     const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |
1848     VCFVelocityCurve * 5;
1849 persson 1179 pData[138] = vcfvelocity;
1850 schoenebeck 809
1851     const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
1852 persson 1179 pData[139] = vcftype;
1853 persson 1070
1854     if (chunksize >= 148) {
1855     memcpy(&pData[140], DimensionUpperLimits, 8);
1856     }
1857 schoenebeck 809 }
1858    
1859 persson 613 // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
1860     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
1861     {
1862     double* table;
1863     uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
1864 schoenebeck 16 if (pVelocityTables->count(tableKey)) { // if key exists
1865 persson 613 table = (*pVelocityTables)[tableKey];
1866 schoenebeck 16 }
1867     else {
1868 persson 613 table = CreateVelocityTable(curveType, depth, scaling);
1869     (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
1870 schoenebeck 16 }
1871 persson 613 return table;
1872 schoenebeck 2 }
1873 schoenebeck 55
1874 schoenebeck 1316 Region* DimensionRegion::GetParent() const {
1875     return pRegion;
1876     }
1877    
1878 schoenebeck 36 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
1879     leverage_ctrl_t decodedcontroller;
1880     switch (EncodedController) {
1881     // special controller
1882     case _lev_ctrl_none:
1883     decodedcontroller.type = leverage_ctrl_t::type_none;
1884     decodedcontroller.controller_number = 0;
1885     break;
1886     case _lev_ctrl_velocity:
1887     decodedcontroller.type = leverage_ctrl_t::type_velocity;
1888     decodedcontroller.controller_number = 0;
1889     break;
1890     case _lev_ctrl_channelaftertouch:
1891     decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
1892     decodedcontroller.controller_number = 0;
1893     break;
1894 schoenebeck 55
1895 schoenebeck 36 // ordinary MIDI control change controller
1896     case _lev_ctrl_modwheel:
1897     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1898     decodedcontroller.controller_number = 1;
1899     break;
1900     case _lev_ctrl_breath:
1901     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1902     decodedcontroller.controller_number = 2;
1903     break;
1904     case _lev_ctrl_foot:
1905     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1906     decodedcontroller.controller_number = 4;
1907     break;
1908     case _lev_ctrl_effect1:
1909     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1910     decodedcontroller.controller_number = 12;
1911     break;
1912     case _lev_ctrl_effect2:
1913     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1914     decodedcontroller.controller_number = 13;
1915     break;
1916     case _lev_ctrl_genpurpose1:
1917     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1918     decodedcontroller.controller_number = 16;
1919     break;
1920     case _lev_ctrl_genpurpose2:
1921     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1922     decodedcontroller.controller_number = 17;
1923     break;
1924     case _lev_ctrl_genpurpose3:
1925     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1926     decodedcontroller.controller_number = 18;
1927     break;
1928     case _lev_ctrl_genpurpose4:
1929     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1930     decodedcontroller.controller_number = 19;
1931     break;
1932     case _lev_ctrl_portamentotime:
1933     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1934     decodedcontroller.controller_number = 5;
1935     break;
1936     case _lev_ctrl_sustainpedal:
1937     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1938     decodedcontroller.controller_number = 64;
1939     break;
1940     case _lev_ctrl_portamento:
1941     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1942     decodedcontroller.controller_number = 65;
1943     break;
1944     case _lev_ctrl_sostenutopedal:
1945     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1946     decodedcontroller.controller_number = 66;
1947     break;
1948     case _lev_ctrl_softpedal:
1949     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1950     decodedcontroller.controller_number = 67;
1951     break;
1952     case _lev_ctrl_genpurpose5:
1953     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1954     decodedcontroller.controller_number = 80;
1955     break;
1956     case _lev_ctrl_genpurpose6:
1957     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1958     decodedcontroller.controller_number = 81;
1959     break;
1960     case _lev_ctrl_genpurpose7:
1961     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1962     decodedcontroller.controller_number = 82;
1963     break;
1964     case _lev_ctrl_genpurpose8:
1965     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1966     decodedcontroller.controller_number = 83;
1967     break;
1968     case _lev_ctrl_effect1depth:
1969     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1970     decodedcontroller.controller_number = 91;
1971     break;
1972     case _lev_ctrl_effect2depth:
1973     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1974     decodedcontroller.controller_number = 92;
1975     break;
1976     case _lev_ctrl_effect3depth:
1977     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1978     decodedcontroller.controller_number = 93;
1979     break;
1980     case _lev_ctrl_effect4depth:
1981     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1982     decodedcontroller.controller_number = 94;
1983     break;
1984     case _lev_ctrl_effect5depth:
1985     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
1986     decodedcontroller.controller_number = 95;
1987     break;
1988 schoenebeck 55
1989 schoenebeck 36 // unknown controller type
1990     default:
1991     throw gig::Exception("Unknown leverage controller type.");
1992     }
1993     return decodedcontroller;
1994     }
1995 schoenebeck 2
1996 schoenebeck 809 DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
1997     _lev_ctrl_t encodedcontroller;
1998     switch (DecodedController.type) {
1999     // special controller
2000     case leverage_ctrl_t::type_none:
2001     encodedcontroller = _lev_ctrl_none;
2002     break;
2003     case leverage_ctrl_t::type_velocity:
2004     encodedcontroller = _lev_ctrl_velocity;
2005     break;
2006     case leverage_ctrl_t::type_channelaftertouch:
2007     encodedcontroller = _lev_ctrl_channelaftertouch;
2008     break;
2009    
2010     // ordinary MIDI control change controller
2011     case leverage_ctrl_t::type_controlchange:
2012     switch (DecodedController.controller_number) {
2013     case 1:
2014     encodedcontroller = _lev_ctrl_modwheel;
2015     break;
2016     case 2:
2017     encodedcontroller = _lev_ctrl_breath;
2018     break;
2019     case 4:
2020     encodedcontroller = _lev_ctrl_foot;
2021     break;
2022     case 12:
2023     encodedcontroller = _lev_ctrl_effect1;
2024     break;
2025     case 13:
2026     encodedcontroller = _lev_ctrl_effect2;
2027     break;
2028     case 16:
2029     encodedcontroller = _lev_ctrl_genpurpose1;
2030     break;
2031     case 17:
2032     encodedcontroller = _lev_ctrl_genpurpose2;
2033     break;
2034     case 18:
2035     encodedcontroller = _lev_ctrl_genpurpose3;
2036     break;
2037     case 19:
2038     encodedcontroller = _lev_ctrl_genpurpose4;
2039     break;
2040     case 5:
2041     encodedcontroller = _lev_ctrl_portamentotime;
2042     break;
2043     case 64:
2044     encodedcontroller = _lev_ctrl_sustainpedal;
2045     break;
2046     case 65:
2047     encodedcontroller = _lev_ctrl_portamento;
2048     break;
2049     case 66:
2050     encodedcontroller = _lev_ctrl_sostenutopedal;
2051     break;
2052     case 67:
2053     encodedcontroller = _lev_ctrl_softpedal;
2054     break;
2055     case 80:
2056     encodedcontroller = _lev_ctrl_genpurpose5;
2057     break;
2058     case 81:
2059     encodedcontroller = _lev_ctrl_genpurpose6;
2060     break;
2061     case 82:
2062     encodedcontroller = _lev_ctrl_genpurpose7;
2063     break;
2064     case 83:
2065     encodedcontroller = _lev_ctrl_genpurpose8;
2066     break;
2067     case 91:
2068     encodedcontroller = _lev_ctrl_effect1depth;
2069     break;
2070     case 92:
2071     encodedcontroller = _lev_ctrl_effect2depth;
2072     break;
2073     case 93:
2074     encodedcontroller = _lev_ctrl_effect3depth;
2075     break;
2076     case 94:
2077     encodedcontroller = _lev_ctrl_effect4depth;
2078     break;
2079     case 95:
2080     encodedcontroller = _lev_ctrl_effect5depth;
2081     break;
2082     default:
2083     throw gig::Exception("leverage controller number is not supported by the gig format");
2084     }
2085 persson 1182 break;
2086 schoenebeck 809 default:
2087     throw gig::Exception("Unknown leverage controller type.");
2088     }
2089     return encodedcontroller;
2090     }
2091    
2092 schoenebeck 16 DimensionRegion::~DimensionRegion() {
2093     Instances--;
2094     if (!Instances) {
2095     // delete the velocity->volume tables
2096     VelocityTableMap::iterator iter;
2097     for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
2098     double* pTable = iter->second;
2099     if (pTable) delete[] pTable;
2100     }
2101     pVelocityTables->clear();
2102     delete pVelocityTables;
2103     pVelocityTables = NULL;
2104     }
2105 persson 858 if (VelocityTable) delete[] VelocityTable;
2106 schoenebeck 16 }
2107 schoenebeck 2
2108 schoenebeck 16 /**
2109     * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
2110     * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
2111     * and VelocityResponseCurveScaling) involved are taken into account to
2112     * calculate the amplitude factor. Use this method when a key was
2113     * triggered to get the volume with which the sample should be played
2114     * back.
2115     *
2116 schoenebeck 36 * @param MIDIKeyVelocity MIDI velocity value of the triggered key (between 0 and 127)
2117     * @returns amplitude factor (between 0.0 and 1.0)
2118 schoenebeck 16 */
2119     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
2120     return pVelocityAttenuationTable[MIDIKeyVelocity];
2121     }
2122 schoenebeck 2
2123 persson 613 double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
2124     return pVelocityReleaseTable[MIDIKeyVelocity];
2125     }
2126    
2127 persson 728 double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
2128     return pVelocityCutoffTable[MIDIKeyVelocity];
2129     }
2130    
2131 schoenebeck 308 double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
2132 schoenebeck 317
2133 schoenebeck 308 // line-segment approximations of the 15 velocity curves
2134 schoenebeck 16
2135 schoenebeck 308 // linear
2136     const int lin0[] = { 1, 1, 127, 127 };
2137     const int lin1[] = { 1, 21, 127, 127 };
2138     const int lin2[] = { 1, 45, 127, 127 };
2139     const int lin3[] = { 1, 74, 127, 127 };
2140     const int lin4[] = { 1, 127, 127, 127 };
2141 schoenebeck 16
2142 schoenebeck 308 // non-linear
2143     const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
2144 schoenebeck 317 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
2145 schoenebeck 308 127, 127 };
2146     const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
2147     127, 127 };
2148     const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
2149     127, 127 };
2150     const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
2151 schoenebeck 317
2152 schoenebeck 308 // special
2153 schoenebeck 317 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
2154 schoenebeck 308 113, 127, 127, 127 };
2155     const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
2156     118, 127, 127, 127 };
2157 schoenebeck 317 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
2158 schoenebeck 308 85, 90, 91, 127, 127, 127 };
2159 schoenebeck 317 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
2160 schoenebeck 308 117, 127, 127, 127 };
2161 schoenebeck 317 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
2162 schoenebeck 308 127, 127 };
2163 schoenebeck 317
2164 persson 728 // this is only used by the VCF velocity curve
2165     const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
2166     91, 127, 127, 127 };
2167    
2168 schoenebeck 308 const int* const curves[] = { non0, non1, non2, non3, non4,
2169 schoenebeck 317 lin0, lin1, lin2, lin3, lin4,
2170 persson 728 spe0, spe1, spe2, spe3, spe4, spe5 };
2171 schoenebeck 317
2172 schoenebeck 308 double* const table = new double[128];
2173    
2174     const int* curve = curves[curveType * 5 + depth];
2175     const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
2176 schoenebeck 317
2177 schoenebeck 308 table[0] = 0;
2178     for (int x = 1 ; x < 128 ; x++) {
2179    
2180     if (x > curve[2]) curve += 2;
2181 schoenebeck 317 double y = curve[1] + (x - curve[0]) *
2182 schoenebeck 308 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
2183     y = y / 127;
2184    
2185     // Scale up for s > 20, down for s < 20. When
2186     // down-scaling, the curve still ends at 1.0.
2187     if (s < 20 && y >= 0.5)
2188     y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
2189     else
2190     y = y * (s / 20.0);
2191     if (y > 1) y = 1;
2192    
2193     table[x] = y;
2194     }
2195     return table;
2196     }
2197    
2198    
2199 schoenebeck 2 // *************** Region ***************
2200     // *
2201    
2202     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
2203     // Initialization
2204     Dimensions = 0;
2205 schoenebeck 347 for (int i = 0; i < 256; i++) {
2206 schoenebeck 2 pDimensionRegions[i] = NULL;
2207     }
2208 schoenebeck 282 Layers = 1;
2209 schoenebeck 347 File* file = (File*) GetParent()->GetParent();
2210     int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
2211 schoenebeck 2
2212     // Actual Loading
2213    
2214     LoadDimensionRegions(rgnList);
2215    
2216     RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
2217     if (_3lnk) {
2218     DimensionRegions = _3lnk->ReadUint32();
2219 schoenebeck 347 for (int i = 0; i < dimensionBits; i++) {
2220 schoenebeck 2 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
2221     uint8_t bits = _3lnk->ReadUint8();
2222 persson 1199 _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
2223     _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
2224 persson 774 uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
2225 schoenebeck 2 if (dimension == dimension_none) { // inactive dimension
2226     pDimensionDefinitions[i].dimension = dimension_none;
2227     pDimensionDefinitions[i].bits = 0;
2228     pDimensionDefinitions[i].zones = 0;
2229     pDimensionDefinitions[i].split_type = split_type_bit;
2230     pDimensionDefinitions[i].zone_size = 0;
2231     }
2232     else { // active dimension
2233     pDimensionDefinitions[i].dimension = dimension;
2234     pDimensionDefinitions[i].bits = bits;
2235 persson 774 pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
2236 schoenebeck 1113 pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
2237     pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
2238 schoenebeck 2 Dimensions++;
2239 schoenebeck 282
2240     // if this is a layer dimension, remember the amount of layers
2241     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
2242 schoenebeck 2 }
2243 persson 774 _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
2244 schoenebeck 2 }
2245 persson 834 for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
2246 schoenebeck 2
2247 persson 858 // if there's a velocity dimension and custom velocity zone splits are used,
2248     // update the VelocityTables in the dimension regions
2249     UpdateVelocityTable();
2250 schoenebeck 2
2251 schoenebeck 317 // jump to start of the wave pool indices (if not already there)
2252     if (file->pVersion && file->pVersion->major == 3)
2253     _3lnk->SetPos(68); // version 3 has a different 3lnk structure
2254     else
2255     _3lnk->SetPos(44);
2256    
2257 schoenebeck 2 // load sample references
2258     for (uint i = 0; i < DimensionRegions; i++) {
2259     uint32_t wavepoolindex = _3lnk->ReadUint32();
2260 persson 902 if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
2261 schoenebeck 2 }
2262 persson 918 GetSample(); // load global region sample reference
2263 persson 1102 } else {
2264     DimensionRegions = 0;
2265 persson 1182 for (int i = 0 ; i < 8 ; i++) {
2266     pDimensionDefinitions[i].dimension = dimension_none;
2267     pDimensionDefinitions[i].bits = 0;
2268     pDimensionDefinitions[i].zones = 0;
2269     }
2270 schoenebeck 2 }
2271 schoenebeck 823
2272     // make sure there is at least one dimension region
2273     if (!DimensionRegions) {
2274     RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
2275     if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
2276     RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
2277 schoenebeck 1316 pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
2278 schoenebeck 823 DimensionRegions = 1;
2279     }
2280 schoenebeck 2 }
2281    
2282 schoenebeck 809 /**
2283     * Apply Region settings and all its DimensionRegions to the respective
2284     * RIFF chunks. You have to call File::Save() to make changes persistent.
2285     *
2286     * Usually there is absolutely no need to call this method explicitly.
2287     * It will be called automatically when File::Save() was called.
2288     *
2289     * @throws gig::Exception if samples cannot be dereferenced
2290     */
2291     void Region::UpdateChunks() {
2292 schoenebeck 1106 // in the gig format we don't care about the Region's sample reference
2293     // but we still have to provide some existing one to not corrupt the
2294     // file, so to avoid the latter we simply always assign the sample of
2295     // the first dimension region of this region
2296     pSample = pDimensionRegions[0]->pSample;
2297    
2298 schoenebeck 809 // first update base class's chunks
2299     DLS::Region::UpdateChunks();
2300    
2301     // update dimension region's chunks
2302 schoenebeck 823 for (int i = 0; i < DimensionRegions; i++) {
2303 persson 1317 pDimensionRegions[i]->UpdateChunks();
2304 schoenebeck 823 }
2305 schoenebeck 809
2306 persson 1317 File* pFile = (File*) GetParent()->GetParent();
2307     bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
2308 persson 1247 const int iMaxDimensions = version3 ? 8 : 5;
2309     const int iMaxDimensionRegions = version3 ? 256 : 32;
2310 schoenebeck 809
2311     // make sure '3lnk' chunk exists
2312     RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
2313     if (!_3lnk) {
2314 persson 1247 const int _3lnkChunkSize = version3 ? 1092 : 172;
2315 schoenebeck 809 _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
2316 persson 1182 memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
2317 persson 1192
2318     // move 3prg to last position
2319     pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), 0);
2320 schoenebeck 809 }
2321    
2322     // update dimension definitions in '3lnk' chunk
2323     uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
2324 persson 1179 store32(&pData[0], DimensionRegions);
2325 persson 1199 int shift = 0;
2326 schoenebeck 809 for (int i = 0; i < iMaxDimensions; i++) {
2327 persson 918 pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
2328     pData[5 + i * 8] = pDimensionDefinitions[i].bits;
2329 persson 1266 pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
2330 persson 1199 pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
2331 persson 918 pData[8 + i * 8] = pDimensionDefinitions[i].zones;
2332 persson 1199 // next 3 bytes unknown, always zero?
2333    
2334     shift += pDimensionDefinitions[i].bits;
2335 schoenebeck 809 }
2336    
2337     // update wave pool table in '3lnk' chunk
2338 persson 1247 const int iWavePoolOffset = version3 ? 68 : 44;
2339 schoenebeck 809 for (uint i = 0; i < iMaxDimensionRegions; i++) {
2340     int iWaveIndex = -1;
2341     if (i < DimensionRegions) {
2342 schoenebeck 823 if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
2343     File::SampleList::iterator iter = pFile->pSamples->begin();
2344     File::SampleList::iterator end = pFile->pSamples->end();
2345 schoenebeck 809 for (int index = 0; iter != end; ++iter, ++index) {
2346 schoenebeck 823 if (*iter == pDimensionRegions[i]->pSample) {
2347     iWaveIndex = index;
2348     break;
2349     }
2350 schoenebeck 809 }
2351     }
2352 persson 1179 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
2353 schoenebeck 809 }
2354     }
2355    
2356 schoenebeck 2 void Region::LoadDimensionRegions(RIFF::List* rgn) {
2357     RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
2358     if (_3prg) {
2359     int dimensionRegionNr = 0;
2360     RIFF::List* _3ewl = _3prg->GetFirstSubList();
2361     while (_3ewl) {
2362     if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
2363 schoenebeck 1316 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
2364 schoenebeck 2 dimensionRegionNr++;
2365     }
2366     _3ewl = _3prg->GetNextSubList();
2367     }
2368     if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
2369     }
2370     }
2371    
2372 schoenebeck 1335 void Region::SetKeyRange(uint16_t Low, uint16_t High) {
2373     // update KeyRange struct and make sure regions are in correct order
2374     DLS::Region::SetKeyRange(Low, High);
2375     // update Region key table for fast lookup
2376     ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
2377     }
2378    
2379 persson 858 void Region::UpdateVelocityTable() {
2380     // get velocity dimension's index
2381     int veldim = -1;
2382     for (int i = 0 ; i < Dimensions ; i++) {
2383     if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
2384     veldim = i;
2385 schoenebeck 809 break;
2386     }
2387     }
2388 persson 858 if (veldim == -1) return;
2389 schoenebeck 809
2390 persson 858 int step = 1;
2391     for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
2392     int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
2393     int end = step * pDimensionDefinitions[veldim].zones;
2394 schoenebeck 809
2395 persson 858 // loop through all dimension regions for all dimensions except the velocity dimension
2396     int dim[8] = { 0 };
2397     for (int i = 0 ; i < DimensionRegions ; i++) {
2398    
2399 persson 1070 if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
2400     pDimensionRegions[i]->VelocityUpperLimit) {
2401 persson 858 // create the velocity table
2402     uint8_t* table = pDimensionRegions[i]->VelocityTable;
2403     if (!table) {
2404     table = new uint8_t[128];
2405     pDimensionRegions[i]->VelocityTable = table;
2406     }
2407     int tableidx = 0;
2408     int velocityZone = 0;
2409 persson 1070 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
2410     for (int k = i ; k < end ; k += step) {
2411     DimensionRegion *d = pDimensionRegions[k];
2412     for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
2413     velocityZone++;
2414     }
2415     } else { // gig2
2416     for (int k = i ; k < end ; k += step) {
2417     DimensionRegion *d = pDimensionRegions[k];
2418     for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
2419     velocityZone++;
2420     }
2421 persson 858 }
2422     } else {
2423     if (pDimensionRegions[i]->VelocityTable) {
2424     delete[] pDimensionRegions[i]->VelocityTable;
2425     pDimensionRegions[i]->VelocityTable = 0;
2426     }
2427 schoenebeck 809 }
2428 persson 858
2429     int j;
2430     int shift = 0;
2431     for (j = 0 ; j < Dimensions ; j++) {
2432     if (j == veldim) i += skipveldim; // skip velocity dimension
2433     else {
2434     dim[j]++;
2435     if (dim[j] < pDimensionDefinitions[j].zones) break;
2436     else {
2437     // skip unused dimension regions
2438     dim[j] = 0;
2439     i += ((1 << pDimensionDefinitions[j].bits) -
2440     pDimensionDefinitions[j].zones) << shift;
2441     }
2442     }
2443     shift += pDimensionDefinitions[j].bits;
2444     }
2445     if (j == Dimensions) break;
2446 schoenebeck 809 }
2447     }
2448    
2449     /** @brief Einstein would have dreamed of it - create a new dimension.
2450     *
2451     * Creates a new dimension with the dimension definition given by
2452     * \a pDimDef. The appropriate amount of DimensionRegions will be created.
2453     * There is a hard limit of dimensions and total amount of "bits" all
2454     * dimensions can have. This limit is dependant to what gig file format
2455     * version this file refers to. The gig v2 (and lower) format has a
2456     * dimension limit and total amount of bits limit of 5, whereas the gig v3
2457     * format has a limit of 8.
2458     *
2459     * @param pDimDef - defintion of the new dimension
2460     * @throws gig::Exception if dimension of the same type exists already
2461     * @throws gig::Exception if amount of dimensions or total amount of
2462     * dimension bits limit is violated
2463     */
2464     void Region::AddDimension(dimension_def_t* pDimDef) {
2465     // check if max. amount of dimensions reached
2466     File* file = (File*) GetParent()->GetParent();
2467     const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
2468     if (Dimensions >= iMaxDimensions)
2469     throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
2470     // check if max. amount of dimension bits reached
2471     int iCurrentBits = 0;
2472     for (int i = 0; i < Dimensions; i++)
2473     iCurrentBits += pDimensionDefinitions[i].bits;
2474     if (iCurrentBits >= iMaxDimensions)
2475     throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
2476     const int iNewBits = iCurrentBits + pDimDef->bits;
2477     if (iNewBits > iMaxDimensions)
2478     throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
2479     // check if there's already a dimensions of the same type
2480     for (int i = 0; i < Dimensions; i++)
2481     if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
2482     throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
2483    
2484 persson 1301 // pos is where the new dimension should be placed, normally
2485     // last in list, except for the samplechannel dimension which
2486     // has to be first in list
2487     int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
2488     int bitpos = 0;
2489     for (int i = 0 ; i < pos ; i++)
2490     bitpos += pDimensionDefinitions[i].bits;
2491    
2492     // make room for the new dimension
2493     for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
2494     for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
2495     for (int j = Dimensions ; j > pos ; j--) {
2496     pDimensionRegions[i]->DimensionUpperLimits[j] =
2497     pDimensionRegions[i]->DimensionUpperLimits[j - 1];
2498     }
2499     }
2500    
2501 schoenebeck 809 // assign definition of new dimension
2502 persson 1301 pDimensionDefinitions[pos] = *pDimDef;
2503 schoenebeck 809
2504 schoenebeck 1113 // auto correct certain dimension definition fields (where possible)
2505 persson 1301 pDimensionDefinitions[pos].split_type =
2506     __resolveSplitType(pDimensionDefinitions[pos].dimension);
2507     pDimensionDefinitions[pos].zone_size =
2508     __resolveZoneSize(pDimensionDefinitions[pos]);
2509 schoenebeck 1113
2510 persson 1301 // create new dimension region(s) for this new dimension, and make
2511     // sure that the dimension regions are placed correctly in both the
2512     // RIFF list and the pDimensionRegions array
2513     RIFF::Chunk* moveTo = NULL;
2514     RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
2515     for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
2516     for (int k = 0 ; k < (1 << bitpos) ; k++) {
2517     pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
2518     }
2519     for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
2520     for (int k = 0 ; k < (1 << bitpos) ; k++) {
2521     RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
2522     if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
2523     // create a new dimension region and copy all parameter values from
2524     // an existing dimension region
2525     pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
2526     new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
2527 persson 1247
2528 persson 1301 DimensionRegions++;
2529     }
2530     }
2531     moveTo = pDimensionRegions[i]->pParentList;
2532 schoenebeck 809 }
2533    
2534 persson 1247 // initialize the upper limits for this dimension
2535 persson 1301 int mask = (1 << bitpos) - 1;
2536     for (int z = 0 ; z < pDimDef->zones ; z++) {
2537 persson 1264 uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
2538 persson 1247 for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
2539 persson 1301 pDimensionRegions[((i & ~mask) << pDimDef->bits) |
2540     (z << bitpos) |
2541     (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
2542 persson 1247 }
2543     }
2544    
2545 schoenebeck 809 Dimensions++;
2546    
2547     // if this is a layer dimension, update 'Layers' attribute
2548     if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
2549    
2550 persson 858 UpdateVelocityTable();
2551 schoenebeck 809 }
2552    
2553     /** @brief Delete an existing dimension.
2554     *
2555     * Deletes the dimension given by \a pDimDef and deletes all respective
2556     * dimension regions, that is all dimension regions where the dimension's
2557     * bit(s) part is greater than 0. In case of a 'sustain pedal' dimension
2558     * for example this would delete all dimension regions for the case(s)
2559     * where the sustain pedal is pressed down.
2560     *
2561     * @param pDimDef - dimension to delete
2562     * @throws gig::Exception if given dimension cannot be found
2563     */
2564     void Region::DeleteDimension(dimension_def_t* pDimDef) {
2565     // get dimension's index
2566     int iDimensionNr = -1;
2567     for (int i = 0; i < Dimensions; i++) {
2568     if (&pDimensionDefinitions[i] == pDimDef) {
2569     iDimensionNr = i;
2570     break;
2571     }
2572     }
2573     if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
2574    
2575     // get amount of bits below the dimension to delete
2576     int iLowerBits = 0;
2577     for (int i = 0; i < iDimensionNr; i++)
2578     iLowerBits += pDimensionDefinitions[i].bits;
2579    
2580     // get amount ot bits above the dimension to delete
2581     int iUpperBits = 0;
2582     for (int i = iDimensionNr + 1; i < Dimensions; i++)
2583     iUpperBits += pDimensionDefinitions[i].bits;
2584    
2585 persson 1247 RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
2586    
2587 schoenebeck 809 // delete dimension regions which belong to the given dimension
2588     // (that is where the dimension's bit > 0)
2589     for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
2590     for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
2591     for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
2592     int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
2593     iObsoleteBit << iLowerBits |
2594     iLowerBit;
2595 persson 1247
2596     _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
2597 schoenebeck 809 delete pDimensionRegions[iToDelete];
2598     pDimensionRegions[iToDelete] = NULL;
2599     DimensionRegions--;
2600     }
2601     }
2602     }
2603    
2604     // defrag pDimensionRegions array
2605     // (that is remove the NULL spaces within the pDimensionRegions array)
2606     for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
2607     if (!pDimensionRegions[iTo]) {
2608     if (iFrom <= iTo) iFrom = iTo + 1;
2609     while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
2610     if (iFrom < 256 && pDimensionRegions[iFrom]) {
2611     pDimensionRegions[iTo] = pDimensionRegions[iFrom];
2612     pDimensionRegions[iFrom] = NULL;
2613     }
2614     }
2615     }
2616    
2617 persson 1247 // remove the this dimension from the upper limits arrays
2618     for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
2619     DimensionRegion* d = pDimensionRegions[j];
2620     for (int i = iDimensionNr + 1; i < Dimensions; i++) {
2621     d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
2622     }
2623     d->DimensionUpperLimits[Dimensions - 1] = 127;
2624     }
2625    
2626 schoenebeck 809 // 'remove' dimension definition
2627     for (int i = iDimensionNr + 1; i < Dimensions; i++) {
2628     pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
2629     }
2630     pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
2631     pDimensionDefinitions[Dimensions - 1].bits = 0;
2632     pDimensionDefinitions[Dimensions - 1].zones = 0;
2633    
2634     Dimensions--;
2635    
2636     // if this was a layer dimension, update 'Layers' attribute
2637     if (pDimDef->dimension == dimension_layer) Layers = 1;
2638     }
2639    
2640 schoenebeck 2 Region::~Region() {
2641 schoenebeck 350 for (int i = 0; i < 256; i++) {
2642 schoenebeck 2 if (pDimensionRegions[i]) delete pDimensionRegions[i];
2643     }
2644     }
2645    
2646     /**
2647     * Use this method in your audio engine to get the appropriate dimension
2648     * region with it's articulation data for the current situation. Just
2649     * call the method with the current MIDI controller values and you'll get
2650     * the DimensionRegion with the appropriate articulation data for the
2651     * current situation (for this Region of course only). To do that you'll
2652     * first have to look which dimensions with which controllers and in
2653     * which order are defined for this Region when you load the .gig file.
2654     * Special cases are e.g. layer or channel dimensions where you just put
2655     * in the index numbers instead of a MIDI controller value (means 0 for
2656     * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
2657     * etc.).
2658     *
2659 schoenebeck 347 * @param DimValues MIDI controller values (0-127) for dimension 0 to 7
2660 schoenebeck 2 * @returns adress to the DimensionRegion for the given situation
2661     * @see pDimensionDefinitions
2662     * @see Dimensions
2663     */
2664 schoenebeck 347 DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
2665 persson 858 uint8_t bits;
2666     int veldim = -1;
2667     int velbitpos;
2668     int bitpos = 0;
2669     int dimregidx = 0;
2670 schoenebeck 2 for (uint i = 0; i < Dimensions; i++) {
2671 persson 858 if (pDimensionDefinitions[i].dimension == dimension_velocity) {
2672     // the velocity dimension must be handled after the other dimensions
2673     veldim = i;
2674     velbitpos = bitpos;
2675     } else {
2676     switch (pDimensionDefinitions[i].split_type) {
2677     case split_type_normal:
2678 persson 1070 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
2679     // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
2680     for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
2681     if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
2682     }
2683     } else {
2684     // gig2: evenly sized zones
2685     bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
2686     }
2687 persson 858 break;
2688     case split_type_bit: // the value is already the sought dimension bit number
2689     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
2690     bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
2691     break;
2692     }
2693     dimregidx |= bits << bitpos;
2694 schoenebeck 2 }
2695 persson 858 bitpos += pDimensionDefinitions[i].bits;
2696 schoenebeck 2 }
2697 persson 858 DimensionRegion* dimreg = pDimensionRegions[dimregidx];
2698     if (veldim != -1) {
2699     // (dimreg is now the dimension region for the lowest velocity)
2700 persson 1070 if (dimreg->VelocityTable) // custom defined zone ranges
2701 persson 858 bits = dimreg->VelocityTable[DimValues[veldim]];
2702     else // normal split type
2703     bits = uint8_t(DimValues[veldim] / pDimensionDefinitions[veldim].zone_size);
2704    
2705     dimregidx |= bits << velbitpos;
2706     dimreg = pDimensionRegions[dimregidx];
2707     }
2708     return dimreg;
2709 schoenebeck 2 }
2710    
2711     /**
2712     * Returns the appropriate DimensionRegion for the given dimension bit
2713     * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
2714     * instead of calling this method directly!
2715     *
2716 schoenebeck 347 * @param DimBits Bit numbers for dimension 0 to 7
2717 schoenebeck 2 * @returns adress to the DimensionRegion for the given dimension
2718     * bit numbers
2719     * @see GetDimensionRegionByValue()
2720     */
2721 schoenebeck 347 DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
2722     return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
2723     << pDimensionDefinitions[5].bits | DimBits[5])
2724     << pDimensionDefinitions[4].bits | DimBits[4])
2725     << pDimensionDefinitions[3].bits | DimBits[3])
2726     << pDimensionDefinitions[2].bits | DimBits[2])
2727     << pDimensionDefinitions[1].bits | DimBits[1])
2728     << pDimensionDefinitions[0].bits | DimBits[0]];
2729 schoenebeck 2 }
2730    
2731     /**
2732     * Returns pointer address to the Sample referenced with this region.
2733     * This is the global Sample for the entire Region (not sure if this is
2734     * actually used by the Gigasampler engine - I would only use the Sample
2735     * referenced by the appropriate DimensionRegion instead of this sample).
2736     *
2737     * @returns address to Sample or NULL if there is no reference to a
2738     * sample saved in the .gig file
2739     */
2740     Sample* Region::GetSample() {
2741     if (pSample) return static_cast<gig::Sample*>(pSample);
2742     else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
2743     }
2744    
2745 schoenebeck 515 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
2746 schoenebeck 352 if ((int32_t)WavePoolTableIndex == -1) return NULL;
2747 schoenebeck 2 File* file = (File*) GetParent()->GetParent();
2748 persson 902 if (!file->pWavePoolTable) return NULL;
2749 schoenebeck 2 unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
2750 persson 666 unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
2751 schoenebeck 515 Sample* sample = file->GetFirstSample(pProgress);
2752 schoenebeck 2 while (sample) {
2753 persson 666 if (sample->ulWavePoolOffset == soughtoffset &&
2754 persson 918 sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
2755 schoenebeck 2 sample = file->GetNextSample();
2756     }
2757     return NULL;
2758     }
2759    
2760    
2761    
2762     // *************** Instrument ***************
2763     // *
2764    
2765 schoenebeck 515 Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
2766 persson 1180 static const DLS::Info::FixedStringLength fixedStringLengths[] = {
2767     { CHUNK_ID_INAM, 64 },
2768     { CHUNK_ID_ISFT, 12 },
2769     { 0, 0 }
2770     };
2771     pInfo->FixedStringLengths = fixedStringLengths;
2772 persson 918
2773 schoenebeck 2 // Initialization
2774     for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
2775 persson 1182 EffectSend = 0;
2776     Attenuation = 0;
2777     FineTune = 0;
2778     PitchbendRange = 0;
2779     PianoReleaseMode = false;
2780     DimensionKeyRange.low = 0;
2781     DimensionKeyRange.high = 0;
2782 schoenebeck 2
2783     // Loading
2784     RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
2785     if (lart) {
2786     RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
2787     if (_3ewg) {
2788     EffectSend = _3ewg->ReadUint16();
2789     Attenuation = _3ewg->ReadInt32();
2790     FineTune = _3ewg->ReadInt16();
2791     PitchbendRange = _3ewg->ReadInt16();
2792     uint8_t dimkeystart = _3ewg->ReadUint8();
2793     PianoReleaseMode = dimkeystart & 0x01;
2794     DimensionKeyRange.low = dimkeystart >> 1;
2795     DimensionKeyRange.high = _3ewg->ReadUint8();
2796     }
2797     }
2798    
2799 schoenebeck 823 if (!pRegions) pRegions = new RegionList;
2800 schoenebeck 2 RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
2801 schoenebeck 809 if (lrgn) {
2802     RIFF::List* rgn = lrgn->GetFirstSubList();
2803     while (rgn) {
2804     if (rgn->GetListType() == LIST_TYPE_RGN) {
2805 schoenebeck 823 __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
2806     pRegions->push_back(new Region(this, rgn));
2807 schoenebeck 809 }
2808     rgn = lrgn->GetNextSubList();
2809 schoenebeck 2 }
2810 schoenebeck 809 // Creating Region Key Table for fast lookup
2811     UpdateRegionKeyTable();
2812 schoenebeck 2 }
2813    
2814 schoenebeck 809 __notify_progress(pProgress, 1.0f); // notify done
2815     }
2816    
2817     void Instrument::UpdateRegionKeyTable() {
2818 schoenebeck 1335 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
2819 schoenebeck 823 RegionList::iterator iter = pRegions->begin();
2820     RegionList::iterator end = pRegions->end();
2821     for (; iter != end; ++iter) {
2822     gig::Region* pRegion = static_cast<gig::Region*>(*iter);
2823     for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
2824     RegionKeyTable[iKey] = pRegion;
2825 schoenebeck 2 }
2826     }
2827     }
2828    
2829     Instrument::~Instrument() {
2830     }
2831    
2832     /**
2833 schoenebeck 809 * Apply Instrument with all its Regions to the respective RIFF chunks.
2834     * You have to call File::Save() to make changes persistent.
2835     *
2836     * Usually there is absolutely no need to call this method explicitly.
2837     * It will be called automatically when File::Save() was called.
2838     *
2839     * @throws gig::Exception if samples cannot be dereferenced
2840     */
2841     void Instrument::UpdateChunks() {
2842     // first update base classes' chunks
2843     DLS::Instrument::UpdateChunks();
2844    
2845     // update Regions' chunks
2846 schoenebeck 823 {
2847     RegionList::iterator iter = pRegions->begin();
2848     RegionList::iterator end = pRegions->end();
2849     for (; iter != end; ++iter)
2850     (*iter)->UpdateChunks();
2851     }
2852 schoenebeck 809
2853     // make sure 'lart' RIFF list chunk exists
2854     RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
2855     if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
2856     // make sure '3ewg' RIFF chunk exists
2857     RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
2858 persson 1264 if (!_3ewg) {
2859     File* pFile = (File*) GetParent();
2860    
2861     // 3ewg is bigger in gig3, as it includes the iMIDI rules
2862     int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
2863     _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
2864     memset(_3ewg->LoadChunkData(), 0, size);
2865     }
2866 schoenebeck 809 // update '3ewg' RIFF chunk
2867     uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
2868 persson 1179 store16(&pData[0], EffectSend);
2869     store32(&pData[2], Attenuation);
2870     store16(&pData[6], FineTune);
2871     store16(&pData[8], PitchbendRange);
2872 persson 1266 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
2873 schoenebeck 809 DimensionKeyRange.low << 1;
2874 persson 1179 pData[10] = dimkeystart;
2875     pData[11] = DimensionKeyRange.high;
2876 schoenebeck 809 }
2877    
2878     /**
2879 schoenebeck 2 * Returns the appropriate Region for a triggered note.
2880     *
2881     * @param Key MIDI Key number of triggered note / key (0 - 127)
2882     * @returns pointer adress to the appropriate Region or NULL if there
2883     * there is no Region defined for the given \a Key
2884     */
2885     Region* Instrument::GetRegion(unsigned int Key) {
2886 schoenebeck 1335 if (!pRegions || pRegions->empty() || Key > 127) return NULL;
2887 schoenebeck 2 return RegionKeyTable[Key];
2888 schoenebeck 823
2889 schoenebeck 2 /*for (int i = 0; i < Regions; i++) {
2890     if (Key <= pRegions[i]->KeyRange.high &&
2891     Key >= pRegions[i]->KeyRange.low) return pRegions[i];
2892     }
2893     return NULL;*/
2894     }
2895    
2896     /**
2897     * Returns the first Region of the instrument. You have to call this
2898     * method once before you use GetNextRegion().
2899     *
2900     * @returns pointer address to first region or NULL if there is none
2901     * @see GetNextRegion()
2902     */
2903     Region* Instrument::GetFirstRegion() {
2904 schoenebeck 823 if (!pRegions) return NULL;
2905     RegionsIterator = pRegions->begin();
2906     return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
2907 schoenebeck 2 }
2908    
2909     /**
2910     * Returns the next Region of the instrument. You have to call
2911     * GetFirstRegion() once before you can use this method. By calling this
2912     * method multiple times it iterates through the available Regions.
2913     *
2914     * @returns pointer address to the next region or NULL if end reached
2915     * @see GetFirstRegion()
2916     */
2917     Region* Instrument::GetNextRegion() {
2918 schoenebeck 823 if (!pRegions) return NULL;
2919     RegionsIterator++;
2920     return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
2921 schoenebeck 2 }
2922    
2923 schoenebeck 809 Region* Instrument::AddRegion() {
2924     // create new Region object (and its RIFF chunks)
2925     RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
2926     if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
2927     RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
2928     Region* pNewRegion = new Region(this, rgn);
2929 schoenebeck 823 pRegions->push_back(pNewRegion);
2930     Regions = pRegions->size();
2931 schoenebeck 809 // update Region key table for fast lookup
2932     UpdateRegionKeyTable();
2933     // done
2934     return pNewRegion;
2935     }
2936 schoenebeck 2
2937 schoenebeck 809 void Instrument::DeleteRegion(Region* pRegion) {
2938     if (!pRegions) return;
2939 schoenebeck 823 DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
2940 schoenebeck 809 // update Region key table for fast lookup
2941     UpdateRegionKeyTable();
2942     }
2943 schoenebeck 2
2944 schoenebeck 809
2945    
2946 schoenebeck 929 // *************** Group ***************
2947     // *
2948    
2949     /** @brief Constructor.
2950     *
2951 schoenebeck 930 * @param file - pointer to the gig::File object
2952     * @param ck3gnm - pointer to 3gnm chunk associated with this group or
2953     * NULL if this is a new Group
2954 schoenebeck 929 */
2955 schoenebeck 930 Group::Group(File* file, RIFF::Chunk* ck3gnm) {
2956 schoenebeck 929 pFile = file;
2957     pNameChunk = ck3gnm;
2958     ::LoadString(pNameChunk, Name);
2959     }
2960    
2961     Group::~Group() {
2962 schoenebeck 1099 // remove the chunk associated with this group (if any)
2963     if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
2964 schoenebeck 929 }
2965    
2966     /** @brief Update chunks with current group settings.
2967     *
2968 schoenebeck 1098 * Apply current Group field values to the respective chunks. You have
2969     * to call File::Save() to make changes persistent.
2970     *
2971     * Usually there is absolutely no need to call this method explicitly.
2972     * It will be called automatically when File::Save() was called.
2973 schoenebeck 929 */
2974     void Group::UpdateChunks() {
2975     // make sure <3gri> and <3gnl> list chunks exist
2976 schoenebeck 930 RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
2977 persson 1192 if (!_3gri) {
2978     _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
2979     pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
2980     }
2981 schoenebeck 929 RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
2982 persson 1182 if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
2983 persson 1266
2984     if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
2985     // v3 has a fixed list of 128 strings, find a free one
2986     for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
2987     if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
2988     pNameChunk = ck;
2989     break;
2990     }
2991     }
2992     }
2993    
2994 schoenebeck 929 // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
2995     ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
2996     }
2997    
2998 schoenebeck 930 /**
2999     * Returns the first Sample of this Group. You have to call this method
3000     * once before you use GetNextSample().
3001     *
3002     * <b>Notice:</b> this method might block for a long time, in case the
3003     * samples of this .gig file were not scanned yet
3004     *
3005     * @returns pointer address to first Sample or NULL if there is none
3006     * applied to this Group
3007     * @see GetNextSample()
3008     */
3009     Sample* Group::GetFirstSample() {
3010     // FIXME: lazy und unsafe implementation, should be an autonomous iterator
3011     for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
3012     if (pSample->GetGroup() == this) return pSample;
3013     }
3014     return NULL;
3015     }
3016 schoenebeck 929
3017 schoenebeck 930 /**
3018     * Returns the next Sample of the Group. You have to call
3019     * GetFirstSample() once before you can use this method. By calling this
3020     * method multiple times it iterates through the Samples assigned to
3021     * this Group.
3022     *
3023     * @returns pointer address to the next Sample of this Group or NULL if
3024     * end reached
3025     * @see GetFirstSample()
3026     */
3027     Sample* Group::GetNextSample() {
3028     // FIXME: lazy und unsafe implementation, should be an autonomous iterator
3029     for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
3030     if (pSample->GetGroup() == this) return pSample;
3031     }
3032     return NULL;
3033     }
3034 schoenebeck 929
3035 schoenebeck 930 /**
3036     * Move Sample given by \a pSample from another Group to this Group.
3037     */
3038     void Group::AddSample(Sample* pSample) {
3039     pSample->pGroup = this;
3040     }
3041    
3042     /**
3043     * Move all members of this group to another group (preferably the 1st
3044     * one except this). This method is called explicitly by
3045     * File::DeleteGroup() thus when a Group was deleted. This code was
3046     * intentionally not placed in the destructor!
3047     */
3048     void Group::MoveAll() {
3049     // get "that" other group first
3050     Group* pOtherGroup = NULL;
3051     for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
3052     if (pOtherGroup != this) break;
3053     }
3054     if (!pOtherGroup) throw Exception(
3055     "Could not move samples to another group, since there is no "
3056     "other Group. This is a bug, report it!"
3057     );
3058     // now move all samples of this group to the other group
3059     for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
3060     pOtherGroup->AddSample(pSample);
3061     }
3062     }
3063    
3064    
3065    
3066 schoenebeck 2 // *************** File ***************
3067     // *
3068    
3069 persson 1199 // File version 2.0, 1998-06-28
3070     const DLS::version_t File::VERSION_2 = {
3071     0, 2, 19980628 & 0xffff, 19980628 >> 16
3072     };
3073    
3074     // File version 3.0, 2003-03-31
3075     const DLS::version_t File::VERSION_3 = {
3076     0, 3, 20030331 & 0xffff, 20030331 >> 16
3077     };
3078    
3079 persson 1180 const DLS::Info::FixedStringLength File::FixedStringLengths[] = {
3080     { CHUNK_ID_IARL, 256 },
3081     { CHUNK_ID_IART, 128 },
3082     { CHUNK_ID_ICMS, 128 },
3083     { CHUNK_ID_ICMT, 1024 },
3084     { CHUNK_ID_ICOP, 128 },
3085     { CHUNK_ID_ICRD, 128 },
3086     { CHUNK_ID_IENG, 128 },
3087     { CHUNK_ID_IGNR, 128 },
3088     { CHUNK_ID_IKEY, 128 },
3089     { CHUNK_ID_IMED, 128 },
3090     { CHUNK_ID_INAM, 128 },
3091     { CHUNK_ID_IPRD, 128 },
3092     { CHUNK_ID_ISBJ, 128 },
3093     { CHUNK_ID_ISFT, 128 },
3094     { CHUNK_ID_ISRC, 128 },
3095     { CHUNK_ID_ISRF, 128 },
3096     { CHUNK_ID_ITCH, 128 },
3097     { 0, 0 }
3098     };
3099    
3100 schoenebeck 809 File::File() : DLS::File() {
3101 persson 1264 *pVersion = VERSION_3;
3102 schoenebeck 929 pGroups = NULL;
3103 persson 1180 pInfo->FixedStringLengths = FixedStringLengths;
3104 persson 1182 pInfo->ArchivalLocation = String(256, ' ');
3105 persson 1192
3106     // add some mandatory chunks to get the file chunks in right
3107     // order (INFO chunk will be moved to first position later)
3108     pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
3109     pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
3110 persson 1209 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
3111    
3112     GenerateDLSID();
3113 schoenebeck 809 }
3114    
3115 schoenebeck 2 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
3116 schoenebeck 929 pGroups = NULL;
3117 persson 1180 pInfo->FixedStringLengths = FixedStringLengths;
3118 schoenebeck 2 }
3119    
3120 schoenebeck 929 File::~File() {
3121     if (pGroups) {
3122     std::list<Group*>::iterator iter = pGroups->begin();
3123     std::list<Group*>::iterator end = pGroups->end();
3124     while (iter != end) {
3125     delete *iter;
3126     ++iter;
3127     }
3128     delete pGroups;
3129     }
3130     }
3131    
3132 schoenebeck 515 Sample* File::GetFirstSample(progress_t* pProgress) {
3133     if (!pSamples) LoadSamples(pProgress);
3134 schoenebeck 2 if (!pSamples) return NULL;
3135     SamplesIterator = pSamples->begin();
3136     return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
3137     }
3138    
3139     Sample* File::GetNextSample() {
3140     if (!pSamples) return NULL;
3141     SamplesIterator++;
3142     return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
3143     }
3144    
3145 schoenebeck 809 /** @brief Add a new sample.
3146     *
3147     * This will create a new Sample object for the gig file. You have to
3148     * call Save() to make this persistent to the file.
3149     *
3150     * @returns pointer to new Sample object
3151     */
3152     Sample* File::AddSample() {
3153     if (!pSamples) LoadSamples();
3154     __ensureMandatoryChunksExist();
3155     RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
3156     // create new Sample object and its respective 'wave' list chunk
3157     RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
3158     Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
3159 persson 1192
3160     // add mandatory chunks to get the chunks in right order
3161     wave->AddSubChunk(CHUNK_ID_FMT, 16);
3162     wave->AddSubList(LIST_TYPE_INFO);
3163    
3164 schoenebeck 809 pSamples->push_back(pSample);
3165     return pSample;
3166     }
3167    
3168     /** @brief Delete a sample.
3169     *
3170 schoenebeck 1292 * This will delete the given Sample object from the gig file. Any
3171     * references to this sample from Regions and DimensionRegions will be
3172     * removed. You have to call Save() to make this persistent to the file.
3173 schoenebeck 809 *
3174     * @param pSample - sample to delete
3175     * @throws gig::Exception if given sample could not be found
3176     */
3177     void File::DeleteSample(Sample* pSample) {
3178 schoenebeck 823 if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
3179     SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
3180 schoenebeck 809 if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
3181 schoenebeck 1083 if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
3182 schoenebeck 809 pSamples->erase(iter);
3183     delete pSample;
3184 persson 1266
3185     // remove all references to the sample
3186     for (Instrument* instrument = GetFirstInstrument() ; instrument ;
3187     instrument = GetNextInstrument()) {
3188     for (Region* region = instrument->GetFirstRegion() ; region ;
3189     region = instrument->GetNextRegion()) {
3190    
3191     if (region->GetSample() == pSample) region->SetSample(NULL);
3192    
3193     for (int i = 0 ; i < region->DimensionRegions ; i++) {
3194     gig::DimensionRegion *d = region->pDimensionRegions[i];
3195     if (d->pSample == pSample) d->pSample = NULL;
3196     }
3197     }
3198     }
3199 schoenebeck 809 }
3200    
3201 schoenebeck 823 void File::LoadSamples() {
3202     LoadSamples(NULL);
3203     }
3204    
3205 schoenebeck 515 void File::LoadSamples(progress_t* pProgress) {
3206 schoenebeck 930 // Groups must be loaded before samples, because samples will try
3207     // to resolve the group they belong to
3208 schoenebeck 1158 if (!pGroups) LoadGroups();
3209 schoenebeck 930
3210 schoenebeck 823 if (!pSamples) pSamples = new SampleList;
3211    
3212 persson 666 RIFF::File* file = pRIFF;
3213 schoenebeck 515
3214 persson 666 // just for progress calculation
3215     int iSampleIndex = 0;
3216     int iTotalSamples = WavePoolCount;
3217 schoenebeck 515
3218 persson 666 // check if samples should be loaded from extension files
3219     int lastFileNo = 0;
3220     for (int i = 0 ; i < WavePoolCount ; i++) {
3221     if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
3222     }
3223 schoenebeck 780 String name(pRIFF->GetFileName());
3224     int nameLen = name.length();
3225 persson 666 char suffix[6];
3226 schoenebeck 780 if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
3227 schoenebeck 515
3228 persson 666 for (int fileNo = 0 ; ; ) {
3229     RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
3230     if (wvpl) {
3231     unsigned long wvplFileOffset = wvpl->GetFilePos();
3232     RIFF::List* wave = wvpl->GetFirstSubList();
3233     while (wave) {
3234     if (wave->GetListType() == LIST_TYPE_WAVE) {
3235     // notify current progress
3236     const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
3237     __notify_progress(pProgress, subprogress);
3238    
3239     unsigned long waveFileOffset = wave->GetFilePos();
3240     pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
3241    
3242     iSampleIndex++;
3243     }
3244     wave = wvpl->GetNextSubList();
3245 schoenebeck 2 }
3246 persson 666
3247     if (fileNo == lastFileNo) break;
3248    
3249     // open extension file (*.gx01, *.gx02, ...)
3250     fileNo++;
3251     sprintf(suffix, ".gx%02d", fileNo);
3252     name.replace(nameLen, 5, suffix);
3253     file = new RIFF::File(name);
3254     ExtensionFiles.push_back(file);
3255 schoenebeck 823 } else break;
3256 schoenebeck 2 }
3257 persson 666
3258     __notify_progress(pProgress, 1.0); // notify done
3259 schoenebeck 2 }
3260    
3261     Instrument* File::GetFirstInstrument() {
3262     if (!pInstruments) LoadInstruments();
3263     if (!pInstruments) return NULL;
3264     InstrumentsIterator = pInstruments->begin();
3265 schoenebeck 823 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
3266 schoenebeck 2 }
3267    
3268     Instrument* File::GetNextInstrument() {
3269     if (!pInstruments) return NULL;
3270     InstrumentsIterator++;
3271 schoenebeck 823 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
3272 schoenebeck 2 }
3273    
3274 schoenebeck 21 /**
3275     * Returns the instrument with the given index.
3276     *
3277 schoenebeck 515 * @param index - number of the sought instrument (0..n)
3278     * @param pProgress - optional: callback function for progress notification
3279 schoenebeck 21 * @returns sought instrument or NULL if there's no such instrument
3280     */
3281 schoenebeck 515 Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
3282     if (!pInstruments) {
3283     // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
3284    
3285     // sample loading subtask
3286     progress_t subprogress;
3287     __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
3288     __notify_progress(&subprogress, 0.0f);
3289     GetFirstSample(&subprogress); // now force all samples to be loaded
3290     __notify_progress(&subprogress, 1.0f);
3291    
3292     // instrument loading subtask
3293     if (pProgress && pProgress->callback) {
3294     subprogress.__range_min = subprogress.__range_max;
3295     subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
3296     }
3297     __notify_progress(&subprogress, 0.0f);
3298     LoadInstruments(&subprogress);
3299     __notify_progress(&subprogress, 1.0f);
3300     }
3301 schoenebeck 21 if (!pInstruments) return NULL;
3302     InstrumentsIterator = pInstruments->begin();
3303     for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
3304 schoenebeck 823 if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
3305 schoenebeck 21 InstrumentsIterator++;
3306     }
3307     return NULL;
3308     }
3309    
3310 schoenebeck 809 /** @brief Add a new instrument definition.
3311     *
3312     * This will create a new Instrument object for the gig file. You have
3313     * to call Save() to make this persistent to the file.
3314     *
3315     * @returns pointer to new Instrument object
3316     */
3317     Instrument* File::AddInstrument() {
3318     if (!pInstruments) LoadInstruments();
3319     __ensureMandatoryChunksExist();
3320     RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
3321     RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
3322 persson 1192
3323     // add mandatory chunks to get the chunks in right order
3324     lstInstr->AddSubList(LIST_TYPE_INFO);
3325 persson 1209 lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
3326 persson 1192
3327 schoenebeck 809 Instrument* pInstrument = new Instrument(this, lstInstr);
3328 persson 1209 pInstrument->GenerateDLSID();
3329 persson 1182
3330 persson 1192 lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
3331    
3332 persson 1182 // this string is needed for the gig to be loadable in GSt:
3333     pInstrument->pInfo->Software = "Endless Wave";
3334    
3335 schoenebeck 809 pInstruments->push_back(pInstrument);
3336     return pInstrument;
3337     }
3338    
3339     /** @brief Delete an instrument.
3340     *
3341     * This will delete the given Instrument object from the gig file. You
3342     * have to call Save() to make this persistent to the file.
3343     *
3344     * @param pInstrument - instrument to delete
3345 schoenebeck 1081 * @throws gig::Exception if given instrument could not be found
3346 schoenebeck 809 */
3347     void File::DeleteInstrument(Instrument* pInstrument) {
3348     if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
3349 schoenebeck 823 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
3350 schoenebeck 809 if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
3351     pInstruments->erase(iter);
3352     delete pInstrument;
3353     }
3354    
3355 schoenebeck 823 void File::LoadInstruments() {
3356     LoadInstruments(NULL);
3357     }
3358    
3359 schoenebeck 515 void File::LoadInstruments(progress_t* pProgress) {
3360 schoenebeck 823 if (!pInstruments) pInstruments = new InstrumentList;
3361 schoenebeck 2 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
3362     if (lstInstruments) {
3363 schoenebeck 515 int iInstrumentIndex = 0;
3364 schoenebeck 2 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
3365     while (lstInstr) {
3366     if (lstInstr->GetListType() == LIST_TYPE_INS) {
3367 schoenebeck 515 // notify current progress
3368     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
3369     __notify_progress(pProgress, localProgress);
3370    
3371     // divide local progress into subprogress for loading current Instrument
3372     progress_t subprogress;
3373     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
3374    
3375     pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
3376    
3377     iInstrumentIndex++;
3378 schoenebeck 2 }
3379     lstInstr = lstInstruments->GetNextSubList();
3380     }
3381 schoenebeck 515 __notify_progress(pProgress, 1.0); // notify done
3382 schoenebeck 2 }
3383     }
3384    
3385 persson 1207 /// Updates the 3crc chunk with the checksum of a sample. The
3386     /// update is done directly to disk, as this method is called
3387     /// after File::Save()
3388 persson 1199 void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
3389     RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
3390     if (!_3crc) return;
3391 persson 1207
3392     // get the index of the sample
3393 persson 1199 int iWaveIndex = -1;
3394     File::SampleList::iterator iter = pSamples->begin();
3395     File::SampleList::iterator end = pSamples->end();
3396     for (int index = 0; iter != end; ++iter, ++index) {
3397     if (*iter == pSample) {
3398     iWaveIndex = index;
3399     break;
3400     }
3401     }
3402     if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
3403    
3404 persson 1207 // write the CRC-32 checksum to disk
3405 persson 1199 _3crc->SetPos(iWaveIndex * 8);
3406     uint32_t tmp = 1;
3407     _3crc->WriteUint32(&tmp); // unknown, always 1?
3408     _3crc->WriteUint32(&crc);
3409     }
3410    
3411 schoenebeck 929 Group* File::GetFirstGroup() {
3412     if (!pGroups) LoadGroups();
3413 schoenebeck 930 // there must always be at least one group
3414 schoenebeck 929 GroupsIterator = pGroups->begin();
3415 schoenebeck 930 return *GroupsIterator;
3416 schoenebeck 929 }
3417 schoenebeck 2
3418 schoenebeck 929 Group* File::GetNextGroup() {
3419     if (!pGroups) return NULL;
3420     ++GroupsIterator;
3421     return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
3422     }
3423 schoenebeck 2
3424 schoenebeck 929 /**
3425     * Returns the group with the given index.
3426     *
3427     * @param index - number of the sought group (0..n)
3428     * @returns sought group or NULL if there's no such group
3429     */
3430     Group* File::GetGroup(uint index) {
3431     if (!pGroups) LoadGroups();
3432     GroupsIterator = pGroups->begin();
3433     for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
3434     if (i == index) return *GroupsIterator;
3435     ++GroupsIterator;
3436     }
3437     return NULL;
3438     }
3439    
3440     Group* File::AddGroup() {
3441     if (!pGroups) LoadGroups();
3442 schoenebeck 930 // there must always be at least one group
3443 schoenebeck 929 __ensureMandatoryChunksExist();
3444 schoenebeck 930 Group* pGroup = new Group(this, NULL);
3445 schoenebeck 929 pGroups->push_back(pGroup);
3446     return pGroup;
3447     }
3448    
3449 schoenebeck 1081 /** @brief Delete a group and its samples.
3450     *
3451     * This will delete the given Group object and all the samples that
3452     * belong to this group from the gig file. You have to call Save() to
3453     * make this persistent to the file.
3454     *
3455     * @param pGroup - group to delete
3456     * @throws gig::Exception if given group could not be found
3457     */
3458 schoenebeck 929 void File::DeleteGroup(Group* pGroup) {
3459 schoenebeck 930 if (!pGroups) LoadGroups();
3460 schoenebeck 929 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
3461     if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
3462 schoenebeck 930 if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
3463 schoenebeck 1081 // delete all members of this group
3464     for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
3465     DeleteSample(pSample);
3466     }
3467     // now delete this group object
3468     pGroups->erase(iter);
3469     delete pGroup;
3470     }
3471    
3472     /** @brief Delete a group.
3473     *
3474     * This will delete the given Group object from the gig file. All the
3475     * samples that belong to this group will not be deleted, but instead
3476     * be moved to another group. You have to call Save() to make this
3477     * persistent to the file.
3478     *
3479     * @param pGroup - group to delete
3480     * @throws gig::Exception if given group could not be found
3481     */
3482     void File::DeleteGroupOnly(Group* pGroup) {
3483     if (!pGroups) LoadGroups();
3484     std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
3485     if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
3486     if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
3487 schoenebeck 930 // move all members of this group to another group
3488     pGroup->MoveAll();
3489 schoenebeck 929 pGroups->erase(iter);
3490     delete pGroup;
3491     }
3492    
3493     void File::LoadGroups() {
3494     if (!pGroups) pGroups = new std::list<Group*>;
3495 schoenebeck 930 // try to read defined groups from file
3496 schoenebeck 929 RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
3497 schoenebeck 930 if (lst3gri) {
3498     RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
3499     if (lst3gnl) {
3500     RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
3501     while (ck) {
3502     if (ck->GetChunkID() == CHUNK_ID_3GNM) {
3503 persson 1266 if (pVersion && pVersion->major == 3 &&
3504     strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
3505    
3506 schoenebeck 930 pGroups->push_back(new Group(this, ck));
3507     }
3508     ck = lst3gnl->GetNextSubChunk();
3509 schoenebeck 929 }
3510     }
3511     }
3512 schoenebeck 930 // if there were no group(s), create at least the mandatory default group
3513     if (!pGroups->size()) {
3514     Group* pGroup = new Group(this, NULL);
3515     pGroup->Name = "Default Group";
3516     pGroups->push_back(pGroup);
3517     }
3518 schoenebeck 929 }
3519    
3520 schoenebeck 1098 /**
3521     * Apply all the gig file's current instruments, samples, groups and settings
3522     * to the respective RIFF chunks. You have to call Save() to make changes
3523     * persistent.
3524     *
3525     * Usually there is absolutely no need to call this method explicitly.
3526     * It will be called automatically when File::Save() was called.
3527     *
3528     * @throws Exception - on errors
3529     */
3530     void File::UpdateChunks() {
3531 persson 1199 bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
3532 persson 1192
3533 persson 1247 b64BitWavePoolOffsets = pVersion && pVersion->major == 3;
3534    
3535 schoenebeck 1098 // first update base class's chunks
3536     DLS::File::UpdateChunks();
3537 schoenebeck 929
3538 persson 1199 if (newFile) {
3539 persson 1192 // INFO was added by Resource::UpdateChunks - make sure it
3540     // is placed first in file
3541 persson 1199 RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
3542 persson 1192 RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
3543     if (first != info) {
3544     pRIFF->MoveSubChunk(info, first);
3545     }
3546     }
3547    
3548 schoenebeck 1098 // update group's chunks
3549     if (pGroups) {
3550     std::list<Group*>::iterator iter = pGroups->begin();
3551     std::list<Group*>::iterator end = pGroups->end();
3552     for (; iter != end; ++iter) {
3553     (*iter)->UpdateChunks();
3554     }
3555 persson 1266
3556     // v3: make sure the file has 128 3gnm chunks
3557     if (pVersion && pVersion->major == 3) {
3558     RIFF::List* _3gnl = pRIFF->GetSubList(LIST_TYPE_3GRI)->GetSubList(LIST_TYPE_3GNL);
3559     RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
3560     for (int i = 0 ; i < 128 ; i++) {
3561     if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
3562     if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
3563     }
3564     }
3565 schoenebeck 1098 }
3566 persson 1199
3567     // update einf chunk
3568    
3569     // The einf chunk contains statistics about the gig file, such
3570     // as the number of regions and samples used by each
3571     // instrument. It is divided in equally sized parts, where the
3572     // first part contains information about the whole gig file,
3573     // and the rest of the parts map to each instrument in the
3574     // file.
3575     //
3576     // At the end of each part there is a bit map of each sample
3577     // in the file, where a set bit means that the sample is used
3578     // by the file/instrument.
3579     //
3580     // Note that there are several fields with unknown use. These
3581     // are set to zero.
3582    
3583     int sublen = pSamples->size() / 8 + 49;
3584     int einfSize = (Instruments + 1) * sublen;
3585    
3586     RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
3587     if (einf) {
3588     if (einf->GetSize() != einfSize) {
3589     einf->Resize(einfSize);
3590     memset(einf->LoadChunkData(), 0, einfSize);
3591     }
3592     } else if (newFile) {
3593     einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
3594     }
3595     if (einf) {
3596     uint8_t* pData = (uint8_t*) einf->LoadChunkData();
3597    
3598     std::map<gig::Sample*,int> sampleMap;
3599     int sampleIdx = 0;
3600     for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
3601     sampleMap[pSample] = sampleIdx++;
3602     }
3603    
3604     int totnbusedsamples = 0;
3605     int totnbusedchannels = 0;
3606     int totnbregions = 0;
3607     int totnbdimregions = 0;
3608 persson 1264 int totnbloops = 0;
3609 persson 1199 int instrumentIdx = 0;
3610    
3611     memset(&pData[48], 0, sublen - 48);
3612    
3613     for (Instrument* instrument = GetFirstInstrument() ; instrument ;
3614     instrument = GetNextInstrument()) {
3615     int nbusedsamples = 0;
3616     int nbusedchannels = 0;
3617     int nbdimregions = 0;
3618 persson 1264 int nbloops = 0;
3619 persson 1199
3620     memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
3621    
3622     for (Region* region = instrument->GetFirstRegion() ; region ;
3623     region = instrument->GetNextRegion()) {
3624     for (int i = 0 ; i < region->DimensionRegions ; i++) {
3625     gig::DimensionRegion *d = region->pDimensionRegions[i];
3626     if (d->pSample) {
3627     int sampleIdx = sampleMap[d->pSample];
3628     int byte = 48 + sampleIdx / 8;
3629     int bit = 1 << (sampleIdx & 7);
3630     if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
3631     pData[(instrumentIdx + 1) * sublen + byte] |= bit;
3632     nbusedsamples++;
3633     nbusedchannels += d->pSample->Channels;
3634    
3635     if ((pData[byte] & bit) == 0) {
3636     pData[byte] |= bit;
3637     totnbusedsamples++;
3638     totnbusedchannels += d->pSample->Channels;
3639     }
3640     }
3641     }
3642 persson 1264 if (d->SampleLoops) nbloops++;
3643 persson 1199 }
3644     nbdimregions += region->DimensionRegions;
3645     }
3646     // first 4 bytes unknown - sometimes 0, sometimes length of einf part
3647     // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
3648     store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
3649     store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
3650     store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
3651     store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
3652     store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
3653 persson 1264 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
3654     // next 8 bytes unknown
3655 persson 1199 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
3656     store32(&pData[(instrumentIdx + 1) * sublen + 40], pSamples->size());
3657     // next 4 bytes unknown
3658    
3659     totnbregions += instrument->Regions;
3660     totnbdimregions += nbdimregions;
3661 persson 1264 totnbloops += nbloops;
3662 persson 1199 instrumentIdx++;
3663     }
3664     // first 4 bytes unknown - sometimes 0, sometimes length of einf part
3665     // store32(&pData[0], sublen);
3666     store32(&pData[4], totnbusedchannels);
3667     store32(&pData[8], totnbusedsamples);
3668     store32(&pData[12], Instruments);
3669     store32(&pData[16], totnbregions);
3670     store32(&pData[20], totnbdimregions);
3671 persson 1264 store32(&pData[24], totnbloops);
3672     // next 8 bytes unknown
3673     // next 4 bytes unknown, not always 0
3674 persson 1199 store32(&pData[40], pSamples->size());
3675     // next 4 bytes unknown
3676     }
3677    
3678     // update 3crc chunk
3679    
3680     // The 3crc chunk contains CRC-32 checksums for the
3681     // samples. The actual checksum values will be filled in
3682     // later, by Sample::Write.
3683    
3684     RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
3685     if (_3crc) {
3686     _3crc->Resize(pSamples->size() * 8);
3687     } else if (newFile) {
3688     _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
3689     _3crc->LoadChunkData();
3690 persson 1264
3691     // the order of einf and 3crc is not the same in v2 and v3
3692     if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
3693 persson 1199 }
3694 schoenebeck 1098 }
3695 schoenebeck 929
3696 schoenebeck 1098
3697    
3698 schoenebeck 2 // *************** Exception ***************
3699     // *
3700    
3701     Exception::Exception(String Message) : DLS::Exception(Message) {
3702     }
3703    
3704     void Exception::PrintMessage() {
3705     std::cout << "gig::Exception: " << Message << std::endl;
3706     }
3707    
3708 schoenebeck 518
3709     // *************** functions ***************
3710     // *
3711    
3712     /**
3713     * Returns the name of this C++ library. This is usually "libgig" of
3714     * course. This call is equivalent to RIFF::libraryName() and
3715     * DLS::libraryName().
3716     */
3717     String libraryName() {
3718     return PACKAGE;
3719     }
3720    
3721     /**
3722     * Returns version of this C++ library. This call is equivalent to
3723     * RIFF::libraryVersion() and DLS::libraryVersion().
3724     */
3725     String libraryVersion() {
3726     return VERSION;
3727     }
3728    
3729 schoenebeck 2 } // namespace gig

  ViewVC Help
Powered by ViewVC