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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3799 - (hide annotations) (download)
Sat Jul 25 09:28:56 2020 UTC (3 years, 8 months ago) by schoenebeck
File size: 323370 byte(s)
* src/gig.cpp: Fixed undefined behaviour when modifying script slots on an
  instrument that had been cloned and not been saved yet (e.g. unintended
  modification of original instrument's script slots, and crash on
  Instrument destruction due to double free of pScriptRefs).

* Bumped version (4.2.0.svn17).

1 schoenebeck 2 /***************************************************************************
2     * *
3 schoenebeck 933 * libgig - C++ cross-platform Gigasampler format file access library *
4 schoenebeck 2 * *
5 schoenebeck 3710 * Copyright (C) 2003-2020 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 schoenebeck 3140 #include "Serialization.h"
28 schoenebeck 809
29 persson 1713 #include <algorithm>
30 schoenebeck 809 #include <math.h>
31 schoenebeck 384 #include <iostream>
32 schoenebeck 2555 #include <assert.h>
33 schoenebeck 384
34 schoenebeck 2912 /// libgig's current file format version (for extending the original Giga file
35     /// format with libgig's own custom data / custom features).
36     #define GIG_FILE_EXT_VERSION 2
37    
38 schoenebeck 809 /// Initial size of the sample buffer which is used for decompression of
39     /// compressed sample wave streams - this value should always be bigger than
40     /// the biggest sample piece expected to be read by the sampler engine,
41     /// otherwise the buffer size will be raised at runtime and thus the buffer
42     /// reallocated which is time consuming and unefficient.
43     #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
44    
45     /** (so far) every exponential paramater in the gig format has a basis of 1.000000008813822 */
46     #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x))
47     #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822))
48     #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01))
49     #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01)
50     #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03)
51     #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4)
52     #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03)
53     #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03)
54     #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
55     #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1)
56     #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3)
57     #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5)
58    
59 schoenebeck 3138 #define SRLZ(member) \
60     archive->serializeMember(*this, member, #member);
61    
62 schoenebeck 515 namespace gig {
63 schoenebeck 2
64 schoenebeck 809 // *************** Internal functions for sample decompression ***************
65 persson 365 // *
66    
67 schoenebeck 515 namespace {
68    
69 persson 365 inline int get12lo(const unsigned char* pSrc)
70     {
71     const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
72     return x & 0x800 ? x - 0x1000 : x;
73     }
74    
75     inline int get12hi(const unsigned char* pSrc)
76     {
77     const int x = pSrc[1] >> 4 | pSrc[2] << 4;
78     return x & 0x800 ? x - 0x1000 : x;
79     }
80    
81     inline int16_t get16(const unsigned char* pSrc)
82     {
83     return int16_t(pSrc[0] | pSrc[1] << 8);
84     }
85    
86     inline int get24(const unsigned char* pSrc)
87     {
88     const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
89     return x & 0x800000 ? x - 0x1000000 : x;
90     }
91    
92 persson 902 inline void store24(unsigned char* pDst, int x)
93     {
94     pDst[0] = x;
95     pDst[1] = x >> 8;
96     pDst[2] = x >> 16;
97     }
98    
99 persson 365 void Decompress16(int compressionmode, const unsigned char* params,
100 persson 372 int srcStep, int dstStep,
101     const unsigned char* pSrc, int16_t* pDst,
102 schoenebeck 2912 file_offset_t currentframeoffset,
103     file_offset_t copysamples)
104 persson 365 {
105     switch (compressionmode) {
106     case 0: // 16 bit uncompressed
107     pSrc += currentframeoffset * srcStep;
108     while (copysamples) {
109     *pDst = get16(pSrc);
110 persson 372 pDst += dstStep;
111 persson 365 pSrc += srcStep;
112     copysamples--;
113     }
114     break;
115    
116     case 1: // 16 bit compressed to 8 bit
117     int y = get16(params);
118     int dy = get16(params + 2);
119     while (currentframeoffset) {
120     dy -= int8_t(*pSrc);
121     y -= dy;
122     pSrc += srcStep;
123     currentframeoffset--;
124     }
125     while (copysamples) {
126     dy -= int8_t(*pSrc);
127     y -= dy;
128     *pDst = y;
129 persson 372 pDst += dstStep;
130 persson 365 pSrc += srcStep;
131     copysamples--;
132     }
133     break;
134     }
135     }
136    
137     void Decompress24(int compressionmode, const unsigned char* params,
138 persson 902 int dstStep, const unsigned char* pSrc, uint8_t* pDst,
139 schoenebeck 2912 file_offset_t currentframeoffset,
140     file_offset_t copysamples, int truncatedBits)
141 persson 365 {
142 persson 695 int y, dy, ddy, dddy;
143 persson 437
144 persson 695 #define GET_PARAMS(params) \
145     y = get24(params); \
146     dy = y - get24((params) + 3); \
147     ddy = get24((params) + 6); \
148     dddy = get24((params) + 9)
149 persson 365
150     #define SKIP_ONE(x) \
151 persson 695 dddy -= (x); \
152     ddy -= dddy; \
153     dy = -dy - ddy; \
154     y += dy
155 persson 365
156     #define COPY_ONE(x) \
157     SKIP_ONE(x); \
158 persson 902 store24(pDst, y << truncatedBits); \
159 persson 372 pDst += dstStep
160 persson 365
161     switch (compressionmode) {
162     case 2: // 24 bit uncompressed
163     pSrc += currentframeoffset * 3;
164     while (copysamples) {
165 persson 902 store24(pDst, get24(pSrc) << truncatedBits);
166 persson 372 pDst += dstStep;
167 persson 365 pSrc += 3;
168     copysamples--;
169     }
170     break;
171    
172     case 3: // 24 bit compressed to 16 bit
173     GET_PARAMS(params);
174     while (currentframeoffset) {
175     SKIP_ONE(get16(pSrc));
176     pSrc += 2;
177     currentframeoffset--;
178     }
179     while (copysamples) {
180     COPY_ONE(get16(pSrc));
181     pSrc += 2;
182     copysamples--;
183     }
184     break;
185    
186     case 4: // 24 bit compressed to 12 bit
187     GET_PARAMS(params);
188     while (currentframeoffset > 1) {
189     SKIP_ONE(get12lo(pSrc));
190     SKIP_ONE(get12hi(pSrc));
191     pSrc += 3;
192     currentframeoffset -= 2;
193     }
194     if (currentframeoffset) {
195     SKIP_ONE(get12lo(pSrc));
196     currentframeoffset--;
197     if (copysamples) {
198     COPY_ONE(get12hi(pSrc));
199     pSrc += 3;
200     copysamples--;
201     }
202     }
203     while (copysamples > 1) {
204     COPY_ONE(get12lo(pSrc));
205     COPY_ONE(get12hi(pSrc));
206     pSrc += 3;
207     copysamples -= 2;
208     }
209     if (copysamples) {
210     COPY_ONE(get12lo(pSrc));
211     }
212     break;
213    
214     case 5: // 24 bit compressed to 8 bit
215     GET_PARAMS(params);
216     while (currentframeoffset) {
217     SKIP_ONE(int8_t(*pSrc++));
218     currentframeoffset--;
219     }
220     while (copysamples) {
221     COPY_ONE(int8_t(*pSrc++));
222     copysamples--;
223     }
224     break;
225     }
226     }
227    
228     const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
229     const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
230     const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
231     const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
232     }
233    
234    
235 schoenebeck 1113
236 schoenebeck 1381 // *************** Internal CRC-32 (Cyclic Redundancy Check) functions ***************
237     // *
238    
239     static uint32_t* __initCRCTable() {
240     static uint32_t res[256];
241    
242     for (int i = 0 ; i < 256 ; i++) {
243     uint32_t c = i;
244     for (int j = 0 ; j < 8 ; j++) {
245     c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
246     }
247     res[i] = c;
248     }
249     return res;
250     }
251    
252     static const uint32_t* __CRCTable = __initCRCTable();
253    
254     /**
255     * Initialize a CRC variable.
256     *
257     * @param crc - variable to be initialized
258     */
259     inline static void __resetCRC(uint32_t& crc) {
260     crc = 0xffffffff;
261     }
262    
263     /**
264     * Used to calculate checksums of the sample data in a gig file. The
265     * checksums are stored in the 3crc chunk of the gig file and
266     * automatically updated when a sample is written with Sample::Write().
267     *
268     * One should call __resetCRC() to initialize the CRC variable to be
269     * used before calling this function the first time.
270     *
271     * After initializing the CRC variable one can call this function
272     * arbitrary times, i.e. to split the overall CRC calculation into
273     * steps.
274     *
275     * Once the whole data was processed by __calculateCRC(), one should
276 schoenebeck 3115 * call __finalizeCRC() to get the final CRC result.
277 schoenebeck 1381 *
278     * @param buf - pointer to data the CRC shall be calculated of
279     * @param bufSize - size of the data to be processed
280     * @param crc - variable the CRC sum shall be stored to
281     */
282 schoenebeck 3053 static void __calculateCRC(unsigned char* buf, size_t bufSize, uint32_t& crc) {
283     for (size_t i = 0 ; i < bufSize ; i++) {
284 schoenebeck 1381 crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
285     }
286     }
287    
288     /**
289     * Returns the final CRC result.
290     *
291     * @param crc - variable previously passed to __calculateCRC()
292     */
293 schoenebeck 3115 inline static void __finalizeCRC(uint32_t& crc) {
294     crc ^= 0xffffffff;
295 schoenebeck 1381 }
296    
297    
298    
299 schoenebeck 1113 // *************** Other Internal functions ***************
300     // *
301    
302     static split_type_t __resolveSplitType(dimension_t dimension) {
303     return (
304     dimension == dimension_layer ||
305     dimension == dimension_samplechannel ||
306     dimension == dimension_releasetrigger ||
307     dimension == dimension_keyboard ||
308     dimension == dimension_roundrobin ||
309     dimension == dimension_random ||
310     dimension == dimension_smartmidi ||
311     dimension == dimension_roundrobinkeyboard
312     ) ? split_type_bit : split_type_normal;
313     }
314    
315     static int __resolveZoneSize(dimension_def_t& dimension_definition) {
316     return (dimension_definition.split_type == split_type_normal)
317     ? int(128.0 / dimension_definition.zones) : 0;
318     }
319    
320    
321    
322 schoenebeck 3138 // *************** leverage_ctrl_t ***************
323     // *
324    
325     void leverage_ctrl_t::serialize(Serialization::Archive* archive) {
326     SRLZ(type);
327     SRLZ(controller_number);
328     }
329    
330    
331    
332     // *************** crossfade_t ***************
333     // *
334    
335     void crossfade_t::serialize(Serialization::Archive* archive) {
336     SRLZ(in_start);
337     SRLZ(in_end);
338     SRLZ(out_start);
339     SRLZ(out_end);
340     }
341    
342    
343    
344 schoenebeck 3323 // *************** eg_opt_t ***************
345     // *
346    
347     eg_opt_t::eg_opt_t() {
348     AttackCancel = true;
349     AttackHoldCancel = true;
350 schoenebeck 3324 Decay1Cancel = true;
351     Decay2Cancel = true;
352 schoenebeck 3323 ReleaseCancel = true;
353     }
354    
355     void eg_opt_t::serialize(Serialization::Archive* archive) {
356     SRLZ(AttackCancel);
357     SRLZ(AttackHoldCancel);
358 schoenebeck 3324 SRLZ(Decay1Cancel);
359     SRLZ(Decay2Cancel);
360 schoenebeck 3323 SRLZ(ReleaseCancel);
361     }
362    
363    
364    
365 schoenebeck 2 // *************** Sample ***************
366     // *
367    
368 schoenebeck 2922 size_t Sample::Instances = 0;
369 schoenebeck 384 buffer_t Sample::InternalDecompressionBuffer;
370 schoenebeck 2
371 schoenebeck 809 /** @brief Constructor.
372     *
373     * Load an existing sample or create a new one. A 'wave' list chunk must
374     * be given to this constructor. In case the given 'wave' list chunk
375     * contains a 'fmt', 'data' (and optionally a '3gix', 'smpl') chunk, the
376     * format and sample data will be loaded from there, otherwise default
377     * values will be used and those chunks will be created when
378     * File::Save() will be called later on.
379     *
380     * @param pFile - pointer to gig::File where this sample is
381     * located (or will be located)
382     * @param waveList - pointer to 'wave' list chunk which is (or
383     * will be) associated with this sample
384     * @param WavePoolOffset - offset of this sample data from wave pool
385     * ('wvpl') list chunk
386     * @param fileNo - number of an extension file where this sample
387     * is located, 0 otherwise
388 schoenebeck 2989 * @param index - wave pool index of sample (may be -1 on new sample)
389 schoenebeck 809 */
390 schoenebeck 2989 Sample::Sample(File* pFile, RIFF::List* waveList, file_offset_t WavePoolOffset, unsigned long fileNo, int index)
391     : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset)
392     {
393 schoenebeck 1416 static const DLS::Info::string_length_t fixedStringLengths[] = {
394 persson 1180 { CHUNK_ID_INAM, 64 },
395     { 0, 0 }
396     };
397 schoenebeck 1416 pInfo->SetFixedStringLengths(fixedStringLengths);
398 schoenebeck 2 Instances++;
399 persson 666 FileNo = fileNo;
400 schoenebeck 2
401 schoenebeck 1381 __resetCRC(crc);
402 schoenebeck 2989 // if this is not a new sample, try to get the sample's already existing
403     // CRC32 checksum from disk, this checksum will reflect the sample's CRC32
404     // checksum of the time when the sample was consciously modified by the
405     // user for the last time (by calling Sample::Write() that is).
406     if (index >= 0) { // not a new file ...
407     try {
408     uint32_t crc = pFile->GetSampleChecksumByIndex(index);
409     this->crc = crc;
410     } catch (...) {}
411     }
412 schoenebeck 1381
413 schoenebeck 809 pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
414     if (pCk3gix) {
415 schoenebeck 3478 pCk3gix->SetPos(0);
416    
417 schoenebeck 929 uint16_t iSampleGroup = pCk3gix->ReadInt16();
418 schoenebeck 930 pGroup = pFile->GetGroup(iSampleGroup);
419 schoenebeck 809 } else { // '3gix' chunk missing
420 schoenebeck 930 // by default assigned to that mandatory "Default Group"
421     pGroup = pFile->GetGroup(0);
422 schoenebeck 809 }
423 schoenebeck 2
424 schoenebeck 809 pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
425     if (pCkSmpl) {
426 schoenebeck 3478 pCkSmpl->SetPos(0);
427    
428 schoenebeck 809 Manufacturer = pCkSmpl->ReadInt32();
429     Product = pCkSmpl->ReadInt32();
430     SamplePeriod = pCkSmpl->ReadInt32();
431     MIDIUnityNote = pCkSmpl->ReadInt32();
432     FineTune = pCkSmpl->ReadInt32();
433     pCkSmpl->Read(&SMPTEFormat, 1, 4);
434     SMPTEOffset = pCkSmpl->ReadInt32();
435     Loops = pCkSmpl->ReadInt32();
436     pCkSmpl->ReadInt32(); // manufByt
437     LoopID = pCkSmpl->ReadInt32();
438     pCkSmpl->Read(&LoopType, 1, 4);
439     LoopStart = pCkSmpl->ReadInt32();
440     LoopEnd = pCkSmpl->ReadInt32();
441     LoopFraction = pCkSmpl->ReadInt32();
442     LoopPlayCount = pCkSmpl->ReadInt32();
443     } else { // 'smpl' chunk missing
444     // use default values
445     Manufacturer = 0;
446     Product = 0;
447 persson 928 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
448 persson 1218 MIDIUnityNote = 60;
449 schoenebeck 809 FineTune = 0;
450 persson 1182 SMPTEFormat = smpte_format_no_offset;
451 schoenebeck 809 SMPTEOffset = 0;
452     Loops = 0;
453     LoopID = 0;
454 persson 1182 LoopType = loop_type_normal;
455 schoenebeck 809 LoopStart = 0;
456     LoopEnd = 0;
457     LoopFraction = 0;
458     LoopPlayCount = 0;
459     }
460 schoenebeck 2
461     FrameTable = NULL;
462     SamplePos = 0;
463     RAMCache.Size = 0;
464     RAMCache.pStart = NULL;
465     RAMCache.NullExtensionSize = 0;
466    
467 persson 365 if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
468    
469 persson 437 RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
470     Compressed = ewav;
471     Dithered = false;
472     TruncatedBits = 0;
473 schoenebeck 2 if (Compressed) {
474 schoenebeck 3478 ewav->SetPos(0);
475    
476 persson 437 uint32_t version = ewav->ReadInt32();
477 schoenebeck 3440 if (version > 2 && BitDepth == 24) {
478 persson 437 Dithered = ewav->ReadInt32();
479     ewav->SetPos(Channels == 2 ? 84 : 64);
480     TruncatedBits = ewav->ReadInt32();
481     }
482 schoenebeck 2 ScanCompressedSample();
483     }
484 schoenebeck 317
485     // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
486 schoenebeck 384 if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) {
487     InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
488     InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE;
489 schoenebeck 317 }
490 persson 437 FrameOffset = 0; // just for streaming compressed samples
491 schoenebeck 21
492 persson 864 LoopSize = LoopEnd - LoopStart + 1;
493 schoenebeck 2 }
494    
495 schoenebeck 809 /**
496 schoenebeck 2482 * Make a (semi) deep copy of the Sample object given by @a orig (without
497     * the actual waveform data) and assign it to this object.
498     *
499     * Discussion: copying .gig samples is a bit tricky. It requires three
500     * steps:
501     * 1. Copy sample's meta informations (done by CopyAssignMeta()) including
502     * its new sample waveform data size.
503     * 2. Saving the file (done by File::Save()) so that it gains correct size
504     * and layout for writing the actual wave form data directly to disc
505     * in next step.
506     * 3. Copy the waveform data with disk streaming (done by CopyAssignWave()).
507     *
508     * @param orig - original Sample object to be copied from
509     */
510     void Sample::CopyAssignMeta(const Sample* orig) {
511     // handle base classes
512     DLS::Sample::CopyAssignCore(orig);
513    
514     // handle actual own attributes of this class
515     Manufacturer = orig->Manufacturer;
516     Product = orig->Product;
517     SamplePeriod = orig->SamplePeriod;
518     MIDIUnityNote = orig->MIDIUnityNote;
519     FineTune = orig->FineTune;
520     SMPTEFormat = orig->SMPTEFormat;
521     SMPTEOffset = orig->SMPTEOffset;
522     Loops = orig->Loops;
523     LoopID = orig->LoopID;
524     LoopType = orig->LoopType;
525     LoopStart = orig->LoopStart;
526     LoopEnd = orig->LoopEnd;
527     LoopSize = orig->LoopSize;
528     LoopFraction = orig->LoopFraction;
529     LoopPlayCount = orig->LoopPlayCount;
530    
531     // schedule resizing this sample to the given sample's size
532     Resize(orig->GetSize());
533     }
534    
535     /**
536     * Should be called after CopyAssignMeta() and File::Save() sequence.
537     * Read more about it in the discussion of CopyAssignMeta(). This method
538     * copies the actual waveform data by disk streaming.
539     *
540     * @e CAUTION: this method is currently not thread safe! During this
541     * operation the sample must not be used for other purposes by other
542     * threads!
543     *
544     * @param orig - original Sample object to be copied from
545     */
546     void Sample::CopyAssignWave(const Sample* orig) {
547     const int iReadAtOnce = 32*1024;
548     char* buf = new char[iReadAtOnce * orig->FrameSize];
549     Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
550 schoenebeck 2912 file_offset_t restorePos = pOrig->GetPos();
551 schoenebeck 2482 pOrig->SetPos(0);
552     SetPos(0);
553 schoenebeck 2912 for (file_offset_t n = pOrig->Read(buf, iReadAtOnce); n;
554 schoenebeck 2482 n = pOrig->Read(buf, iReadAtOnce))
555     {
556     Write(buf, n);
557     }
558     pOrig->SetPos(restorePos);
559     delete [] buf;
560     }
561    
562     /**
563 schoenebeck 809 * Apply sample and its settings to the respective RIFF chunks. You have
564     * to call File::Save() to make changes persistent.
565     *
566     * Usually there is absolutely no need to call this method explicitly.
567     * It will be called automatically when File::Save() was called.
568     *
569 schoenebeck 2682 * @param pProgress - callback function for progress notification
570 schoenebeck 1050 * @throws DLS::Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data
571 schoenebeck 809 * was provided yet
572     * @throws gig::Exception if there is any invalid sample setting
573     */
574 schoenebeck 2682 void Sample::UpdateChunks(progress_t* pProgress) {
575 schoenebeck 809 // first update base class's chunks
576 schoenebeck 2682 DLS::Sample::UpdateChunks(pProgress);
577 schoenebeck 809
578     // make sure 'smpl' chunk exists
579     pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
580 persson 1182 if (!pCkSmpl) {
581     pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
582     memset(pCkSmpl->LoadChunkData(), 0, 60);
583     }
584 schoenebeck 809 // update 'smpl' chunk
585     uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
586 persson 918 SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
587 persson 1179 store32(&pData[0], Manufacturer);
588     store32(&pData[4], Product);
589     store32(&pData[8], SamplePeriod);
590     store32(&pData[12], MIDIUnityNote);
591     store32(&pData[16], FineTune);
592     store32(&pData[20], SMPTEFormat);
593     store32(&pData[24], SMPTEOffset);
594     store32(&pData[28], Loops);
595 schoenebeck 809
596     // we skip 'manufByt' for now (4 bytes)
597    
598 persson 1179 store32(&pData[36], LoopID);
599     store32(&pData[40], LoopType);
600     store32(&pData[44], LoopStart);
601     store32(&pData[48], LoopEnd);
602     store32(&pData[52], LoopFraction);
603     store32(&pData[56], LoopPlayCount);
604 schoenebeck 809
605     // make sure '3gix' chunk exists
606     pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
607     if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
608 schoenebeck 929 // determine appropriate sample group index (to be stored in chunk)
609 schoenebeck 930 uint16_t iSampleGroup = 0; // 0 refers to default sample group
610 schoenebeck 929 File* pFile = static_cast<File*>(pParent);
611     if (pFile->pGroups) {
612     std::list<Group*>::iterator iter = pFile->pGroups->begin();
613     std::list<Group*>::iterator end = pFile->pGroups->end();
614 schoenebeck 930 for (int i = 0; iter != end; i++, iter++) {
615 schoenebeck 929 if (*iter == pGroup) {
616     iSampleGroup = i;
617     break; // found
618     }
619     }
620     }
621 schoenebeck 809 // update '3gix' chunk
622     pData = (uint8_t*) pCk3gix->LoadChunkData();
623 persson 1179 store16(&pData[0], iSampleGroup);
624 schoenebeck 2484
625     // if the library user toggled the "Compressed" attribute from true to
626     // false, then the EWAV chunk associated with compressed samples needs
627     // to be deleted
628     RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
629     if (ewav && !Compressed) {
630     pWaveList->DeleteSubChunk(ewav);
631     }
632 schoenebeck 809 }
633    
634 schoenebeck 2 /// Scans compressed samples for mandatory informations (e.g. actual number of total sample points).
635     void Sample::ScanCompressedSample() {
636     //TODO: we have to add some more scans here (e.g. determine compression rate)
637     this->SamplesTotal = 0;
638 schoenebeck 2912 std::list<file_offset_t> frameOffsets;
639 schoenebeck 2
640 persson 365 SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
641 schoenebeck 384 WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
642 persson 365
643 schoenebeck 2 // Scanning
644     pCkData->SetPos(0);
645 persson 365 if (Channels == 2) { // Stereo
646     for (int i = 0 ; ; i++) {
647     // for 24 bit samples every 8:th frame offset is
648     // stored, to save some memory
649     if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
650    
651     const int mode_l = pCkData->ReadUint8();
652     const int mode_r = pCkData->ReadUint8();
653     if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
654 schoenebeck 2912 const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
655 persson 365
656     if (pCkData->RemainingBytes() <= frameSize) {
657     SamplesInLastFrame =
658     ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
659     (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
660     SamplesTotal += SamplesInLastFrame;
661 schoenebeck 2 break;
662 persson 365 }
663     SamplesTotal += SamplesPerFrame;
664     pCkData->SetPos(frameSize, RIFF::stream_curpos);
665     }
666     }
667     else { // Mono
668     for (int i = 0 ; ; i++) {
669     if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
670    
671     const int mode = pCkData->ReadUint8();
672     if (mode > 5) throw gig::Exception("Unknown compression mode");
673 schoenebeck 2912 const file_offset_t frameSize = bytesPerFrame[mode];
674 persson 365
675     if (pCkData->RemainingBytes() <= frameSize) {
676     SamplesInLastFrame =
677     ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
678     SamplesTotal += SamplesInLastFrame;
679 schoenebeck 2 break;
680 persson 365 }
681     SamplesTotal += SamplesPerFrame;
682     pCkData->SetPos(frameSize, RIFF::stream_curpos);
683 schoenebeck 2 }
684     }
685     pCkData->SetPos(0);
686    
687     // Build the frames table (which is used for fast resolving of a frame's chunk offset)
688     if (FrameTable) delete[] FrameTable;
689 schoenebeck 2912 FrameTable = new file_offset_t[frameOffsets.size()];
690     std::list<file_offset_t>::iterator end = frameOffsets.end();
691     std::list<file_offset_t>::iterator iter = frameOffsets.begin();
692 schoenebeck 2 for (int i = 0; iter != end; i++, iter++) {
693     FrameTable[i] = *iter;
694     }
695     }
696    
697     /**
698     * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
699     * ReleaseSampleData() to free the memory if you don't need the cached
700     * sample data anymore.
701     *
702     * @returns buffer_t structure with start address and size of the buffer
703     * in bytes
704     * @see ReleaseSampleData(), Read(), SetPos()
705     */
706     buffer_t Sample::LoadSampleData() {
707     return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
708     }
709    
710     /**
711     * Reads (uncompresses if needed) and caches the first \a SampleCount
712     * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
713     * memory space if you don't need the cached samples anymore. There is no
714     * guarantee that exactly \a SampleCount samples will be cached; this is
715     * not an error. The size will be eventually truncated e.g. to the
716     * beginning of a frame of a compressed sample. This is done for
717     * efficiency reasons while streaming the wave by your sampler engine
718     * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
719     * that will be returned to determine the actual cached samples, but note
720     * that the size is given in bytes! You get the number of actually cached
721     * samples by dividing it by the frame size of the sample:
722 schoenebeck 384 * @code
723 schoenebeck 2 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
724     * long cachedsamples = buf.Size / pSample->FrameSize;
725 schoenebeck 384 * @endcode
726 schoenebeck 2 *
727     * @param SampleCount - number of sample points to load into RAM
728     * @returns buffer_t structure with start address and size of
729     * the cached sample data in bytes
730     * @see ReleaseSampleData(), Read(), SetPos()
731     */
732 schoenebeck 2912 buffer_t Sample::LoadSampleData(file_offset_t SampleCount) {
733 schoenebeck 2 return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
734     }
735    
736     /**
737     * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
738     * ReleaseSampleData() to free the memory if you don't need the cached
739     * sample data anymore.
740     * The method will add \a NullSamplesCount silence samples past the
741     * official buffer end (this won't affect the 'Size' member of the
742     * buffer_t structure, that means 'Size' always reflects the size of the
743     * actual sample data, the buffer might be bigger though). Silence
744     * samples past the official buffer are needed for differential
745     * algorithms that always have to take subsequent samples into account
746     * (resampling/interpolation would be an important example) and avoids
747     * memory access faults in such cases.
748     *
749     * @param NullSamplesCount - number of silence samples the buffer should
750     * be extended past it's data end
751     * @returns buffer_t structure with start address and
752     * size of the buffer in bytes
753     * @see ReleaseSampleData(), Read(), SetPos()
754     */
755     buffer_t Sample::LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount) {
756     return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
757     }
758    
759     /**
760     * Reads (uncompresses if needed) and caches the first \a SampleCount
761     * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
762     * memory space if you don't need the cached samples anymore. There is no
763     * guarantee that exactly \a SampleCount samples will be cached; this is
764     * not an error. The size will be eventually truncated e.g. to the
765     * beginning of a frame of a compressed sample. This is done for
766     * efficiency reasons while streaming the wave by your sampler engine
767     * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
768     * that will be returned to determine the actual cached samples, but note
769     * that the size is given in bytes! You get the number of actually cached
770     * samples by dividing it by the frame size of the sample:
771 schoenebeck 384 * @code
772 schoenebeck 2 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
773     * long cachedsamples = buf.Size / pSample->FrameSize;
774 schoenebeck 384 * @endcode
775 schoenebeck 2 * The method will add \a NullSamplesCount silence samples past the
776     * official buffer end (this won't affect the 'Size' member of the
777     * buffer_t structure, that means 'Size' always reflects the size of the
778     * actual sample data, the buffer might be bigger though). Silence
779     * samples past the official buffer are needed for differential
780     * algorithms that always have to take subsequent samples into account
781     * (resampling/interpolation would be an important example) and avoids
782     * memory access faults in such cases.
783     *
784     * @param SampleCount - number of sample points to load into RAM
785     * @param NullSamplesCount - number of silence samples the buffer should
786     * be extended past it's data end
787     * @returns buffer_t structure with start address and
788     * size of the cached sample data in bytes
789     * @see ReleaseSampleData(), Read(), SetPos()
790     */
791 schoenebeck 2912 buffer_t Sample::LoadSampleDataWithNullSamplesExtension(file_offset_t SampleCount, uint NullSamplesCount) {
792 schoenebeck 2 if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
793     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
794 schoenebeck 2912 file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
795 schoenebeck 1851 SetPos(0); // reset read position to begin of sample
796 schoenebeck 2 RAMCache.pStart = new int8_t[allocationsize];
797     RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
798     RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
799     // fill the remaining buffer space with silence samples
800     memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
801     return GetCache();
802     }
803    
804     /**
805     * Returns current cached sample points. A buffer_t structure will be
806     * returned which contains address pointer to the begin of the cache and
807     * the size of the cached sample data in bytes. Use
808     * <i>LoadSampleData()</i> to cache a specific amount of sample points in
809     * RAM.
810     *
811     * @returns buffer_t structure with current cached sample points
812     * @see LoadSampleData();
813     */
814     buffer_t Sample::GetCache() {
815     // return a copy of the buffer_t structure
816     buffer_t result;
817     result.Size = this->RAMCache.Size;
818     result.pStart = this->RAMCache.pStart;
819     result.NullExtensionSize = this->RAMCache.NullExtensionSize;
820     return result;
821     }
822    
823     /**
824     * Frees the cached sample from RAM if loaded with
825     * <i>LoadSampleData()</i> previously.
826     *
827     * @see LoadSampleData();
828     */
829     void Sample::ReleaseSampleData() {
830     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
831     RAMCache.pStart = NULL;
832     RAMCache.Size = 0;
833 schoenebeck 1851 RAMCache.NullExtensionSize = 0;
834 schoenebeck 2 }
835    
836 schoenebeck 809 /** @brief Resize sample.
837     *
838     * Resizes the sample's wave form data, that is the actual size of
839     * sample wave data possible to be written for this sample. This call
840     * will return immediately and just schedule the resize operation. You
841     * should call File::Save() to actually perform the resize operation(s)
842     * "physically" to the file. As this can take a while on large files, it
843     * is recommended to call Resize() first on all samples which have to be
844     * resized and finally to call File::Save() to perform all those resize
845     * operations in one rush.
846     *
847     * The actual size (in bytes) is dependant to the current FrameSize
848     * value. You may want to set FrameSize before calling Resize().
849     *
850     * <b>Caution:</b> You cannot directly write (i.e. with Write()) to
851     * enlarged samples before calling File::Save() as this might exceed the
852     * current sample's boundary!
853     *
854 schoenebeck 1050 * Also note: only DLS_WAVE_FORMAT_PCM is currently supported, that is
855     * FormatTag must be DLS_WAVE_FORMAT_PCM. Trying to resize samples with
856 schoenebeck 809 * other formats will fail!
857     *
858 schoenebeck 2922 * @param NewSize - new sample wave data size in sample points (must be
859     * greater than zero)
860 schoenebeck 1050 * @throws DLS::Excecption if FormatTag != DLS_WAVE_FORMAT_PCM
861 schoenebeck 2922 * @throws DLS::Exception if \a NewSize is less than 1 or unrealistic large
862 schoenebeck 809 * @throws gig::Exception if existing sample is compressed
863     * @see DLS::Sample::GetSize(), DLS::Sample::FrameSize,
864     * DLS::Sample::FormatTag, File::Save()
865     */
866 schoenebeck 2922 void Sample::Resize(file_offset_t NewSize) {
867 schoenebeck 809 if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
868 schoenebeck 2922 DLS::Sample::Resize(NewSize);
869 schoenebeck 809 }
870    
871 schoenebeck 2 /**
872     * Sets the position within the sample (in sample points, not in
873     * bytes). Use this method and <i>Read()</i> if you don't want to load
874     * the sample into RAM, thus for disk streaming.
875     *
876     * Although the original Gigasampler engine doesn't allow positioning
877     * within compressed samples, I decided to implement it. Even though
878     * the Gigasampler format doesn't allow to define loops for compressed
879     * samples at the moment, positioning within compressed samples might be
880     * interesting for some sampler engines though. The only drawback about
881     * my decision is that it takes longer to load compressed gig Files on
882     * startup, because it's neccessary to scan the samples for some
883     * mandatory informations. But I think as it doesn't affect the runtime
884     * efficiency, nobody will have a problem with that.
885     *
886     * @param SampleCount number of sample points to jump
887     * @param Whence optional: to which relation \a SampleCount refers
888     * to, if omited <i>RIFF::stream_start</i> is assumed
889     * @returns the new sample position
890     * @see Read()
891     */
892 schoenebeck 2912 file_offset_t Sample::SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence) {
893 schoenebeck 2 if (Compressed) {
894     switch (Whence) {
895     case RIFF::stream_curpos:
896     this->SamplePos += SampleCount;
897     break;
898     case RIFF::stream_end:
899     this->SamplePos = this->SamplesTotal - 1 - SampleCount;
900     break;
901     case RIFF::stream_backward:
902     this->SamplePos -= SampleCount;
903     break;
904     case RIFF::stream_start: default:
905     this->SamplePos = SampleCount;
906     break;
907     }
908     if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
909    
910 schoenebeck 2912 file_offset_t frame = this->SamplePos / 2048; // to which frame to jump
911 schoenebeck 2 this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
912     pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
913     return this->SamplePos;
914     }
915     else { // not compressed
916 schoenebeck 2912 file_offset_t orderedBytes = SampleCount * this->FrameSize;
917     file_offset_t result = pCkData->SetPos(orderedBytes, Whence);
918 schoenebeck 2 return (result == orderedBytes) ? SampleCount
919     : result / this->FrameSize;
920     }
921     }
922    
923     /**
924     * Returns the current position in the sample (in sample points).
925     */
926 schoenebeck 2912 file_offset_t Sample::GetPos() const {
927 schoenebeck 2 if (Compressed) return SamplePos;
928     else return pCkData->GetPos() / FrameSize;
929     }
930    
931     /**
932 schoenebeck 24 * Reads \a SampleCount number of sample points from the position stored
933     * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
934     * the position within the sample respectively, this method honors the
935     * looping informations of the sample (if any). The sample wave stream
936     * will be decompressed on the fly if using a compressed sample. Use this
937     * method if you don't want to load the sample into RAM, thus for disk
938     * streaming. All this methods needs to know to proceed with streaming
939     * for the next time you call this method is stored in \a pPlaybackState.
940     * You have to allocate and initialize the playback_state_t structure by
941     * yourself before you use it to stream a sample:
942 schoenebeck 384 * @code
943     * gig::playback_state_t playbackstate;
944     * playbackstate.position = 0;
945     * playbackstate.reverse = false;
946     * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
947     * @endcode
948 schoenebeck 24 * You don't have to take care of things like if there is actually a loop
949     * defined or if the current read position is located within a loop area.
950     * The method already handles such cases by itself.
951     *
952 schoenebeck 384 * <b>Caution:</b> If you are using more than one streaming thread, you
953     * have to use an external decompression buffer for <b>EACH</b>
954     * streaming thread to avoid race conditions and crashes!
955     *
956 schoenebeck 24 * @param pBuffer destination buffer
957     * @param SampleCount number of sample points to read
958     * @param pPlaybackState will be used to store and reload the playback
959     * state for the next ReadAndLoop() call
960 persson 864 * @param pDimRgn dimension region with looping information
961 schoenebeck 384 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
962 schoenebeck 24 * @returns number of successfully read sample points
963 schoenebeck 384 * @see CreateDecompressionBuffer()
964 schoenebeck 24 */
965 schoenebeck 2912 file_offset_t Sample::ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState,
966 persson 864 DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
967 schoenebeck 2912 file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
968 schoenebeck 24 uint8_t* pDst = (uint8_t*) pBuffer;
969    
970     SetPos(pPlaybackState->position); // recover position from the last time
971    
972 persson 864 if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
973 schoenebeck 24
974 persson 864 const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
975     const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
976 schoenebeck 24
977 persson 864 if (GetPos() <= loopEnd) {
978     switch (loop.LoopType) {
979 schoenebeck 24
980 persson 864 case loop_type_bidirectional: { //TODO: not tested yet!
981     do {
982     // if not endless loop check if max. number of loop cycles have been passed
983     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
984 schoenebeck 24
985 persson 864 if (!pPlaybackState->reverse) { // forward playback
986     do {
987     samplestoloopend = loopEnd - GetPos();
988     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
989     samplestoread -= readsamples;
990     totalreadsamples += readsamples;
991     if (readsamples == samplestoloopend) {
992     pPlaybackState->reverse = true;
993     break;
994     }
995     } while (samplestoread && readsamples);
996     }
997     else { // backward playback
998 schoenebeck 24
999 persson 864 // as we can only read forward from disk, we have to
1000     // determine the end position within the loop first,
1001     // read forward from that 'end' and finally after
1002     // reading, swap all sample frames so it reflects
1003     // backward playback
1004 schoenebeck 24
1005 schoenebeck 2912 file_offset_t swapareastart = totalreadsamples;
1006     file_offset_t loopoffset = GetPos() - loop.LoopStart;
1007     file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
1008     file_offset_t reverseplaybackend = GetPos() - samplestoreadinloop;
1009 schoenebeck 24
1010 persson 864 SetPos(reverseplaybackend);
1011 schoenebeck 24
1012 persson 864 // read samples for backward playback
1013     do {
1014     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
1015     samplestoreadinloop -= readsamples;
1016     samplestoread -= readsamples;
1017     totalreadsamples += readsamples;
1018     } while (samplestoreadinloop && readsamples);
1019 schoenebeck 24
1020 persson 864 SetPos(reverseplaybackend); // pretend we really read backwards
1021    
1022     if (reverseplaybackend == loop.LoopStart) {
1023     pPlaybackState->loop_cycles_left--;
1024     pPlaybackState->reverse = false;
1025     }
1026    
1027     // reverse the sample frames for backward playback
1028 schoenebeck 1875 if (totalreadsamples > swapareastart) //FIXME: this if() is just a crash workaround for now (#102), but totalreadsamples <= swapareastart should never be the case, so there's probably still a bug above!
1029     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1030 schoenebeck 24 }
1031 persson 864 } while (samplestoread && readsamples);
1032     break;
1033     }
1034 schoenebeck 24
1035 persson 864 case loop_type_backward: { // TODO: not tested yet!
1036     // forward playback (not entered the loop yet)
1037     if (!pPlaybackState->reverse) do {
1038     samplestoloopend = loopEnd - GetPos();
1039     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1040     samplestoread -= readsamples;
1041     totalreadsamples += readsamples;
1042     if (readsamples == samplestoloopend) {
1043     pPlaybackState->reverse = true;
1044     break;
1045     }
1046     } while (samplestoread && readsamples);
1047 schoenebeck 24
1048 persson 864 if (!samplestoread) break;
1049 schoenebeck 24
1050 persson 864 // as we can only read forward from disk, we have to
1051     // determine the end position within the loop first,
1052     // read forward from that 'end' and finally after
1053     // reading, swap all sample frames so it reflects
1054     // backward playback
1055 schoenebeck 24
1056 schoenebeck 2912 file_offset_t swapareastart = totalreadsamples;
1057     file_offset_t loopoffset = GetPos() - loop.LoopStart;
1058     file_offset_t samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
1059 persson 864 : samplestoread;
1060 schoenebeck 2912 file_offset_t reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
1061 schoenebeck 24
1062 persson 864 SetPos(reverseplaybackend);
1063 schoenebeck 24
1064 persson 864 // read samples for backward playback
1065     do {
1066     // if not endless loop check if max. number of loop cycles have been passed
1067     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1068     samplestoloopend = loopEnd - GetPos();
1069     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1070     samplestoreadinloop -= readsamples;
1071     samplestoread -= readsamples;
1072     totalreadsamples += readsamples;
1073     if (readsamples == samplestoloopend) {
1074     pPlaybackState->loop_cycles_left--;
1075     SetPos(loop.LoopStart);
1076     }
1077     } while (samplestoreadinloop && readsamples);
1078 schoenebeck 24
1079 persson 864 SetPos(reverseplaybackend); // pretend we really read backwards
1080 schoenebeck 24
1081 persson 864 // reverse the sample frames for backward playback
1082     SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1083     break;
1084     }
1085 schoenebeck 24
1086 persson 864 default: case loop_type_normal: {
1087     do {
1088     // if not endless loop check if max. number of loop cycles have been passed
1089     if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1090     samplestoloopend = loopEnd - GetPos();
1091     readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1092     samplestoread -= readsamples;
1093     totalreadsamples += readsamples;
1094     if (readsamples == samplestoloopend) {
1095     pPlaybackState->loop_cycles_left--;
1096     SetPos(loop.LoopStart);
1097     }
1098     } while (samplestoread && readsamples);
1099     break;
1100     }
1101 schoenebeck 24 }
1102     }
1103     }
1104    
1105     // read on without looping
1106     if (samplestoread) do {
1107 schoenebeck 384 readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
1108 schoenebeck 24 samplestoread -= readsamples;
1109     totalreadsamples += readsamples;
1110     } while (readsamples && samplestoread);
1111    
1112     // store current position
1113     pPlaybackState->position = GetPos();
1114    
1115     return totalreadsamples;
1116     }
1117    
1118     /**
1119 schoenebeck 2 * Reads \a SampleCount number of sample points from the current
1120     * position into the buffer pointed by \a pBuffer and increments the
1121     * position within the sample. The sample wave stream will be
1122     * decompressed on the fly if using a compressed sample. Use this method
1123     * and <i>SetPos()</i> if you don't want to load the sample into RAM,
1124     * thus for disk streaming.
1125     *
1126 schoenebeck 384 * <b>Caution:</b> If you are using more than one streaming thread, you
1127     * have to use an external decompression buffer for <b>EACH</b>
1128     * streaming thread to avoid race conditions and crashes!
1129     *
1130 persson 902 * For 16 bit samples, the data in the buffer will be int16_t
1131     * (using native endianness). For 24 bit, the buffer will
1132     * contain three bytes per sample, little-endian.
1133     *
1134 schoenebeck 2 * @param pBuffer destination buffer
1135     * @param SampleCount number of sample points to read
1136 schoenebeck 384 * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
1137 schoenebeck 2 * @returns number of successfully read sample points
1138 schoenebeck 384 * @see SetPos(), CreateDecompressionBuffer()
1139 schoenebeck 2 */
1140 schoenebeck 2912 file_offset_t Sample::Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer) {
1141 schoenebeck 21 if (SampleCount == 0) return 0;
1142 schoenebeck 317 if (!Compressed) {
1143     if (BitDepth == 24) {
1144 persson 902 return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1145 schoenebeck 317 }
1146 persson 365 else { // 16 bit
1147     // (pCkData->Read does endian correction)
1148     return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
1149     : pCkData->Read(pBuffer, SampleCount, 2);
1150     }
1151 schoenebeck 317 }
1152 persson 365 else {
1153 schoenebeck 11 if (this->SamplePos >= this->SamplesTotal) return 0;
1154 persson 365 //TODO: efficiency: maybe we should test for an average compression rate
1155 schoenebeck 2912 file_offset_t assumedsize = GuessSize(SampleCount),
1156 schoenebeck 2 remainingbytes = 0, // remaining bytes in the local buffer
1157     remainingsamples = SampleCount,
1158 persson 365 copysamples, skipsamples,
1159     currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
1160 schoenebeck 2 this->FrameOffset = 0;
1161    
1162 schoenebeck 384 buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
1163    
1164     // if decompression buffer too small, then reduce amount of samples to read
1165     if (pDecompressionBuffer->Size < assumedsize) {
1166     std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1167     SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1168     remainingsamples = SampleCount;
1169     assumedsize = GuessSize(SampleCount);
1170 schoenebeck 2 }
1171    
1172 schoenebeck 384 unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1173 persson 365 int16_t* pDst = static_cast<int16_t*>(pBuffer);
1174 persson 902 uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1175 schoenebeck 2 remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1176    
1177 persson 365 while (remainingsamples && remainingbytes) {
1178 schoenebeck 2912 file_offset_t framesamples = SamplesPerFrame;
1179     file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1180 schoenebeck 2
1181 persson 365 int mode_l = *pSrc++, mode_r = 0;
1182    
1183     if (Channels == 2) {
1184     mode_r = *pSrc++;
1185     framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1186     rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1187     nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1188     if (remainingbytes < framebytes) { // last frame in sample
1189     framesamples = SamplesInLastFrame;
1190     if (mode_l == 4 && (framesamples & 1)) {
1191     rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1192     }
1193     else {
1194     rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1195     }
1196 schoenebeck 2 }
1197     }
1198 persson 365 else {
1199     framebytes = bytesPerFrame[mode_l] + 1;
1200     nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1201     if (remainingbytes < framebytes) {
1202     framesamples = SamplesInLastFrame;
1203     }
1204     }
1205 schoenebeck 2
1206     // determine how many samples in this frame to skip and read
1207 persson 365 if (currentframeoffset + remainingsamples >= framesamples) {
1208     if (currentframeoffset <= framesamples) {
1209     copysamples = framesamples - currentframeoffset;
1210     skipsamples = currentframeoffset;
1211     }
1212     else {
1213     copysamples = 0;
1214     skipsamples = framesamples;
1215     }
1216 schoenebeck 2 }
1217     else {
1218 persson 365 // This frame has enough data for pBuffer, but not
1219     // all of the frame is needed. Set file position
1220     // to start of this frame for next call to Read.
1221 schoenebeck 2 copysamples = remainingsamples;
1222 persson 365 skipsamples = currentframeoffset;
1223     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1224     this->FrameOffset = currentframeoffset + copysamples;
1225     }
1226     remainingsamples -= copysamples;
1227    
1228     if (remainingbytes > framebytes) {
1229     remainingbytes -= framebytes;
1230     if (remainingsamples == 0 &&
1231     currentframeoffset + copysamples == framesamples) {
1232     // This frame has enough data for pBuffer, and
1233     // all of the frame is needed. Set file
1234     // position to start of next frame for next
1235     // call to Read. FrameOffset is 0.
1236 schoenebeck 2 pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1237     }
1238     }
1239 persson 365 else remainingbytes = 0;
1240 schoenebeck 2
1241 persson 365 currentframeoffset -= skipsamples;
1242 schoenebeck 2
1243 persson 365 if (copysamples == 0) {
1244     // skip this frame
1245     pSrc += framebytes - Channels;
1246     }
1247     else {
1248     const unsigned char* const param_l = pSrc;
1249     if (BitDepth == 24) {
1250     if (mode_l != 2) pSrc += 12;
1251 schoenebeck 2
1252 persson 365 if (Channels == 2) { // Stereo
1253     const unsigned char* const param_r = pSrc;
1254     if (mode_r != 2) pSrc += 12;
1255    
1256 persson 902 Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1257 persson 437 skipsamples, copysamples, TruncatedBits);
1258 persson 902 Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1259 persson 437 skipsamples, copysamples, TruncatedBits);
1260 persson 902 pDst24 += copysamples * 6;
1261 schoenebeck 2 }
1262 persson 365 else { // Mono
1263 persson 902 Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1264 persson 437 skipsamples, copysamples, TruncatedBits);
1265 persson 902 pDst24 += copysamples * 3;
1266 schoenebeck 2 }
1267 persson 365 }
1268     else { // 16 bit
1269     if (mode_l) pSrc += 4;
1270 schoenebeck 2
1271 persson 365 int step;
1272     if (Channels == 2) { // Stereo
1273     const unsigned char* const param_r = pSrc;
1274     if (mode_r) pSrc += 4;
1275    
1276     step = (2 - mode_l) + (2 - mode_r);
1277 persson 372 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1278     Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1279 persson 365 skipsamples, copysamples);
1280     pDst += copysamples << 1;
1281 schoenebeck 2 }
1282 persson 365 else { // Mono
1283     step = 2 - mode_l;
1284 persson 372 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1285 persson 365 pDst += copysamples;
1286 schoenebeck 2 }
1287 persson 365 }
1288     pSrc += nextFrameOffset;
1289     }
1290 schoenebeck 2
1291 persson 365 // reload from disk to local buffer if needed
1292     if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1293     assumedsize = GuessSize(remainingsamples);
1294     pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1295     if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1296 schoenebeck 384 remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1297     pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1298 schoenebeck 2 }
1299 persson 365 } // while
1300    
1301 schoenebeck 2 this->SamplePos += (SampleCount - remainingsamples);
1302 schoenebeck 11 if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1303 schoenebeck 2 return (SampleCount - remainingsamples);
1304     }
1305     }
1306    
1307 schoenebeck 809 /** @brief Write sample wave data.
1308     *
1309     * Writes \a SampleCount number of sample points from the buffer pointed
1310     * by \a pBuffer and increments the position within the sample. Use this
1311     * method to directly write the sample data to disk, i.e. if you don't
1312     * want or cannot load the whole sample data into RAM.
1313     *
1314     * You have to Resize() the sample to the desired size and call
1315     * File::Save() <b>before</b> using Write().
1316     *
1317     * Note: there is currently no support for writing compressed samples.
1318     *
1319 persson 1264 * For 16 bit samples, the data in the source buffer should be
1320     * int16_t (using native endianness). For 24 bit, the buffer
1321     * should contain three bytes per sample, little-endian.
1322     *
1323 schoenebeck 809 * @param pBuffer - source buffer
1324     * @param SampleCount - number of sample points to write
1325     * @throws DLS::Exception if current sample size is too small
1326     * @throws gig::Exception if sample is compressed
1327     * @see DLS::LoadSampleData()
1328     */
1329 schoenebeck 2912 file_offset_t Sample::Write(void* pBuffer, file_offset_t SampleCount) {
1330 schoenebeck 809 if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1331 persson 1207
1332     // if this is the first write in this sample, reset the
1333     // checksum calculator
1334 persson 1199 if (pCkData->GetPos() == 0) {
1335 schoenebeck 1381 __resetCRC(crc);
1336 persson 1199 }
1337 persson 1264 if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1338 schoenebeck 2912 file_offset_t res;
1339 persson 1264 if (BitDepth == 24) {
1340     res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1341     } else { // 16 bit
1342     res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1343     : pCkData->Write(pBuffer, SampleCount, 2);
1344     }
1345 schoenebeck 1381 __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1346 persson 1199
1347 persson 1207 // if this is the last write, update the checksum chunk in the
1348     // file
1349 persson 1199 if (pCkData->GetPos() == pCkData->GetSize()) {
1350 schoenebeck 3115 __finalizeCRC(crc);
1351 persson 1199 File* pFile = static_cast<File*>(GetParent());
1352 schoenebeck 3115 pFile->SetSampleChecksum(this, crc);
1353 persson 1199 }
1354     return res;
1355 schoenebeck 809 }
1356    
1357 schoenebeck 384 /**
1358     * Allocates a decompression buffer for streaming (compressed) samples
1359     * with Sample::Read(). If you are using more than one streaming thread
1360     * in your application you <b>HAVE</b> to create a decompression buffer
1361     * for <b>EACH</b> of your streaming threads and provide it with the
1362     * Sample::Read() call in order to avoid race conditions and crashes.
1363     *
1364     * You should free the memory occupied by the allocated buffer(s) once
1365     * you don't need one of your streaming threads anymore by calling
1366     * DestroyDecompressionBuffer().
1367     *
1368     * @param MaxReadSize - the maximum size (in sample points) you ever
1369     * expect to read with one Read() call
1370     * @returns allocated decompression buffer
1371     * @see DestroyDecompressionBuffer()
1372     */
1373 schoenebeck 2912 buffer_t Sample::CreateDecompressionBuffer(file_offset_t MaxReadSize) {
1374 schoenebeck 384 buffer_t result;
1375     const double worstCaseHeaderOverhead =
1376     (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1377 schoenebeck 2912 result.Size = (file_offset_t) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1378 schoenebeck 384 result.pStart = new int8_t[result.Size];
1379     result.NullExtensionSize = 0;
1380     return result;
1381     }
1382    
1383     /**
1384     * Free decompression buffer, previously created with
1385     * CreateDecompressionBuffer().
1386     *
1387     * @param DecompressionBuffer - previously allocated decompression
1388     * buffer to free
1389     */
1390     void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1391     if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1392     delete[] (int8_t*) DecompressionBuffer.pStart;
1393     DecompressionBuffer.pStart = NULL;
1394     DecompressionBuffer.Size = 0;
1395     DecompressionBuffer.NullExtensionSize = 0;
1396     }
1397     }
1398    
1399 schoenebeck 930 /**
1400     * Returns pointer to the Group this Sample belongs to. In the .gig
1401     * format a sample always belongs to one group. If it wasn't explicitly
1402     * assigned to a certain group, it will be automatically assigned to a
1403     * default group.
1404     *
1405     * @returns Sample's Group (never NULL)
1406     */
1407     Group* Sample::GetGroup() const {
1408     return pGroup;
1409     }
1410    
1411 schoenebeck 2985 /**
1412 schoenebeck 2989 * Returns the CRC-32 checksum of the sample's raw wave form data at the
1413     * time when this sample's wave form data was modified for the last time
1414     * by calling Write(). This checksum only covers the raw wave form data,
1415     * not any meta informations like i.e. bit depth or loop points. Since
1416     * this method just returns the checksum stored for this sample i.e. when
1417     * the gig file was loaded, this method returns immediately. So it does no
1418     * recalcuation of the checksum with the currently available sample wave
1419     * form data.
1420     *
1421     * @see VerifyWaveData()
1422     */
1423     uint32_t Sample::GetWaveDataCRC32Checksum() {
1424     return crc;
1425     }
1426    
1427     /**
1428 schoenebeck 2985 * Checks the integrity of this sample's raw audio wave data. Whenever a
1429     * Sample's raw wave data is intentionally modified (i.e. by calling
1430     * Write() and supplying the new raw audio wave form data) a CRC32 checksum
1431     * is calculated and stored/updated for this sample, along to the sample's
1432     * meta informations.
1433     *
1434     * Now by calling this method the current raw audio wave data is checked
1435     * against the already stored CRC32 check sum in order to check whether the
1436     * sample data had been damaged unintentionally for some reason. Since by
1437     * calling this method always the entire raw audio wave data has to be
1438     * read, verifying all samples this way may take a long time accordingly.
1439     * And that's also the reason why the sample integrity is not checked by
1440     * default whenever a gig file is loaded. So this method must be called
1441     * explicitly to fulfill this task.
1442     *
1443 schoenebeck 2989 * @param pActually - (optional) if provided, will be set to the actually
1444     * calculated checksum of the current raw wave form data,
1445     * you can get the expected checksum instead by calling
1446     * GetWaveDataCRC32Checksum()
1447 schoenebeck 2985 * @returns true if sample is OK or false if the sample is damaged
1448     * @throws Exception if no checksum had been stored to disk for this
1449     * sample yet, or on I/O issues
1450 schoenebeck 2989 * @see GetWaveDataCRC32Checksum()
1451 schoenebeck 2985 */
1452 schoenebeck 2989 bool Sample::VerifyWaveData(uint32_t* pActually) {
1453 schoenebeck 3053 //File* pFile = static_cast<File*>(GetParent());
1454 schoenebeck 2985 uint32_t crc = CalculateWaveDataChecksum();
1455 schoenebeck 2989 if (pActually) *pActually = crc;
1456     return crc == this->crc;
1457 schoenebeck 2985 }
1458    
1459     uint32_t Sample::CalculateWaveDataChecksum() {
1460     const size_t sz = 20*1024; // 20kB buffer size
1461     std::vector<uint8_t> buffer(sz);
1462     buffer.resize(sz);
1463    
1464     const size_t n = sz / FrameSize;
1465     SetPos(0);
1466     uint32_t crc = 0;
1467     __resetCRC(crc);
1468     while (true) {
1469     file_offset_t nRead = Read(&buffer[0], n);
1470     if (nRead <= 0) break;
1471     __calculateCRC(&buffer[0], nRead * FrameSize, crc);
1472     }
1473 schoenebeck 3115 __finalizeCRC(crc);
1474 schoenebeck 2985 return crc;
1475     }
1476    
1477 schoenebeck 2 Sample::~Sample() {
1478     Instances--;
1479 schoenebeck 384 if (!Instances && InternalDecompressionBuffer.Size) {
1480     delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1481     InternalDecompressionBuffer.pStart = NULL;
1482     InternalDecompressionBuffer.Size = 0;
1483 schoenebeck 355 }
1484 schoenebeck 2 if (FrameTable) delete[] FrameTable;
1485     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1486     }
1487    
1488    
1489    
1490     // *************** DimensionRegion ***************
1491     // *
1492    
1493 schoenebeck 2922 size_t DimensionRegion::Instances = 0;
1494 schoenebeck 16 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1495    
1496 schoenebeck 1316 DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1497 schoenebeck 16 Instances++;
1498    
1499 schoenebeck 823 pSample = NULL;
1500 schoenebeck 1316 pRegion = pParent;
1501 schoenebeck 823
1502 persson 1247 if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1503     else memset(&Crossfade, 0, 4);
1504    
1505 schoenebeck 16 if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1506 schoenebeck 2
1507     RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1508 schoenebeck 809 if (_3ewa) { // if '3ewa' chunk exists
1509 schoenebeck 3478 _3ewa->SetPos(0);
1510    
1511 persson 918 _3ewa->ReadInt32(); // unknown, always == chunk size ?
1512 schoenebeck 809 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1513     EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1514     _3ewa->ReadInt16(); // unknown
1515     LFO1InternalDepth = _3ewa->ReadUint16();
1516     _3ewa->ReadInt16(); // unknown
1517     LFO3InternalDepth = _3ewa->ReadInt16();
1518     _3ewa->ReadInt16(); // unknown
1519     LFO1ControlDepth = _3ewa->ReadUint16();
1520     _3ewa->ReadInt16(); // unknown
1521     LFO3ControlDepth = _3ewa->ReadInt16();
1522     EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1523     EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1524     _3ewa->ReadInt16(); // unknown
1525     EG1Sustain = _3ewa->ReadUint16();
1526     EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1527     EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1528     uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1529     EG1ControllerInvert = eg1ctrloptions & 0x01;
1530     EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1531     EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1532     EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1533     EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1534     uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1535     EG2ControllerInvert = eg2ctrloptions & 0x01;
1536     EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1537     EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1538     EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1539     LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1540     EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1541     EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1542     _3ewa->ReadInt16(); // unknown
1543     EG2Sustain = _3ewa->ReadUint16();
1544     EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1545     _3ewa->ReadInt16(); // unknown
1546     LFO2ControlDepth = _3ewa->ReadUint16();
1547     LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1548     _3ewa->ReadInt16(); // unknown
1549     LFO2InternalDepth = _3ewa->ReadUint16();
1550     int32_t eg1decay2 = _3ewa->ReadInt32();
1551     EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1552     EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1553     _3ewa->ReadInt16(); // unknown
1554     EG1PreAttack = _3ewa->ReadUint16();
1555     int32_t eg2decay2 = _3ewa->ReadInt32();
1556     EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1557     EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1558     _3ewa->ReadInt16(); // unknown
1559     EG2PreAttack = _3ewa->ReadUint16();
1560     uint8_t velocityresponse = _3ewa->ReadUint8();
1561     if (velocityresponse < 5) {
1562     VelocityResponseCurve = curve_type_nonlinear;
1563     VelocityResponseDepth = velocityresponse;
1564     } else if (velocityresponse < 10) {
1565     VelocityResponseCurve = curve_type_linear;
1566     VelocityResponseDepth = velocityresponse - 5;
1567     } else if (velocityresponse < 15) {
1568     VelocityResponseCurve = curve_type_special;
1569     VelocityResponseDepth = velocityresponse - 10;
1570     } else {
1571     VelocityResponseCurve = curve_type_unknown;
1572     VelocityResponseDepth = 0;
1573     }
1574     uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1575     if (releasevelocityresponse < 5) {
1576     ReleaseVelocityResponseCurve = curve_type_nonlinear;
1577     ReleaseVelocityResponseDepth = releasevelocityresponse;
1578     } else if (releasevelocityresponse < 10) {
1579     ReleaseVelocityResponseCurve = curve_type_linear;
1580     ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1581     } else if (releasevelocityresponse < 15) {
1582     ReleaseVelocityResponseCurve = curve_type_special;
1583     ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1584     } else {
1585     ReleaseVelocityResponseCurve = curve_type_unknown;
1586     ReleaseVelocityResponseDepth = 0;
1587     }
1588     VelocityResponseCurveScaling = _3ewa->ReadUint8();
1589     AttenuationControllerThreshold = _3ewa->ReadInt8();
1590     _3ewa->ReadInt32(); // unknown
1591     SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1592     _3ewa->ReadInt16(); // unknown
1593     uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1594     PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1595     if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1596     else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1597     else DimensionBypass = dim_bypass_ctrl_none;
1598     uint8_t pan = _3ewa->ReadUint8();
1599     Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1600     SelfMask = _3ewa->ReadInt8() & 0x01;
1601     _3ewa->ReadInt8(); // unknown
1602     uint8_t lfo3ctrl = _3ewa->ReadUint8();
1603     LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1604     LFO3Sync = lfo3ctrl & 0x20; // bit 5
1605     InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1606     AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1607     uint8_t lfo2ctrl = _3ewa->ReadUint8();
1608     LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1609     LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1610     LFO2Sync = lfo2ctrl & 0x20; // bit 5
1611     bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1612     uint8_t lfo1ctrl = _3ewa->ReadUint8();
1613     LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1614     LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1615     LFO1Sync = lfo1ctrl & 0x40; // bit 6
1616     VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1617     : vcf_res_ctrl_none;
1618     uint16_t eg3depth = _3ewa->ReadUint16();
1619     EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1620 persson 2402 : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1621 schoenebeck 809 _3ewa->ReadInt16(); // unknown
1622     ChannelOffset = _3ewa->ReadUint8() / 4;
1623     uint8_t regoptions = _3ewa->ReadUint8();
1624     MSDecode = regoptions & 0x01; // bit 0
1625     SustainDefeat = regoptions & 0x02; // bit 1
1626     _3ewa->ReadInt16(); // unknown
1627     VelocityUpperLimit = _3ewa->ReadInt8();
1628     _3ewa->ReadInt8(); // unknown
1629     _3ewa->ReadInt16(); // unknown
1630     ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1631     _3ewa->ReadInt8(); // unknown
1632     _3ewa->ReadInt8(); // unknown
1633     EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1634     uint8_t vcfcutoff = _3ewa->ReadUint8();
1635     VCFEnabled = vcfcutoff & 0x80; // bit 7
1636     VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1637     VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1638     uint8_t vcfvelscale = _3ewa->ReadUint8();
1639     VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1640     VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1641     _3ewa->ReadInt8(); // unknown
1642     uint8_t vcfresonance = _3ewa->ReadUint8();
1643     VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1644     VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1645     uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1646     VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1647     VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1648     uint8_t vcfvelocity = _3ewa->ReadUint8();
1649     VCFVelocityDynamicRange = vcfvelocity % 5;
1650     VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1651     VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1652     if (VCFType == vcf_type_lowpass) {
1653     if (lfo3ctrl & 0x40) // bit 6
1654     VCFType = vcf_type_lowpassturbo;
1655     }
1656 persson 1070 if (_3ewa->RemainingBytes() >= 8) {
1657     _3ewa->Read(DimensionUpperLimits, 1, 8);
1658     } else {
1659     memset(DimensionUpperLimits, 0, 8);
1660     }
1661 schoenebeck 809 } else { // '3ewa' chunk does not exist yet
1662     // use default values
1663     LFO3Frequency = 1.0;
1664     EG3Attack = 0.0;
1665     LFO1InternalDepth = 0;
1666     LFO3InternalDepth = 0;
1667     LFO1ControlDepth = 0;
1668     LFO3ControlDepth = 0;
1669     EG1Attack = 0.0;
1670 persson 1218 EG1Decay1 = 0.005;
1671     EG1Sustain = 1000;
1672     EG1Release = 0.3;
1673 schoenebeck 809 EG1Controller.type = eg1_ctrl_t::type_none;
1674     EG1Controller.controller_number = 0;
1675     EG1ControllerInvert = false;
1676     EG1ControllerAttackInfluence = 0;
1677     EG1ControllerDecayInfluence = 0;
1678     EG1ControllerReleaseInfluence = 0;
1679     EG2Controller.type = eg2_ctrl_t::type_none;
1680     EG2Controller.controller_number = 0;
1681     EG2ControllerInvert = false;
1682     EG2ControllerAttackInfluence = 0;
1683     EG2ControllerDecayInfluence = 0;
1684     EG2ControllerReleaseInfluence = 0;
1685     LFO1Frequency = 1.0;
1686     EG2Attack = 0.0;
1687 persson 1218 EG2Decay1 = 0.005;
1688     EG2Sustain = 1000;
1689 schoenebeck 2990 EG2Release = 60;
1690 schoenebeck 809 LFO2ControlDepth = 0;
1691     LFO2Frequency = 1.0;
1692     LFO2InternalDepth = 0;
1693     EG1Decay2 = 0.0;
1694 persson 1218 EG1InfiniteSustain = true;
1695     EG1PreAttack = 0;
1696 schoenebeck 809 EG2Decay2 = 0.0;
1697 persson 1218 EG2InfiniteSustain = true;
1698     EG2PreAttack = 0;
1699 schoenebeck 809 VelocityResponseCurve = curve_type_nonlinear;
1700     VelocityResponseDepth = 3;
1701     ReleaseVelocityResponseCurve = curve_type_nonlinear;
1702     ReleaseVelocityResponseDepth = 3;
1703     VelocityResponseCurveScaling = 32;
1704     AttenuationControllerThreshold = 0;
1705     SampleStartOffset = 0;
1706     PitchTrack = true;
1707     DimensionBypass = dim_bypass_ctrl_none;
1708     Pan = 0;
1709     SelfMask = true;
1710     LFO3Controller = lfo3_ctrl_modwheel;
1711     LFO3Sync = false;
1712     InvertAttenuationController = false;
1713     AttenuationController.type = attenuation_ctrl_t::type_none;
1714     AttenuationController.controller_number = 0;
1715     LFO2Controller = lfo2_ctrl_internal;
1716     LFO2FlipPhase = false;
1717     LFO2Sync = false;
1718     LFO1Controller = lfo1_ctrl_internal;
1719     LFO1FlipPhase = false;
1720     LFO1Sync = false;
1721     VCFResonanceController = vcf_res_ctrl_none;
1722     EG3Depth = 0;
1723     ChannelOffset = 0;
1724     MSDecode = false;
1725     SustainDefeat = false;
1726     VelocityUpperLimit = 0;
1727     ReleaseTriggerDecay = 0;
1728     EG1Hold = false;
1729     VCFEnabled = false;
1730     VCFCutoff = 0;
1731     VCFCutoffController = vcf_cutoff_ctrl_none;
1732     VCFCutoffControllerInvert = false;
1733     VCFVelocityScale = 0;
1734     VCFResonance = 0;
1735     VCFResonanceDynamic = false;
1736     VCFKeyboardTracking = false;
1737     VCFKeyboardTrackingBreakpoint = 0;
1738     VCFVelocityDynamicRange = 0x04;
1739     VCFVelocityCurve = curve_type_linear;
1740     VCFType = vcf_type_lowpass;
1741 persson 1247 memset(DimensionUpperLimits, 127, 8);
1742 schoenebeck 2 }
1743 schoenebeck 3623
1744 schoenebeck 3442 // chunk for own format extensions, these will *NOT* work with Gigasampler/GigaStudio !
1745 schoenebeck 3323 RIFF::Chunk* lsde = _3ewl->GetSubChunk(CHUNK_ID_LSDE);
1746 schoenebeck 3442 if (lsde) { // format extension for EG behavior options
1747 schoenebeck 3478 lsde->SetPos(0);
1748    
1749 schoenebeck 3327 eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1750 schoenebeck 3442 for (int i = 0; i < 2; ++i) { // NOTE: we reserved a 3rd byte for a potential future EG3 option
1751 schoenebeck 3327 unsigned char byte = lsde->ReadUint8();
1752     pEGOpts[i]->AttackCancel = byte & 1;
1753     pEGOpts[i]->AttackHoldCancel = byte & (1 << 1);
1754     pEGOpts[i]->Decay1Cancel = byte & (1 << 2);
1755     pEGOpts[i]->Decay2Cancel = byte & (1 << 3);
1756     pEGOpts[i]->ReleaseCancel = byte & (1 << 4);
1757     }
1758 schoenebeck 3323 }
1759 schoenebeck 3442 // format extension for sustain pedal up effect on release trigger samples
1760     if (lsde && lsde->GetSize() > 3) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
1761     lsde->SetPos(3);
1762 schoenebeck 3446 uint8_t byte = lsde->ReadUint8();
1763     SustainReleaseTrigger = static_cast<sust_rel_trg_t>(byte & 0x03);
1764     NoNoteOffReleaseTrigger = byte >> 7;
1765     } else {
1766     SustainReleaseTrigger = sust_rel_trg_none;
1767     NoNoteOffReleaseTrigger = false;
1768     }
1769 schoenebeck 3623 // format extension for LFOs' wave form, phase displacement and for
1770     // LFO3's flip phase
1771     if (lsde && lsde->GetSize() > 4) {
1772     lsde->SetPos(4);
1773     LFO1WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1774     LFO2WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1775     LFO3WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1776     lsde->ReadUint16(); // unused 16 bits, reserved for potential future use
1777     LFO1Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1778     LFO2Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1779     LFO3Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1780     const uint32_t flags = lsde->ReadInt32();
1781     LFO3FlipPhase = flags & 1;
1782     } else {
1783     LFO1WaveForm = lfo_wave_sine;
1784     LFO2WaveForm = lfo_wave_sine;
1785     LFO3WaveForm = lfo_wave_sine;
1786     LFO1Phase = 0.0;
1787     LFO2Phase = 0.0;
1788     LFO3Phase = 0.0;
1789     LFO3FlipPhase = false;
1790     }
1791 schoenebeck 16
1792 persson 613 pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1793     VelocityResponseDepth,
1794     VelocityResponseCurveScaling);
1795    
1796 schoenebeck 1358 pVelocityReleaseTable = GetReleaseVelocityTable(
1797     ReleaseVelocityResponseCurve,
1798     ReleaseVelocityResponseDepth
1799     );
1800 persson 613
1801 schoenebeck 1358 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1802     VCFVelocityDynamicRange,
1803     VCFVelocityScale,
1804     VCFCutoffController);
1805 persson 613
1806     SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1807 persson 858 VelocityTable = 0;
1808 persson 613 }
1809    
1810 persson 1301 /*
1811     * Constructs a DimensionRegion by copying all parameters from
1812     * another DimensionRegion
1813     */
1814     DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1815     Instances++;
1816 schoenebeck 2394 //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1817 persson 1301 *this = src; // default memberwise shallow copy of all parameters
1818     pParentList = _3ewl; // restore the chunk pointer
1819    
1820     // deep copy of owned structures
1821     if (src.VelocityTable) {
1822     VelocityTable = new uint8_t[128];
1823     for (int k = 0 ; k < 128 ; k++)
1824     VelocityTable[k] = src.VelocityTable[k];
1825     }
1826     if (src.pSampleLoops) {
1827     pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1828     for (int k = 0 ; k < src.SampleLoops ; k++)
1829     pSampleLoops[k] = src.pSampleLoops[k];
1830     }
1831     }
1832 schoenebeck 2394
1833     /**
1834     * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1835     * and assign it to this object.
1836     *
1837     * Note that all sample pointers referenced by @a orig are simply copied as
1838     * memory address. Thus the respective samples are shared, not duplicated!
1839     *
1840     * @param orig - original DimensionRegion object to be copied from
1841     */
1842     void DimensionRegion::CopyAssign(const DimensionRegion* orig) {
1843 schoenebeck 2482 CopyAssign(orig, NULL);
1844     }
1845    
1846     /**
1847     * Make a (semi) deep copy of the DimensionRegion object given by @a orig
1848     * and assign it to this object.
1849     *
1850     * @param orig - original DimensionRegion object to be copied from
1851     * @param mSamples - crosslink map between the foreign file's samples and
1852     * this file's samples
1853     */
1854     void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1855 schoenebeck 2394 // delete all allocated data first
1856     if (VelocityTable) delete [] VelocityTable;
1857     if (pSampleLoops) delete [] pSampleLoops;
1858    
1859     // backup parent list pointer
1860     RIFF::List* p = pParentList;
1861    
1862 schoenebeck 2482 gig::Sample* pOriginalSample = pSample;
1863     gig::Region* pOriginalRegion = pRegion;
1864    
1865 schoenebeck 2394 //NOTE: copy code copied from assignment constructor above, see comment there as well
1866    
1867     *this = *orig; // default memberwise shallow copy of all parameters
1868 schoenebeck 2547
1869     // restore members that shall not be altered
1870 schoenebeck 2394 pParentList = p; // restore the chunk pointer
1871 schoenebeck 2547 pRegion = pOriginalRegion;
1872 schoenebeck 2482
1873 schoenebeck 2547 // only take the raw sample reference reference if the
1874 schoenebeck 2482 // two DimensionRegion objects are part of the same file
1875     if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1876     pSample = pOriginalSample;
1877     }
1878    
1879     if (mSamples && mSamples->count(orig->pSample)) {
1880     pSample = mSamples->find(orig->pSample)->second;
1881     }
1882 persson 1301
1883 schoenebeck 2394 // deep copy of owned structures
1884     if (orig->VelocityTable) {
1885     VelocityTable = new uint8_t[128];
1886     for (int k = 0 ; k < 128 ; k++)
1887     VelocityTable[k] = orig->VelocityTable[k];
1888     }
1889     if (orig->pSampleLoops) {
1890     pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops];
1891     for (int k = 0 ; k < orig->SampleLoops ; k++)
1892     pSampleLoops[k] = orig->pSampleLoops[k];
1893     }
1894     }
1895    
1896 schoenebeck 3138 void DimensionRegion::serialize(Serialization::Archive* archive) {
1897 schoenebeck 3182 // in case this class will become backward incompatible one day,
1898     // then set a version and minimum version for this class like:
1899     //archive->setVersion(*this, 2);
1900     //archive->setMinVersion(*this, 1);
1901    
1902 schoenebeck 3138 SRLZ(VelocityUpperLimit);
1903     SRLZ(EG1PreAttack);
1904     SRLZ(EG1Attack);
1905     SRLZ(EG1Decay1);
1906     SRLZ(EG1Decay2);
1907     SRLZ(EG1InfiniteSustain);
1908     SRLZ(EG1Sustain);
1909     SRLZ(EG1Release);
1910     SRLZ(EG1Hold);
1911     SRLZ(EG1Controller);
1912     SRLZ(EG1ControllerInvert);
1913     SRLZ(EG1ControllerAttackInfluence);
1914     SRLZ(EG1ControllerDecayInfluence);
1915     SRLZ(EG1ControllerReleaseInfluence);
1916 schoenebeck 3623 SRLZ(LFO1WaveForm);
1917 schoenebeck 3138 SRLZ(LFO1Frequency);
1918 schoenebeck 3623 SRLZ(LFO1Phase);
1919 schoenebeck 3138 SRLZ(LFO1InternalDepth);
1920     SRLZ(LFO1ControlDepth);
1921     SRLZ(LFO1Controller);
1922     SRLZ(LFO1FlipPhase);
1923     SRLZ(LFO1Sync);
1924     SRLZ(EG2PreAttack);
1925     SRLZ(EG2Attack);
1926     SRLZ(EG2Decay1);
1927     SRLZ(EG2Decay2);
1928     SRLZ(EG2InfiniteSustain);
1929     SRLZ(EG2Sustain);
1930     SRLZ(EG2Release);
1931     SRLZ(EG2Controller);
1932     SRLZ(EG2ControllerInvert);
1933     SRLZ(EG2ControllerAttackInfluence);
1934     SRLZ(EG2ControllerDecayInfluence);
1935     SRLZ(EG2ControllerReleaseInfluence);
1936 schoenebeck 3623 SRLZ(LFO2WaveForm);
1937 schoenebeck 3138 SRLZ(LFO2Frequency);
1938 schoenebeck 3623 SRLZ(LFO2Phase);
1939 schoenebeck 3138 SRLZ(LFO2InternalDepth);
1940     SRLZ(LFO2ControlDepth);
1941     SRLZ(LFO2Controller);
1942     SRLZ(LFO2FlipPhase);
1943     SRLZ(LFO2Sync);
1944     SRLZ(EG3Attack);
1945     SRLZ(EG3Depth);
1946 schoenebeck 3623 SRLZ(LFO3WaveForm);
1947 schoenebeck 3138 SRLZ(LFO3Frequency);
1948 schoenebeck 3623 SRLZ(LFO3Phase);
1949 schoenebeck 3138 SRLZ(LFO3InternalDepth);
1950     SRLZ(LFO3ControlDepth);
1951     SRLZ(LFO3Controller);
1952 schoenebeck 3623 SRLZ(LFO3FlipPhase);
1953 schoenebeck 3138 SRLZ(LFO3Sync);
1954     SRLZ(VCFEnabled);
1955     SRLZ(VCFType);
1956     SRLZ(VCFCutoffController);
1957     SRLZ(VCFCutoffControllerInvert);
1958     SRLZ(VCFCutoff);
1959     SRLZ(VCFVelocityCurve);
1960     SRLZ(VCFVelocityScale);
1961     SRLZ(VCFVelocityDynamicRange);
1962     SRLZ(VCFResonance);
1963     SRLZ(VCFResonanceDynamic);
1964     SRLZ(VCFResonanceController);
1965     SRLZ(VCFKeyboardTracking);
1966     SRLZ(VCFKeyboardTrackingBreakpoint);
1967     SRLZ(VelocityResponseCurve);
1968     SRLZ(VelocityResponseDepth);
1969     SRLZ(VelocityResponseCurveScaling);
1970     SRLZ(ReleaseVelocityResponseCurve);
1971     SRLZ(ReleaseVelocityResponseDepth);
1972     SRLZ(ReleaseTriggerDecay);
1973     SRLZ(Crossfade);
1974     SRLZ(PitchTrack);
1975     SRLZ(DimensionBypass);
1976     SRLZ(Pan);
1977     SRLZ(SelfMask);
1978     SRLZ(AttenuationController);
1979     SRLZ(InvertAttenuationController);
1980     SRLZ(AttenuationControllerThreshold);
1981     SRLZ(ChannelOffset);
1982     SRLZ(SustainDefeat);
1983     SRLZ(MSDecode);
1984     //SRLZ(SampleStartOffset);
1985     SRLZ(SampleAttenuation);
1986 schoenebeck 3327 SRLZ(EG1Options);
1987     SRLZ(EG2Options);
1988 schoenebeck 3442 SRLZ(SustainReleaseTrigger);
1989 schoenebeck 3446 SRLZ(NoNoteOffReleaseTrigger);
1990 schoenebeck 3138
1991     // derived attributes from DLS::Sampler
1992     SRLZ(FineTune);
1993     SRLZ(Gain);
1994     }
1995    
1996 schoenebeck 809 /**
1997 schoenebeck 1358 * Updates the respective member variable and updates @c SampleAttenuation
1998     * which depends on this value.
1999     */
2000     void DimensionRegion::SetGain(int32_t gain) {
2001     DLS::Sampler::SetGain(gain);
2002     SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
2003     }
2004    
2005     /**
2006 schoenebeck 809 * Apply dimension region settings to the respective RIFF chunks. You
2007     * have to call File::Save() to make changes persistent.
2008     *
2009     * Usually there is absolutely no need to call this method explicitly.
2010     * It will be called automatically when File::Save() was called.
2011 schoenebeck 2682 *
2012     * @param pProgress - callback function for progress notification
2013 schoenebeck 809 */
2014 schoenebeck 2682 void DimensionRegion::UpdateChunks(progress_t* pProgress) {
2015 schoenebeck 809 // first update base class's chunk
2016 schoenebeck 2682 DLS::Sampler::UpdateChunks(pProgress);
2017 schoenebeck 809
2018 persson 1247 RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
2019     uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
2020     pData[12] = Crossfade.in_start;
2021     pData[13] = Crossfade.in_end;
2022     pData[14] = Crossfade.out_start;
2023     pData[15] = Crossfade.out_end;
2024    
2025 schoenebeck 809 // make sure '3ewa' chunk exists
2026     RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
2027 persson 1317 if (!_3ewa) {
2028     File* pFile = (File*) GetParent()->GetParent()->GetParent();
2029 schoenebeck 3440 bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
2030     _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, versiongt2 ? 148 : 140);
2031 persson 1264 }
2032 persson 1247 pData = (uint8_t*) _3ewa->LoadChunkData();
2033 schoenebeck 809
2034     // update '3ewa' chunk with DimensionRegion's current settings
2035    
2036 schoenebeck 3053 const uint32_t chunksize = (uint32_t) _3ewa->GetNewSize();
2037 persson 1179 store32(&pData[0], chunksize); // unknown, always chunk size?
2038 schoenebeck 809
2039     const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
2040 persson 1179 store32(&pData[4], lfo3freq);
2041 schoenebeck 809
2042     const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
2043 persson 1179 store32(&pData[8], eg3attack);
2044 schoenebeck 809
2045     // next 2 bytes unknown
2046    
2047 persson 1179 store16(&pData[14], LFO1InternalDepth);
2048 schoenebeck 809
2049     // next 2 bytes unknown
2050    
2051 persson 1179 store16(&pData[18], LFO3InternalDepth);
2052 schoenebeck 809
2053     // next 2 bytes unknown
2054    
2055 persson 1179 store16(&pData[22], LFO1ControlDepth);
2056 schoenebeck 809
2057     // next 2 bytes unknown
2058    
2059 persson 1179 store16(&pData[26], LFO3ControlDepth);
2060 schoenebeck 809
2061     const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
2062 persson 1179 store32(&pData[28], eg1attack);
2063 schoenebeck 809
2064     const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
2065 persson 1179 store32(&pData[32], eg1decay1);
2066 schoenebeck 809
2067     // next 2 bytes unknown
2068    
2069 persson 1179 store16(&pData[38], EG1Sustain);
2070 schoenebeck 809
2071     const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
2072 persson 1179 store32(&pData[40], eg1release);
2073 schoenebeck 809
2074     const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
2075 persson 1179 pData[44] = eg1ctl;
2076 schoenebeck 809
2077     const uint8_t eg1ctrloptions =
2078 persson 1266 (EG1ControllerInvert ? 0x01 : 0x00) |
2079 schoenebeck 809 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2080     GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2081     GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2082 persson 1179 pData[45] = eg1ctrloptions;
2083 schoenebeck 809
2084     const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2085 persson 1179 pData[46] = eg2ctl;
2086 schoenebeck 809
2087     const uint8_t eg2ctrloptions =
2088 persson 1266 (EG2ControllerInvert ? 0x01 : 0x00) |
2089 schoenebeck 809 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2090     GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2091     GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
2092 persson 1179 pData[47] = eg2ctrloptions;
2093 schoenebeck 809
2094     const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
2095 persson 1179 store32(&pData[48], lfo1freq);
2096 schoenebeck 809
2097     const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
2098 persson 1179 store32(&pData[52], eg2attack);
2099 schoenebeck 809
2100     const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
2101 persson 1179 store32(&pData[56], eg2decay1);
2102 schoenebeck 809
2103     // next 2 bytes unknown
2104    
2105 persson 1179 store16(&pData[62], EG2Sustain);
2106 schoenebeck 809
2107     const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2108 persson 1179 store32(&pData[64], eg2release);
2109 schoenebeck 809
2110     // next 2 bytes unknown
2111    
2112 persson 1179 store16(&pData[70], LFO2ControlDepth);
2113 schoenebeck 809
2114     const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2115 persson 1179 store32(&pData[72], lfo2freq);
2116 schoenebeck 809
2117     // next 2 bytes unknown
2118    
2119 persson 1179 store16(&pData[78], LFO2InternalDepth);
2120 schoenebeck 809
2121     const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2122 persson 1179 store32(&pData[80], eg1decay2);
2123 schoenebeck 809
2124     // next 2 bytes unknown
2125    
2126 persson 1179 store16(&pData[86], EG1PreAttack);
2127 schoenebeck 809
2128     const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2129 persson 1179 store32(&pData[88], eg2decay2);
2130 schoenebeck 809
2131     // next 2 bytes unknown
2132    
2133 persson 1179 store16(&pData[94], EG2PreAttack);
2134 schoenebeck 809
2135     {
2136     if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
2137     uint8_t velocityresponse = VelocityResponseDepth;
2138     switch (VelocityResponseCurve) {
2139     case curve_type_nonlinear:
2140     break;
2141     case curve_type_linear:
2142     velocityresponse += 5;
2143     break;
2144     case curve_type_special:
2145     velocityresponse += 10;
2146     break;
2147     case curve_type_unknown:
2148     default:
2149     throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2150     }
2151 persson 1179 pData[96] = velocityresponse;
2152 schoenebeck 809 }
2153    
2154     {
2155     if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
2156     uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2157     switch (ReleaseVelocityResponseCurve) {
2158     case curve_type_nonlinear:
2159     break;
2160     case curve_type_linear:
2161     releasevelocityresponse += 5;
2162     break;
2163     case curve_type_special:
2164     releasevelocityresponse += 10;
2165     break;
2166     case curve_type_unknown:
2167     default:
2168     throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2169     }
2170 persson 1179 pData[97] = releasevelocityresponse;
2171 schoenebeck 809 }
2172    
2173 persson 1179 pData[98] = VelocityResponseCurveScaling;
2174 schoenebeck 809
2175 persson 1179 pData[99] = AttenuationControllerThreshold;
2176 schoenebeck 809
2177     // next 4 bytes unknown
2178    
2179 persson 1179 store16(&pData[104], SampleStartOffset);
2180 schoenebeck 809
2181     // next 2 bytes unknown
2182    
2183     {
2184     uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2185     switch (DimensionBypass) {
2186     case dim_bypass_ctrl_94:
2187     pitchTrackDimensionBypass |= 0x10;
2188     break;
2189     case dim_bypass_ctrl_95:
2190     pitchTrackDimensionBypass |= 0x20;
2191     break;
2192     case dim_bypass_ctrl_none:
2193     //FIXME: should we set anything here?
2194     break;
2195     default:
2196     throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2197     }
2198 persson 1179 pData[108] = pitchTrackDimensionBypass;
2199 schoenebeck 809 }
2200    
2201     const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
2202 persson 1179 pData[109] = pan;
2203 schoenebeck 809
2204     const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
2205 persson 1179 pData[110] = selfmask;
2206 schoenebeck 809
2207     // next byte unknown
2208    
2209     {
2210     uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
2211     if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
2212     if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
2213     if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
2214 persson 1179 pData[112] = lfo3ctrl;
2215 schoenebeck 809 }
2216    
2217     const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2218 persson 1179 pData[113] = attenctl;
2219 schoenebeck 809
2220     {
2221     uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
2222     if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
2223     if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
2224     if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
2225 persson 1179 pData[114] = lfo2ctrl;
2226 schoenebeck 809 }
2227    
2228     {
2229     uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
2230     if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
2231     if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
2232     if (VCFResonanceController != vcf_res_ctrl_none)
2233     lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2234 persson 1179 pData[115] = lfo1ctrl;
2235 schoenebeck 809 }
2236    
2237     const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2238 persson 2402 : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
2239 persson 1869 store16(&pData[116], eg3depth);
2240 schoenebeck 809
2241     // next 2 bytes unknown
2242    
2243     const uint8_t channeloffset = ChannelOffset * 4;
2244 persson 1179 pData[120] = channeloffset;
2245 schoenebeck 809
2246     {
2247     uint8_t regoptions = 0;
2248     if (MSDecode) regoptions |= 0x01; // bit 0
2249     if (SustainDefeat) regoptions |= 0x02; // bit 1
2250 persson 1179 pData[121] = regoptions;
2251 schoenebeck 809 }
2252    
2253     // next 2 bytes unknown
2254    
2255 persson 1179 pData[124] = VelocityUpperLimit;
2256 schoenebeck 809
2257     // next 3 bytes unknown
2258    
2259 persson 1179 pData[128] = ReleaseTriggerDecay;
2260 schoenebeck 809
2261     // next 2 bytes unknown
2262    
2263     const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
2264 persson 1179 pData[131] = eg1hold;
2265 schoenebeck 809
2266 persson 1266 const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
2267 persson 918 (VCFCutoff & 0x7f); /* lower 7 bits */
2268 persson 1179 pData[132] = vcfcutoff;
2269 schoenebeck 809
2270 persson 1179 pData[133] = VCFCutoffController;
2271 schoenebeck 809
2272 persson 1266 const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
2273 persson 918 (VCFVelocityScale & 0x7f); /* lower 7 bits */
2274 persson 1179 pData[134] = vcfvelscale;
2275 schoenebeck 809
2276     // next byte unknown
2277    
2278 persson 1266 const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
2279 persson 918 (VCFResonance & 0x7f); /* lower 7 bits */
2280 persson 1179 pData[136] = vcfresonance;
2281 schoenebeck 809
2282 persson 1266 const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2283 persson 918 (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2284 persson 1179 pData[137] = vcfbreakpoint;
2285 schoenebeck 809
2286 persson 2152 const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2287 schoenebeck 809 VCFVelocityCurve * 5;
2288 persson 1179 pData[138] = vcfvelocity;
2289 schoenebeck 809
2290     const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2291 persson 1179 pData[139] = vcftype;
2292 persson 1070
2293     if (chunksize >= 148) {
2294     memcpy(&pData[140], DimensionUpperLimits, 8);
2295     }
2296 schoenebeck 3323
2297 schoenebeck 3442 // chunk for own format extensions, these will *NOT* work with
2298 schoenebeck 3323 // Gigasampler/GigaStudio !
2299     RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2300 schoenebeck 3623 const int lsdeSize =
2301     3 /* EG cancel options */ +
2302     1 /* sustain pedal up on release trigger option */ +
2303     8 /* LFOs' wave forms */ + 12 /* LFOs' phase */ + 4 /* flags (LFO3FlipPhase) */;
2304     if (!lsde && UsesAnyGigFormatExtension()) {
2305     // only add this "LSDE" chunk if there is some (format extension)
2306     // setting effective that would require our "LSDE" format extension
2307     // chunk to be stored
2308     lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2309     // move LSDE chunk to the end of parent list
2310     pParentList->MoveSubChunk(lsde, (RIFF::Chunk*)NULL);
2311 schoenebeck 3323 }
2312     if (lsde) {
2313 schoenebeck 3442 if (lsde->GetNewSize() < lsdeSize)
2314     lsde->Resize(lsdeSize);
2315     // format extension for EG behavior options
2316 schoenebeck 3327 unsigned char* pData = (unsigned char*) lsde->LoadChunkData();
2317     eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
2318 schoenebeck 3442 for (int i = 0; i < 2; ++i) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
2319 schoenebeck 3327 pData[i] =
2320     (pEGOpts[i]->AttackCancel ? 1 : 0) |
2321     (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2322     (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2323     (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2324     (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2325     }
2326 schoenebeck 3446 // format extension for release trigger options
2327     pData[3] = static_cast<uint8_t>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 0);
2328 schoenebeck 3623 // format extension for LFOs' wave form, phase displacement and for
2329     // LFO3's flip phase
2330     store16(&pData[4], LFO1WaveForm);
2331     store16(&pData[6], LFO2WaveForm);
2332     store16(&pData[8], LFO3WaveForm);
2333     //NOTE: 16 bits reserved here for potential future use !
2334     const int32_t lfo1Phase = (int32_t) GIG_EXP_ENCODE(LFO1Phase);
2335     const int32_t lfo2Phase = (int32_t) GIG_EXP_ENCODE(LFO2Phase);
2336     const int32_t lfo3Phase = (int32_t) GIG_EXP_ENCODE(LFO3Phase);
2337     store32(&pData[12], lfo1Phase);
2338     store32(&pData[16], lfo2Phase);
2339     store32(&pData[20], lfo3Phase);
2340     const int32_t flags = LFO3FlipPhase ? 1 : 0;
2341     store32(&pData[24], flags);
2342    
2343     // compile time sanity check: is our last store access here
2344     // consistent with the initial lsdeSize value assignment?
2345     static_assert(lsdeSize == 28, "Inconsistency in assumed 'LSDE' RIFF chunk size");
2346 schoenebeck 3323 }
2347 schoenebeck 809 }
2348    
2349 schoenebeck 3623 /**
2350     * Returns @c true in case this DimensionRegion object uses any gig format
2351     * extension, that is whether this DimensionRegion object currently has any
2352     * setting effective that would require our "LSDE" RIFF chunk to be stored
2353     * to the gig file.
2354     *
2355     * Right now this is a private method. It is considerable though this method
2356     * to become (in slightly modified form) a public API method in future, i.e.
2357     * to allow instrument editors to visualize and/or warn the user of any
2358     * format extension being used. Right now this method really just serves to
2359     * answer the question whether an LSDE chunk is required, for the public API
2360     * purpose this method would also need to check whether any other setting
2361     * stored to the regular value '3ewa' chunk, is actually a format extension
2362     * as well.
2363     */
2364     bool DimensionRegion::UsesAnyGigFormatExtension() const {
2365     eg_opt_t defaultOpt;
2366     return memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||
2367     memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)) ||
2368     SustainReleaseTrigger || NoNoteOffReleaseTrigger ||
2369     LFO1WaveForm || LFO2WaveForm || LFO3WaveForm ||
2370     LFO1Phase || LFO2Phase || LFO3Phase ||
2371     LFO3FlipPhase;
2372     }
2373    
2374 schoenebeck 1358 double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2375     curve_type_t curveType = releaseVelocityResponseCurve;
2376     uint8_t depth = releaseVelocityResponseDepth;
2377     // this models a strange behaviour or bug in GSt: two of the
2378     // velocity response curves for release time are not used even
2379     // if specified, instead another curve is chosen.
2380     if ((curveType == curve_type_nonlinear && depth == 0) ||
2381     (curveType == curve_type_special && depth == 4)) {
2382     curveType = curve_type_nonlinear;
2383     depth = 3;
2384     }
2385     return GetVelocityTable(curveType, depth, 0);
2386     }
2387    
2388     double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2389     uint8_t vcfVelocityDynamicRange,
2390     uint8_t vcfVelocityScale,
2391     vcf_cutoff_ctrl_t vcfCutoffController)
2392     {
2393     curve_type_t curveType = vcfVelocityCurve;
2394     uint8_t depth = vcfVelocityDynamicRange;
2395     // even stranger GSt: two of the velocity response curves for
2396     // filter cutoff are not used, instead another special curve
2397     // is chosen. This curve is not used anywhere else.
2398     if ((curveType == curve_type_nonlinear && depth == 0) ||
2399     (curveType == curve_type_special && depth == 4)) {
2400     curveType = curve_type_special;
2401     depth = 5;
2402     }
2403     return GetVelocityTable(curveType, depth,
2404     (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2405     ? vcfVelocityScale : 0);
2406     }
2407    
2408 persson 613 // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
2409     double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2410     {
2411 schoenebeck 3349 // sanity check input parameters
2412     // (fallback to some default parameters on ill input)
2413     switch (curveType) {
2414     case curve_type_nonlinear:
2415     case curve_type_linear:
2416     if (depth > 4) {
2417     printf("Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2418     depth = 0;
2419     scaling = 0;
2420     }
2421     break;
2422     case curve_type_special:
2423     if (depth > 5) {
2424     printf("Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2425     depth = 0;
2426     scaling = 0;
2427     }
2428     break;
2429     case curve_type_unknown:
2430     default:
2431     printf("Warning: Unknown velocity curve type (0x%x).\n", curveType);
2432     curveType = curve_type_linear;
2433     depth = 0;
2434     scaling = 0;
2435     break;
2436     }
2437    
2438 persson 613 double* table;
2439     uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2440 schoenebeck 16 if (pVelocityTables->count(tableKey)) { // if key exists
2441 persson 613 table = (*pVelocityTables)[tableKey];
2442 schoenebeck 16 }
2443     else {
2444 persson 613 table = CreateVelocityTable(curveType, depth, scaling);
2445     (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
2446 schoenebeck 16 }
2447 persson 613 return table;
2448 schoenebeck 2 }
2449 schoenebeck 55
2450 schoenebeck 1316 Region* DimensionRegion::GetParent() const {
2451     return pRegion;
2452     }
2453    
2454 schoenebeck 2540 // show error if some _lev_ctrl_* enum entry is not listed in the following function
2455     // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2456     // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2457     //#pragma GCC diagnostic push
2458     //#pragma GCC diagnostic error "-Wswitch"
2459    
2460 schoenebeck 36 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2461     leverage_ctrl_t decodedcontroller;
2462     switch (EncodedController) {
2463     // special controller
2464     case _lev_ctrl_none:
2465     decodedcontroller.type = leverage_ctrl_t::type_none;
2466     decodedcontroller.controller_number = 0;
2467     break;
2468     case _lev_ctrl_velocity:
2469     decodedcontroller.type = leverage_ctrl_t::type_velocity;
2470     decodedcontroller.controller_number = 0;
2471     break;
2472     case _lev_ctrl_channelaftertouch:
2473     decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
2474     decodedcontroller.controller_number = 0;
2475     break;
2476 schoenebeck 55
2477 schoenebeck 36 // ordinary MIDI control change controller
2478     case _lev_ctrl_modwheel:
2479     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2480     decodedcontroller.controller_number = 1;
2481     break;
2482     case _lev_ctrl_breath:
2483     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2484     decodedcontroller.controller_number = 2;
2485     break;
2486     case _lev_ctrl_foot:
2487     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2488     decodedcontroller.controller_number = 4;
2489     break;
2490     case _lev_ctrl_effect1:
2491     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2492     decodedcontroller.controller_number = 12;
2493     break;
2494     case _lev_ctrl_effect2:
2495     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2496     decodedcontroller.controller_number = 13;
2497     break;
2498     case _lev_ctrl_genpurpose1:
2499     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2500     decodedcontroller.controller_number = 16;
2501     break;
2502     case _lev_ctrl_genpurpose2:
2503     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2504     decodedcontroller.controller_number = 17;
2505     break;
2506     case _lev_ctrl_genpurpose3:
2507     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2508     decodedcontroller.controller_number = 18;
2509     break;
2510     case _lev_ctrl_genpurpose4:
2511     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2512     decodedcontroller.controller_number = 19;
2513     break;
2514     case _lev_ctrl_portamentotime:
2515     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2516     decodedcontroller.controller_number = 5;
2517     break;
2518     case _lev_ctrl_sustainpedal:
2519     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2520     decodedcontroller.controller_number = 64;
2521     break;
2522     case _lev_ctrl_portamento:
2523     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2524     decodedcontroller.controller_number = 65;
2525     break;
2526     case _lev_ctrl_sostenutopedal:
2527     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2528     decodedcontroller.controller_number = 66;
2529     break;
2530     case _lev_ctrl_softpedal:
2531     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2532     decodedcontroller.controller_number = 67;
2533     break;
2534     case _lev_ctrl_genpurpose5:
2535     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2536     decodedcontroller.controller_number = 80;
2537     break;
2538     case _lev_ctrl_genpurpose6:
2539     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2540     decodedcontroller.controller_number = 81;
2541     break;
2542     case _lev_ctrl_genpurpose7:
2543     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2544     decodedcontroller.controller_number = 82;
2545     break;
2546     case _lev_ctrl_genpurpose8:
2547     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2548     decodedcontroller.controller_number = 83;
2549     break;
2550     case _lev_ctrl_effect1depth:
2551     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2552     decodedcontroller.controller_number = 91;
2553     break;
2554     case _lev_ctrl_effect2depth:
2555     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2556     decodedcontroller.controller_number = 92;
2557     break;
2558     case _lev_ctrl_effect3depth:
2559     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2560     decodedcontroller.controller_number = 93;
2561     break;
2562     case _lev_ctrl_effect4depth:
2563     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2564     decodedcontroller.controller_number = 94;
2565     break;
2566     case _lev_ctrl_effect5depth:
2567     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2568     decodedcontroller.controller_number = 95;
2569     break;
2570 schoenebeck 55
2571 schoenebeck 2540 // format extension (these controllers are so far only supported by
2572     // LinuxSampler & gigedit) they will *NOT* work with
2573     // Gigasampler/GigaStudio !
2574     case _lev_ctrl_CC3_EXT:
2575     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2576     decodedcontroller.controller_number = 3;
2577     break;
2578     case _lev_ctrl_CC6_EXT:
2579     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2580     decodedcontroller.controller_number = 6;
2581     break;
2582     case _lev_ctrl_CC7_EXT:
2583     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2584     decodedcontroller.controller_number = 7;
2585     break;
2586     case _lev_ctrl_CC8_EXT:
2587     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2588     decodedcontroller.controller_number = 8;
2589     break;
2590     case _lev_ctrl_CC9_EXT:
2591     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2592     decodedcontroller.controller_number = 9;
2593     break;
2594     case _lev_ctrl_CC10_EXT:
2595     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2596     decodedcontroller.controller_number = 10;
2597     break;
2598     case _lev_ctrl_CC11_EXT:
2599     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2600     decodedcontroller.controller_number = 11;
2601     break;
2602     case _lev_ctrl_CC14_EXT:
2603     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2604     decodedcontroller.controller_number = 14;
2605     break;
2606     case _lev_ctrl_CC15_EXT:
2607     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2608     decodedcontroller.controller_number = 15;
2609     break;
2610     case _lev_ctrl_CC20_EXT:
2611     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2612     decodedcontroller.controller_number = 20;
2613     break;
2614     case _lev_ctrl_CC21_EXT:
2615     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2616     decodedcontroller.controller_number = 21;
2617     break;
2618     case _lev_ctrl_CC22_EXT:
2619     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2620     decodedcontroller.controller_number = 22;
2621     break;
2622     case _lev_ctrl_CC23_EXT:
2623     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2624     decodedcontroller.controller_number = 23;
2625     break;
2626     case _lev_ctrl_CC24_EXT:
2627     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2628     decodedcontroller.controller_number = 24;
2629     break;
2630     case _lev_ctrl_CC25_EXT:
2631     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2632     decodedcontroller.controller_number = 25;
2633     break;
2634     case _lev_ctrl_CC26_EXT:
2635     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2636     decodedcontroller.controller_number = 26;
2637     break;
2638     case _lev_ctrl_CC27_EXT:
2639     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2640     decodedcontroller.controller_number = 27;
2641     break;
2642     case _lev_ctrl_CC28_EXT:
2643     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2644     decodedcontroller.controller_number = 28;
2645     break;
2646     case _lev_ctrl_CC29_EXT:
2647     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2648     decodedcontroller.controller_number = 29;
2649     break;
2650     case _lev_ctrl_CC30_EXT:
2651     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2652     decodedcontroller.controller_number = 30;
2653     break;
2654     case _lev_ctrl_CC31_EXT:
2655     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2656     decodedcontroller.controller_number = 31;
2657     break;
2658     case _lev_ctrl_CC68_EXT:
2659     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2660     decodedcontroller.controller_number = 68;
2661     break;
2662     case _lev_ctrl_CC69_EXT:
2663     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2664     decodedcontroller.controller_number = 69;
2665     break;
2666     case _lev_ctrl_CC70_EXT:
2667     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2668     decodedcontroller.controller_number = 70;
2669     break;
2670     case _lev_ctrl_CC71_EXT:
2671     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2672     decodedcontroller.controller_number = 71;
2673     break;
2674     case _lev_ctrl_CC72_EXT:
2675     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2676     decodedcontroller.controller_number = 72;
2677     break;
2678     case _lev_ctrl_CC73_EXT:
2679     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2680     decodedcontroller.controller_number = 73;
2681     break;
2682     case _lev_ctrl_CC74_EXT:
2683     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2684     decodedcontroller.controller_number = 74;
2685     break;
2686     case _lev_ctrl_CC75_EXT:
2687     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2688     decodedcontroller.controller_number = 75;
2689     break;
2690     case _lev_ctrl_CC76_EXT:
2691     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2692     decodedcontroller.controller_number = 76;
2693     break;
2694     case _lev_ctrl_CC77_EXT:
2695     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2696     decodedcontroller.controller_number = 77;
2697     break;
2698     case _lev_ctrl_CC78_EXT:
2699     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2700     decodedcontroller.controller_number = 78;
2701     break;
2702     case _lev_ctrl_CC79_EXT:
2703     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2704     decodedcontroller.controller_number = 79;
2705     break;
2706     case _lev_ctrl_CC84_EXT:
2707     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2708     decodedcontroller.controller_number = 84;
2709     break;
2710     case _lev_ctrl_CC85_EXT:
2711     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2712     decodedcontroller.controller_number = 85;
2713     break;
2714     case _lev_ctrl_CC86_EXT:
2715     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2716     decodedcontroller.controller_number = 86;
2717     break;
2718     case _lev_ctrl_CC87_EXT:
2719     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2720     decodedcontroller.controller_number = 87;
2721     break;
2722     case _lev_ctrl_CC89_EXT:
2723     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2724     decodedcontroller.controller_number = 89;
2725     break;
2726     case _lev_ctrl_CC90_EXT:
2727     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2728     decodedcontroller.controller_number = 90;
2729     break;
2730     case _lev_ctrl_CC96_EXT:
2731     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2732     decodedcontroller.controller_number = 96;
2733     break;
2734     case _lev_ctrl_CC97_EXT:
2735     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2736     decodedcontroller.controller_number = 97;
2737     break;
2738     case _lev_ctrl_CC102_EXT:
2739     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2740     decodedcontroller.controller_number = 102;
2741     break;
2742     case _lev_ctrl_CC103_EXT:
2743     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2744     decodedcontroller.controller_number = 103;
2745     break;
2746     case _lev_ctrl_CC104_EXT:
2747     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2748     decodedcontroller.controller_number = 104;
2749     break;
2750     case _lev_ctrl_CC105_EXT:
2751     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2752     decodedcontroller.controller_number = 105;
2753     break;
2754     case _lev_ctrl_CC106_EXT:
2755     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2756     decodedcontroller.controller_number = 106;
2757     break;
2758     case _lev_ctrl_CC107_EXT:
2759     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2760     decodedcontroller.controller_number = 107;
2761     break;
2762     case _lev_ctrl_CC108_EXT:
2763     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2764     decodedcontroller.controller_number = 108;
2765     break;
2766     case _lev_ctrl_CC109_EXT:
2767     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2768     decodedcontroller.controller_number = 109;
2769     break;
2770     case _lev_ctrl_CC110_EXT:
2771     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2772     decodedcontroller.controller_number = 110;
2773     break;
2774     case _lev_ctrl_CC111_EXT:
2775     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2776     decodedcontroller.controller_number = 111;
2777     break;
2778     case _lev_ctrl_CC112_EXT:
2779     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2780     decodedcontroller.controller_number = 112;
2781     break;
2782     case _lev_ctrl_CC113_EXT:
2783     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2784     decodedcontroller.controller_number = 113;
2785     break;
2786     case _lev_ctrl_CC114_EXT:
2787     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2788     decodedcontroller.controller_number = 114;
2789     break;
2790     case _lev_ctrl_CC115_EXT:
2791     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2792     decodedcontroller.controller_number = 115;
2793     break;
2794     case _lev_ctrl_CC116_EXT:
2795     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2796     decodedcontroller.controller_number = 116;
2797     break;
2798     case _lev_ctrl_CC117_EXT:
2799     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2800     decodedcontroller.controller_number = 117;
2801     break;
2802     case _lev_ctrl_CC118_EXT:
2803     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2804     decodedcontroller.controller_number = 118;
2805     break;
2806     case _lev_ctrl_CC119_EXT:
2807     decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2808     decodedcontroller.controller_number = 119;
2809     break;
2810    
2811 schoenebeck 36 // unknown controller type
2812     default:
2813 schoenebeck 3203 decodedcontroller.type = leverage_ctrl_t::type_none;
2814     decodedcontroller.controller_number = 0;
2815     printf("Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2816     break;
2817 schoenebeck 36 }
2818     return decodedcontroller;
2819     }
2820 schoenebeck 2540
2821     // see above (diagnostic push not supported prior GCC 4.6)
2822     //#pragma GCC diagnostic pop
2823 schoenebeck 2
2824 schoenebeck 809 DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2825     _lev_ctrl_t encodedcontroller;
2826     switch (DecodedController.type) {
2827     // special controller
2828     case leverage_ctrl_t::type_none:
2829     encodedcontroller = _lev_ctrl_none;
2830     break;
2831     case leverage_ctrl_t::type_velocity:
2832     encodedcontroller = _lev_ctrl_velocity;
2833     break;
2834     case leverage_ctrl_t::type_channelaftertouch:
2835     encodedcontroller = _lev_ctrl_channelaftertouch;
2836     break;
2837    
2838     // ordinary MIDI control change controller
2839     case leverage_ctrl_t::type_controlchange:
2840     switch (DecodedController.controller_number) {
2841     case 1:
2842     encodedcontroller = _lev_ctrl_modwheel;
2843     break;
2844     case 2:
2845     encodedcontroller = _lev_ctrl_breath;
2846     break;
2847     case 4:
2848     encodedcontroller = _lev_ctrl_foot;
2849     break;
2850     case 12:
2851     encodedcontroller = _lev_ctrl_effect1;
2852     break;
2853     case 13:
2854     encodedcontroller = _lev_ctrl_effect2;
2855     break;
2856     case 16:
2857     encodedcontroller = _lev_ctrl_genpurpose1;
2858     break;
2859     case 17:
2860     encodedcontroller = _lev_ctrl_genpurpose2;
2861     break;
2862     case 18:
2863     encodedcontroller = _lev_ctrl_genpurpose3;
2864     break;
2865     case 19:
2866     encodedcontroller = _lev_ctrl_genpurpose4;
2867     break;
2868     case 5:
2869     encodedcontroller = _lev_ctrl_portamentotime;
2870     break;
2871     case 64:
2872     encodedcontroller = _lev_ctrl_sustainpedal;
2873     break;
2874     case 65:
2875     encodedcontroller = _lev_ctrl_portamento;
2876     break;
2877     case 66:
2878     encodedcontroller = _lev_ctrl_sostenutopedal;
2879     break;
2880     case 67:
2881     encodedcontroller = _lev_ctrl_softpedal;
2882     break;
2883     case 80:
2884     encodedcontroller = _lev_ctrl_genpurpose5;
2885     break;
2886     case 81:
2887     encodedcontroller = _lev_ctrl_genpurpose6;
2888     break;
2889     case 82:
2890     encodedcontroller = _lev_ctrl_genpurpose7;
2891     break;
2892     case 83:
2893     encodedcontroller = _lev_ctrl_genpurpose8;
2894     break;
2895     case 91:
2896     encodedcontroller = _lev_ctrl_effect1depth;
2897     break;
2898     case 92:
2899     encodedcontroller = _lev_ctrl_effect2depth;
2900     break;
2901     case 93:
2902     encodedcontroller = _lev_ctrl_effect3depth;
2903     break;
2904     case 94:
2905     encodedcontroller = _lev_ctrl_effect4depth;
2906     break;
2907     case 95:
2908     encodedcontroller = _lev_ctrl_effect5depth;
2909     break;
2910 schoenebeck 2540
2911     // format extension (these controllers are so far only
2912     // supported by LinuxSampler & gigedit) they will *NOT*
2913     // work with Gigasampler/GigaStudio !
2914     case 3:
2915     encodedcontroller = _lev_ctrl_CC3_EXT;
2916     break;
2917     case 6:
2918     encodedcontroller = _lev_ctrl_CC6_EXT;
2919     break;
2920     case 7:
2921     encodedcontroller = _lev_ctrl_CC7_EXT;
2922     break;
2923     case 8:
2924     encodedcontroller = _lev_ctrl_CC8_EXT;
2925     break;
2926     case 9:
2927     encodedcontroller = _lev_ctrl_CC9_EXT;
2928     break;
2929     case 10:
2930     encodedcontroller = _lev_ctrl_CC10_EXT;
2931     break;
2932     case 11:
2933     encodedcontroller = _lev_ctrl_CC11_EXT;
2934     break;
2935     case 14:
2936     encodedcontroller = _lev_ctrl_CC14_EXT;
2937     break;
2938     case 15:
2939     encodedcontroller = _lev_ctrl_CC15_EXT;
2940     break;
2941     case 20:
2942     encodedcontroller = _lev_ctrl_CC20_EXT;
2943     break;
2944     case 21:
2945     encodedcontroller = _lev_ctrl_CC21_EXT;
2946     break;
2947     case 22:
2948     encodedcontroller = _lev_ctrl_CC22_EXT;
2949     break;
2950     case 23:
2951     encodedcontroller = _lev_ctrl_CC23_EXT;
2952     break;
2953     case 24:
2954     encodedcontroller = _lev_ctrl_CC24_EXT;
2955     break;
2956     case 25:
2957     encodedcontroller = _lev_ctrl_CC25_EXT;
2958     break;
2959     case 26:
2960     encodedcontroller = _lev_ctrl_CC26_EXT;
2961     break;
2962     case 27:
2963     encodedcontroller = _lev_ctrl_CC27_EXT;
2964     break;
2965     case 28:
2966     encodedcontroller = _lev_ctrl_CC28_EXT;
2967     break;
2968     case 29:
2969     encodedcontroller = _lev_ctrl_CC29_EXT;
2970     break;
2971     case 30:
2972     encodedcontroller = _lev_ctrl_CC30_EXT;
2973     break;
2974     case 31:
2975     encodedcontroller = _lev_ctrl_CC31_EXT;
2976     break;
2977     case 68:
2978     encodedcontroller = _lev_ctrl_CC68_EXT;
2979     break;
2980     case 69:
2981     encodedcontroller = _lev_ctrl_CC69_EXT;
2982     break;
2983     case 70:
2984     encodedcontroller = _lev_ctrl_CC70_EXT;
2985     break;
2986     case 71:
2987     encodedcontroller = _lev_ctrl_CC71_EXT;
2988     break;
2989     case 72:
2990     encodedcontroller = _lev_ctrl_CC72_EXT;
2991     break;
2992     case 73:
2993     encodedcontroller = _lev_ctrl_CC73_EXT;
2994     break;
2995     case 74:
2996     encodedcontroller = _lev_ctrl_CC74_EXT;
2997     break;
2998     case 75:
2999     encodedcontroller = _lev_ctrl_CC75_EXT;
3000     break;
3001     case 76:
3002     encodedcontroller = _lev_ctrl_CC76_EXT;
3003     break;
3004     case 77:
3005     encodedcontroller = _lev_ctrl_CC77_EXT;
3006     break;
3007     case 78:
3008     encodedcontroller = _lev_ctrl_CC78_EXT;
3009     break;
3010     case 79:
3011     encodedcontroller = _lev_ctrl_CC79_EXT;
3012     break;
3013     case 84:
3014     encodedcontroller = _lev_ctrl_CC84_EXT;
3015     break;
3016     case 85:
3017     encodedcontroller = _lev_ctrl_CC85_EXT;
3018     break;
3019     case 86:
3020     encodedcontroller = _lev_ctrl_CC86_EXT;
3021     break;
3022     case 87:
3023     encodedcontroller = _lev_ctrl_CC87_EXT;
3024     break;
3025     case 89:
3026     encodedcontroller = _lev_ctrl_CC89_EXT;
3027     break;
3028     case 90:
3029     encodedcontroller = _lev_ctrl_CC90_EXT;
3030     break;
3031     case 96:
3032     encodedcontroller = _lev_ctrl_CC96_EXT;
3033     break;
3034     case 97:
3035     encodedcontroller = _lev_ctrl_CC97_EXT;
3036     break;
3037     case 102:
3038     encodedcontroller = _lev_ctrl_CC102_EXT;
3039     break;
3040     case 103:
3041     encodedcontroller = _lev_ctrl_CC103_EXT;
3042     break;
3043     case 104:
3044     encodedcontroller = _lev_ctrl_CC104_EXT;
3045     break;
3046     case 105:
3047     encodedcontroller = _lev_ctrl_CC105_EXT;
3048     break;
3049     case 106:
3050     encodedcontroller = _lev_ctrl_CC106_EXT;
3051     break;
3052     case 107:
3053     encodedcontroller = _lev_ctrl_CC107_EXT;
3054     break;
3055     case 108:
3056     encodedcontroller = _lev_ctrl_CC108_EXT;
3057     break;
3058     case 109:
3059     encodedcontroller = _lev_ctrl_CC109_EXT;
3060     break;
3061     case 110:
3062     encodedcontroller = _lev_ctrl_CC110_EXT;
3063     break;
3064     case 111:
3065     encodedcontroller = _lev_ctrl_CC111_EXT;
3066     break;
3067     case 112:
3068     encodedcontroller = _lev_ctrl_CC112_EXT;
3069     break;
3070     case 113:
3071     encodedcontroller = _lev_ctrl_CC113_EXT;
3072     break;
3073     case 114:
3074     encodedcontroller = _lev_ctrl_CC114_EXT;
3075     break;
3076     case 115:
3077     encodedcontroller = _lev_ctrl_CC115_EXT;
3078     break;
3079     case 116:
3080     encodedcontroller = _lev_ctrl_CC116_EXT;
3081     break;
3082     case 117:
3083     encodedcontroller = _lev_ctrl_CC117_EXT;
3084     break;
3085     case 118:
3086     encodedcontroller = _lev_ctrl_CC118_EXT;
3087     break;
3088     case 119:
3089     encodedcontroller = _lev_ctrl_CC119_EXT;
3090     break;
3091    
3092 schoenebeck 809 default:
3093     throw gig::Exception("leverage controller number is not supported by the gig format");
3094     }
3095 persson 1182 break;
3096 schoenebeck 809 default:
3097     throw gig::Exception("Unknown leverage controller type.");
3098     }
3099     return encodedcontroller;
3100     }
3101    
3102 schoenebeck 16 DimensionRegion::~DimensionRegion() {
3103     Instances--;
3104     if (!Instances) {
3105     // delete the velocity->volume tables
3106     VelocityTableMap::iterator iter;
3107     for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3108     double* pTable = iter->second;
3109     if (pTable) delete[] pTable;
3110     }
3111     pVelocityTables->clear();
3112     delete pVelocityTables;
3113     pVelocityTables = NULL;
3114     }
3115 persson 858 if (VelocityTable) delete[] VelocityTable;
3116 schoenebeck 16 }
3117 schoenebeck 2
3118 schoenebeck 16 /**
3119     * Returns the correct amplitude factor for the given \a MIDIKeyVelocity.
3120     * All involved parameters (VelocityResponseCurve, VelocityResponseDepth
3121     * and VelocityResponseCurveScaling) involved are taken into account to
3122     * calculate the amplitude factor. Use this method when a key was
3123     * triggered to get the volume with which the sample should be played
3124     * back.
3125     *
3126 schoenebeck 36 * @param MIDIKeyVelocity MIDI velocity value of the triggered key (between 0 and 127)
3127     * @returns amplitude factor (between 0.0 and 1.0)
3128 schoenebeck 16 */
3129     double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
3130     return pVelocityAttenuationTable[MIDIKeyVelocity];
3131     }
3132 schoenebeck 2
3133 persson 613 double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3134     return pVelocityReleaseTable[MIDIKeyVelocity];
3135     }
3136    
3137 persson 728 double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3138     return pVelocityCutoffTable[MIDIKeyVelocity];
3139     }
3140    
3141 schoenebeck 1358 /**
3142     * Updates the respective member variable and the lookup table / cache
3143     * that depends on this value.
3144     */
3145     void DimensionRegion::SetVelocityResponseCurve(curve_type_t curve) {
3146     pVelocityAttenuationTable =
3147     GetVelocityTable(
3148     curve, VelocityResponseDepth, VelocityResponseCurveScaling
3149     );
3150     VelocityResponseCurve = curve;
3151     }
3152    
3153     /**
3154     * Updates the respective member variable and the lookup table / cache
3155     * that depends on this value.
3156     */
3157     void DimensionRegion::SetVelocityResponseDepth(uint8_t depth) {
3158     pVelocityAttenuationTable =
3159     GetVelocityTable(
3160     VelocityResponseCurve, depth, VelocityResponseCurveScaling
3161     );
3162     VelocityResponseDepth = depth;
3163     }
3164    
3165     /**
3166     * Updates the respective member variable and the lookup table / cache
3167     * that depends on this value.
3168     */
3169     void DimensionRegion::SetVelocityResponseCurveScaling(uint8_t scaling) {
3170     pVelocityAttenuationTable =
3171     GetVelocityTable(
3172     VelocityResponseCurve, VelocityResponseDepth, scaling
3173     );
3174     VelocityResponseCurveScaling = scaling;
3175     }
3176    
3177     /**
3178     * Updates the respective member variable and the lookup table / cache
3179     * that depends on this value.
3180     */
3181     void DimensionRegion::SetReleaseVelocityResponseCurve(curve_type_t curve) {
3182     pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3183     ReleaseVelocityResponseCurve = curve;
3184     }
3185    
3186     /**
3187     * Updates the respective member variable and the lookup table / cache
3188     * that depends on this value.
3189     */
3190     void DimensionRegion::SetReleaseVelocityResponseDepth(uint8_t depth) {
3191     pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3192     ReleaseVelocityResponseDepth = depth;
3193     }
3194    
3195     /**
3196     * Updates the respective member variable and the lookup table / cache
3197     * that depends on this value.
3198     */
3199     void DimensionRegion::SetVCFCutoffController(vcf_cutoff_ctrl_t controller) {
3200     pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3201     VCFCutoffController = controller;
3202     }
3203    
3204     /**
3205     * Updates the respective member variable and the lookup table / cache
3206     * that depends on this value.
3207     */
3208     void DimensionRegion::SetVCFVelocityCurve(curve_type_t curve) {
3209     pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3210     VCFVelocityCurve = curve;
3211     }
3212    
3213     /**
3214     * Updates the respective member variable and the lookup table / cache
3215     * that depends on this value.
3216     */
3217     void DimensionRegion::SetVCFVelocityDynamicRange(uint8_t range) {
3218     pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3219     VCFVelocityDynamicRange = range;
3220     }
3221    
3222     /**
3223     * Updates the respective member variable and the lookup table / cache
3224     * that depends on this value.
3225     */
3226     void DimensionRegion::SetVCFVelocityScale(uint8_t scaling) {
3227     pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3228     VCFVelocityScale = scaling;
3229     }
3230    
3231 schoenebeck 308 double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3232 schoenebeck 317
3233 schoenebeck 308 // line-segment approximations of the 15 velocity curves
3234 schoenebeck 16
3235 schoenebeck 308 // linear
3236     const int lin0[] = { 1, 1, 127, 127 };
3237     const int lin1[] = { 1, 21, 127, 127 };
3238     const int lin2[] = { 1, 45, 127, 127 };
3239     const int lin3[] = { 1, 74, 127, 127 };
3240     const int lin4[] = { 1, 127, 127, 127 };
3241 schoenebeck 16
3242 schoenebeck 308 // non-linear
3243     const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3244 schoenebeck 317 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3245 schoenebeck 308 127, 127 };
3246     const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3247     127, 127 };
3248     const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3249     127, 127 };
3250     const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3251 schoenebeck 317
3252 schoenebeck 308 // special
3253 schoenebeck 317 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3254 schoenebeck 308 113, 127, 127, 127 };
3255     const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3256     118, 127, 127, 127 };
3257 schoenebeck 317 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3258 schoenebeck 308 85, 90, 91, 127, 127, 127 };
3259 schoenebeck 317 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3260 schoenebeck 308 117, 127, 127, 127 };
3261 schoenebeck 317 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3262 schoenebeck 308 127, 127 };
3263 schoenebeck 317
3264 persson 728 // this is only used by the VCF velocity curve
3265     const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3266     91, 127, 127, 127 };
3267    
3268 schoenebeck 308 const int* const curves[] = { non0, non1, non2, non3, non4,
3269 schoenebeck 317 lin0, lin1, lin2, lin3, lin4,
3270 persson 728 spe0, spe1, spe2, spe3, spe4, spe5 };
3271 schoenebeck 317
3272 schoenebeck 308 double* const table = new double[128];
3273    
3274     const int* curve = curves[curveType * 5 + depth];
3275     const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
3276 schoenebeck 317
3277 schoenebeck 308 table[0] = 0;
3278     for (int x = 1 ; x < 128 ; x++) {
3279    
3280     if (x > curve[2]) curve += 2;
3281 schoenebeck 317 double y = curve[1] + (x - curve[0]) *
3282 schoenebeck 308 (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3283     y = y / 127;
3284    
3285     // Scale up for s > 20, down for s < 20. When
3286     // down-scaling, the curve still ends at 1.0.
3287     if (s < 20 && y >= 0.5)
3288     y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3289     else
3290     y = y * (s / 20.0);
3291     if (y > 1) y = 1;
3292    
3293     table[x] = y;
3294     }
3295     return table;
3296     }
3297    
3298    
3299 schoenebeck 2 // *************** Region ***************
3300     // *
3301    
3302     Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
3303     // Initialization
3304     Dimensions = 0;
3305 schoenebeck 347 for (int i = 0; i < 256; i++) {
3306 schoenebeck 2 pDimensionRegions[i] = NULL;
3307     }
3308 schoenebeck 282 Layers = 1;
3309 schoenebeck 347 File* file = (File*) GetParent()->GetParent();
3310 schoenebeck 3440 int dimensionBits = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3311 schoenebeck 2
3312     // Actual Loading
3313    
3314 schoenebeck 1524 if (!file->GetAutoLoad()) return;
3315    
3316 schoenebeck 2 LoadDimensionRegions(rgnList);
3317    
3318     RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
3319     if (_3lnk) {
3320 schoenebeck 3478 _3lnk->SetPos(0);
3321    
3322 schoenebeck 2 DimensionRegions = _3lnk->ReadUint32();
3323 schoenebeck 347 for (int i = 0; i < dimensionBits; i++) {
3324 schoenebeck 2 dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
3325     uint8_t bits = _3lnk->ReadUint8();
3326 persson 1199 _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
3327     _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
3328 persson 774 uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
3329 schoenebeck 2 if (dimension == dimension_none) { // inactive dimension
3330     pDimensionDefinitions[i].dimension = dimension_none;
3331     pDimensionDefinitions[i].bits = 0;
3332     pDimensionDefinitions[i].zones = 0;
3333     pDimensionDefinitions[i].split_type = split_type_bit;
3334     pDimensionDefinitions[i].zone_size = 0;
3335     }
3336     else { // active dimension
3337     pDimensionDefinitions[i].dimension = dimension;
3338     pDimensionDefinitions[i].bits = bits;
3339 persson 774 pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
3340 schoenebeck 1113 pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3341     pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3342 schoenebeck 2 Dimensions++;
3343 schoenebeck 282
3344     // if this is a layer dimension, remember the amount of layers
3345     if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
3346 schoenebeck 2 }
3347 persson 774 _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
3348 schoenebeck 2 }
3349 persson 834 for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3350 schoenebeck 2
3351 persson 858 // if there's a velocity dimension and custom velocity zone splits are used,
3352     // update the VelocityTables in the dimension regions
3353     UpdateVelocityTable();
3354 schoenebeck 2
3355 schoenebeck 317 // jump to start of the wave pool indices (if not already there)
3356 schoenebeck 3440 if (file->pVersion && file->pVersion->major > 2)
3357 schoenebeck 317 _3lnk->SetPos(68); // version 3 has a different 3lnk structure
3358     else
3359     _3lnk->SetPos(44);
3360    
3361 schoenebeck 1524 // load sample references (if auto loading is enabled)
3362     if (file->GetAutoLoad()) {
3363     for (uint i = 0; i < DimensionRegions; i++) {
3364     uint32_t wavepoolindex = _3lnk->ReadUint32();
3365 schoenebeck 3348 if (file->pWavePoolTable && pDimensionRegions[i])
3366     pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3367 schoenebeck 1524 }
3368     GetSample(); // load global region sample reference
3369 schoenebeck 2 }
3370 persson 1102 } else {
3371     DimensionRegions = 0;
3372 persson 1182 for (int i = 0 ; i < 8 ; i++) {
3373     pDimensionDefinitions[i].dimension = dimension_none;
3374     pDimensionDefinitions[i].bits = 0;
3375     pDimensionDefinitions[i].zones = 0;
3376     }
3377 schoenebeck 2 }
3378 schoenebeck 823
3379     // make sure there is at least one dimension region
3380     if (!DimensionRegions) {
3381     RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
3382     if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
3383     RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
3384 schoenebeck 1316 pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
3385 schoenebeck 823 DimensionRegions = 1;
3386     }
3387 schoenebeck 2 }
3388    
3389 schoenebeck 809 /**
3390     * Apply Region settings and all its DimensionRegions to the respective
3391     * RIFF chunks. You have to call File::Save() to make changes persistent.
3392     *
3393     * Usually there is absolutely no need to call this method explicitly.
3394     * It will be called automatically when File::Save() was called.
3395     *
3396 schoenebeck 2682 * @param pProgress - callback function for progress notification
3397 schoenebeck 809 * @throws gig::Exception if samples cannot be dereferenced
3398     */
3399 schoenebeck 2682 void Region::UpdateChunks(progress_t* pProgress) {
3400 schoenebeck 1106 // in the gig format we don't care about the Region's sample reference
3401     // but we still have to provide some existing one to not corrupt the
3402     // file, so to avoid the latter we simply always assign the sample of
3403     // the first dimension region of this region
3404     pSample = pDimensionRegions[0]->pSample;
3405    
3406 schoenebeck 809 // first update base class's chunks
3407 schoenebeck 2682 DLS::Region::UpdateChunks(pProgress);
3408 schoenebeck 809
3409     // update dimension region's chunks
3410 schoenebeck 823 for (int i = 0; i < DimensionRegions; i++) {
3411 schoenebeck 2682 pDimensionRegions[i]->UpdateChunks(pProgress);
3412 schoenebeck 823 }
3413 schoenebeck 809
3414 persson 1317 File* pFile = (File*) GetParent()->GetParent();
3415 schoenebeck 3657 const bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
3416 schoenebeck 3440 const int iMaxDimensions = versiongt2 ? 8 : 5;
3417     const int iMaxDimensionRegions = versiongt2 ? 256 : 32;
3418 schoenebeck 809
3419     // make sure '3lnk' chunk exists
3420     RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3421     if (!_3lnk) {
3422 schoenebeck 3440 const int _3lnkChunkSize = versiongt2 ? 1092 : 172;
3423 schoenebeck 809 _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3424 persson 1182 memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3425 persson 1192
3426     // move 3prg to last position
3427 schoenebeck 2584 pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (RIFF::Chunk*)NULL);
3428 schoenebeck 809 }
3429    
3430     // update dimension definitions in '3lnk' chunk
3431     uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3432 persson 1179 store32(&pData[0], DimensionRegions);
3433 persson 1199 int shift = 0;
3434 schoenebeck 809 for (int i = 0; i < iMaxDimensions; i++) {
3435 persson 918 pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3436     pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3437 persson 1266 pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3438 persson 1199 pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3439 persson 918 pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3440 persson 1199 // next 3 bytes unknown, always zero?
3441    
3442     shift += pDimensionDefinitions[i].bits;
3443 schoenebeck 809 }
3444    
3445     // update wave pool table in '3lnk' chunk
3446 schoenebeck 3440 const int iWavePoolOffset = versiongt2 ? 68 : 44;
3447 schoenebeck 809 for (uint i = 0; i < iMaxDimensionRegions; i++) {
3448     int iWaveIndex = -1;
3449     if (i < DimensionRegions) {
3450 schoenebeck 823 if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
3451     File::SampleList::iterator iter = pFile->pSamples->begin();
3452     File::SampleList::iterator end = pFile->pSamples->end();
3453 schoenebeck 809 for (int index = 0; iter != end; ++iter, ++index) {
3454 schoenebeck 823 if (*iter == pDimensionRegions[i]->pSample) {
3455     iWaveIndex = index;
3456     break;
3457     }
3458 schoenebeck 809 }
3459     }
3460 persson 1179 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3461 schoenebeck 809 }
3462 schoenebeck 3657
3463 schoenebeck 3710 // The following chunks are just added for compatibility with the
3464     // GigaStudio software, which would show a warning if these were
3465     // missing. However currently these chunks don't cover any useful
3466     // data. So if this gig file uses any of our own gig format
3467     // extensions which would cause this gig file to be unloadable
3468     // with GSt software anyway, then just skip these GSt compatibility
3469     // chunks here as well.
3470     if (versiongt2 && !UsesAnyGigFormatExtension()) {
3471 schoenebeck 3657 // add 3dnm list which always seems to be empty
3472     RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM);
3473     if (!_3dnm) _3dnm = pCkRegion->AddSubList(LIST_TYPE_3DNM);
3474    
3475     // add 3ddp chunk which always seems to have 16 bytes of 0xFF
3476     RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP);
3477     if (!_3ddp) _3ddp = pCkRegion->AddSubChunk(CHUNK_ID_3DDP, 16);
3478     uint8_t* pData = (uint8_t*) _3ddp->LoadChunkData();
3479     for (int i = 0; i < 16; i += 4) {
3480     store32(&pData[i], 0xFFFFFFFF);
3481     }
3482    
3483     // move 3dnm and 3ddp to the end of the region list
3484     pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3DNM), (RIFF::Chunk*)NULL);
3485     pCkRegion->MoveSubChunk(pCkRegion->GetSubChunk(CHUNK_ID_3DDP), (RIFF::Chunk*)NULL);
3486     } else {
3487     // this is intended for the user switching from GSt >= 3 version
3488     // back to an older format version, delete GSt3 chunks ...
3489     RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM);
3490     if (_3dnm) pCkRegion->DeleteSubChunk(_3dnm);
3491    
3492     RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP);
3493     if (_3ddp) pCkRegion->DeleteSubChunk(_3ddp);
3494     }
3495 schoenebeck 809 }
3496    
3497 schoenebeck 2 void Region::LoadDimensionRegions(RIFF::List* rgn) {
3498     RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
3499     if (_3prg) {
3500     int dimensionRegionNr = 0;
3501     RIFF::List* _3ewl = _3prg->GetFirstSubList();
3502     while (_3ewl) {
3503     if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3504 schoenebeck 1316 pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3505 schoenebeck 2 dimensionRegionNr++;
3506     }
3507     _3ewl = _3prg->GetNextSubList();
3508     }
3509     if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
3510     }
3511     }
3512    
3513 schoenebeck 1335 void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3514     // update KeyRange struct and make sure regions are in correct order
3515     DLS::Region::SetKeyRange(Low, High);
3516     // update Region key table for fast lookup
3517     ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3518     }
3519    
3520 persson 858 void Region::UpdateVelocityTable() {
3521     // get velocity dimension's index
3522     int veldim = -1;
3523     for (int i = 0 ; i < Dimensions ; i++) {
3524     if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3525     veldim = i;
3526 schoenebeck 809 break;
3527     }
3528     }
3529 persson 858 if (veldim == -1) return;
3530 schoenebeck 809
3531 persson 858 int step = 1;
3532     for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3533     int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3534 schoenebeck 809
3535 persson 858 // loop through all dimension regions for all dimensions except the velocity dimension
3536     int dim[8] = { 0 };
3537     for (int i = 0 ; i < DimensionRegions ; i++) {
3538 schoenebeck 2923 const int end = i + step * pDimensionDefinitions[veldim].zones;
3539 persson 858
3540 schoenebeck 2923 // create a velocity table for all cases where the velocity zone is zero
3541 persson 1070 if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3542     pDimensionRegions[i]->VelocityUpperLimit) {
3543 persson 858 // create the velocity table
3544     uint8_t* table = pDimensionRegions[i]->VelocityTable;
3545     if (!table) {
3546     table = new uint8_t[128];
3547     pDimensionRegions[i]->VelocityTable = table;
3548     }
3549     int tableidx = 0;
3550     int velocityZone = 0;
3551 persson 1070 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
3552     for (int k = i ; k < end ; k += step) {
3553     DimensionRegion *d = pDimensionRegions[k];
3554     for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3555     velocityZone++;
3556     }
3557     } else { // gig2
3558     for (int k = i ; k < end ; k += step) {
3559     DimensionRegion *d = pDimensionRegions[k];
3560     for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3561     velocityZone++;
3562     }
3563 persson 858 }
3564     } else {
3565     if (pDimensionRegions[i]->VelocityTable) {
3566     delete[] pDimensionRegions[i]->VelocityTable;
3567     pDimensionRegions[i]->VelocityTable = 0;
3568     }
3569 schoenebeck 809 }
3570 persson 858
3571 schoenebeck 2923 // jump to the next case where the velocity zone is zero
3572 persson 858 int j;
3573     int shift = 0;
3574     for (j = 0 ; j < Dimensions ; j++) {
3575     if (j == veldim) i += skipveldim; // skip velocity dimension
3576     else {
3577     dim[j]++;
3578     if (dim[j] < pDimensionDefinitions[j].zones) break;
3579     else {
3580     // skip unused dimension regions
3581     dim[j] = 0;
3582     i += ((1 << pDimensionDefinitions[j].bits) -
3583     pDimensionDefinitions[j].zones) << shift;
3584     }
3585     }
3586     shift += pDimensionDefinitions[j].bits;
3587     }
3588     if (j == Dimensions) break;
3589 schoenebeck 809 }
3590     }
3591    
3592     /** @brief Einstein would have dreamed of it - create a new dimension.
3593     *
3594     * Creates a new dimension with the dimension definition given by
3595     * \a pDimDef. The appropriate amount of DimensionRegions will be created.
3596     * There is a hard limit of dimensions and total amount of "bits" all
3597     * dimensions can have. This limit is dependant to what gig file format
3598     * version this file refers to. The gig v2 (and lower) format has a
3599     * dimension limit and total amount of bits limit of 5, whereas the gig v3
3600     * format has a limit of 8.
3601     *
3602     * @param pDimDef - defintion of the new dimension
3603     * @throws gig::Exception if dimension of the same type exists already
3604     * @throws gig::Exception if amount of dimensions or total amount of
3605     * dimension bits limit is violated
3606     */
3607     void Region::AddDimension(dimension_def_t* pDimDef) {
3608 schoenebeck 2547 // some initial sanity checks of the given dimension definition
3609     if (pDimDef->zones < 2)
3610     throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3611     if (pDimDef->bits < 1)
3612     throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3613     if (pDimDef->dimension == dimension_samplechannel) {
3614     if (pDimDef->zones != 2)
3615     throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3616     if (pDimDef->bits != 1)
3617     throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3618     }
3619    
3620 schoenebeck 809 // check if max. amount of dimensions reached
3621     File* file = (File*) GetParent()->GetParent();
3622 schoenebeck 3440 const int iMaxDimensions = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3623 schoenebeck 809 if (Dimensions >= iMaxDimensions)
3624     throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
3625     // check if max. amount of dimension bits reached
3626     int iCurrentBits = 0;
3627     for (int i = 0; i < Dimensions; i++)
3628     iCurrentBits += pDimensionDefinitions[i].bits;
3629     if (iCurrentBits >= iMaxDimensions)
3630     throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
3631     const int iNewBits = iCurrentBits + pDimDef->bits;
3632     if (iNewBits > iMaxDimensions)
3633     throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
3634     // check if there's already a dimensions of the same type
3635     for (int i = 0; i < Dimensions; i++)
3636     if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3637     throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3638    
3639 persson 1301 // pos is where the new dimension should be placed, normally
3640     // last in list, except for the samplechannel dimension which
3641     // has to be first in list
3642     int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3643     int bitpos = 0;
3644     for (int i = 0 ; i < pos ; i++)
3645     bitpos += pDimensionDefinitions[i].bits;
3646    
3647     // make room for the new dimension
3648     for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3649     for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3650     for (int j = Dimensions ; j > pos ; j--) {
3651     pDimensionRegions[i]->DimensionUpperLimits[j] =
3652     pDimensionRegions[i]->DimensionUpperLimits[j - 1];
3653     }
3654     }
3655    
3656 schoenebeck 809 // assign definition of new dimension
3657 persson 1301 pDimensionDefinitions[pos] = *pDimDef;
3658 schoenebeck 809
3659 schoenebeck 1113 // auto correct certain dimension definition fields (where possible)
3660 persson 1301 pDimensionDefinitions[pos].split_type =
3661     __resolveSplitType(pDimensionDefinitions[pos].dimension);
3662     pDimensionDefinitions[pos].zone_size =
3663     __resolveZoneSize(pDimensionDefinitions[pos]);
3664 schoenebeck 1113
3665 persson 1301 // create new dimension region(s) for this new dimension, and make
3666     // sure that the dimension regions are placed correctly in both the
3667     // RIFF list and the pDimensionRegions array
3668     RIFF::Chunk* moveTo = NULL;
3669     RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3670     for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3671     for (int k = 0 ; k < (1 << bitpos) ; k++) {
3672     pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3673     }
3674     for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3675     for (int k = 0 ; k < (1 << bitpos) ; k++) {
3676     RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3677     if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3678     // create a new dimension region and copy all parameter values from
3679     // an existing dimension region
3680     pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3681     new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3682 persson 1247
3683 persson 1301 DimensionRegions++;
3684     }
3685     }
3686     moveTo = pDimensionRegions[i]->pParentList;
3687 schoenebeck 809 }
3688    
3689 persson 1247 // initialize the upper limits for this dimension
3690 persson 1301 int mask = (1 << bitpos) - 1;
3691     for (int z = 0 ; z < pDimDef->zones ; z++) {
3692 persson 1264 uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3693 persson 1247 for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3694 persson 1301 pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3695     (z << bitpos) |
3696     (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3697 persson 1247 }
3698     }
3699    
3700 schoenebeck 809 Dimensions++;
3701    
3702     // if this is a layer dimension, update 'Layers' attribute
3703     if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
3704    
3705 persson 858 UpdateVelocityTable();
3706 schoenebeck 809 }
3707    
3708     /** @brief Delete an existing dimension.
3709     *
3710     * Deletes the dimension given by \a pDimDef and deletes all respective
3711     * dimension regions, that is all dimension regions where the dimension's
3712     * bit(s) part is greater than 0. In case of a 'sustain pedal' dimension
3713     * for example this would delete all dimension regions for the case(s)
3714     * where the sustain pedal is pressed down.
3715     *
3716     * @param pDimDef - dimension to delete
3717     * @throws gig::Exception if given dimension cannot be found
3718     */
3719     void Region::DeleteDimension(dimension_def_t* pDimDef) {
3720     // get dimension's index
3721     int iDimensionNr = -1;
3722     for (int i = 0; i < Dimensions; i++) {
3723     if (&pDimensionDefinitions[i] == pDimDef) {
3724     iDimensionNr = i;
3725     break;
3726     }
3727     }
3728     if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
3729    
3730     // get amount of bits below the dimension to delete
3731     int iLowerBits = 0;
3732     for (int i = 0; i < iDimensionNr; i++)
3733     iLowerBits += pDimensionDefinitions[i].bits;
3734    
3735     // get amount ot bits above the dimension to delete
3736     int iUpperBits = 0;
3737     for (int i = iDimensionNr + 1; i < Dimensions; i++)
3738     iUpperBits += pDimensionDefinitions[i].bits;
3739    
3740 persson 1247 RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3741    
3742 schoenebeck 809 // delete dimension regions which belong to the given dimension
3743     // (that is where the dimension's bit > 0)
3744     for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3745     for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3746     for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3747     int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3748     iObsoleteBit << iLowerBits |
3749     iLowerBit;
3750 persson 1247
3751     _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3752 schoenebeck 809 delete pDimensionRegions[iToDelete];
3753     pDimensionRegions[iToDelete] = NULL;
3754     DimensionRegions--;
3755     }
3756     }
3757     }
3758    
3759     // defrag pDimensionRegions array
3760     // (that is remove the NULL spaces within the pDimensionRegions array)
3761     for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3762     if (!pDimensionRegions[iTo]) {
3763     if (iFrom <= iTo) iFrom = iTo + 1;
3764     while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3765     if (iFrom < 256 && pDimensionRegions[iFrom]) {
3766     pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3767     pDimensionRegions[iFrom] = NULL;
3768     }
3769     }
3770     }
3771    
3772 persson 1247 // remove the this dimension from the upper limits arrays
3773     for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3774     DimensionRegion* d = pDimensionRegions[j];
3775     for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3776     d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3777     }
3778     d->DimensionUpperLimits[Dimensions - 1] = 127;
3779     }
3780    
3781 schoenebeck 809 // 'remove' dimension definition
3782     for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3783     pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
3784     }
3785     pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
3786     pDimensionDefinitions[Dimensions - 1].bits = 0;
3787     pDimensionDefinitions[Dimensions - 1].zones = 0;
3788    
3789     Dimensions--;
3790    
3791     // if this was a layer dimension, update 'Layers' attribute
3792     if (pDimDef->dimension == dimension_layer) Layers = 1;
3793     }
3794    
3795 schoenebeck 2555 /** @brief Delete one split zone of a dimension (decrement zone amount).
3796     *
3797     * Instead of deleting an entire dimensions, this method will only delete
3798     * one particular split zone given by @a zone of the Region's dimension
3799     * given by @a type. So this method will simply decrement the amount of
3800     * zones by one of the dimension in question. To be able to do that, the
3801     * respective dimension must exist on this Region and it must have at least
3802     * 3 zones. All DimensionRegion objects associated with the zone will be
3803     * deleted.
3804     *
3805     * @param type - identifies the dimension where a zone shall be deleted
3806     * @param zone - index of the dimension split zone that shall be deleted
3807     * @throws gig::Exception if requested zone could not be deleted
3808     */
3809     void Region::DeleteDimensionZone(dimension_t type, int zone) {
3810     dimension_def_t* oldDef = GetDimensionDefinition(type);
3811     if (!oldDef)
3812     throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3813     if (oldDef->zones <= 2)
3814     throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3815     if (zone < 0 || zone >= oldDef->zones)
3816     throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3817    
3818     const int newZoneSize = oldDef->zones - 1;
3819    
3820     // create a temporary Region which just acts as a temporary copy
3821     // container and will be deleted at the end of this function and will
3822     // also not be visible through the API during this process
3823     gig::Region* tempRgn = NULL;
3824     {
3825     // adding these temporary chunks is probably not even necessary
3826     Instrument* instr = static_cast<Instrument*>(GetParent());
3827     RIFF::List* pCkInstrument = instr->pCkInstrument;
3828     RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3829     if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3830     RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3831     tempRgn = new Region(instr, rgn);
3832     }
3833    
3834     // copy this region's dimensions (with already the dimension split size
3835     // requested by the arguments of this method call) to the temporary
3836     // region, and don't use Region::CopyAssign() here for this task, since
3837     // it would also alter fast lookup helper variables here and there
3838     dimension_def_t newDef;
3839     for (int i = 0; i < Dimensions; ++i) {
3840     dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3841     // is this the dimension requested by the method arguments? ...
3842     if (def.dimension == type) { // ... if yes, decrement zone amount by one
3843     def.zones = newZoneSize;
3844     if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3845     newDef = def;
3846     }
3847     tempRgn->AddDimension(&def);
3848     }
3849    
3850     // find the dimension index in the tempRegion which is the dimension
3851     // type passed to this method (paranoidly expecting different order)
3852     int tempReducedDimensionIndex = -1;
3853     for (int d = 0; d < tempRgn->Dimensions; ++d) {
3854     if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3855     tempReducedDimensionIndex = d;
3856     break;
3857     }
3858     }
3859    
3860     // copy dimension regions from this region to the temporary region
3861     for (int iDst = 0; iDst < 256; ++iDst) {
3862     DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3863     if (!dstDimRgn) continue;
3864     std::map<dimension_t,int> dimCase;
3865     bool isValidZone = true;
3866     for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3867     const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3868     dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3869     (iDst >> baseBits) & ((1 << dstBits) - 1);
3870     baseBits += dstBits;
3871     // there are also DimensionRegion objects of unused zones, skip them
3872     if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3873     isValidZone = false;
3874     break;
3875     }
3876     }
3877     if (!isValidZone) continue;
3878     // a bit paranoid: cope with the chance that the dimensions would
3879     // have different order in source and destination regions
3880     const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3881     if (dimCase[type] >= zone) dimCase[type]++;
3882     DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3883     dstDimRgn->CopyAssign(srcDimRgn);
3884     // if this is the upper most zone of the dimension passed to this
3885     // method, then correct (raise) its upper limit to 127
3886     if (newDef.split_type == split_type_normal && isLastZone)
3887     dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3888     }
3889    
3890     // now tempRegion's dimensions and DimensionRegions basically reflect
3891     // what we wanted to get for this actual Region here, so we now just
3892     // delete and recreate the dimension in question with the new amount
3893 schoenebeck 3720 // zones and then copy back from tempRegion. we're actually deleting and
3894     // recreating all dimensions here, to avoid altering the precise order
3895     // of the dimensions (which would not be an error per se, but it would
3896     // cause usability issues with instrument editors)
3897     {
3898     std::vector<dimension_def_t> oldDefs;
3899     for (int i = 0; i < Dimensions; ++i)
3900     oldDefs.push_back(pDimensionDefinitions[i]); // copy, don't reference
3901     for (int i = Dimensions - 1; i >= 0; --i)
3902     DeleteDimension(&pDimensionDefinitions[i]);
3903     for (int i = 0; i < oldDefs.size(); ++i) {
3904     dimension_def_t& def = oldDefs[i];
3905     AddDimension(
3906     (def.dimension == newDef.dimension) ? &newDef : &def
3907     );
3908     }
3909     }
3910 schoenebeck 2555 for (int iSrc = 0; iSrc < 256; ++iSrc) {
3911     DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3912     if (!srcDimRgn) continue;
3913     std::map<dimension_t,int> dimCase;
3914     for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3915     const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3916     dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3917     (iSrc >> baseBits) & ((1 << srcBits) - 1);
3918     baseBits += srcBits;
3919     }
3920     // a bit paranoid: cope with the chance that the dimensions would
3921     // have different order in source and destination regions
3922     DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3923     if (!dstDimRgn) continue;
3924     dstDimRgn->CopyAssign(srcDimRgn);
3925     }
3926    
3927     // delete temporary region
3928 schoenebeck 3478 tempRgn->DeleteChunks();
3929 schoenebeck 2555 delete tempRgn;
3930 schoenebeck 2557
3931     UpdateVelocityTable();
3932 schoenebeck 2555 }
3933    
3934     /** @brief Divide split zone of a dimension in two (increment zone amount).
3935     *
3936     * This will increment the amount of zones for the dimension (given by
3937     * @a type) by one. It will do so by dividing the zone (given by @a zone)
3938     * in the middle of its zone range in two. So the two zones resulting from
3939     * the zone being splitted, will be an equivalent copy regarding all their
3940     * articulation informations and sample reference. The two zones will only
3941     * differ in their zone's upper limit
3942     * (DimensionRegion::DimensionUpperLimits).
3943     *
3944     * @param type - identifies the dimension where a zone shall be splitted
3945     * @param zone - index of the dimension split zone that shall be splitted
3946     * @throws gig::Exception if requested zone could not be splitted
3947     */
3948     void Region::SplitDimensionZone(dimension_t type, int zone) {
3949     dimension_def_t* oldDef = GetDimensionDefinition(type);
3950     if (!oldDef)
3951     throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3952     if (zone < 0 || zone >= oldDef->zones)
3953     throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3954    
3955     const int newZoneSize = oldDef->zones + 1;
3956    
3957     // create a temporary Region which just acts as a temporary copy
3958     // container and will be deleted at the end of this function and will
3959     // also not be visible through the API during this process
3960     gig::Region* tempRgn = NULL;
3961     {
3962     // adding these temporary chunks is probably not even necessary
3963     Instrument* instr = static_cast<Instrument*>(GetParent());
3964     RIFF::List* pCkInstrument = instr->pCkInstrument;
3965     RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3966     if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3967     RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3968     tempRgn = new Region(instr, rgn);
3969     }
3970    
3971     // copy this region's dimensions (with already the dimension split size
3972     // requested by the arguments of this method call) to the temporary
3973     // region, and don't use Region::CopyAssign() here for this task, since
3974     // it would also alter fast lookup helper variables here and there
3975     dimension_def_t newDef;
3976     for (int i = 0; i < Dimensions; ++i) {
3977     dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3978     // is this the dimension requested by the method arguments? ...
3979     if (def.dimension == type) { // ... if yes, increment zone amount by one
3980     def.zones = newZoneSize;
3981     if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3982     newDef = def;
3983     }
3984     tempRgn->AddDimension(&def);
3985     }
3986    
3987     // find the dimension index in the tempRegion which is the dimension
3988     // type passed to this method (paranoidly expecting different order)
3989     int tempIncreasedDimensionIndex = -1;
3990     for (int d = 0; d < tempRgn->Dimensions; ++d) {
3991     if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3992     tempIncreasedDimensionIndex = d;
3993     break;
3994     }
3995     }
3996    
3997     // copy dimension regions from this region to the temporary region
3998     for (int iSrc = 0; iSrc < 256; ++iSrc) {
3999     DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
4000     if (!srcDimRgn) continue;
4001     std::map<dimension_t,int> dimCase;
4002     bool isValidZone = true;
4003     for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
4004     const int srcBits = pDimensionDefinitions[d].bits;
4005     dimCase[pDimensionDefinitions[d].dimension] =
4006     (iSrc >> baseBits) & ((1 << srcBits) - 1);
4007     // there are also DimensionRegion objects for unused zones, skip them
4008     if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
4009     isValidZone = false;
4010     break;
4011     }
4012     baseBits += srcBits;
4013     }
4014     if (!isValidZone) continue;
4015     // a bit paranoid: cope with the chance that the dimensions would
4016     // have different order in source and destination regions
4017     if (dimCase[type] > zone) dimCase[type]++;
4018     DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
4019     dstDimRgn->CopyAssign(srcDimRgn);
4020     // if this is the requested zone to be splitted, then also copy
4021     // the source DimensionRegion to the newly created target zone
4022     // and set the old zones upper limit lower
4023     if (dimCase[type] == zone) {
4024     // lower old zones upper limit
4025     if (newDef.split_type == split_type_normal) {
4026     const int high =
4027     dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
4028     int low = 0;
4029     if (zone > 0) {
4030     std::map<dimension_t,int> lowerCase = dimCase;
4031     lowerCase[type]--;
4032     DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
4033     low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
4034     }
4035     dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
4036     }
4037     // fill the newly created zone of the divided zone as well
4038     dimCase[type]++;
4039     dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
4040     dstDimRgn->CopyAssign(srcDimRgn);
4041     }
4042     }
4043    
4044     // now tempRegion's dimensions and DimensionRegions basically reflect
4045     // what we wanted to get for this actual Region here, so we now just
4046     // delete and recreate the dimension in question with the new amount
4047 schoenebeck 3709 // zones and then copy back from tempRegion. we're actually deleting and
4048     // recreating all dimensions here, to avoid altering the precise order
4049 schoenebeck 3720 // of the dimensions (which would not be an error per se, but it would
4050 schoenebeck 3709 // cause usability issues with instrument editors)
4051     {
4052     std::vector<dimension_def_t> oldDefs;
4053     for (int i = 0; i < Dimensions; ++i)
4054     oldDefs.push_back(pDimensionDefinitions[i]); // copy, don't reference
4055     for (int i = Dimensions - 1; i >= 0; --i)
4056     DeleteDimension(&pDimensionDefinitions[i]);
4057     for (int i = 0; i < oldDefs.size(); ++i) {
4058     dimension_def_t& def = oldDefs[i];
4059     AddDimension(
4060     (def.dimension == newDef.dimension) ? &newDef : &def
4061     );
4062     }
4063     }
4064 schoenebeck 2555 for (int iSrc = 0; iSrc < 256; ++iSrc) {
4065     DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
4066     if (!srcDimRgn) continue;
4067     std::map<dimension_t,int> dimCase;
4068     for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
4069     const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
4070     dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
4071     (iSrc >> baseBits) & ((1 << srcBits) - 1);
4072     baseBits += srcBits;
4073     }
4074     // a bit paranoid: cope with the chance that the dimensions would
4075     // have different order in source and destination regions
4076     DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
4077     if (!dstDimRgn) continue;
4078     dstDimRgn->CopyAssign(srcDimRgn);
4079     }
4080    
4081     // delete temporary region
4082 schoenebeck 3478 tempRgn->DeleteChunks();
4083 schoenebeck 2555 delete tempRgn;
4084 schoenebeck 2557
4085     UpdateVelocityTable();
4086 schoenebeck 2555 }
4087    
4088 schoenebeck 2639 /** @brief Change type of an existing dimension.
4089     *
4090     * Alters the dimension type of a dimension already existing on this
4091     * region. If there is currently no dimension on this Region with type
4092     * @a oldType, then this call with throw an Exception. Likewise there are
4093     * cases where the requested dimension type cannot be performed. For example
4094     * if the new dimension type shall be gig::dimension_samplechannel, and the
4095     * current dimension has more than 2 zones. In such cases an Exception is
4096     * thrown as well.
4097     *
4098     * @param oldType - identifies the existing dimension to be changed
4099     * @param newType - to which dimension type it should be changed to
4100     * @throws gig::Exception if requested change cannot be performed
4101     */
4102     void Region::SetDimensionType(dimension_t oldType, dimension_t newType) {
4103     if (oldType == newType) return;
4104     dimension_def_t* def = GetDimensionDefinition(oldType);
4105     if (!def)
4106     throw gig::Exception("No dimension with provided old dimension type exists on this region");
4107     if (newType == dimension_samplechannel && def->zones != 2)
4108     throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
4109 schoenebeck 2640 if (GetDimensionDefinition(newType))
4110     throw gig::Exception("There is already a dimension with requested new dimension type on this region");
4111     def->dimension = newType;
4112 schoenebeck 2639 def->split_type = __resolveSplitType(newType);
4113     }
4114    
4115 schoenebeck 2555 DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
4116     uint8_t bits[8] = {};
4117     for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
4118     it != DimCase.end(); ++it)
4119     {
4120     for (int d = 0; d < Dimensions; ++d) {
4121     if (pDimensionDefinitions[d].dimension == it->first) {
4122     bits[d] = it->second;
4123     goto nextDimCaseSlice;
4124     }
4125     }
4126     assert(false); // do crash ... too harsh maybe ? ignore it instead ?
4127     nextDimCaseSlice:
4128     ; // noop
4129     }
4130     return GetDimensionRegionByBit(bits);
4131     }
4132    
4133 schoenebeck 2547 /**
4134     * Searches in the current Region for a dimension of the given dimension
4135     * type and returns the precise configuration of that dimension in this
4136     * Region.
4137     *
4138     * @param type - dimension type of the sought dimension
4139     * @returns dimension definition or NULL if there is no dimension with
4140     * sought type in this Region.
4141     */
4142     dimension_def_t* Region::GetDimensionDefinition(dimension_t type) {
4143     for (int i = 0; i < Dimensions; ++i)
4144     if (pDimensionDefinitions[i].dimension == type)
4145     return &pDimensionDefinitions[i];
4146     return NULL;
4147     }
4148    
4149 schoenebeck 2 Region::~Region() {
4150 schoenebeck 350 for (int i = 0; i < 256; i++) {
4151 schoenebeck 2 if (pDimensionRegions[i]) delete pDimensionRegions[i];
4152     }
4153     }
4154    
4155     /**
4156     * Use this method in your audio engine to get the appropriate dimension
4157     * region with it's articulation data for the current situation. Just
4158     * call the method with the current MIDI controller values and you'll get
4159     * the DimensionRegion with the appropriate articulation data for the
4160     * current situation (for this Region of course only). To do that you'll
4161     * first have to look which dimensions with which controllers and in
4162     * which order are defined for this Region when you load the .gig file.
4163     * Special cases are e.g. layer or channel dimensions where you just put
4164     * in the index numbers instead of a MIDI controller value (means 0 for
4165     * left channel, 1 for right channel or 0 for layer 0, 1 for layer 1,
4166     * etc.).
4167     *
4168 schoenebeck 347 * @param DimValues MIDI controller values (0-127) for dimension 0 to 7
4169 schoenebeck 2 * @returns adress to the DimensionRegion for the given situation
4170     * @see pDimensionDefinitions
4171     * @see Dimensions
4172     */
4173 schoenebeck 347 DimensionRegion* Region::GetDimensionRegionByValue(const uint DimValues[8]) {
4174 persson 858 uint8_t bits;
4175     int veldim = -1;
4176 schoenebeck 3053 int velbitpos = 0;
4177 persson 858 int bitpos = 0;
4178     int dimregidx = 0;
4179 schoenebeck 2 for (uint i = 0; i < Dimensions; i++) {
4180 persson 858 if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4181     // the velocity dimension must be handled after the other dimensions
4182     veldim = i;
4183     velbitpos = bitpos;
4184     } else {
4185     switch (pDimensionDefinitions[i].split_type) {
4186     case split_type_normal:
4187 persson 1070 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4188     // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4189     for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4190     if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4191     }
4192     } else {
4193     // gig2: evenly sized zones
4194     bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4195     }
4196 persson 858 break;
4197     case split_type_bit: // the value is already the sought dimension bit number
4198     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4199     bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4200     break;
4201     }
4202     dimregidx |= bits << bitpos;
4203 schoenebeck 2 }
4204 persson 858 bitpos += pDimensionDefinitions[i].bits;
4205 schoenebeck 2 }
4206 schoenebeck 2564 DimensionRegion* dimreg = pDimensionRegions[dimregidx & 255];
4207     if (!dimreg) return NULL;
4208 persson 858 if (veldim != -1) {
4209     // (dimreg is now the dimension region for the lowest velocity)
4210 persson 1070 if (dimreg->VelocityTable) // custom defined zone ranges
4211 schoenebeck 2564 bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4212 persson 858 else // normal split type
4213 schoenebeck 2564 bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4214 persson 858
4215 schoenebeck 2564 const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4216     dimregidx |= (bits & limiter_mask) << velbitpos;
4217     dimreg = pDimensionRegions[dimregidx & 255];
4218 persson 858 }
4219     return dimreg;
4220 schoenebeck 2 }
4221    
4222 schoenebeck 2599 int Region::GetDimensionRegionIndexByValue(const uint DimValues[8]) {
4223     uint8_t bits;
4224     int veldim = -1;
4225 schoenebeck 3053 int velbitpos = 0;
4226 schoenebeck 2599 int bitpos = 0;
4227     int dimregidx = 0;
4228     for (uint i = 0; i < Dimensions; i++) {
4229     if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4230     // the velocity dimension must be handled after the other dimensions
4231     veldim = i;
4232     velbitpos = bitpos;
4233     } else {
4234     switch (pDimensionDefinitions[i].split_type) {
4235     case split_type_normal:
4236     if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4237     // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4238     for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4239     if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4240     }
4241     } else {
4242     // gig2: evenly sized zones
4243     bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4244     }
4245     break;
4246     case split_type_bit: // the value is already the sought dimension bit number
4247     const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4248     bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4249     break;
4250     }
4251     dimregidx |= bits << bitpos;
4252     }
4253     bitpos += pDimensionDefinitions[i].bits;
4254     }
4255     dimregidx &= 255;
4256     DimensionRegion* dimreg = pDimensionRegions[dimregidx];
4257     if (!dimreg) return -1;
4258     if (veldim != -1) {
4259     // (dimreg is now the dimension region for the lowest velocity)
4260     if (dimreg->VelocityTable) // custom defined zone ranges
4261     bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4262     else // normal split type
4263     bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4264    
4265     const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4266     dimregidx |= (bits & limiter_mask) << velbitpos;
4267     dimregidx &= 255;
4268     }
4269     return dimregidx;
4270     }
4271    
4272 schoenebeck 2 /**
4273     * Returns the appropriate DimensionRegion for the given dimension bit
4274     * numbers (zone index). You usually use <i>GetDimensionRegionByValue</i>
4275     * instead of calling this method directly!
4276     *
4277 schoenebeck 347 * @param DimBits Bit numbers for dimension 0 to 7
4278 schoenebeck 2 * @returns adress to the DimensionRegion for the given dimension
4279     * bit numbers
4280     * @see GetDimensionRegionByValue()
4281     */
4282 schoenebeck 347 DimensionRegion* Region::GetDimensionRegionByBit(const uint8_t DimBits[8]) {
4283     return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4284     << pDimensionDefinitions[5].bits | DimBits[5])
4285     << pDimensionDefinitions[4].bits | DimBits[4])
4286     << pDimensionDefinitions[3].bits | DimBits[3])
4287     << pDimensionDefinitions[2].bits | DimBits[2])
4288     << pDimensionDefinitions[1].bits | DimBits[1])
4289     << pDimensionDefinitions[0].bits | DimBits[0]];
4290 schoenebeck 2 }
4291    
4292     /**
4293     * Returns pointer address to the Sample referenced with this region.
4294     * This is the global Sample for the entire Region (not sure if this is
4295     * actually used by the Gigasampler engine - I would only use the Sample
4296     * referenced by the appropriate DimensionRegion instead of this sample).
4297     *
4298     * @returns address to Sample or NULL if there is no reference to a
4299     * sample saved in the .gig file
4300     */
4301     Sample* Region::GetSample() {
4302     if (pSample) return static_cast<gig::Sample*>(pSample);
4303     else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4304     }
4305    
4306 schoenebeck 515 Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
4307 schoenebeck 352 if ((int32_t)WavePoolTableIndex == -1) return NULL;
4308 schoenebeck 2 File* file = (File*) GetParent()->GetParent();
4309 persson 902 if (!file->pWavePoolTable) return NULL;
4310 schoenebeck 3350 if (WavePoolTableIndex + 1 > file->WavePoolCount) return NULL;
4311 schoenebeck 2913 // for new files or files >= 2 GB use 64 bit wave pool offsets
4312     if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
4313     // use 64 bit wave pool offsets (treating this as large file)
4314 schoenebeck 2912 uint64_t soughtoffset =
4315     uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4316     uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4317     Sample* sample = file->GetFirstSample(pProgress);
4318     while (sample) {
4319     if (sample->ullWavePoolOffset == soughtoffset)
4320     return static_cast<gig::Sample*>(sample);
4321     sample = file->GetNextSample();
4322     }
4323     } else {
4324 schoenebeck 2913 // use extension files and 32 bit wave pool offsets
4325 schoenebeck 2912 file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4326     file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4327     Sample* sample = file->GetFirstSample(pProgress);
4328     while (sample) {
4329     if (sample->ullWavePoolOffset == soughtoffset &&
4330     sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
4331     sample = file->GetNextSample();
4332     }
4333 schoenebeck 2 }
4334     return NULL;
4335     }
4336 schoenebeck 2394
4337     /**
4338     * Make a (semi) deep copy of the Region object given by @a orig
4339     * and assign it to this object.
4340     *
4341     * Note that all sample pointers referenced by @a orig are simply copied as
4342     * memory address. Thus the respective samples are shared, not duplicated!
4343     *
4344     * @param orig - original Region object to be copied from
4345     */
4346     void Region::CopyAssign(const Region* orig) {
4347 schoenebeck 2482 CopyAssign(orig, NULL);
4348     }
4349    
4350     /**
4351     * Make a (semi) deep copy of the Region object given by @a orig and
4352     * assign it to this object
4353     *
4354     * @param mSamples - crosslink map between the foreign file's samples and
4355     * this file's samples
4356     */
4357     void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
4358 schoenebeck 2394 // handle base classes
4359     DLS::Region::CopyAssign(orig);
4360    
4361 schoenebeck 2482 if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
4362     pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
4363     }
4364    
4365 schoenebeck 2394 // handle own member variables
4366     for (int i = Dimensions - 1; i >= 0; --i) {
4367     DeleteDimension(&pDimensionDefinitions[i]);
4368     }
4369     Layers = 0; // just to be sure
4370     for (int i = 0; i < orig->Dimensions; i++) {
4371     // we need to copy the dim definition here, to avoid the compiler
4372     // complaining about const-ness issue
4373     dimension_def_t def = orig->pDimensionDefinitions[i];
4374     AddDimension(&def);
4375     }
4376     for (int i = 0; i < 256; i++) {
4377     if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
4378     pDimensionRegions[i]->CopyAssign(
4379 schoenebeck 2482 orig->pDimensionRegions[i],
4380     mSamples
4381 schoenebeck 2394 );
4382     }
4383     }
4384     Layers = orig->Layers;
4385     }
4386 schoenebeck 2
4387 schoenebeck 3710 /**
4388     * Returns @c true in case this Region object uses any gig format
4389     * extension, that is e.g. whether any DimensionRegion object currently
4390     * has any setting effective that would require our "LSDE" RIFF chunk to
4391     * be stored to the gig file.
4392     *
4393     * Right now this is a private method. It is considerable though this method
4394     * to become (in slightly modified form) a public API method in future, i.e.
4395     * to allow instrument editors to visualize and/or warn the user of any gig
4396     * format extension being used. See also comments on
4397     * DimensionRegion::UsesAnyGigFormatExtension() for details about such a
4398     * potential public API change in future.
4399     */
4400     bool Region::UsesAnyGigFormatExtension() const {
4401     for (int i = 0; i < 256; i++) {
4402     if (pDimensionRegions[i]) {
4403     if (pDimensionRegions[i]->UsesAnyGigFormatExtension())
4404     return true;
4405     }
4406     }
4407     return false;
4408     }
4409 schoenebeck 2
4410 schoenebeck 3710
4411 persson 1627 // *************** MidiRule ***************
4412     // *
4413 schoenebeck 2
4414 persson 2450 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
4415     _3ewg->SetPos(36);
4416     Triggers = _3ewg->ReadUint8();
4417     _3ewg->SetPos(40);
4418     ControllerNumber = _3ewg->ReadUint8();
4419     _3ewg->SetPos(46);
4420     for (int i = 0 ; i < Triggers ; i++) {
4421     pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
4422     pTriggers[i].Descending = _3ewg->ReadUint8();
4423     pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
4424     pTriggers[i].Key = _3ewg->ReadUint8();
4425     pTriggers[i].NoteOff = _3ewg->ReadUint8();
4426     pTriggers[i].Velocity = _3ewg->ReadUint8();
4427     pTriggers[i].OverridePedal = _3ewg->ReadUint8();
4428     _3ewg->ReadUint8();
4429     }
4430 persson 1627 }
4431    
4432 persson 2450 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4433     ControllerNumber(0),
4434     Triggers(0) {
4435     }
4436 persson 1627
4437 persson 2450 void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
4438     pData[32] = 4;
4439     pData[33] = 16;
4440     pData[36] = Triggers;
4441     pData[40] = ControllerNumber;
4442     for (int i = 0 ; i < Triggers ; i++) {
4443     pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4444     pData[47 + i * 8] = pTriggers[i].Descending;
4445     pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4446     pData[49 + i * 8] = pTriggers[i].Key;
4447     pData[50 + i * 8] = pTriggers[i].NoteOff;
4448     pData[51 + i * 8] = pTriggers[i].Velocity;
4449     pData[52 + i * 8] = pTriggers[i].OverridePedal;
4450     }
4451     }
4452    
4453     MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
4454     _3ewg->SetPos(36);
4455     LegatoSamples = _3ewg->ReadUint8(); // always 12
4456     _3ewg->SetPos(40);
4457     BypassUseController = _3ewg->ReadUint8();
4458     BypassKey = _3ewg->ReadUint8();
4459     BypassController = _3ewg->ReadUint8();
4460     ThresholdTime = _3ewg->ReadUint16();
4461     _3ewg->ReadInt16();
4462     ReleaseTime = _3ewg->ReadUint16();
4463     _3ewg->ReadInt16();
4464     KeyRange.low = _3ewg->ReadUint8();
4465     KeyRange.high = _3ewg->ReadUint8();
4466     _3ewg->SetPos(64);
4467     ReleaseTriggerKey = _3ewg->ReadUint8();
4468     AltSustain1Key = _3ewg->ReadUint8();
4469     AltSustain2Key = _3ewg->ReadUint8();
4470     }
4471    
4472     MidiRuleLegato::MidiRuleLegato() :
4473     LegatoSamples(12),
4474     BypassUseController(false),
4475     BypassKey(0),
4476     BypassController(1),
4477     ThresholdTime(20),
4478     ReleaseTime(20),
4479     ReleaseTriggerKey(0),
4480     AltSustain1Key(0),
4481     AltSustain2Key(0)
4482     {
4483     KeyRange.low = KeyRange.high = 0;
4484     }
4485    
4486     void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
4487     pData[32] = 0;
4488     pData[33] = 16;
4489     pData[36] = LegatoSamples;
4490     pData[40] = BypassUseController;
4491     pData[41] = BypassKey;
4492     pData[42] = BypassController;
4493     store16(&pData[43], ThresholdTime);
4494     store16(&pData[47], ReleaseTime);
4495     pData[51] = KeyRange.low;
4496     pData[52] = KeyRange.high;
4497     pData[64] = ReleaseTriggerKey;
4498     pData[65] = AltSustain1Key;
4499     pData[66] = AltSustain2Key;
4500     }
4501    
4502     MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
4503     _3ewg->SetPos(36);
4504     Articulations = _3ewg->ReadUint8();
4505     int flags = _3ewg->ReadUint8();
4506     Polyphonic = flags & 8;
4507     Chained = flags & 4;
4508     Selector = (flags & 2) ? selector_controller :
4509     (flags & 1) ? selector_key_switch : selector_none;
4510     Patterns = _3ewg->ReadUint8();
4511     _3ewg->ReadUint8(); // chosen row
4512     _3ewg->ReadUint8(); // unknown
4513     _3ewg->ReadUint8(); // unknown
4514     _3ewg->ReadUint8(); // unknown
4515     KeySwitchRange.low = _3ewg->ReadUint8();
4516     KeySwitchRange.high = _3ewg->ReadUint8();
4517     Controller = _3ewg->ReadUint8();
4518     PlayRange.low = _3ewg->ReadUint8();
4519     PlayRange.high = _3ewg->ReadUint8();
4520    
4521     int n = std::min(int(Articulations), 32);
4522     for (int i = 0 ; i < n ; i++) {
4523     _3ewg->ReadString(pArticulations[i], 32);
4524     }
4525     _3ewg->SetPos(1072);
4526     n = std::min(int(Patterns), 32);
4527     for (int i = 0 ; i < n ; i++) {
4528     _3ewg->ReadString(pPatterns[i].Name, 16);
4529     pPatterns[i].Size = _3ewg->ReadUint8();
4530     _3ewg->Read(&pPatterns[i][0], 1, 32);
4531     }
4532     }
4533    
4534     MidiRuleAlternator::MidiRuleAlternator() :
4535     Articulations(0),
4536     Patterns(0),
4537     Selector(selector_none),
4538     Controller(0),
4539     Polyphonic(false),
4540     Chained(false)
4541     {
4542     PlayRange.low = PlayRange.high = 0;
4543     KeySwitchRange.low = KeySwitchRange.high = 0;
4544     }
4545    
4546     void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
4547     pData[32] = 3;
4548     pData[33] = 16;
4549     pData[36] = Articulations;
4550     pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4551     (Selector == selector_controller ? 2 :
4552     (Selector == selector_key_switch ? 1 : 0));
4553     pData[38] = Patterns;
4554    
4555     pData[43] = KeySwitchRange.low;
4556     pData[44] = KeySwitchRange.high;
4557     pData[45] = Controller;
4558     pData[46] = PlayRange.low;
4559     pData[47] = PlayRange.high;
4560    
4561     char* str = reinterpret_cast<char*>(pData);
4562     int pos = 48;
4563     int n = std::min(int(Articulations), 32);
4564     for (int i = 0 ; i < n ; i++, pos += 32) {
4565     strncpy(&str[pos], pArticulations[i].c_str(), 32);
4566     }
4567    
4568     pos = 1072;
4569     n = std::min(int(Patterns), 32);
4570     for (int i = 0 ; i < n ; i++, pos += 49) {
4571     strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4572     pData[pos + 16] = pPatterns[i].Size;
4573     memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4574     }
4575     }
4576    
4577 schoenebeck 2584 // *************** Script ***************
4578     // *
4579    
4580     Script::Script(ScriptGroup* group, RIFF::Chunk* ckScri) {
4581     pGroup = group;
4582     pChunk = ckScri;
4583     if (ckScri) { // object is loaded from file ...
4584 schoenebeck 3478 ckScri->SetPos(0);
4585    
4586 schoenebeck 2584 // read header
4587     uint32_t headerSize = ckScri->ReadUint32();
4588     Compression = (Compression_t) ckScri->ReadUint32();
4589     Encoding = (Encoding_t) ckScri->ReadUint32();
4590     Language = (Language_t) ckScri->ReadUint32();
4591 schoenebeck 3722 Bypass = ckScri->ReadUint32() & 1;
4592 schoenebeck 2584 crc = ckScri->ReadUint32();
4593     uint32_t nameSize = ckScri->ReadUint32();
4594     Name.resize(nameSize, ' ');
4595     for (int i = 0; i < nameSize; ++i)
4596     Name[i] = ckScri->ReadUint8();
4597 schoenebeck 3723 // check if an uuid was already stored along with this script
4598     if (headerSize >= 6*sizeof(int32_t) + nameSize + 16) { // yes ...
4599     for (uint i = 0; i < 16; ++i) {
4600     Uuid[i] = ckScri->ReadUint8();
4601     }
4602     } else { // no uuid yet, generate one now ...
4603     GenerateUuid();
4604     }
4605 schoenebeck 2584 // to handle potential future extensions of the header
4606 schoenebeck 2602 ckScri->SetPos(sizeof(int32_t) + headerSize);
4607 schoenebeck 2584 // read actual script data
4608 schoenebeck 3053 uint32_t scriptSize = uint32_t(ckScri->GetSize() - ckScri->GetPos());
4609 schoenebeck 2584 data.resize(scriptSize);
4610     for (int i = 0; i < scriptSize; ++i)
4611     data[i] = ckScri->ReadUint8();
4612     } else { // this is a new script object, so just initialize it as such ...
4613     Compression = COMPRESSION_NONE;
4614     Encoding = ENCODING_ASCII;
4615     Language = LANGUAGE_NKSP;
4616     Bypass = false;
4617     crc = 0;
4618     Name = "Unnamed Script";
4619 schoenebeck 3723 GenerateUuid();
4620 schoenebeck 2584 }
4621     }
4622    
4623     Script::~Script() {
4624     }
4625    
4626     /**
4627     * Returns the current script (i.e. as source code) in text format.
4628     */
4629     String Script::GetScriptAsText() {
4630     String s;
4631     s.resize(data.size(), ' ');
4632     memcpy(&s[0], &data[0], data.size());
4633     return s;
4634     }
4635    
4636     /**
4637     * Replaces the current script with the new script source code text given
4638     * by @a text.
4639     *
4640     * @param text - new script source code
4641     */
4642     void Script::SetScriptAsText(const String& text) {
4643     data.resize(text.size());
4644     memcpy(&data[0], &text[0], text.size());
4645     }
4646    
4647 schoenebeck 3478 /** @brief Remove all RIFF chunks associated with this Script object.
4648     *
4649     * At the moment Script::DeleteChunks() does nothing. It is
4650     * recommended to call this method explicitly though from deriving classes's
4651     * own overridden implementation of this method to avoid potential future
4652     * compatiblity issues.
4653     *
4654     * See DLS::Storage::DeleteChunks() for details.
4655     */
4656     void Script::DeleteChunks() {
4657     }
4658    
4659 schoenebeck 2682 /**
4660     * Apply this script to the respective RIFF chunks. You have to call
4661     * File::Save() to make changes persistent.
4662     *
4663     * Usually there is absolutely no need to call this method explicitly.
4664     * It will be called automatically when File::Save() was called.
4665     *
4666     * @param pProgress - callback function for progress notification
4667     */
4668     void Script::UpdateChunks(progress_t* pProgress) {
4669 schoenebeck 2584 // recalculate CRC32 check sum
4670     __resetCRC(crc);
4671     __calculateCRC(&data[0], data.size(), crc);
4672 schoenebeck 3115 __finalizeCRC(crc);
4673 schoenebeck 2584 // make sure chunk exists and has the required size
4674 schoenebeck 3723 const file_offset_t chunkSize =
4675     (file_offset_t) 7*sizeof(int32_t) + Name.size() + 16 + data.size();
4676 schoenebeck 2584 if (!pChunk) pChunk = pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4677     else pChunk->Resize(chunkSize);
4678     // fill the chunk data to be written to disk
4679     uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4680     int pos = 0;
4681 schoenebeck 3723 store32(&pData[pos], uint32_t(6*sizeof(int32_t) + Name.size() + 16)); // total header size
4682 schoenebeck 2584 pos += sizeof(int32_t);
4683     store32(&pData[pos], Compression);
4684     pos += sizeof(int32_t);
4685     store32(&pData[pos], Encoding);
4686     pos += sizeof(int32_t);
4687     store32(&pData[pos], Language);
4688     pos += sizeof(int32_t);
4689     store32(&pData[pos], Bypass ? 1 : 0);
4690     pos += sizeof(int32_t);
4691     store32(&pData[pos], crc);
4692     pos += sizeof(int32_t);
4693 schoenebeck 3053 store32(&pData[pos], (uint32_t) Name.size());
4694 schoenebeck 2584 pos += sizeof(int32_t);
4695     for (int i = 0; i < Name.size(); ++i, ++pos)
4696     pData[pos] = Name[i];
4697 schoenebeck 3723 for (int i = 0; i < 16; ++i, ++pos)
4698     pData[pos] = Uuid[i];
4699 schoenebeck 2584 for (int i = 0; i < data.size(); ++i, ++pos)
4700     pData[pos] = data[i];
4701     }
4702    
4703     /**
4704 schoenebeck 3723 * Generate a new Universally Unique Identifier (UUID) for this script.
4705     */
4706     void Script::GenerateUuid() {
4707     DLS::dlsid_t dlsid;
4708     DLS::Resource::GenerateDLSID(&dlsid);
4709     Uuid[0] = dlsid.ulData1 & 0xff;
4710     Uuid[1] = dlsid.ulData1 >> 8 & 0xff;
4711     Uuid[2] = dlsid.ulData1 >> 16 & 0xff;
4712     Uuid[3] = dlsid.ulData1 >> 24 & 0xff;
4713     Uuid[4] = dlsid.usData2 & 0xff;
4714     Uuid[5] = dlsid.usData2 >> 8 & 0xff;
4715     Uuid[6] = dlsid.usData3 & 0xff;
4716     Uuid[7] = dlsid.usData3 >> 8 & 0xff;
4717     Uuid[8] = dlsid.abData[0];
4718     Uuid[9] = dlsid.abData[1];
4719     Uuid[10] = dlsid.abData[2];
4720     Uuid[11] = dlsid.abData[3];
4721     Uuid[12] = dlsid.abData[4];
4722     Uuid[13] = dlsid.abData[5];
4723     Uuid[14] = dlsid.abData[6];
4724     Uuid[15] = dlsid.abData[7];
4725     }
4726    
4727     /**
4728 schoenebeck 2584 * Move this script from its current ScriptGroup to another ScriptGroup
4729     * given by @a pGroup.
4730     *
4731     * @param pGroup - script's new group
4732     */
4733     void Script::SetGroup(ScriptGroup* pGroup) {
4734 persson 2836 if (this->pGroup == pGroup) return;
4735 schoenebeck 2584 if (pChunk)
4736     pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4737     this->pGroup = pGroup;
4738     }
4739    
4740 schoenebeck 2601 /**
4741     * Returns the script group this script currently belongs to. Each script
4742     * is a member of exactly one ScriptGroup.
4743     *
4744     * @returns current script group
4745     */
4746     ScriptGroup* Script::GetGroup() const {
4747     return pGroup;
4748     }
4749    
4750 schoenebeck 3117 /**
4751     * Make a (semi) deep copy of the Script object given by @a orig
4752     * and assign it to this object. Note: the ScriptGroup this Script
4753     * object belongs to remains untouched by this call.
4754     *
4755     * @param orig - original Script object to be copied from
4756     */
4757     void Script::CopyAssign(const Script* orig) {
4758     Name = orig->Name;
4759     Compression = orig->Compression;
4760     Encoding = orig->Encoding;
4761     Language = orig->Language;
4762     Bypass = orig->Bypass;
4763     data = orig->data;
4764     }
4765    
4766 schoenebeck 2584 void Script::RemoveAllScriptReferences() {
4767     File* pFile = pGroup->pFile;
4768     for (int i = 0; pFile->GetInstrument(i); ++i) {
4769     Instrument* instr = pFile->GetInstrument(i);
4770     instr->RemoveScript(this);
4771     }
4772     }
4773    
4774     // *************** ScriptGroup ***************
4775     // *
4776    
4777     ScriptGroup::ScriptGroup(File* file, RIFF::List* lstRTIS) {
4778     pFile = file;
4779     pList = lstRTIS;
4780     pScripts = NULL;
4781     if (lstRTIS) {
4782     RIFF::Chunk* ckName = lstRTIS->GetSubChunk(CHUNK_ID_LSNM);
4783     ::LoadString(ckName, Name);
4784     } else {
4785     Name = "Default Group";
4786     }
4787     }
4788    
4789     ScriptGroup::~ScriptGroup() {
4790     if (pScripts) {
4791     std::list<Script*>::iterator iter = pScripts->begin();
4792     std::list<Script*>::iterator end = pScripts->end();
4793     while (iter != end) {
4794     delete *iter;
4795     ++iter;
4796     }
4797     delete pScripts;
4798     }
4799     }
4800    
4801 schoenebeck 3478 /** @brief Remove all RIFF chunks associated with this ScriptGroup object.
4802     *
4803     * At the moment ScriptGroup::DeleteChunks() does nothing. It is
4804     * recommended to call this method explicitly though from deriving classes's
4805     * own overridden implementation of this method to avoid potential future
4806     * compatiblity issues.
4807     *
4808     * See DLS::Storage::DeleteChunks() for details.
4809     */
4810     void ScriptGroup::DeleteChunks() {
4811     }
4812    
4813 schoenebeck 2682 /**
4814     * Apply this script group to the respective RIFF chunks. You have to call
4815     * File::Save() to make changes persistent.
4816     *
4817     * Usually there is absolutely no need to call this method explicitly.
4818     * It will be called automatically when File::Save() was called.
4819     *
4820     * @param pProgress - callback function for progress notification
4821     */
4822     void ScriptGroup::UpdateChunks(progress_t* pProgress) {
4823 schoenebeck 2584 if (pScripts) {
4824     if (!pList)
4825     pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4826    
4827     // now store the name of this group as <LSNM> chunk as subchunk of the <RTIS> list chunk
4828     ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String("Unnamed Group"), true, 64);
4829    
4830     for (std::list<Script*>::iterator it = pScripts->begin();
4831     it != pScripts->end(); ++it)
4832     {
4833 schoenebeck 2682 (*it)->UpdateChunks(pProgress);
4834 schoenebeck 2584 }
4835     }
4836     }
4837    
4838     /** @brief Get instrument script.
4839     *
4840     * Returns the real-time instrument script with the given index.
4841     *
4842     * @param index - number of the sought script (0..n)
4843     * @returns sought script or NULL if there's no such script
4844     */
4845     Script* ScriptGroup::GetScript(uint index) {
4846     if (!pScripts) LoadScripts();
4847     std::list<Script*>::iterator it = pScripts->begin();
4848     for (uint i = 0; it != pScripts->end(); ++i, ++it)
4849     if (i == index) return *it;
4850     return NULL;
4851     }
4852    
4853     /** @brief Add new instrument script.
4854     *
4855     * Adds a new real-time instrument script to the file. The script is not
4856     * actually used / executed unless it is referenced by an instrument to be
4857     * used. This is similar to samples, which you can add to a file, without
4858     * an instrument necessarily actually using it.
4859     *
4860     * You have to call Save() to make this persistent to the file.
4861     *
4862     * @return new empty script object
4863     */
4864     Script* ScriptGroup::AddScript() {
4865     if (!pScripts) LoadScripts();
4866     Script* pScript = new Script(this, NULL);
4867     pScripts->push_back(pScript);
4868     return pScript;
4869     }
4870    
4871     /** @brief Delete an instrument script.
4872     *
4873     * This will delete the given real-time instrument script. References of
4874     * instruments that are using that script will be removed accordingly.
4875     *
4876     * You have to call Save() to make this persistent to the file.
4877     *
4878     * @param pScript - script to delete
4879     * @throws gig::Exception if given script could not be found
4880     */
4881     void ScriptGroup::DeleteScript(Script* pScript) {
4882     if (!pScripts) LoadScripts();
4883     std::list<Script*>::iterator iter =
4884     find(pScripts->begin(), pScripts->end(), pScript);
4885     if (iter == pScripts->end())
4886     throw gig::Exception("Could not delete script, could not find given script");
4887     pScripts->erase(iter);
4888     pScript->RemoveAllScriptReferences();
4889     if (pScript->pChunk)
4890     pScript->pChunk->GetParent()->DeleteSubChunk(pScript->pChunk);
4891     delete pScript;
4892     }
4893    
4894     void ScriptGroup::LoadScripts() {
4895     if (pScripts) return;
4896     pScripts = new std::list<Script*>;
4897     if (!pList) return;
4898    
4899     for (RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4900     ck = pList->GetNextSubChunk())
4901     {
4902     if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4903     pScripts->push_back(new Script(this, ck));
4904     }
4905     }
4906     }
4907    
4908 schoenebeck 2 // *************** Instrument ***************
4909     // *
4910    
4911 schoenebeck 515 Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
4912 schoenebeck 1416 static const DLS::Info::string_length_t fixedStringLengths[] = {
4913 persson 1180 { CHUNK_ID_INAM, 64 },
4914     { CHUNK_ID_ISFT, 12 },
4915     { 0, 0 }
4916     };
4917 schoenebeck 1416 pInfo->SetFixedStringLengths(fixedStringLengths);
4918 persson 918
4919 schoenebeck 2 // Initialization
4920     for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4921 persson 1182 EffectSend = 0;
4922     Attenuation = 0;
4923     FineTune = 0;
4924 schoenebeck 3112 PitchbendRange = 2;
4925 persson 1182 PianoReleaseMode = false;
4926     DimensionKeyRange.low = 0;
4927     DimensionKeyRange.high = 0;
4928 persson 1678 pMidiRules = new MidiRule*[3];
4929     pMidiRules[0] = NULL;
4930 schoenebeck 2584 pScriptRefs = NULL;
4931 schoenebeck 2
4932     // Loading
4933     RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
4934     if (lart) {
4935     RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4936     if (_3ewg) {
4937 schoenebeck 3478 _3ewg->SetPos(0);
4938    
4939 schoenebeck 2 EffectSend = _3ewg->ReadUint16();
4940     Attenuation = _3ewg->ReadInt32();
4941     FineTune = _3ewg->ReadInt16();
4942     PitchbendRange = _3ewg->ReadInt16();
4943     uint8_t dimkeystart = _3ewg->ReadUint8();
4944     PianoReleaseMode = dimkeystart & 0x01;
4945     DimensionKeyRange.low = dimkeystart >> 1;
4946     DimensionKeyRange.high = _3ewg->ReadUint8();
4947 persson 1627
4948     if (_3ewg->GetSize() > 32) {
4949     // read MIDI rules
4950 persson 1678 int i = 0;
4951 persson 1627 _3ewg->SetPos(32);
4952     uint8_t id1 = _3ewg->ReadUint8();
4953     uint8_t id2 = _3ewg->ReadUint8();
4954    
4955 persson 2450 if (id2 == 16) {
4956     if (id1 == 4) {
4957     pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4958     } else if (id1 == 0) {
4959     pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4960     } else if (id1 == 3) {
4961     pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4962     } else {
4963     pMidiRules[i++] = new MidiRuleUnknown;
4964     }
4965 persson 1627 }
4966 persson 2450 else if (id1 != 0 || id2 != 0) {
4967     pMidiRules[i++] = new MidiRuleUnknown;
4968     }
4969 persson 1627 //TODO: all the other types of rules
4970 persson 1678
4971     pMidiRules[i] = NULL;
4972 persson 1627 }
4973 schoenebeck 2 }
4974     }
4975    
4976 schoenebeck 1524 if (pFile->GetAutoLoad()) {
4977     if (!pRegions) pRegions = new RegionList;
4978     RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
4979     if (lrgn) {
4980     RIFF::List* rgn = lrgn->GetFirstSubList();
4981     while (rgn) {
4982     if (rgn->GetListType() == LIST_TYPE_RGN) {
4983 schoenebeck 3488 if (pProgress)
4984     __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
4985 schoenebeck 1524 pRegions->push_back(new Region(this, rgn));
4986     }
4987     rgn = lrgn->GetNextSubList();
4988 schoenebeck 809 }
4989 schoenebeck 1524 // Creating Region Key Table for fast lookup
4990     UpdateRegionKeyTable();
4991 schoenebeck 2 }
4992     }
4993    
4994 schoenebeck 2584 // own gig format extensions
4995     RIFF::List* lst3LS = insList->GetSubList(LIST_TYPE_3LS);
4996     if (lst3LS) {
4997 schoenebeck 3731 // script slots (that is references to instrument scripts)
4998 schoenebeck 2584 RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4999     if (ckSCSL) {
5000 schoenebeck 3478 ckSCSL->SetPos(0);
5001    
5002 schoenebeck 2609 int headerSize = ckSCSL->ReadUint32();
5003     int slotCount = ckSCSL->ReadUint32();
5004     if (slotCount) {
5005     int slotSize = ckSCSL->ReadUint32();
5006     ckSCSL->SetPos(headerSize); // in case of future header extensions
5007     int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions
5008     for (int i = 0; i < slotCount; ++i) {
5009     _ScriptPooolEntry e;
5010     e.fileOffset = ckSCSL->ReadUint32();
5011     e.bypass = ckSCSL->ReadUint32() & 1;
5012     if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions
5013     scriptPoolFileOffsets.push_back(e);
5014     }
5015 schoenebeck 2584 }
5016     }
5017 schoenebeck 3731
5018     // overridden script 'patch' variables
5019     RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5020     if (ckSCPV) {
5021     ckSCPV->SetPos(0);
5022    
5023     int nScripts = ckSCPV->ReadUint32();
5024     for (int iScript = 0; iScript < nScripts; ++iScript) {
5025     _UUID uuid;
5026     for (int i = 0; i < 16; ++i)
5027     uuid[i] = ckSCPV->ReadUint8();
5028     uint slot = ckSCPV->ReadUint32();
5029     ckSCPV->ReadUint32(); // unused, reserved 32 bit
5030     int nVars = ckSCPV->ReadUint32();
5031     for (int iVar = 0; iVar < nVars; ++iVar) {
5032     uint8_t type = ckSCPV->ReadUint8();
5033     ckSCPV->ReadUint8(); // unused, reserved byte
5034     int blobSize = ckSCPV->ReadUint16();
5035     RIFF::file_offset_t pos = ckSCPV->GetPos();
5036     // assuming 1st bit is set in 'type', otherwise blob not
5037     // supported for decoding
5038     if (type & 1) {
5039     String name, value;
5040     int len = ckSCPV->ReadUint16();
5041     for (int i = 0; i < len; ++i)
5042     name += (char) ckSCPV->ReadUint8();
5043     len = ckSCPV->ReadUint16();
5044     for (int i = 0; i < len; ++i)
5045     value += (char) ckSCPV->ReadUint8();
5046     if (!name.empty()) // 'name' should never be empty, but just to be sure
5047     scriptVars[uuid][slot][name] = value;
5048     }
5049     // also for potential future extensions: seek forward
5050     // according to blob size
5051     ckSCPV->SetPos(pos + blobSize);
5052     }
5053     }
5054     }
5055 schoenebeck 2584 }
5056    
5057 schoenebeck 3488 if (pProgress)
5058     __notify_progress(pProgress, 1.0f); // notify done
5059 schoenebeck 809 }
5060    
5061     void Instrument::UpdateRegionKeyTable() {
5062 schoenebeck 1335 for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
5063 schoenebeck 823 RegionList::iterator iter = pRegions->begin();
5064     RegionList::iterator end = pRegions->end();
5065     for (; iter != end; ++iter) {
5066     gig::Region* pRegion = static_cast<gig::Region*>(*iter);
5067 schoenebeck 3348 const int low = std::max(int(pRegion->KeyRange.low), 0);
5068     const int high = std::min(int(pRegion->KeyRange.high), 127);
5069     for (int iKey = low; iKey <= high; iKey++) {
5070 schoenebeck 823 RegionKeyTable[iKey] = pRegion;
5071 schoenebeck 2 }
5072     }
5073     }
5074    
5075     Instrument::~Instrument() {
5076 persson 1950 for (int i = 0 ; pMidiRules[i] ; i++) {
5077     delete pMidiRules[i];
5078     }
5079 persson 1678 delete[] pMidiRules;
5080 schoenebeck 2584 if (pScriptRefs) delete pScriptRefs;
5081 schoenebeck 2 }
5082    
5083     /**
5084 schoenebeck 809 * Apply Instrument with all its Regions to the respective RIFF chunks.
5085     * You have to call File::Save() to make changes persistent.
5086     *
5087     * Usually there is absolutely no need to call this method explicitly.
5088     * It will be called automatically when File::Save() was called.
5089     *
5090 schoenebeck 2682 * @param pProgress - callback function for progress notification
5091 schoenebeck 809 * @throws gig::Exception if samples cannot be dereferenced
5092     */
5093 schoenebeck 2682 void Instrument::UpdateChunks(progress_t* pProgress) {
5094 schoenebeck 809 // first update base classes' chunks
5095 schoenebeck 2682 DLS::Instrument::UpdateChunks(pProgress);
5096 schoenebeck 809
5097     // update Regions' chunks
5098 schoenebeck 823 {
5099     RegionList::iterator iter = pRegions->begin();
5100     RegionList::iterator end = pRegions->end();
5101     for (; iter != end; ++iter)
5102 schoenebeck 2682 (*iter)->UpdateChunks(pProgress);
5103 schoenebeck 823 }
5104 schoenebeck 809
5105     // make sure 'lart' RIFF list chunk exists
5106     RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
5107     if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
5108     // make sure '3ewg' RIFF chunk exists
5109     RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
5110 persson 1264 if (!_3ewg) {
5111     File* pFile = (File*) GetParent();
5112    
5113     // 3ewg is bigger in gig3, as it includes the iMIDI rules
5114 schoenebeck 3440 int size = (pFile->pVersion && pFile->pVersion->major > 2) ? 16416 : 12;
5115 persson 1264 _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
5116     memset(_3ewg->LoadChunkData(), 0, size);
5117     }
5118 schoenebeck 809 // update '3ewg' RIFF chunk
5119     uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
5120 persson 1179 store16(&pData[0], EffectSend);
5121     store32(&pData[2], Attenuation);
5122     store16(&pData[6], FineTune);
5123     store16(&pData[8], PitchbendRange);
5124 persson 1266 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
5125 schoenebeck 809 DimensionKeyRange.low << 1;
5126 persson 1179 pData[10] = dimkeystart;
5127     pData[11] = DimensionKeyRange.high;
5128 persson 2450
5129     if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
5130     pData[32] = 0;
5131     pData[33] = 0;
5132     } else {
5133     for (int i = 0 ; pMidiRules[i] ; i++) {
5134     pMidiRules[i]->UpdateChunks(pData);
5135     }
5136     }
5137 schoenebeck 2584
5138     // own gig format extensions
5139 schoenebeck 2648 if (ScriptSlotCount()) {
5140     // make sure we have converted the original loaded script file
5141     // offsets into valid Script object pointers
5142     LoadScripts();
5143    
5144 schoenebeck 2584 RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5145     if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS);
5146 schoenebeck 3731
5147     // save script slots (that is references to instrument scripts)
5148 schoenebeck 3053 const int slotCount = (int) pScriptRefs->size();
5149 schoenebeck 2609 const int headerSize = 3 * sizeof(uint32_t);
5150     const int slotSize = 2 * sizeof(uint32_t);
5151     const int totalChunkSize = headerSize + slotCount * slotSize;
5152 schoenebeck 2584 RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
5153 schoenebeck 2609 if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
5154     else ckSCSL->Resize(totalChunkSize);
5155 schoenebeck 2584 uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData();
5156 schoenebeck 2609 int pos = 0;
5157     store32(&pData[pos], headerSize);
5158     pos += sizeof(uint32_t);
5159     store32(&pData[pos], slotCount);
5160     pos += sizeof(uint32_t);
5161     store32(&pData[pos], slotSize);
5162     pos += sizeof(uint32_t);
5163     for (int i = 0; i < slotCount; ++i) {
5164     // arbitrary value, the actual file offset will be updated in
5165     // UpdateScriptFileOffsets() after the file has been resized
5166     int bogusFileOffset = 0;
5167     store32(&pData[pos], bogusFileOffset);
5168 schoenebeck 2584 pos += sizeof(uint32_t);
5169     store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
5170     pos += sizeof(uint32_t);
5171     }
5172 schoenebeck 3731
5173     // save overridden script 'patch' variables ...
5174    
5175     // the actual 'scriptVars' member variable might contain variables of
5176     // scripts which are currently no longer assigned to any script slot
5177     // of this instrument, we need to get rid of these variables here to
5178     // prevent saving those persistently, however instead of touching the
5179     // member variable 'scriptVars' directly, rather strip a separate
5180     // copy such that the overridden values are not lost during an
5181     // instrument editor session (i.e. if script might be re-assigned)
5182     _VarsByScript vars = stripScriptVars();
5183     if (!vars.empty()) {
5184     // determine total size required for 'SCPV' RIFF chunk, and the
5185     // total amount of scripts being overridden (the latter is
5186     // required because a script might be used on several script
5187     // slots, hence vars.size() could then not be used here instead)
5188     size_t totalChunkSize = 4;
5189     size_t totalScriptsOverridden = 0;
5190     for (const auto& script : vars) {
5191     for (const auto& slot : script.second) {
5192     totalScriptsOverridden++;
5193     totalChunkSize += 16 + 4 + 4 + 4;
5194     for (const auto& var : slot.second) {
5195     totalChunkSize += 4 + 2 + var.first.length() +
5196     2 + var.second.length();
5197     }
5198     }
5199     }
5200    
5201     // ensure 'SCPV' RIFF chunk exists (with required size)
5202     RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5203     if (!ckSCPV) ckSCPV = lst3LS->AddSubChunk(CHUNK_ID_SCPV, totalChunkSize);
5204     else ckSCPV->Resize(totalChunkSize);
5205    
5206     // store the actual data to 'SCPV' RIFF chunk
5207     uint8_t* pData = (uint8_t*) ckSCPV->LoadChunkData();
5208     int pos = 0;
5209     store32(&pData[pos], (uint32_t) totalScriptsOverridden); // scripts count
5210     pos += 4;
5211     for (const auto& script : vars) {
5212     for (const auto& slot : script.second) {
5213     for (int i = 0; i < 16; ++i)
5214     pData[pos+i] = script.first[i]; // uuid
5215     pos += 16;
5216     store32(&pData[pos], (uint32_t) slot.first); // slot index
5217     pos += 4;
5218     store32(&pData[pos], (uint32_t) 0); // unused, reserved 32 bit
5219     pos += 4;
5220     store32(&pData[pos], (uint32_t) slot.second.size()); // variables count
5221     pos += 4;
5222     for (const auto& var : slot.second) {
5223     pData[pos++] = 1; // type
5224     pData[pos++] = 0; // reserved byte
5225     store16(&pData[pos], 2 + var.first.size() + 2 + var.second.size()); // blob size
5226     pos += 2;
5227     store16(&pData[pos], var.first.size()); // variable name length
5228     pos += 2;
5229     for (int i = 0; i < var.first.size(); ++i)
5230     pData[pos++] = var.first[i];
5231     store16(&pData[pos], var.second.size()); // variable value length
5232     pos += 2;
5233     for (int i = 0; i < var.second.size(); ++i)
5234     pData[pos++] = var.second[i];
5235     }
5236     }
5237     }
5238     } else {
5239     // no script variable overridden by this instrument, so get rid
5240     // of 'SCPV' RIFF chunk (if any)
5241     RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5242     if (ckSCPV) lst3LS->DeleteSubChunk(ckSCPV);
5243     }
5244 schoenebeck 2648 } else {
5245     // no script slots, so get rid of any LS custom RIFF chunks (if any)
5246     RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5247     if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS);
5248 schoenebeck 2584 }
5249 schoenebeck 809 }
5250    
5251 schoenebeck 2609 void Instrument::UpdateScriptFileOffsets() {
5252     // own gig format extensions
5253 schoenebeck 2667 if (pScriptRefs && pScriptRefs->size() > 0) {
5254 schoenebeck 2609 RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5255     RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
5256 schoenebeck 3053 const int slotCount = (int) pScriptRefs->size();
5257 schoenebeck 2609 const int headerSize = 3 * sizeof(uint32_t);
5258     ckSCSL->SetPos(headerSize);
5259     for (int i = 0; i < slotCount; ++i) {
5260 schoenebeck 3053 uint32_t fileOffset = uint32_t(
5261 schoenebeck 2609 (*pScriptRefs)[i].script->pChunk->GetFilePos() -
5262     (*pScriptRefs)[i].script->pChunk->GetPos() -
5263 schoenebeck 3053 CHUNK_HEADER_SIZE(ckSCSL->GetFile()->GetFileOffsetSize())
5264     );
5265 schoenebeck 2609 ckSCSL->WriteUint32(&fileOffset);
5266     // jump over flags entry (containing the bypass flag)
5267     ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos);
5268     }
5269     }
5270     }
5271    
5272 schoenebeck 809 /**
5273 schoenebeck 2 * Returns the appropriate Region for a triggered note.
5274     *
5275     * @param Key MIDI Key number of triggered note / key (0 - 127)
5276     * @returns pointer adress to the appropriate Region or NULL if there
5277     * there is no Region defined for the given \a Key
5278     */
5279     Region* Instrument::GetRegion(unsigned int Key) {
5280 schoenebeck 1335 if (!pRegions || pRegions->empty() || Key > 127) return NULL;
5281 schoenebeck 2 return RegionKeyTable[Key];
5282 schoenebeck 823
5283 schoenebeck 2 /*for (int i = 0; i < Regions; i++) {
5284     if (Key <= pRegions[i]->KeyRange.high &&
5285     Key >= pRegions[i]->KeyRange.low) return pRegions[i];
5286     }
5287     return NULL;*/
5288     }
5289    
5290     /**
5291     * Returns the first Region of the instrument. You have to call this
5292     * method once before you use GetNextRegion().
5293     *
5294     * @returns pointer address to first region or NULL if there is none
5295     * @see GetNextRegion()
5296     */
5297     Region* Instrument::GetFirstRegion() {
5298 schoenebeck 823 if (!pRegions) return NULL;
5299     RegionsIterator = pRegions->begin();
5300     return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5301 schoenebeck 2 }
5302    
5303     /**
5304     * Returns the next Region of the instrument. You have to call
5305     * GetFirstRegion() once before you can use this method. By calling this
5306     * method multiple times it iterates through the available Regions.
5307     *
5308     * @returns pointer address to the next region or NULL if end reached
5309     * @see GetFirstRegion()
5310     */
5311     Region* Instrument::GetNextRegion() {
5312 schoenebeck 823 if (!pRegions) return NULL;
5313     RegionsIterator++;
5314     return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5315 schoenebeck 2 }
5316    
5317 schoenebeck 809 Region* Instrument::AddRegion() {
5318     // create new Region object (and its RIFF chunks)
5319     RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
5320     if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
5321     RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
5322     Region* pNewRegion = new Region(this, rgn);
5323 schoenebeck 823 pRegions->push_back(pNewRegion);
5324 schoenebeck 3053 Regions = (uint32_t) pRegions->size();
5325 schoenebeck 809 // update Region key table for fast lookup
5326     UpdateRegionKeyTable();
5327     // done
5328     return pNewRegion;
5329     }
5330 schoenebeck 2
5331 schoenebeck 809 void Instrument::DeleteRegion(Region* pRegion) {
5332     if (!pRegions) return;
5333 schoenebeck 823 DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
5334 schoenebeck 809 // update Region key table for fast lookup
5335     UpdateRegionKeyTable();
5336     }
5337 schoenebeck 2
5338 persson 1627 /**
5339 schoenebeck 2700 * Move this instrument at the position before @arg dst.
5340     *
5341     * This method can be used to reorder the sequence of instruments in a
5342     * .gig file. This might be helpful especially on large .gig files which
5343     * contain a large number of instruments within the same .gig file. So
5344     * grouping such instruments to similar ones, can help to keep track of them
5345     * when working with such complex .gig files.
5346     *
5347     * When calling this method, this instrument will be removed from in its
5348     * current position in the instruments list and moved to the requested
5349     * target position provided by @param dst. You may also pass NULL as
5350     * argument to this method, in that case this intrument will be moved to the
5351     * very end of the .gig file's instrument list.
5352     *
5353     * You have to call Save() to make the order change persistent to the .gig
5354     * file.
5355     *
5356     * Currently this method is limited to moving the instrument within the same
5357     * .gig file. Trying to move it to another .gig file by calling this method
5358     * will throw an exception.
5359     *
5360     * @param dst - destination instrument at which this instrument will be
5361     * moved to, or pass NULL for moving to end of list
5362     * @throw gig::Exception if this instrument and target instrument are not
5363     * part of the same file
5364     */
5365     void Instrument::MoveTo(Instrument* dst) {
5366     if (dst && GetParent() != dst->GetParent())
5367     throw Exception(
5368     "gig::Instrument::MoveTo() can only be used for moving within "
5369     "the same gig file."
5370     );
5371    
5372     File* pFile = (File*) GetParent();
5373    
5374     // move this instrument within the instrument list
5375     {
5376 persson 2836 File::InstrumentList& list = *pFile->pInstruments;
5377 schoenebeck 2700
5378 persson 2836 File::InstrumentList::iterator itFrom =
5379 schoenebeck 2700 std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(this));
5380    
5381 persson 2836 File::InstrumentList::iterator itTo =
5382 schoenebeck 2700 std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(dst));
5383    
5384     list.splice(itTo, list, itFrom);
5385     }
5386    
5387     // move the instrument's actual list RIFF chunk appropriately
5388     RIFF::List* lstCkInstruments = pFile->pRIFF->GetSubList(LIST_TYPE_LINS);
5389     lstCkInstruments->MoveSubChunk(
5390     this->pCkInstrument,
5391 schoenebeck 2702 (RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5392 schoenebeck 2700 );
5393     }
5394    
5395     /**
5396 persson 1678 * Returns a MIDI rule of the instrument.
5397 persson 1627 *
5398     * The list of MIDI rules, at least in gig v3, always contains at
5399     * most two rules. The second rule can only be the DEF filter
5400     * (which currently isn't supported by libgig).
5401     *
5402 persson 1678 * @param i - MIDI rule number
5403     * @returns pointer address to MIDI rule number i or NULL if there is none
5404 persson 1627 */
5405 persson 1678 MidiRule* Instrument::GetMidiRule(int i) {
5406     return pMidiRules[i];
5407 persson 1627 }
5408 persson 2450
5409 schoenebeck 2394 /**
5410 persson 2450 * Adds the "controller trigger" MIDI rule to the instrument.
5411     *
5412     * @returns the new MIDI rule
5413     */
5414     MidiRuleCtrlTrigger* Instrument::AddMidiRuleCtrlTrigger() {
5415     delete pMidiRules[0];
5416     MidiRuleCtrlTrigger* r = new MidiRuleCtrlTrigger;
5417     pMidiRules[0] = r;
5418     pMidiRules[1] = 0;
5419     return r;
5420     }
5421    
5422     /**
5423     * Adds the legato MIDI rule to the instrument.
5424     *
5425     * @returns the new MIDI rule
5426     */
5427     MidiRuleLegato* Instrument::AddMidiRuleLegato() {
5428     delete pMidiRules[0];
5429     MidiRuleLegato* r = new MidiRuleLegato;
5430     pMidiRules[0] = r;
5431     pMidiRules[1] = 0;
5432     return r;
5433     }
5434    
5435     /**
5436     * Adds the alternator MIDI rule to the instrument.
5437     *
5438     * @returns the new MIDI rule
5439     */
5440     MidiRuleAlternator* Instrument::AddMidiRuleAlternator() {
5441     delete pMidiRules[0];
5442     MidiRuleAlternator* r = new MidiRuleAlternator;
5443     pMidiRules[0] = r;
5444     pMidiRules[1] = 0;
5445     return r;
5446     }
5447    
5448     /**
5449     * Deletes a MIDI rule from the instrument.
5450     *
5451     * @param i - MIDI rule number
5452     */
5453     void Instrument::DeleteMidiRule(int i) {
5454     delete pMidiRules[i];
5455     pMidiRules[i] = 0;
5456     }
5457    
5458 schoenebeck 2584 void Instrument::LoadScripts() {
5459     if (pScriptRefs) return;
5460     pScriptRefs = new std::vector<_ScriptPooolRef>;
5461     if (scriptPoolFileOffsets.empty()) return;
5462     File* pFile = (File*) GetParent();
5463     for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5464 schoenebeck 2609 uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5465 schoenebeck 2584 for (uint i = 0; pFile->GetScriptGroup(i); ++i) {
5466     ScriptGroup* group = pFile->GetScriptGroup(i);
5467     for (uint s = 0; group->GetScript(s); ++s) {
5468     Script* script = group->GetScript(s);
5469     if (script->pChunk) {
5470 schoenebeck 3053 uint32_t offset = uint32_t(
5471     script->pChunk->GetFilePos() -
5472     script->pChunk->GetPos() -
5473     CHUNK_HEADER_SIZE(script->pChunk->GetFile()->GetFileOffsetSize())
5474     );
5475 schoenebeck 2609 if (offset == soughtOffset)
5476 schoenebeck 2584 {
5477     _ScriptPooolRef ref;
5478     ref.script = script;
5479     ref.bypass = scriptPoolFileOffsets[k].bypass;
5480     pScriptRefs->push_back(ref);
5481     break;
5482     }
5483     }
5484     }
5485     }
5486     }
5487     // we don't need that anymore
5488     scriptPoolFileOffsets.clear();
5489     }
5490    
5491 schoenebeck 2593 /** @brief Get instrument script (gig format extension).
5492 schoenebeck 2584 *
5493 schoenebeck 2593 * Returns the real-time instrument script of instrument script slot
5494     * @a index.
5495     *
5496     * @note This is an own format extension which did not exist i.e. in the
5497     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5498     * gigedit.
5499     *
5500     * @param index - instrument script slot index
5501     * @returns script or NULL if index is out of bounds
5502     */
5503     Script* Instrument::GetScriptOfSlot(uint index) {
5504     LoadScripts();
5505     if (index >= pScriptRefs->size()) return NULL;
5506     return pScriptRefs->at(index).script;
5507     }
5508    
5509     /** @brief Add new instrument script slot (gig format extension).
5510     *
5511 schoenebeck 2584 * Add the given real-time instrument script reference to this instrument,
5512     * which shall be executed by the sampler for for this instrument. The
5513     * script will be added to the end of the script list of this instrument.
5514     * The positions of the scripts in the Instrument's Script list are
5515     * relevant, because they define in which order they shall be executed by
5516     * the sampler. For this reason it is also legal to add the same script
5517     * twice to an instrument, for example you might have a script called
5518     * "MyFilter" which performs an event filter task, and you might have
5519     * another script called "MyNoteTrigger" which triggers new notes, then you
5520     * might for example have the following list of scripts on the instrument:
5521     *
5522     * 1. Script "MyFilter"
5523     * 2. Script "MyNoteTrigger"
5524     * 3. Script "MyFilter"
5525     *
5526     * Which would make sense, because the 2nd script launched new events, which
5527     * you might need to filter as well.
5528     *
5529     * There are two ways to disable / "bypass" scripts. You can either disable
5530     * a script locally for the respective script slot on an instrument (i.e. by
5531     * passing @c false to the 2nd argument of this method, or by calling
5532     * SetScriptBypassed()). Or you can disable a script globally for all slots
5533     * and all instruments by setting Script::Bypass.
5534     *
5535     * @note This is an own format extension which did not exist i.e. in the
5536     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5537     * gigedit.
5538     *
5539     * @param pScript - script that shall be executed for this instrument
5540     * @param bypass - if enabled, the sampler shall skip executing this
5541     * script (in the respective list position)
5542     * @see SetScriptBypassed()
5543     */
5544     void Instrument::AddScriptSlot(Script* pScript, bool bypass) {
5545     LoadScripts();
5546     _ScriptPooolRef ref = { pScript, bypass };
5547     pScriptRefs->push_back(ref);
5548     }
5549    
5550     /** @brief Flip two script slots with each other (gig format extension).
5551     *
5552     * Swaps the position of the two given scripts in the Instrument's Script
5553     * list. The positions of the scripts in the Instrument's Script list are
5554     * relevant, because they define in which order they shall be executed by
5555     * the sampler.
5556     *
5557     * @note This is an own format extension which did not exist i.e. in the
5558     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5559     * gigedit.
5560     *
5561     * @param index1 - index of the first script slot to swap
5562     * @param index2 - index of the second script slot to swap
5563     */
5564     void Instrument::SwapScriptSlots(uint index1, uint index2) {
5565     LoadScripts();
5566     if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5567     return;
5568     _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5569     (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5570     (*pScriptRefs)[index2] = tmp;
5571     }
5572    
5573     /** @brief Remove script slot.
5574     *
5575     * Removes the script slot with the given slot index.
5576     *
5577     * @param index - index of script slot to remove
5578     */
5579     void Instrument::RemoveScriptSlot(uint index) {
5580     LoadScripts();
5581     if (index >= pScriptRefs->size()) return;
5582     pScriptRefs->erase( pScriptRefs->begin() + index );
5583     }
5584    
5585     /** @brief Remove reference to given Script (gig format extension).
5586     *
5587     * This will remove all script slots on the instrument which are referencing
5588     * the given script.
5589     *
5590     * @note This is an own format extension which did not exist i.e. in the
5591     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5592     * gigedit.
5593     *
5594     * @param pScript - script reference to remove from this instrument
5595     * @see RemoveScriptSlot()
5596     */
5597     void Instrument::RemoveScript(Script* pScript) {
5598     LoadScripts();
5599 schoenebeck 3053 for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5600 schoenebeck 2584 if ((*pScriptRefs)[i].script == pScript) {
5601     pScriptRefs->erase( pScriptRefs->begin() + i );
5602     }
5603     }
5604     }
5605    
5606     /** @brief Instrument's amount of script slots.
5607     *
5608     * This method returns the amount of script slots this instrument currently
5609     * uses.
5610     *
5611     * A script slot is a reference of a real-time instrument script to be
5612     * executed by the sampler. The scripts will be executed by the sampler in
5613     * sequence of the slots. One (same) script may be referenced multiple
5614     * times in different slots.
5615     *
5616     * @note This is an own format extension which did not exist i.e. in the
5617     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5618     * gigedit.
5619     */
5620     uint Instrument::ScriptSlotCount() const {
5621 schoenebeck 3053 return uint(pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size());
5622 schoenebeck 2584 }
5623    
5624     /** @brief Whether script execution shall be skipped.
5625     *
5626     * Defines locally for the Script reference slot in the Instrument's Script
5627     * list, whether the script shall be skipped by the sampler regarding
5628     * execution.
5629     *
5630     * It is also possible to ignore exeuction of the script globally, for all
5631     * slots and for all instruments by setting Script::Bypass.
5632     *
5633     * @note This is an own format extension which did not exist i.e. in the
5634     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5635     * gigedit.
5636     *
5637     * @param index - index of the script slot on this instrument
5638     * @see Script::Bypass
5639     */
5640     bool Instrument::IsScriptSlotBypassed(uint index) {
5641     if (index >= ScriptSlotCount()) return false;
5642     return pScriptRefs ? pScriptRefs->at(index).bypass
5643     : scriptPoolFileOffsets.at(index).bypass;
5644    
5645     }
5646    
5647     /** @brief Defines whether execution shall be skipped.
5648     *
5649     * You can call this method to define locally whether or whether not the
5650     * given script slot shall be executed by the sampler.
5651     *
5652     * @note This is an own format extension which did not exist i.e. in the
5653     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5654     * gigedit.
5655     *
5656     * @param index - script slot index on this instrument
5657     * @param bBypass - if true, the script slot will be skipped by the sampler
5658     * @see Script::Bypass
5659     */
5660     void Instrument::SetScriptSlotBypassed(uint index, bool bBypass) {
5661     if (index >= ScriptSlotCount()) return;
5662     if (pScriptRefs)
5663     pScriptRefs->at(index).bypass = bBypass;
5664     else
5665     scriptPoolFileOffsets.at(index).bypass = bBypass;
5666     }
5667    
5668 schoenebeck 3731 /// type cast (by copy) uint8_t[16] -> std::array<uint8_t,16>
5669     inline std::array<uint8_t,16> _UUIDFromCArray(const uint8_t* pData) {
5670     std::array<uint8_t,16> uuid;
5671     memcpy(&uuid[0], pData, 16);
5672     return uuid;
5673     }
5674    
5675 persson 2450 /**
5676 schoenebeck 3731 * Returns true if this @c Instrument has any script slot which references
5677     * the @c Script identified by passed @p uuid.
5678     */
5679     bool Instrument::ReferencesScriptWithUuid(const _UUID& uuid) {
5680     const uint nSlots = ScriptSlotCount();
5681     for (uint iSlot = 0; iSlot < nSlots; ++iSlot)
5682     if (_UUIDFromCArray(&GetScriptOfSlot(iSlot)->Uuid[0]) == uuid)
5683     return true;
5684     return false;
5685     }
5686    
5687     /** @brief Checks whether a certain script 'patch' variable value is set.
5688     *
5689     * Returns @c true if the initial value for the requested script variable is
5690     * currently overridden by this instrument.
5691     *
5692     * @remarks Real-time instrument scripts allow to declare special 'patch'
5693     * variables, which essentially behave like regular variables of their data
5694     * type, however their initial value may optionally be overridden on a per
5695     * instrument basis. That allows to share scripts between instruments while
5696     * still being able to fine tune certain aspects of the script for each
5697     * instrument individually.
5698     *
5699 schoenebeck 3732 * @note This is an own format extension which did not exist i.e. in the
5700     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5701     * Gigedit.
5702     *
5703 schoenebeck 3731 * @param slot - script slot index of the variable to be retrieved
5704     * @param variable - name of the 'patch' variable in that script
5705     */
5706     bool Instrument::IsScriptPatchVariableSet(int slot, String variable) {
5707     if (variable.empty()) return false;
5708     Script* script = GetScriptOfSlot(slot);
5709     if (!script) return false;
5710     const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5711     if (!scriptVars.count(uuid)) return false;
5712     const _VarsBySlot& slots = scriptVars.find(uuid)->second;
5713     if (slots.empty()) return false;
5714     if (slots.count(slot))
5715     return slots.find(slot)->second.count(variable);
5716     else
5717     return slots.begin()->second.count(variable);
5718     }
5719    
5720     /** @brief Get all overridden script 'patch' variables.
5721     *
5722     * Returns map of key-value pairs reflecting all patch variables currently
5723     * being overridden by this instrument for the given script @p slot, where
5724     * key is the variable name and value is the hereby currently overridden
5725     * value for that variable.
5726     *
5727     * @remarks Real-time instrument scripts allow to declare special 'patch'
5728     * variables, which essentially behave like regular variables of their data
5729     * type, however their initial value may optionally be overridden on a per
5730     * instrument basis. That allows to share scripts between instruments while
5731     * still being able to fine tune certain aspects of the script for each
5732     * instrument individually.
5733     *
5734 schoenebeck 3732 * @note This is an own format extension which did not exist i.e. in the
5735     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5736     * Gigedit.
5737     *
5738 schoenebeck 3731 * @param slot - script slot index of the variable to be retrieved
5739     */
5740     std::map<String,String> Instrument::GetScriptPatchVariables(int slot) {
5741     Script* script = GetScriptOfSlot(slot);
5742     if (!script) return std::map<String,String>();
5743     const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5744     if (!scriptVars.count(uuid)) return std::map<String,String>();
5745     const _VarsBySlot& slots = scriptVars.find(uuid)->second;
5746     if (slots.empty()) return std::map<String,String>();
5747     const _PatchVars& vars =
5748     (slots.count(slot)) ?
5749     slots.find(slot)->second : slots.begin()->second;
5750     return vars;
5751     }
5752    
5753     /** @brief Get overridden initial value for 'patch' variable.
5754     *
5755     * Returns current initial value for the requested script variable being
5756     * overridden by this instrument.
5757     *
5758     * @remarks Real-time instrument scripts allow to declare special 'patch'
5759     * variables, which essentially behave like regular variables of their data
5760     * type, however their initial value may optionally be overridden on a per
5761     * instrument basis. That allows to share scripts between instruments while
5762     * still being able to fine tune certain aspects of the script for each
5763     * instrument individually.
5764     *
5765 schoenebeck 3732 * @note This is an own format extension which did not exist i.e. in the
5766     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5767     * Gigedit.
5768     *
5769 schoenebeck 3731 * @param slot - script slot index of the variable to be retrieved
5770     * @param variable - name of the 'patch' variable in that script
5771     */
5772     String Instrument::GetScriptPatchVariable(int slot, String variable) {
5773     std::map<String,String> vars = GetScriptPatchVariables(slot);
5774     return (vars.count(variable)) ? vars.find(variable)->second : "";
5775     }
5776    
5777     /** @brief Override initial value for 'patch' variable.
5778     *
5779     * Overrides initial value for the requested script variable for this
5780     * instrument with the passed value.
5781     *
5782     * @remarks Real-time instrument scripts allow to declare special 'patch'
5783     * variables, which essentially behave like regular variables of their data
5784     * type, however their initial value may optionally be overridden on a per
5785     * instrument basis. That allows to share scripts between instruments while
5786     * still being able to fine tune certain aspects of the script for each
5787     * instrument individually.
5788     *
5789 schoenebeck 3732 * @note This is an own format extension which did not exist i.e. in the
5790     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5791     * Gigedit.
5792     *
5793 schoenebeck 3731 * @param slot - script slot index of the variable to be set
5794     * @param variable - name of the 'patch' variable in that script
5795     * @param value - overridden initial value for that script variable
5796     * @throws gig::Exception if given script @p slot index is invalid or given
5797     * @p variable name is empty
5798     */
5799     void Instrument::SetScriptPatchVariable(int slot, String variable, String value) {
5800     if (variable.empty())
5801     throw Exception("Variable name must not be empty");
5802     Script* script = GetScriptOfSlot(slot);
5803     if (!script)
5804     throw Exception("No script slot with index " + ToString(slot));
5805     const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5806     scriptVars[uuid][slot][variable] = value;
5807     }
5808    
5809     /** @brief Drop overridden initial value(s) for 'patch' variable(s).
5810     *
5811     * Reverts initial value(s) for requested script variable(s) back to their
5812     * default initial value(s) defined in the script itself.
5813     *
5814     * Both arguments of this method are optional. The most obvious use case of
5815     * this method would be passing a valid script @p slot index and a
5816     * (non-emtpy string as) @p variable name to this method, which would cause
5817     * that single variable to be unset for that specific script slot (on this
5818     * @c Instrument level).
5819     *
5820     * Not passing a value (or @c -1 for @p slot and/or empty string for
5821     * @p variable) means 'wildcard'. So accordingly absence of argument(s) will
5822     * cause all variables and/or for all script slots being unset. Hence this
5823     * method serves 2^2 = 4 possible use cases in total and accordingly covers
5824     * 4 different behaviours in one method.
5825     *
5826     * @remarks Real-time instrument scripts allow to declare special 'patch'
5827     * variables, which essentially behave like regular variables of their data
5828     * type, however their initial value may optionally be overridden on a per
5829     * instrument basis. That allows to share scripts between instruments while
5830     * still being able to fine tune certain aspects of the script for each
5831     * instrument individually.
5832     *
5833 schoenebeck 3732 * @note This is an own format extension which did not exist i.e. in the
5834     * GigaStudio 4 software. It will currently only work with LinuxSampler and
5835     * Gigedit.
5836     *
5837 schoenebeck 3731 * @param slot - script slot index of the variable to be unset
5838     * @param variable - name of the 'patch' variable in that script
5839     */
5840     void Instrument::UnsetScriptPatchVariable(int slot, String variable) {
5841     Script* script = GetScriptOfSlot(slot);
5842    
5843     // option 1: unset a particular variable of one particular script slot
5844     if (slot != -1 && !variable.empty()) {
5845     if (!script) return;
5846     const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5847     if (!scriptVars.count(uuid)) return;
5848     if (!scriptVars[uuid].count(slot)) return;
5849     if (scriptVars[uuid][slot].count(variable))
5850     scriptVars[uuid][slot].erase(
5851     scriptVars[uuid][slot].find(variable)
5852     );
5853     if (scriptVars[uuid][slot].empty())
5854     scriptVars[uuid].erase( scriptVars[uuid].find(slot) );
5855     if (scriptVars[uuid].empty())
5856     scriptVars.erase( scriptVars.find(uuid) );
5857     return;
5858     }
5859    
5860     // option 2: unset all variables of all script slots
5861     if (slot == -1 && variable.empty()) {
5862     scriptVars.clear();
5863     return;
5864     }
5865    
5866     // option 3: unset all variables of one particular script slot only
5867     if (slot != -1) {
5868     if (!script) return;
5869     const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5870     if (scriptVars.count(uuid))
5871     scriptVars.erase( scriptVars.find(uuid) );
5872     return;
5873     }
5874    
5875     // option 4: unset a particular variable of all script slots
5876     _VarsByScript::iterator itScript = scriptVars.begin();
5877     _VarsByScript::iterator endScript = scriptVars.end();
5878     while (itScript != endScript) {
5879     _VarsBySlot& slots = itScript->second;
5880     _VarsBySlot::iterator itSlot = slots.begin();
5881     _VarsBySlot::iterator endSlot = slots.end();
5882     while (itSlot != endSlot) {
5883     _PatchVars& vars = itSlot->second;
5884     if (vars.count(variable))
5885     vars.erase( vars.find(variable) );
5886     if (vars.empty())
5887     slots.erase(itSlot++); // postfix increment to avoid iterator invalidation
5888     else
5889     ++itSlot;
5890     }
5891     if (slots.empty())
5892     scriptVars.erase(itScript++); // postfix increment to avoid iterator invalidation
5893     else
5894     ++itScript;
5895     }
5896     }
5897    
5898     /**
5899     * Returns stripped version of member variable @c scriptVars, where scripts
5900     * no longer referenced by this @c Instrument are filtered out, and so are
5901     * variables of meanwhile obsolete slots (i.e. a script still being
5902     * referenced, but previously overridden on a script slot which either no
5903     * longer exists or is hosting another script now).
5904     */
5905     Instrument::_VarsByScript Instrument::stripScriptVars() {
5906     _VarsByScript vars;
5907     _VarsByScript::const_iterator itScript = scriptVars.begin();
5908     _VarsByScript::const_iterator endScript = scriptVars.end();
5909     for (; itScript != endScript; ++itScript) {
5910     const _UUID& uuid = itScript->first;
5911     if (!ReferencesScriptWithUuid(uuid))
5912     continue;
5913     const _VarsBySlot& slots = itScript->second;
5914     _VarsBySlot::const_iterator itSlot = slots.begin();
5915     _VarsBySlot::const_iterator endSlot = slots.end();
5916     for (; itSlot != endSlot; ++itSlot) {
5917     Script* script = GetScriptOfSlot(itSlot->first);
5918     if (!script) continue;
5919     if (_UUIDFromCArray(&script->Uuid[0]) != uuid) continue;
5920     if (itSlot->second.empty()) continue;
5921     vars[uuid][itSlot->first] = itSlot->second;
5922     }
5923     }
5924     return vars;
5925     }
5926    
5927     /**
5928 schoenebeck 2394 * Make a (semi) deep copy of the Instrument object given by @a orig
5929     * and assign it to this object.
5930     *
5931     * Note that all sample pointers referenced by @a orig are simply copied as
5932     * memory address. Thus the respective samples are shared, not duplicated!
5933     *
5934     * @param orig - original Instrument object to be copied from
5935     */
5936     void Instrument::CopyAssign(const Instrument* orig) {
5937 schoenebeck 2482 CopyAssign(orig, NULL);
5938     }
5939    
5940     /**
5941     * Make a (semi) deep copy of the Instrument object given by @a orig
5942     * and assign it to this object.
5943     *
5944     * @param orig - original Instrument object to be copied from
5945     * @param mSamples - crosslink map between the foreign file's samples and
5946     * this file's samples
5947     */
5948     void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
5949 schoenebeck 2394 // handle base class
5950     // (without copying DLS region stuff)
5951     DLS::Instrument::CopyAssignCore(orig);
5952    
5953     // handle own member variables
5954     Attenuation = orig->Attenuation;
5955     EffectSend = orig->EffectSend;
5956     FineTune = orig->FineTune;
5957     PitchbendRange = orig->PitchbendRange;
5958     PianoReleaseMode = orig->PianoReleaseMode;
5959     DimensionKeyRange = orig->DimensionKeyRange;
5960 schoenebeck 2584 scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5961 schoenebeck 3799 // deep copy of pScriptRefs required (to avoid undefined behaviour)
5962     if (pScriptRefs) delete pScriptRefs;
5963     pScriptRefs = new std::vector<_ScriptPooolRef>;
5964     if (orig->pScriptRefs)
5965     *pScriptRefs = *orig->pScriptRefs;
5966 schoenebeck 3731 scriptVars = orig->scriptVars;
5967 schoenebeck 2394
5968     // free old midi rules
5969     for (int i = 0 ; pMidiRules[i] ; i++) {
5970     delete pMidiRules[i];
5971     }
5972     //TODO: MIDI rule copying
5973     pMidiRules[0] = NULL;
5974    
5975     // delete all old regions
5976     while (Regions) DeleteRegion(GetFirstRegion());
5977     // create new regions and copy them from original
5978     {
5979     RegionList::const_iterator it = orig->pRegions->begin();
5980     for (int i = 0; i < orig->Regions; ++i, ++it) {
5981     Region* dstRgn = AddRegion();
5982     //NOTE: Region does semi-deep copy !
5983     dstRgn->CopyAssign(
5984 schoenebeck 2482 static_cast<gig::Region*>(*it),
5985     mSamples
5986 schoenebeck 2394 );
5987     }
5988     }
5989 schoenebeck 809
5990 schoenebeck 2394 UpdateRegionKeyTable();
5991     }
5992 schoenebeck 809
5993 schoenebeck 3710 /**
5994     * Returns @c true in case this Instrument object uses any gig format
5995     * extension, that is e.g. whether any DimensionRegion object currently
5996     * has any setting effective that would require our "LSDE" RIFF chunk to
5997     * be stored to the gig file.
5998     *
5999     * Right now this is a private method. It is considerable though this method
6000     * to become (in slightly modified form) a public API method in future, i.e.
6001     * to allow instrument editors to visualize and/or warn the user of any gig
6002     * format extension being used. See also comments on
6003     * DimensionRegion::UsesAnyGigFormatExtension() for details about such a
6004     * potential public API change in future.
6005     */
6006     bool Instrument::UsesAnyGigFormatExtension() const {
6007     if (!pRegions) return false;
6008 schoenebeck 3731 if (!scriptVars.empty()) return true;
6009 schoenebeck 3710 RegionList::const_iterator iter = pRegions->begin();
6010     RegionList::const_iterator end = pRegions->end();
6011     for (; iter != end; ++iter) {
6012     gig::Region* rgn = static_cast<gig::Region*>(*iter);
6013     if (rgn->UsesAnyGigFormatExtension())
6014     return true;
6015     }
6016     return false;
6017     }
6018 schoenebeck 2394
6019 schoenebeck 3710
6020 schoenebeck 929 // *************** Group ***************
6021     // *
6022    
6023     /** @brief Constructor.
6024     *
6025 schoenebeck 930 * @param file - pointer to the gig::File object
6026     * @param ck3gnm - pointer to 3gnm chunk associated with this group or
6027     * NULL if this is a new Group
6028 schoenebeck 929 */
6029 schoenebeck 930 Group::Group(File* file, RIFF::Chunk* ck3gnm) {
6030 schoenebeck 929 pFile = file;
6031     pNameChunk = ck3gnm;
6032     ::LoadString(pNameChunk, Name);
6033     }
6034    
6035 schoenebeck 3478 /** @brief Destructor.
6036     *
6037     * Currently this destructor implementation does nothing.
6038     */
6039 schoenebeck 929 Group::~Group() {
6040     }
6041    
6042 schoenebeck 3478 /** @brief Remove all RIFF chunks associated with this Group object.
6043     *
6044     * See DLS::Storage::DeleteChunks() for details.
6045     */
6046     void Group::DeleteChunks() {
6047     // handle own RIFF chunks
6048     if (pNameChunk) {
6049     pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
6050     pNameChunk = NULL;
6051     }
6052     }
6053    
6054 schoenebeck 929 /** @brief Update chunks with current group settings.
6055     *
6056 schoenebeck 1098 * Apply current Group field values to the respective chunks. You have
6057     * to call File::Save() to make changes persistent.
6058     *
6059     * Usually there is absolutely no need to call this method explicitly.
6060     * It will be called automatically when File::Save() was called.
6061 schoenebeck 2682 *
6062     * @param pProgress - callback function for progress notification
6063 schoenebeck 929 */
6064 schoenebeck 2682 void Group::UpdateChunks(progress_t* pProgress) {
6065 schoenebeck 929 // make sure <3gri> and <3gnl> list chunks exist
6066 schoenebeck 930 RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
6067 persson 1192 if (!_3gri) {
6068     _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
6069     pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
6070     }
6071 schoenebeck 929 RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
6072 persson 1182 if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
6073 persson 1266
6074 schoenebeck 3440 if (!pNameChunk && pFile->pVersion && pFile->pVersion->major > 2) {
6075 persson 1266 // v3 has a fixed list of 128 strings, find a free one
6076     for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
6077     if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
6078     pNameChunk = ck;
6079     break;
6080     }
6081     }
6082     }
6083    
6084 schoenebeck 929 // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
6085     ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
6086     }
6087    
6088 schoenebeck 930 /**
6089     * Returns the first Sample of this Group. You have to call this method
6090     * once before you use GetNextSample().
6091     *
6092     * <b>Notice:</b> this method might block for a long time, in case the
6093     * samples of this .gig file were not scanned yet
6094     *
6095     * @returns pointer address to first Sample or NULL if there is none
6096     * applied to this Group
6097     * @see GetNextSample()
6098     */
6099     Sample* Group::GetFirstSample() {
6100     // FIXME: lazy und unsafe implementation, should be an autonomous iterator
6101     for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
6102     if (pSample->GetGroup() == this) return pSample;
6103     }
6104     return NULL;
6105     }
6106 schoenebeck 929
6107 schoenebeck 930 /**
6108     * Returns the next Sample of the Group. You have to call
6109     * GetFirstSample() once before you can use this method. By calling this
6110     * method multiple times it iterates through the Samples assigned to
6111     * this Group.
6112     *
6113     * @returns pointer address to the next Sample of this Group or NULL if
6114     * end reached
6115     * @see GetFirstSample()
6116     */
6117     Sample* Group::GetNextSample() {
6118     // FIXME: lazy und unsafe implementation, should be an autonomous iterator
6119     for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
6120     if (pSample->GetGroup() == this) return pSample;
6121     }
6122     return NULL;
6123     }
6124 schoenebeck 929
6125 schoenebeck 930 /**
6126     * Move Sample given by \a pSample from another Group to this Group.
6127     */
6128     void Group::AddSample(Sample* pSample) {
6129     pSample->pGroup = this;
6130     }
6131    
6132     /**
6133     * Move all members of this group to another group (preferably the 1st
6134     * one except this). This method is called explicitly by
6135     * File::DeleteGroup() thus when a Group was deleted. This code was
6136     * intentionally not placed in the destructor!
6137     */
6138     void Group::MoveAll() {
6139     // get "that" other group first
6140     Group* pOtherGroup = NULL;
6141     for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
6142     if (pOtherGroup != this) break;
6143     }
6144     if (!pOtherGroup) throw Exception(
6145     "Could not move samples to another group, since there is no "
6146     "other Group. This is a bug, report it!"
6147     );
6148     // now move all samples of this group to the other group
6149     for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
6150     pOtherGroup->AddSample(pSample);
6151     }
6152     }
6153    
6154    
6155    
6156 schoenebeck 2 // *************** File ***************
6157     // *
6158    
6159 schoenebeck 1384 /// Reflects Gigasampler file format version 2.0 (1998-06-28).
6160 persson 1199 const DLS::version_t File::VERSION_2 = {
6161     0, 2, 19980628 & 0xffff, 19980628 >> 16
6162     };
6163    
6164 schoenebeck 1384 /// Reflects Gigasampler file format version 3.0 (2003-03-31).
6165 persson 1199 const DLS::version_t File::VERSION_3 = {
6166     0, 3, 20030331 & 0xffff, 20030331 >> 16
6167     };
6168    
6169 schoenebeck 3440 /// Reflects Gigasampler file format version 4.0 (2007-10-12).
6170     const DLS::version_t File::VERSION_4 = {
6171     0, 4, 20071012 & 0xffff, 20071012 >> 16
6172     };
6173    
6174 schoenebeck 1416 static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
6175 persson 1180 { CHUNK_ID_IARL, 256 },
6176     { CHUNK_ID_IART, 128 },
6177     { CHUNK_ID_ICMS, 128 },
6178     { CHUNK_ID_ICMT, 1024 },
6179     { CHUNK_ID_ICOP, 128 },
6180     { CHUNK_ID_ICRD, 128 },
6181     { CHUNK_ID_IENG, 128 },
6182     { CHUNK_ID_IGNR, 128 },
6183     { CHUNK_ID_IKEY, 128 },
6184     { CHUNK_ID_IMED, 128 },
6185     { CHUNK_ID_INAM, 128 },
6186     { CHUNK_ID_IPRD, 128 },
6187     { CHUNK_ID_ISBJ, 128 },
6188     { CHUNK_ID_ISFT, 128 },
6189     { CHUNK_ID_ISRC, 128 },
6190     { CHUNK_ID_ISRF, 128 },
6191     { CHUNK_ID_ITCH, 128 },
6192     { 0, 0 }
6193     };
6194    
6195 schoenebeck 809 File::File() : DLS::File() {
6196 schoenebeck 1524 bAutoLoad = true;
6197 persson 1264 *pVersion = VERSION_3;
6198 schoenebeck 929 pGroups = NULL;
6199 schoenebeck 2584 pScriptGroups = NULL;
6200 schoenebeck 1416 pInfo->SetFixedStringLengths(_FileFixedStringLengths);
6201 persson 1182 pInfo->ArchivalLocation = String(256, ' ');
6202 persson 1192
6203     // add some mandatory chunks to get the file chunks in right
6204     // order (INFO chunk will be moved to first position later)
6205     pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
6206     pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
6207 persson 1209 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
6208    
6209     GenerateDLSID();
6210 schoenebeck 809 }
6211    
6212 schoenebeck 2 File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
6213 schoenebeck 1524 bAutoLoad = true;
6214 schoenebeck 929 pGroups = NULL;
6215 schoenebeck 2584 pScriptGroups = NULL;
6216 schoenebeck 1416 pInfo->SetFixedStringLengths(_FileFixedStringLengths);
6217 schoenebeck 2 }
6218    
6219 schoenebeck 929 File::~File() {
6220     if (pGroups) {
6221     std::list<Group*>::iterator iter = pGroups->begin();
6222     std::list<Group*>::iterator end = pGroups->end();
6223     while (iter != end) {
6224     delete *iter;
6225     ++iter;
6226     }
6227     delete pGroups;
6228     }
6229 schoenebeck 2584 if (pScriptGroups) {
6230     std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
6231     std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
6232     while (iter != end) {
6233     delete *iter;
6234     ++iter;
6235     }
6236     delete pScriptGroups;
6237     }
6238 schoenebeck 929 }
6239    
6240 schoenebeck 515 Sample* File::GetFirstSample(progress_t* pProgress) {
6241     if (!pSamples) LoadSamples(pProgress);
6242 schoenebeck 2 if (!pSamples) return NULL;
6243     SamplesIterator = pSamples->begin();
6244     return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
6245     }
6246    
6247     Sample* File::GetNextSample() {
6248     if (!pSamples) return NULL;
6249     SamplesIterator++;
6250     return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
6251     }
6252 schoenebeck 2482
6253     /**
6254     * Returns Sample object of @a index.
6255     *
6256     * @returns sample object or NULL if index is out of bounds
6257     */
6258     Sample* File::GetSample(uint index) {
6259     if (!pSamples) LoadSamples();
6260     if (!pSamples) return NULL;
6261     DLS::File::SampleList::iterator it = pSamples->begin();
6262     for (int i = 0; i < index; ++i) {
6263     ++it;
6264     if (it == pSamples->end()) return NULL;
6265     }
6266     if (it == pSamples->end()) return NULL;
6267     return static_cast<gig::Sample*>( *it );
6268     }
6269 schoenebeck 2
6270 schoenebeck 3414 /**
6271     * Returns the total amount of samples of this gig file.
6272     *
6273     * Note that this method might block for a long time in case it is required
6274     * to load the sample info for the first time.
6275     *
6276     * @returns total amount of samples
6277     */
6278     size_t File::CountSamples() {
6279     if (!pSamples) LoadSamples();
6280     if (!pSamples) return 0;
6281     return pSamples->size();
6282     }
6283    
6284 schoenebeck 809 /** @brief Add a new sample.
6285     *
6286     * This will create a new Sample object for the gig file. You have to
6287     * call Save() to make this persistent to the file.
6288     *
6289     * @returns pointer to new Sample object
6290     */
6291     Sample* File::AddSample() {
6292     if (!pSamples) LoadSamples();
6293     __ensureMandatoryChunksExist();
6294     RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
6295     // create new Sample object and its respective 'wave' list chunk
6296     RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
6297     Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
6298 persson 1192
6299     // add mandatory chunks to get the chunks in right order
6300     wave->AddSubChunk(CHUNK_ID_FMT, 16);
6301     wave->AddSubList(LIST_TYPE_INFO);
6302    
6303 schoenebeck 809 pSamples->push_back(pSample);
6304     return pSample;
6305     }
6306    
6307     /** @brief Delete a sample.
6308     *
6309 schoenebeck 1292 * This will delete the given Sample object from the gig file. Any
6310     * references to this sample from Regions and DimensionRegions will be
6311     * removed. You have to call Save() to make this persistent to the file.
6312 schoenebeck 809 *
6313     * @param pSample - sample to delete
6314     * @throws gig::Exception if given sample could not be found
6315     */
6316     void File::DeleteSample(Sample* pSample) {
6317 schoenebeck 823 if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
6318     SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
6319 schoenebeck 809 if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
6320 schoenebeck 1083 if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
6321 schoenebeck 809 pSamples->erase(iter);
6322 schoenebeck 3478 pSample->DeleteChunks();
6323 schoenebeck 809 delete pSample;
6324 persson 1266
6325 persson 1678 SampleList::iterator tmp = SamplesIterator;
6326 persson 1266 // remove all references to the sample
6327     for (Instrument* instrument = GetFirstInstrument() ; instrument ;
6328     instrument = GetNextInstrument()) {
6329     for (Region* region = instrument->GetFirstRegion() ; region ;
6330     region = instrument->GetNextRegion()) {
6331    
6332     if (region->GetSample() == pSample) region->SetSample(NULL);
6333    
6334     for (int i = 0 ; i < region->DimensionRegions ; i++) {
6335     gig::DimensionRegion *d = region->pDimensionRegions[i];
6336     if (d->pSample == pSample) d->pSample = NULL;
6337     }
6338     }
6339     }
6340 persson 1678 SamplesIterator = tmp; // restore iterator
6341 schoenebeck 809 }
6342    
6343 schoenebeck 823 void File::LoadSamples() {
6344     LoadSamples(NULL);
6345     }
6346    
6347 schoenebeck 515 void File::LoadSamples(progress_t* pProgress) {
6348 schoenebeck 930 // Groups must be loaded before samples, because samples will try
6349     // to resolve the group they belong to
6350 schoenebeck 1158 if (!pGroups) LoadGroups();
6351 schoenebeck 930
6352 schoenebeck 823 if (!pSamples) pSamples = new SampleList;
6353    
6354 persson 666 RIFF::File* file = pRIFF;
6355 schoenebeck 515
6356 persson 666 // just for progress calculation
6357     int iSampleIndex = 0;
6358     int iTotalSamples = WavePoolCount;
6359 schoenebeck 515
6360 schoenebeck 3474 // just for assembling path of optional extension files to be read
6361     const std::string folder = parentPath(pRIFF->GetFileName());
6362     const std::string baseName = pathWithoutExtension(pRIFF->GetFileName());
6363    
6364     // the main gig file and the extension files (.gx01, ... , .gx98) may
6365     // contain wave data (wave pool)
6366     std::vector<RIFF::File*> poolFiles;
6367     poolFiles.push_back(pRIFF);
6368    
6369     // get info about all extension files
6370     RIFF::Chunk* ckXfil = pRIFF->GetSubChunk(CHUNK_ID_XFIL);
6371     if (ckXfil) { // there are extension files (.gx01, ... , .gx98) ...
6372     const uint32_t n = ckXfil->ReadInt32();
6373     for (int i = 0; i < n; i++) {
6374     // read the filename and load the extension file
6375     std::string name;
6376     ckXfil->ReadString(name, 128);
6377     std::string path = concatPath(folder, name);
6378     RIFF::File* pExtFile = new RIFF::File(path);
6379     // check that the dlsids match
6380     RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
6381     if (ckDLSID) {
6382     ::DLS::dlsid_t idExpected;
6383     idExpected.ulData1 = ckXfil->ReadInt32();
6384     idExpected.usData2 = ckXfil->ReadInt16();
6385     idExpected.usData3 = ckXfil->ReadInt16();
6386     ckXfil->Read(idExpected.abData, 8, 1);
6387     ::DLS::dlsid_t idFound;
6388     ckDLSID->Read(&idFound.ulData1, 1, 4);
6389     ckDLSID->Read(&idFound.usData2, 1, 2);
6390     ckDLSID->Read(&idFound.usData3, 1, 2);
6391     ckDLSID->Read(idFound.abData, 8, 1);
6392     if (memcmp(&idExpected, &idFound, 16) != 0)
6393     throw gig::Exception("dlsid mismatch for extension file: %s", path.c_str());
6394     }
6395     poolFiles.push_back(pExtFile);
6396     ExtensionFiles.push_back(pExtFile);
6397 schoenebeck 2912 }
6398 persson 666 }
6399 schoenebeck 515
6400 schoenebeck 3474 // check if a .gx99 (GigaPulse) file exists
6401     RIFF::Chunk* ckDoxf = pRIFF->GetSubChunk(CHUNK_ID_DOXF);
6402     if (ckDoxf) { // there is a .gx99 (GigaPulse) file ...
6403     std::string path = baseName + ".gx99";
6404     RIFF::File* pExtFile = new RIFF::File(path);
6405    
6406     // skip unused int and filename
6407 schoenebeck 3475 ckDoxf->SetPos(132, RIFF::stream_curpos);
6408 schoenebeck 3474
6409     // check that the dlsids match
6410     RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
6411     if (ckDLSID) {
6412     ::DLS::dlsid_t idExpected;
6413     idExpected.ulData1 = ckDoxf->ReadInt32();
6414     idExpected.usData2 = ckDoxf->ReadInt16();
6415     idExpected.usData3 = ckDoxf->ReadInt16();
6416     ckDoxf->Read(idExpected.abData, 8, 1);
6417     ::DLS::dlsid_t idFound;
6418     ckDLSID->Read(&idFound.ulData1, 1, 4);
6419     ckDLSID->Read(&idFound.usData2, 1, 2);
6420     ckDLSID->Read(&idFound.usData3, 1, 2);
6421     ckDLSID->Read(idFound.abData, 8, 1);
6422     if (memcmp(&idExpected, &idFound, 16) != 0)
6423     throw gig::Exception("dlsid mismatch for GigaPulse file: %s", path.c_str());
6424     }
6425     poolFiles.push_back(pExtFile);
6426     ExtensionFiles.push_back(pExtFile);
6427     }
6428    
6429     // load samples from extension files (if required)
6430     for (int i = 0; i < poolFiles.size(); i++) {
6431     RIFF::File* file = poolFiles[i];
6432 persson 666 RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
6433     if (wvpl) {
6434 schoenebeck 3478 file_offset_t wvplFileOffset = wvpl->GetFilePos() -
6435     wvpl->GetPos(); // should be zero, but just to be sure
6436 persson 666 RIFF::List* wave = wvpl->GetFirstSubList();
6437     while (wave) {
6438     if (wave->GetListType() == LIST_TYPE_WAVE) {
6439     // notify current progress
6440 schoenebeck 3488 if (pProgress) {
6441     const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
6442     __notify_progress(pProgress, subprogress);
6443     }
6444 persson 666
6445 schoenebeck 2912 file_offset_t waveFileOffset = wave->GetFilePos();
6446 schoenebeck 3474 pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, i, iSampleIndex));
6447 persson 666
6448     iSampleIndex++;
6449     }
6450     wave = wvpl->GetNextSubList();
6451 schoenebeck 2 }
6452 schoenebeck 3474 }
6453 schoenebeck 2 }
6454 persson 666
6455 schoenebeck 3488 if (pProgress)
6456     __notify_progress(pProgress, 1.0); // notify done
6457 schoenebeck 2 }
6458    
6459     Instrument* File::GetFirstInstrument() {
6460     if (!pInstruments) LoadInstruments();
6461     if (!pInstruments) return NULL;
6462     InstrumentsIterator = pInstruments->begin();
6463 schoenebeck 823 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
6464 schoenebeck 2 }
6465    
6466     Instrument* File::GetNextInstrument() {
6467     if (!pInstruments) return NULL;
6468     InstrumentsIterator++;
6469 schoenebeck 823 return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
6470 schoenebeck 2 }
6471    
6472 schoenebeck 21 /**
6473 schoenebeck 3414 * Returns the total amount of instruments of this gig file.
6474     *
6475     * Note that this method might block for a long time in case it is required
6476     * to load the instruments info for the first time.
6477     *
6478     * @returns total amount of instruments
6479     */
6480     size_t File::CountInstruments() {
6481     if (!pInstruments) LoadInstruments();
6482     if (!pInstruments) return 0;
6483     return pInstruments->size();
6484     }
6485    
6486     /**
6487 schoenebeck 21 * Returns the instrument with the given index.
6488     *
6489 schoenebeck 515 * @param index - number of the sought instrument (0..n)
6490     * @param pProgress - optional: callback function for progress notification
6491 schoenebeck 21 * @returns sought instrument or NULL if there's no such instrument
6492     */
6493 schoenebeck 515 Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
6494     if (!pInstruments) {
6495     // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
6496    
6497 schoenebeck 3488 if (pProgress) {
6498     // sample loading subtask
6499     progress_t subprogress;
6500     __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
6501     __notify_progress(&subprogress, 0.0f);
6502     if (GetAutoLoad())
6503     GetFirstSample(&subprogress); // now force all samples to be loaded
6504     __notify_progress(&subprogress, 1.0f);
6505 schoenebeck 515
6506 schoenebeck 3488 // instrument loading subtask
6507     if (pProgress->callback) {
6508     subprogress.__range_min = subprogress.__range_max;
6509     subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
6510     }
6511     __notify_progress(&subprogress, 0.0f);
6512     LoadInstruments(&subprogress);
6513     __notify_progress(&subprogress, 1.0f);
6514     } else {
6515     // sample loading subtask
6516     if (GetAutoLoad())
6517     GetFirstSample(); // now force all samples to be loaded
6518    
6519     // instrument loading subtask
6520     LoadInstruments();
6521 schoenebeck 515 }
6522     }
6523 schoenebeck 21 if (!pInstruments) return NULL;
6524     InstrumentsIterator = pInstruments->begin();
6525     for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
6526 schoenebeck 823 if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
6527 schoenebeck 21 InstrumentsIterator++;
6528     }
6529     return NULL;
6530     }
6531    
6532 schoenebeck 809 /** @brief Add a new instrument definition.
6533     *
6534     * This will create a new Instrument object for the gig file. You have
6535     * to call Save() to make this persistent to the file.
6536     *
6537     * @returns pointer to new Instrument object
6538     */
6539     Instrument* File::AddInstrument() {
6540     if (!pInstruments) LoadInstruments();
6541     __ensureMandatoryChunksExist();
6542     RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
6543     RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
6544 persson 1192
6545     // add mandatory chunks to get the chunks in right order
6546     lstInstr->AddSubList(LIST_TYPE_INFO);
6547 persson 1209 lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
6548 persson 1192
6549 schoenebeck 809 Instrument* pInstrument = new Instrument(this, lstInstr);
6550 persson 1209 pInstrument->GenerateDLSID();
6551 persson 1182
6552 persson 1192 lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
6553    
6554 persson 1182 // this string is needed for the gig to be loadable in GSt:
6555     pInstrument->pInfo->Software = "Endless Wave";
6556    
6557 schoenebeck 809 pInstruments->push_back(pInstrument);
6558     return pInstrument;
6559     }
6560 schoenebeck 2394
6561     /** @brief Add a duplicate of an existing instrument.
6562     *
6563     * Duplicates the instrument definition given by @a orig and adds it
6564     * to this file. This allows in an instrument editor application to
6565     * easily create variations of an instrument, which will be stored in
6566     * the same .gig file, sharing i.e. the same samples.
6567     *
6568     * Note that all sample pointers referenced by @a orig are simply copied as
6569     * memory address. Thus the respective samples are shared, not duplicated!
6570     *
6571     * You have to call Save() to make this persistent to the file.
6572     *
6573     * @param orig - original instrument to be copied
6574     * @returns duplicated copy of the given instrument
6575     */
6576     Instrument* File::AddDuplicateInstrument(const Instrument* orig) {
6577     Instrument* instr = AddInstrument();
6578     instr->CopyAssign(orig);
6579     return instr;
6580     }
6581 schoenebeck 2482
6582     /** @brief Add content of another existing file.
6583     *
6584     * Duplicates the samples, groups and instruments of the original file
6585     * given by @a pFile and adds them to @c this File. In case @c this File is
6586     * a new one that you haven't saved before, then you have to call
6587     * SetFileName() before calling AddContentOf(), because this method will
6588     * automatically save this file during operation, which is required for
6589     * writing the sample waveform data by disk streaming.
6590     *
6591     * @param pFile - original file whose's content shall be copied from
6592     */
6593     void File::AddContentOf(File* pFile) {
6594     static int iCallCount = -1;
6595     iCallCount++;
6596     std::map<Group*,Group*> mGroups;
6597     std::map<Sample*,Sample*> mSamples;
6598    
6599     // clone sample groups
6600     for (int i = 0; pFile->GetGroup(i); ++i) {
6601     Group* g = AddGroup();
6602     g->Name =
6603     "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
6604     mGroups[pFile->GetGroup(i)] = g;
6605     }
6606    
6607     // clone samples (not waveform data here yet)
6608     for (int i = 0; pFile->GetSample(i); ++i) {
6609     Sample* s = AddSample();
6610     s->CopyAssignMeta(pFile->GetSample(i));
6611     mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
6612     mSamples[pFile->GetSample(i)] = s;
6613     }
6614 schoenebeck 3117
6615     // clone script groups and their scripts
6616     for (int iGroup = 0; pFile->GetScriptGroup(iGroup); ++iGroup) {
6617     ScriptGroup* sg = pFile->GetScriptGroup(iGroup);
6618     ScriptGroup* dg = AddScriptGroup();
6619     dg->Name = "COPY" + ToString(iCallCount) + "_" + sg->Name;
6620     for (int iScript = 0; sg->GetScript(iScript); ++iScript) {
6621     Script* ss = sg->GetScript(iScript);
6622     Script* ds = dg->AddScript();
6623     ds->CopyAssign(ss);
6624     }
6625     }
6626    
6627 schoenebeck 2482 //BUG: For some reason this method only works with this additional
6628     // Save() call in between here.
6629     //
6630     // Important: The correct one of the 2 Save() methods has to be called
6631     // here, depending on whether the file is completely new or has been
6632     // saved to disk already, otherwise it will result in data corruption.
6633     if (pRIFF->IsNew())
6634     Save(GetFileName());
6635     else
6636     Save();
6637    
6638     // clone instruments
6639     // (passing the crosslink table here for the cloned samples)
6640     for (int i = 0; pFile->GetInstrument(i); ++i) {
6641     Instrument* instr = AddInstrument();
6642     instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
6643     }
6644    
6645     // Mandatory: file needs to be saved to disk at this point, so this
6646     // file has the correct size and data layout for writing the samples'
6647     // waveform data to disk.
6648     Save();
6649    
6650     // clone samples' waveform data
6651     // (using direct read & write disk streaming)
6652     for (int i = 0; pFile->GetSample(i); ++i) {
6653     mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
6654     }
6655     }
6656 schoenebeck 809
6657     /** @brief Delete an instrument.
6658     *
6659     * This will delete the given Instrument object from the gig file. You
6660     * have to call Save() to make this persistent to the file.
6661     *
6662     * @param pInstrument - instrument to delete
6663 schoenebeck 1081 * @throws gig::Exception if given instrument could not be found
6664 schoenebeck 809 */
6665     void File::DeleteInstrument(Instrument* pInstrument) {
6666     if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
6667 schoenebeck 823 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
6668 schoenebeck 809 if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
6669     pInstruments->erase(iter);
6670 schoenebeck 3478 pInstrument->DeleteChunks();
6671 schoenebeck 809 delete pInstrument;
6672     }
6673    
6674 schoenebeck 823 void File::LoadInstruments() {
6675     LoadInstruments(NULL);
6676     }
6677    
6678 schoenebeck 515 void File::LoadInstruments(progress_t* pProgress) {
6679 schoenebeck 823 if (!pInstruments) pInstruments = new InstrumentList;
6680 schoenebeck 2 RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
6681     if (lstInstruments) {
6682 schoenebeck 515 int iInstrumentIndex = 0;
6683 schoenebeck 2 RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
6684     while (lstInstr) {
6685     if (lstInstr->GetListType() == LIST_TYPE_INS) {
6686 schoenebeck 3488 if (pProgress) {
6687     // notify current progress
6688     const float localProgress = (float) iInstrumentIndex / (float) Instruments;
6689     __notify_progress(pProgress, localProgress);
6690 schoenebeck 515
6691 schoenebeck 3488 // divide local progress into subprogress for loading current Instrument
6692     progress_t subprogress;
6693     __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
6694 schoenebeck 515
6695 schoenebeck 3488 pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
6696     } else {
6697     pInstruments->push_back(new Instrument(this, lstInstr));
6698     }
6699 schoenebeck 515
6700     iInstrumentIndex++;
6701 schoenebeck 2 }
6702     lstInstr = lstInstruments->GetNextSubList();
6703     }
6704 schoenebeck 3488 if (pProgress)
6705     __notify_progress(pProgress, 1.0); // notify done
6706 schoenebeck 2 }
6707     }
6708    
6709 persson 1207 /// Updates the 3crc chunk with the checksum of a sample. The
6710     /// update is done directly to disk, as this method is called
6711     /// after File::Save()
6712 persson 1199 void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
6713     RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6714     if (!_3crc) return;
6715 persson 1207
6716     // get the index of the sample
6717 schoenebeck 2985 int iWaveIndex = GetWaveTableIndexOf(pSample);
6718 persson 1199 if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
6719    
6720 persson 1207 // write the CRC-32 checksum to disk
6721 persson 1199 _3crc->SetPos(iWaveIndex * 8);
6722 schoenebeck 2985 uint32_t one = 1;
6723     _3crc->WriteUint32(&one); // always 1
6724 persson 1199 _3crc->WriteUint32(&crc);
6725 schoenebeck 2989 }
6726 schoenebeck 2985
6727 schoenebeck 2989 uint32_t File::GetSampleChecksum(Sample* pSample) {
6728     // get the index of the sample
6729     int iWaveIndex = GetWaveTableIndexOf(pSample);
6730     if (iWaveIndex < 0) throw gig::Exception("Could not retrieve reference crc of sample, could not resolve sample's wave table index");
6731    
6732     return GetSampleChecksumByIndex(iWaveIndex);
6733 persson 1199 }
6734    
6735 schoenebeck 2989 uint32_t File::GetSampleChecksumByIndex(int index) {
6736     if (index < 0) throw gig::Exception("Could not retrieve reference crc of sample, invalid wave pool index of sample");
6737    
6738 schoenebeck 2985 RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6739     if (!_3crc) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6740     uint8_t* pData = (uint8_t*) _3crc->LoadChunkData();
6741     if (!pData) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6742    
6743     // read the CRC-32 checksum directly from disk
6744 schoenebeck 2989 size_t pos = index * 8;
6745 schoenebeck 2985 if (pos + 8 > _3crc->GetNewSize())
6746     throw gig::Exception("Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
6747    
6748     uint32_t one = load32(&pData[pos]); // always 1
6749     if (one != 1)
6750 schoenebeck 2989 throw gig::Exception("Could not retrieve reference crc of sample, because reference checksum table is damaged");
6751 schoenebeck 2985
6752     return load32(&pData[pos+4]);
6753     }
6754 schoenebeck 2989
6755 schoenebeck 2985 int File::GetWaveTableIndexOf(gig::Sample* pSample) {
6756     if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
6757     File::SampleList::iterator iter = pSamples->begin();
6758     File::SampleList::iterator end = pSamples->end();
6759     for (int index = 0; iter != end; ++iter, ++index)
6760     if (*iter == pSample)
6761     return index;
6762     return -1;
6763     }
6764    
6765     /**
6766     * Checks whether the file's "3CRC" chunk was damaged. This chunk contains
6767     * the CRC32 check sums of all samples' raw wave data.
6768     *
6769     * @return true if 3CRC chunk is OK, or false if 3CRC chunk is damaged
6770     */
6771     bool File::VerifySampleChecksumTable() {
6772     RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6773     if (!_3crc) return false;
6774     if (_3crc->GetNewSize() <= 0) return false;
6775     if (_3crc->GetNewSize() % 8) return false;
6776     if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
6777     if (_3crc->GetNewSize() != pSamples->size() * 8) return false;
6778    
6779 schoenebeck 3053 const file_offset_t n = _3crc->GetNewSize() / 8;
6780 schoenebeck 2985
6781     uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6782     if (!pData) return false;
6783    
6784 schoenebeck 3053 for (file_offset_t i = 0; i < n; ++i) {
6785 schoenebeck 2985 uint32_t one = pData[i*2];
6786     if (one != 1) return false;
6787     }
6788    
6789     return true;
6790     }
6791    
6792     /**
6793     * Recalculates CRC32 checksums for all samples and rebuilds this gig
6794     * file's checksum table with those new checksums. This might usually
6795     * just be necessary if the checksum table was damaged.
6796     *
6797     * @e IMPORTANT: The current implementation of this method only works
6798     * with files that have not been modified since it was loaded, because
6799     * it expects that no externally caused file structure changes are
6800     * required!
6801     *
6802     * Due to the expectation above, this method is currently protected
6803     * and actually only used by the command line tool "gigdump" yet.
6804     *
6805     * @returns true if Save() is required to be called after this call,
6806     * false if no further action is required
6807     */
6808     bool File::RebuildSampleChecksumTable() {
6809     // make sure sample chunks were scanned
6810     if (!pSamples) GetFirstSample();
6811    
6812     bool bRequiresSave = false;
6813    
6814     // make sure "3CRC" chunk exists with required size
6815     RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6816     if (!_3crc) {
6817     _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6818 schoenebeck 2989 // the order of einf and 3crc is not the same in v2 and v3
6819     RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6820 schoenebeck 3440 if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
6821 schoenebeck 2985 bRequiresSave = true;
6822     } else if (_3crc->GetNewSize() != pSamples->size() * 8) {
6823     _3crc->Resize(pSamples->size() * 8);
6824     bRequiresSave = true;
6825     }
6826    
6827     if (bRequiresSave) { // refill CRC table for all samples in RAM ...
6828     uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6829     {
6830     File::SampleList::iterator iter = pSamples->begin();
6831     File::SampleList::iterator end = pSamples->end();
6832     for (; iter != end; ++iter) {
6833     gig::Sample* pSample = (gig::Sample*) *iter;
6834     int index = GetWaveTableIndexOf(pSample);
6835     if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6836     pData[index*2] = 1; // always 1
6837     pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6838     }
6839     }
6840     } else { // no file structure changes necessary, so directly write to disk and we are done ...
6841     // make sure file is in write mode
6842     pRIFF->SetMode(RIFF::stream_mode_read_write);
6843     {
6844     File::SampleList::iterator iter = pSamples->begin();
6845     File::SampleList::iterator end = pSamples->end();
6846     for (; iter != end; ++iter) {
6847     gig::Sample* pSample = (gig::Sample*) *iter;
6848     int index = GetWaveTableIndexOf(pSample);
6849     if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6850 schoenebeck 2989 pSample->crc = pSample->CalculateWaveDataChecksum();
6851     SetSampleChecksum(pSample, pSample->crc);
6852 schoenebeck 2985 }
6853     }
6854     }
6855    
6856     return bRequiresSave;
6857     }
6858    
6859 schoenebeck 929 Group* File::GetFirstGroup() {
6860     if (!pGroups) LoadGroups();
6861 schoenebeck 930 // there must always be at least one group
6862 schoenebeck 929 GroupsIterator = pGroups->begin();
6863 schoenebeck 930 return *GroupsIterator;
6864 schoenebeck 929 }
6865 schoenebeck 2
6866 schoenebeck 929 Group* File::GetNextGroup() {
6867     if (!pGroups) return NULL;
6868     ++GroupsIterator;
6869     return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6870     }
6871 schoenebeck 2
6872 schoenebeck 929 /**
6873     * Returns the group with the given index.
6874     *
6875     * @param index - number of the sought group (0..n)
6876     * @returns sought group or NULL if there's no such group
6877     */
6878     Group* File::GetGroup(uint index) {
6879     if (!pGroups) LoadGroups();
6880     GroupsIterator = pGroups->begin();
6881     for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
6882     if (i == index) return *GroupsIterator;
6883     ++GroupsIterator;
6884     }
6885     return NULL;
6886     }
6887    
6888 schoenebeck 2543 /**
6889     * Returns the group with the given group name.
6890     *
6891     * Note: group names don't have to be unique in the gig format! So there
6892     * can be multiple groups with the same name. This method will simply
6893     * return the first group found with the given name.
6894     *
6895     * @param name - name of the sought group
6896     * @returns sought group or NULL if there's no group with that name
6897     */
6898     Group* File::GetGroup(String name) {
6899     if (!pGroups) LoadGroups();
6900     GroupsIterator = pGroups->begin();
6901     for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
6902     if ((*GroupsIterator)->Name == name) return *GroupsIterator;
6903     return NULL;
6904     }
6905    
6906 schoenebeck 929 Group* File::AddGroup() {
6907     if (!pGroups) LoadGroups();
6908 schoenebeck 930 // there must always be at least one group
6909 schoenebeck 929 __ensureMandatoryChunksExist();
6910 schoenebeck 930 Group* pGroup = new Group(this, NULL);
6911 schoenebeck 929 pGroups->push_back(pGroup);
6912     return pGroup;
6913     }
6914    
6915 schoenebeck 1081 /** @brief Delete a group and its samples.
6916     *
6917     * This will delete the given Group object and all the samples that
6918     * belong to this group from the gig file. You have to call Save() to
6919     * make this persistent to the file.
6920     *
6921     * @param pGroup - group to delete
6922     * @throws gig::Exception if given group could not be found
6923     */
6924 schoenebeck 929 void File::DeleteGroup(Group* pGroup) {
6925 schoenebeck 930 if (!pGroups) LoadGroups();
6926 schoenebeck 929 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6927     if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6928 schoenebeck 930 if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6929 schoenebeck 1081 // delete all members of this group
6930     for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
6931     DeleteSample(pSample);
6932     }
6933     // now delete this group object
6934     pGroups->erase(iter);
6935 schoenebeck 3478 pGroup->DeleteChunks();
6936 schoenebeck 1081 delete pGroup;
6937     }
6938    
6939     /** @brief Delete a group.
6940     *
6941     * This will delete the given Group object from the gig file. All the
6942     * samples that belong to this group will not be deleted, but instead
6943     * be moved to another group. You have to call Save() to make this
6944     * persistent to the file.
6945     *
6946     * @param pGroup - group to delete
6947     * @throws gig::Exception if given group could not be found
6948     */
6949     void File::DeleteGroupOnly(Group* pGroup) {
6950     if (!pGroups) LoadGroups();
6951     std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6952     if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6953     if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6954 schoenebeck 930 // move all members of this group to another group
6955     pGroup->MoveAll();
6956 schoenebeck 929 pGroups->erase(iter);
6957 schoenebeck 3478 pGroup->DeleteChunks();
6958 schoenebeck 929 delete pGroup;
6959     }
6960    
6961     void File::LoadGroups() {
6962     if (!pGroups) pGroups = new std::list<Group*>;
6963 schoenebeck 930 // try to read defined groups from file
6964 schoenebeck 929 RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
6965 schoenebeck 930 if (lst3gri) {
6966     RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
6967     if (lst3gnl) {
6968     RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
6969     while (ck) {
6970     if (ck->GetChunkID() == CHUNK_ID_3GNM) {
6971 schoenebeck 3440 if (pVersion && pVersion->major > 2 &&
6972 persson 1266 strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
6973    
6974 schoenebeck 930 pGroups->push_back(new Group(this, ck));
6975     }
6976     ck = lst3gnl->GetNextSubChunk();
6977 schoenebeck 929 }
6978     }
6979     }
6980 schoenebeck 930 // if there were no group(s), create at least the mandatory default group
6981     if (!pGroups->size()) {
6982     Group* pGroup = new Group(this, NULL);
6983     pGroup->Name = "Default Group";
6984     pGroups->push_back(pGroup);
6985     }
6986 schoenebeck 929 }
6987    
6988 schoenebeck 2584 /** @brief Get instrument script group (by index).
6989     *
6990     * Returns the real-time instrument script group with the given index.
6991     *
6992     * @param index - number of the sought group (0..n)
6993     * @returns sought script group or NULL if there's no such group
6994     */
6995     ScriptGroup* File::GetScriptGroup(uint index) {
6996     if (!pScriptGroups) LoadScriptGroups();
6997     std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6998     for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6999     if (i == index) return *it;
7000     return NULL;
7001     }
7002    
7003     /** @brief Get instrument script group (by name).
7004     *
7005     * Returns the first real-time instrument script group found with the given
7006     * group name. Note that group names may not necessarily be unique.
7007     *
7008     * @param name - name of the sought script group
7009     * @returns sought script group or NULL if there's no such group
7010     */
7011     ScriptGroup* File::GetScriptGroup(const String& name) {
7012     if (!pScriptGroups) LoadScriptGroups();
7013     std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
7014     for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
7015     if ((*it)->Name == name) return *it;
7016     return NULL;
7017     }
7018    
7019     /** @brief Add new instrument script group.
7020     *
7021     * Adds a new, empty real-time instrument script group to the file.
7022     *
7023     * You have to call Save() to make this persistent to the file.
7024     *
7025     * @return new empty script group
7026     */
7027     ScriptGroup* File::AddScriptGroup() {
7028     if (!pScriptGroups) LoadScriptGroups();
7029     ScriptGroup* pScriptGroup = new ScriptGroup(this, NULL);
7030     pScriptGroups->push_back(pScriptGroup);
7031     return pScriptGroup;
7032     }
7033    
7034     /** @brief Delete an instrument script group.
7035     *
7036     * This will delete the given real-time instrument script group and all its
7037     * instrument scripts it contains. References inside instruments that are
7038     * using the deleted scripts will be removed from the respective instruments
7039     * accordingly.
7040     *
7041     * You have to call Save() to make this persistent to the file.
7042     *
7043     * @param pScriptGroup - script group to delete
7044     * @throws gig::Exception if given script group could not be found
7045     */
7046     void File::DeleteScriptGroup(ScriptGroup* pScriptGroup) {
7047     if (!pScriptGroups) LoadScriptGroups();
7048     std::list<ScriptGroup*>::iterator iter =
7049     find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
7050     if (iter == pScriptGroups->end())
7051     throw gig::Exception("Could not delete script group, could not find given script group");
7052     pScriptGroups->erase(iter);
7053     for (int i = 0; pScriptGroup->GetScript(i); ++i)
7054     pScriptGroup->DeleteScript(pScriptGroup->GetScript(i));
7055     if (pScriptGroup->pList)
7056     pScriptGroup->pList->GetParent()->DeleteSubChunk(pScriptGroup->pList);
7057 schoenebeck 3478 pScriptGroup->DeleteChunks();
7058 schoenebeck 2584 delete pScriptGroup;
7059     }
7060    
7061     void File::LoadScriptGroups() {
7062     if (pScriptGroups) return;
7063     pScriptGroups = new std::list<ScriptGroup*>;
7064     RIFF::List* lstLS = pRIFF->GetSubList(LIST_TYPE_3LS);
7065     if (lstLS) {
7066     for (RIFF::List* lst = lstLS->GetFirstSubList(); lst;
7067     lst = lstLS->GetNextSubList())
7068     {
7069     if (lst->GetListType() == LIST_TYPE_RTIS) {
7070     pScriptGroups->push_back(new ScriptGroup(this, lst));
7071     }
7072     }
7073     }
7074     }
7075    
7076 schoenebeck 1098 /**
7077     * Apply all the gig file's current instruments, samples, groups and settings
7078     * to the respective RIFF chunks. You have to call Save() to make changes
7079     * persistent.
7080     *
7081     * Usually there is absolutely no need to call this method explicitly.
7082     * It will be called automatically when File::Save() was called.
7083     *
7084 schoenebeck 2682 * @param pProgress - callback function for progress notification
7085 schoenebeck 1098 * @throws Exception - on errors
7086     */
7087 schoenebeck 2682 void File::UpdateChunks(progress_t* pProgress) {
7088 persson 1199 bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
7089 persson 1192
7090 schoenebeck 2584 // update own gig format extension chunks
7091     // (not part of the GigaStudio 4 format)
7092 schoenebeck 2912 RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);
7093     if (!lst3LS) {
7094     lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
7095     }
7096     // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
7097 schoenebeck 2913 // location of <3LS > is irrelevant, however it should be located
7098     // before the actual wave data
7099 schoenebeck 2912 RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
7100     pRIFF->MoveSubChunk(lst3LS, ckPTBL);
7101    
7102 schoenebeck 2584 // This must be performed before writing the chunks for instruments,
7103     // because the instruments' script slots will write the file offsets
7104     // of the respective instrument script chunk as reference.
7105     if (pScriptGroups) {
7106 schoenebeck 2912 // Update instrument script (group) chunks.
7107     for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
7108     it != pScriptGroups->end(); ++it)
7109     {
7110     (*it)->UpdateChunks(pProgress);
7111 schoenebeck 2584 }
7112     }
7113    
7114 schoenebeck 2913 // in case no libgig custom format data was added, then remove the
7115     // custom "3LS " chunk again
7116     if (!lst3LS->CountSubChunks()) {
7117     pRIFF->DeleteSubChunk(lst3LS);
7118     lst3LS = NULL;
7119     }
7120    
7121 schoenebeck 1098 // first update base class's chunks
7122 schoenebeck 2682 DLS::File::UpdateChunks(pProgress);
7123 schoenebeck 929
7124 persson 1199 if (newFile) {
7125 persson 1192 // INFO was added by Resource::UpdateChunks - make sure it
7126     // is placed first in file
7127 persson 1199 RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
7128 persson 1192 RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
7129     if (first != info) {
7130     pRIFF->MoveSubChunk(info, first);
7131     }
7132     }
7133    
7134 schoenebeck 1098 // update group's chunks
7135     if (pGroups) {
7136 schoenebeck 2467 // make sure '3gri' and '3gnl' list chunks exist
7137     // (before updating the Group chunks)
7138     RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
7139     if (!_3gri) {
7140     _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
7141     pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
7142 schoenebeck 1098 }
7143 schoenebeck 2467 RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
7144     if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
7145 persson 1266
7146     // v3: make sure the file has 128 3gnm chunks
7147 schoenebeck 2467 // (before updating the Group chunks)
7148 schoenebeck 3440 if (pVersion && pVersion->major > 2) {
7149 persson 1266 RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
7150     for (int i = 0 ; i < 128 ; i++) {
7151 schoenebeck 3656 // create 128 empty placeholder strings which will either
7152     // be filled by Group::UpdateChunks below or left empty.
7153     ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
7154 persson 1266 if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
7155     }
7156     }
7157 schoenebeck 2467
7158     std::list<Group*>::iterator iter = pGroups->begin();
7159     std::list<Group*>::iterator end = pGroups->end();
7160     for (; iter != end; ++iter) {
7161 schoenebeck 2682 (*iter)->UpdateChunks(pProgress);
7162 schoenebeck 2467 }
7163 schoenebeck 1098 }
7164 persson 1199
7165     // update einf chunk
7166    
7167     // The einf chunk contains statistics about the gig file, such
7168     // as the number of regions and samples used by each
7169     // instrument. It is divided in equally sized parts, where the
7170     // first part contains information about the whole gig file,
7171     // and the rest of the parts map to each instrument in the
7172     // file.
7173     //
7174     // At the end of each part there is a bit map of each sample
7175     // in the file, where a set bit means that the sample is used
7176     // by the file/instrument.
7177     //
7178     // Note that there are several fields with unknown use. These
7179     // are set to zero.
7180    
7181 schoenebeck 3053 int sublen = int(pSamples->size() / 8 + 49);
7182 persson 1199 int einfSize = (Instruments + 1) * sublen;
7183    
7184     RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
7185     if (einf) {
7186     if (einf->GetSize() != einfSize) {
7187     einf->Resize(einfSize);
7188     memset(einf->LoadChunkData(), 0, einfSize);
7189     }
7190     } else if (newFile) {
7191     einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
7192     }
7193     if (einf) {
7194     uint8_t* pData = (uint8_t*) einf->LoadChunkData();
7195    
7196     std::map<gig::Sample*,int> sampleMap;
7197     int sampleIdx = 0;
7198     for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
7199     sampleMap[pSample] = sampleIdx++;
7200     }
7201    
7202     int totnbusedsamples = 0;
7203     int totnbusedchannels = 0;
7204     int totnbregions = 0;
7205     int totnbdimregions = 0;
7206 persson 1264 int totnbloops = 0;
7207 persson 1199 int instrumentIdx = 0;
7208    
7209     memset(&pData[48], 0, sublen - 48);
7210    
7211     for (Instrument* instrument = GetFirstInstrument() ; instrument ;
7212     instrument = GetNextInstrument()) {
7213     int nbusedsamples = 0;
7214     int nbusedchannels = 0;
7215     int nbdimregions = 0;
7216 persson 1264 int nbloops = 0;
7217 persson 1199
7218     memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
7219    
7220     for (Region* region = instrument->GetFirstRegion() ; region ;
7221     region = instrument->GetNextRegion()) {
7222     for (int i = 0 ; i < region->DimensionRegions ; i++) {
7223     gig::DimensionRegion *d = region->pDimensionRegions[i];
7224     if (d->pSample) {
7225     int sampleIdx = sampleMap[d->pSample];
7226     int byte = 48 + sampleIdx / 8;
7227     int bit = 1 << (sampleIdx & 7);
7228     if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
7229     pData[(instrumentIdx + 1) * sublen + byte] |= bit;
7230     nbusedsamples++;
7231     nbusedchannels += d->pSample->Channels;
7232    
7233     if ((pData[byte] & bit) == 0) {
7234     pData[byte] |= bit;
7235     totnbusedsamples++;
7236     totnbusedchannels += d->pSample->Channels;
7237     }
7238     }
7239     }
7240 persson 1264 if (d->SampleLoops) nbloops++;
7241 persson 1199 }
7242     nbdimregions += region->DimensionRegions;
7243     }
7244     // first 4 bytes unknown - sometimes 0, sometimes length of einf part
7245     // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
7246     store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
7247     store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
7248     store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
7249     store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
7250     store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
7251 persson 1264 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
7252     // next 8 bytes unknown
7253 persson 1199 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
7254 schoenebeck 3053 store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
7255 persson 1199 // next 4 bytes unknown
7256    
7257     totnbregions += instrument->Regions;
7258     totnbdimregions += nbdimregions;
7259 persson 1264 totnbloops += nbloops;
7260 persson 1199 instrumentIdx++;
7261     }
7262     // first 4 bytes unknown - sometimes 0, sometimes length of einf part
7263     // store32(&pData[0], sublen);
7264     store32(&pData[4], totnbusedchannels);
7265     store32(&pData[8], totnbusedsamples);
7266     store32(&pData[12], Instruments);
7267     store32(&pData[16], totnbregions);
7268     store32(&pData[20], totnbdimregions);
7269 persson 1264 store32(&pData[24], totnbloops);
7270     // next 8 bytes unknown
7271     // next 4 bytes unknown, not always 0
7272 schoenebeck 3053 store32(&pData[40], (uint32_t) pSamples->size());
7273 persson 1199 // next 4 bytes unknown
7274     }
7275    
7276     // update 3crc chunk
7277    
7278     // The 3crc chunk contains CRC-32 checksums for the
7279 schoenebeck 2989 // samples. When saving a gig file to disk, we first update the 3CRC
7280     // chunk here (in RAM) with the old crc values which we read from the
7281     // 3CRC chunk when we opened the file (available with gig::Sample::crc
7282     // member variable). This step is required, because samples might have
7283     // been deleted by the user since the file was opened, which in turn
7284     // changes the order of the (i.e. old) checksums within the 3crc chunk.
7285     // If a sample was conciously modified by the user (that is if
7286     // Sample::Write() was called later on) then Sample::Write() will just
7287     // update the respective individual checksum(s) directly on disk and
7288     // leaves all other sample checksums untouched.
7289 persson 1199
7290 schoenebeck 2989 RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
7291 persson 1199 if (_3crc) {
7292     _3crc->Resize(pSamples->size() * 8);
7293 schoenebeck 2989 } else /*if (newFile)*/ {
7294 persson 1199 _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
7295 persson 1264 // the order of einf and 3crc is not the same in v2 and v3
7296 schoenebeck 3440 if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
7297 persson 1199 }
7298 schoenebeck 2989 { // must be performed in RAM here ...
7299     uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
7300     if (pData) {
7301     File::SampleList::iterator iter = pSamples->begin();
7302     File::SampleList::iterator end = pSamples->end();
7303     for (int index = 0; iter != end; ++iter, ++index) {
7304     gig::Sample* pSample = (gig::Sample*) *iter;
7305     pData[index*2] = 1; // always 1
7306     pData[index*2+1] = pSample->crc;
7307     }
7308     }
7309     }
7310 schoenebeck 1098 }
7311 schoenebeck 2609
7312     void File::UpdateFileOffsets() {
7313     DLS::File::UpdateFileOffsets();
7314 schoenebeck 929
7315 schoenebeck 2609 for (Instrument* instrument = GetFirstInstrument(); instrument;
7316     instrument = GetNextInstrument())
7317     {
7318     instrument->UpdateScriptFileOffsets();
7319     }
7320     }
7321    
7322 schoenebeck 1524 /**
7323 schoenebeck 3481 * Enable / disable automatic loading. By default this property is
7324     * enabled and every information is loaded automatically. However
7325 schoenebeck 1524 * loading all Regions, DimensionRegions and especially samples might
7326     * take a long time for large .gig files, and sometimes one might only
7327     * be interested in retrieving very superficial informations like the
7328     * amount of instruments and their names. In this case one might disable
7329     * automatic loading to avoid very slow response times.
7330     *
7331     * @e CAUTION: by disabling this property many pointers (i.e. sample
7332 schoenebeck 3481 * references) and attributes will have invalid or even undefined
7333 schoenebeck 1524 * data! This feature is currently only intended for retrieving very
7334 schoenebeck 3481 * superficial information in a very fast way. Don't use it to retrieve
7335     * details like synthesis information or even to modify .gig files!
7336 schoenebeck 1524 */
7337     void File::SetAutoLoad(bool b) {
7338     bAutoLoad = b;
7339     }
7340 schoenebeck 1098
7341 schoenebeck 1524 /**
7342     * Returns whether automatic loading is enabled.
7343     * @see SetAutoLoad()
7344     */
7345     bool File::GetAutoLoad() {
7346     return bAutoLoad;
7347     }
7348 schoenebeck 1098
7349 schoenebeck 3710 /**
7350     * Returns @c true in case this gig File object uses any gig format
7351     * extension, that is e.g. whether any DimensionRegion object currently
7352     * has any setting effective that would require our "LSDE" RIFF chunk to
7353     * be stored to the gig file.
7354     *
7355     * Right now this is a private method. It is considerable though this method
7356     * to become (in slightly modified form) a public API method in future, i.e.
7357     * to allow instrument editors to visualize and/or warn the user of any gig
7358     * format extension being used. See also comments on
7359     * DimensionRegion::UsesAnyGigFormatExtension() for details about such a
7360     * potential public API change in future.
7361     */
7362     bool File::UsesAnyGigFormatExtension() const {
7363     if (!pInstruments) return false;
7364     InstrumentList::iterator iter = pInstruments->begin();
7365     InstrumentList::iterator end = pInstruments->end();
7366     for (; iter != end; ++iter) {
7367     Instrument* pInstrument = static_cast<gig::Instrument*>(*iter);
7368     if (pInstrument->UsesAnyGigFormatExtension())
7369     return true;
7370     }
7371     return false;
7372     }
7373 schoenebeck 1524
7374    
7375 schoenebeck 2 // *************** Exception ***************
7376     // *
7377    
7378 schoenebeck 3198 Exception::Exception() : DLS::Exception() {
7379 schoenebeck 2 }
7380    
7381 schoenebeck 3198 Exception::Exception(String format, ...) : DLS::Exception() {
7382     va_list arg;
7383     va_start(arg, format);
7384     Message = assemble(format, arg);
7385     va_end(arg);
7386     }
7387    
7388     Exception::Exception(String format, va_list arg) : DLS::Exception() {
7389     Message = assemble(format, arg);
7390     }
7391    
7392 schoenebeck 2 void Exception::PrintMessage() {
7393     std::cout << "gig::Exception: " << Message << std::endl;
7394     }
7395    
7396 schoenebeck 518
7397     // *************** functions ***************
7398     // *
7399    
7400     /**
7401     * Returns the name of this C++ library. This is usually "libgig" of
7402     * course. This call is equivalent to RIFF::libraryName() and
7403     * DLS::libraryName().
7404     */
7405     String libraryName() {
7406     return PACKAGE;
7407     }
7408    
7409     /**
7410     * Returns version of this C++ library. This call is equivalent to
7411     * RIFF::libraryVersion() and DLS::libraryVersion().
7412     */
7413     String libraryVersion() {
7414     return VERSION;
7415     }
7416    
7417 schoenebeck 2 } // namespace gig

  ViewVC Help
Powered by ViewVC