Parent Directory
|
Revision Log
* 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 | /*************************************************************************** |
2 | * * |
3 | * libgig - C++ cross-platform Gigasampler format file access library * |
4 | * * |
5 | * Copyright (C) 2003-2020 by Christian Schoenebeck * |
6 | * <cuse@users.sourceforge.net> * |
7 | * * |
8 | * This library is free software; you can redistribute it and/or modify * |
9 | * it under the terms of the GNU General Public License as published by * |
10 | * the Free Software Foundation; either version 2 of the License, or * |
11 | * (at your option) any later version. * |
12 | * * |
13 | * This library is distributed in the hope that it will be useful, * |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
16 | * GNU General Public License for more details. * |
17 | * * |
18 | * You should have received a copy of the GNU General Public License * |
19 | * along with this library; if not, write to the Free Software * |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * |
21 | * MA 02111-1307 USA * |
22 | ***************************************************************************/ |
23 | |
24 | #include "gig.h" |
25 | |
26 | #include "helper.h" |
27 | #include "Serialization.h" |
28 | |
29 | #include <algorithm> |
30 | #include <math.h> |
31 | #include <iostream> |
32 | #include <assert.h> |
33 | |
34 | /// 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 | /// 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 | #define SRLZ(member) \ |
60 | archive->serializeMember(*this, member, #member); |
61 | |
62 | namespace gig { |
63 | |
64 | // *************** Internal functions for sample decompression *************** |
65 | // * |
66 | |
67 | namespace { |
68 | |
69 | 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 | 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 | void Decompress16(int compressionmode, const unsigned char* params, |
100 | int srcStep, int dstStep, |
101 | const unsigned char* pSrc, int16_t* pDst, |
102 | file_offset_t currentframeoffset, |
103 | file_offset_t copysamples) |
104 | { |
105 | switch (compressionmode) { |
106 | case 0: // 16 bit uncompressed |
107 | pSrc += currentframeoffset * srcStep; |
108 | while (copysamples) { |
109 | *pDst = get16(pSrc); |
110 | pDst += dstStep; |
111 | 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 | pDst += dstStep; |
130 | pSrc += srcStep; |
131 | copysamples--; |
132 | } |
133 | break; |
134 | } |
135 | } |
136 | |
137 | void Decompress24(int compressionmode, const unsigned char* params, |
138 | int dstStep, const unsigned char* pSrc, uint8_t* pDst, |
139 | file_offset_t currentframeoffset, |
140 | file_offset_t copysamples, int truncatedBits) |
141 | { |
142 | int y, dy, ddy, dddy; |
143 | |
144 | #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 | |
150 | #define SKIP_ONE(x) \ |
151 | dddy -= (x); \ |
152 | ddy -= dddy; \ |
153 | dy = -dy - ddy; \ |
154 | y += dy |
155 | |
156 | #define COPY_ONE(x) \ |
157 | SKIP_ONE(x); \ |
158 | store24(pDst, y << truncatedBits); \ |
159 | pDst += dstStep |
160 | |
161 | switch (compressionmode) { |
162 | case 2: // 24 bit uncompressed |
163 | pSrc += currentframeoffset * 3; |
164 | while (copysamples) { |
165 | store24(pDst, get24(pSrc) << truncatedBits); |
166 | pDst += dstStep; |
167 | 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 | |
236 | // *************** 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 | * call __finalizeCRC() to get the final CRC result. |
277 | * |
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 | static void __calculateCRC(unsigned char* buf, size_t bufSize, uint32_t& crc) { |
283 | for (size_t i = 0 ; i < bufSize ; i++) { |
284 | 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 | inline static void __finalizeCRC(uint32_t& crc) { |
294 | crc ^= 0xffffffff; |
295 | } |
296 | |
297 | |
298 | |
299 | // *************** 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 | // *************** 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 | // *************** eg_opt_t *************** |
345 | // * |
346 | |
347 | eg_opt_t::eg_opt_t() { |
348 | AttackCancel = true; |
349 | AttackHoldCancel = true; |
350 | Decay1Cancel = true; |
351 | Decay2Cancel = true; |
352 | ReleaseCancel = true; |
353 | } |
354 | |
355 | void eg_opt_t::serialize(Serialization::Archive* archive) { |
356 | SRLZ(AttackCancel); |
357 | SRLZ(AttackHoldCancel); |
358 | SRLZ(Decay1Cancel); |
359 | SRLZ(Decay2Cancel); |
360 | SRLZ(ReleaseCancel); |
361 | } |
362 | |
363 | |
364 | |
365 | // *************** Sample *************** |
366 | // * |
367 | |
368 | size_t Sample::Instances = 0; |
369 | buffer_t Sample::InternalDecompressionBuffer; |
370 | |
371 | /** @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 | * @param index - wave pool index of sample (may be -1 on new sample) |
389 | */ |
390 | 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 | static const DLS::Info::string_length_t fixedStringLengths[] = { |
394 | { CHUNK_ID_INAM, 64 }, |
395 | { 0, 0 } |
396 | }; |
397 | pInfo->SetFixedStringLengths(fixedStringLengths); |
398 | Instances++; |
399 | FileNo = fileNo; |
400 | |
401 | __resetCRC(crc); |
402 | // 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 | |
413 | pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX); |
414 | if (pCk3gix) { |
415 | pCk3gix->SetPos(0); |
416 | |
417 | uint16_t iSampleGroup = pCk3gix->ReadInt16(); |
418 | pGroup = pFile->GetGroup(iSampleGroup); |
419 | } else { // '3gix' chunk missing |
420 | // by default assigned to that mandatory "Default Group" |
421 | pGroup = pFile->GetGroup(0); |
422 | } |
423 | |
424 | pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL); |
425 | if (pCkSmpl) { |
426 | pCkSmpl->SetPos(0); |
427 | |
428 | 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 | SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5); |
448 | MIDIUnityNote = 60; |
449 | FineTune = 0; |
450 | SMPTEFormat = smpte_format_no_offset; |
451 | SMPTEOffset = 0; |
452 | Loops = 0; |
453 | LoopID = 0; |
454 | LoopType = loop_type_normal; |
455 | LoopStart = 0; |
456 | LoopEnd = 0; |
457 | LoopFraction = 0; |
458 | LoopPlayCount = 0; |
459 | } |
460 | |
461 | FrameTable = NULL; |
462 | SamplePos = 0; |
463 | RAMCache.Size = 0; |
464 | RAMCache.pStart = NULL; |
465 | RAMCache.NullExtensionSize = 0; |
466 | |
467 | if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported"); |
468 | |
469 | RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV); |
470 | Compressed = ewav; |
471 | Dithered = false; |
472 | TruncatedBits = 0; |
473 | if (Compressed) { |
474 | ewav->SetPos(0); |
475 | |
476 | uint32_t version = ewav->ReadInt32(); |
477 | if (version > 2 && BitDepth == 24) { |
478 | Dithered = ewav->ReadInt32(); |
479 | ewav->SetPos(Channels == 2 ? 84 : 64); |
480 | TruncatedBits = ewav->ReadInt32(); |
481 | } |
482 | ScanCompressedSample(); |
483 | } |
484 | |
485 | // we use a buffer for decompression and for truncating 24 bit samples to 16 bit |
486 | if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) { |
487 | InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE]; |
488 | InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE; |
489 | } |
490 | FrameOffset = 0; // just for streaming compressed samples |
491 | |
492 | LoopSize = LoopEnd - LoopStart + 1; |
493 | } |
494 | |
495 | /** |
496 | * 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 | file_offset_t restorePos = pOrig->GetPos(); |
551 | pOrig->SetPos(0); |
552 | SetPos(0); |
553 | for (file_offset_t n = pOrig->Read(buf, iReadAtOnce); n; |
554 | n = pOrig->Read(buf, iReadAtOnce)) |
555 | { |
556 | Write(buf, n); |
557 | } |
558 | pOrig->SetPos(restorePos); |
559 | delete [] buf; |
560 | } |
561 | |
562 | /** |
563 | * 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 | * @param pProgress - callback function for progress notification |
570 | * @throws DLS::Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data |
571 | * was provided yet |
572 | * @throws gig::Exception if there is any invalid sample setting |
573 | */ |
574 | void Sample::UpdateChunks(progress_t* pProgress) { |
575 | // first update base class's chunks |
576 | DLS::Sample::UpdateChunks(pProgress); |
577 | |
578 | // make sure 'smpl' chunk exists |
579 | pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL); |
580 | if (!pCkSmpl) { |
581 | pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60); |
582 | memset(pCkSmpl->LoadChunkData(), 0, 60); |
583 | } |
584 | // update 'smpl' chunk |
585 | uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData(); |
586 | SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5); |
587 | 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 | |
596 | // we skip 'manufByt' for now (4 bytes) |
597 | |
598 | 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 | |
605 | // make sure '3gix' chunk exists |
606 | pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX); |
607 | if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4); |
608 | // determine appropriate sample group index (to be stored in chunk) |
609 | uint16_t iSampleGroup = 0; // 0 refers to default sample group |
610 | 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 | for (int i = 0; iter != end; i++, iter++) { |
615 | if (*iter == pGroup) { |
616 | iSampleGroup = i; |
617 | break; // found |
618 | } |
619 | } |
620 | } |
621 | // update '3gix' chunk |
622 | pData = (uint8_t*) pCk3gix->LoadChunkData(); |
623 | store16(&pData[0], iSampleGroup); |
624 | |
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 | } |
633 | |
634 | /// 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 | std::list<file_offset_t> frameOffsets; |
639 | |
640 | SamplesPerFrame = BitDepth == 24 ? 256 : 2048; |
641 | WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag |
642 | |
643 | // Scanning |
644 | pCkData->SetPos(0); |
645 | 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 | const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r]; |
655 | |
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 | break; |
662 | } |
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 | const file_offset_t frameSize = bytesPerFrame[mode]; |
674 | |
675 | if (pCkData->RemainingBytes() <= frameSize) { |
676 | SamplesInLastFrame = |
677 | ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode]; |
678 | SamplesTotal += SamplesInLastFrame; |
679 | break; |
680 | } |
681 | SamplesTotal += SamplesPerFrame; |
682 | pCkData->SetPos(frameSize, RIFF::stream_curpos); |
683 | } |
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 | 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 | 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 | * @code |
723 | * buffer_t buf = pSample->LoadSampleData(acquired_samples); |
724 | * long cachedsamples = buf.Size / pSample->FrameSize; |
725 | * @endcode |
726 | * |
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 | buffer_t Sample::LoadSampleData(file_offset_t SampleCount) { |
733 | 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 | * @code |
772 | * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples); |
773 | * long cachedsamples = buf.Size / pSample->FrameSize; |
774 | * @endcode |
775 | * 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 | buffer_t Sample::LoadSampleDataWithNullSamplesExtension(file_offset_t SampleCount, uint NullSamplesCount) { |
792 | if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal; |
793 | if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; |
794 | file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize; |
795 | SetPos(0); // reset read position to begin of sample |
796 | 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 | RAMCache.NullExtensionSize = 0; |
834 | } |
835 | |
836 | /** @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 | * 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 | * other formats will fail! |
857 | * |
858 | * @param NewSize - new sample wave data size in sample points (must be |
859 | * greater than zero) |
860 | * @throws DLS::Excecption if FormatTag != DLS_WAVE_FORMAT_PCM |
861 | * @throws DLS::Exception if \a NewSize is less than 1 or unrealistic large |
862 | * @throws gig::Exception if existing sample is compressed |
863 | * @see DLS::Sample::GetSize(), DLS::Sample::FrameSize, |
864 | * DLS::Sample::FormatTag, File::Save() |
865 | */ |
866 | void Sample::Resize(file_offset_t NewSize) { |
867 | if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)"); |
868 | DLS::Sample::Resize(NewSize); |
869 | } |
870 | |
871 | /** |
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 | file_offset_t Sample::SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence) { |
893 | 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 | file_offset_t frame = this->SamplePos / 2048; // to which frame to jump |
911 | 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 | file_offset_t orderedBytes = SampleCount * this->FrameSize; |
917 | file_offset_t result = pCkData->SetPos(orderedBytes, Whence); |
918 | 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 | file_offset_t Sample::GetPos() const { |
927 | if (Compressed) return SamplePos; |
928 | else return pCkData->GetPos() / FrameSize; |
929 | } |
930 | |
931 | /** |
932 | * 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 | * @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 | * 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 | * <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 | * @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 | * @param pDimRgn dimension region with looping information |
961 | * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression |
962 | * @returns number of successfully read sample points |
963 | * @see CreateDecompressionBuffer() |
964 | */ |
965 | file_offset_t Sample::ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState, |
966 | DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) { |
967 | file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend; |
968 | uint8_t* pDst = (uint8_t*) pBuffer; |
969 | |
970 | SetPos(pPlaybackState->position); // recover position from the last time |
971 | |
972 | if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined |
973 | |
974 | const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0]; |
975 | const uint32_t loopEnd = loop.LoopStart + loop.LoopLength; |
976 | |
977 | if (GetPos() <= loopEnd) { |
978 | switch (loop.LoopType) { |
979 | |
980 | 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 | |
985 | 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 | |
999 | // 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 | |
1005 | 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 | |
1010 | SetPos(reverseplaybackend); |
1011 | |
1012 | // 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 | |
1020 | 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 | 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 | } |
1031 | } while (samplestoread && readsamples); |
1032 | break; |
1033 | } |
1034 | |
1035 | 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 | |
1048 | if (!samplestoread) break; |
1049 | |
1050 | // 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 | |
1056 | 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 | : samplestoread; |
1060 | file_offset_t reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength); |
1061 | |
1062 | SetPos(reverseplaybackend); |
1063 | |
1064 | // 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 | |
1079 | SetPos(reverseplaybackend); // pretend we really read backwards |
1080 | |
1081 | // reverse the sample frames for backward playback |
1082 | SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize); |
1083 | break; |
1084 | } |
1085 | |
1086 | 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 | } |
1102 | } |
1103 | } |
1104 | |
1105 | // read on without looping |
1106 | if (samplestoread) do { |
1107 | readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer); |
1108 | 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 | * 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 | * <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 | * 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 | * @param pBuffer destination buffer |
1135 | * @param SampleCount number of sample points to read |
1136 | * @param pExternalDecompressionBuffer (optional) external buffer to use for decompression |
1137 | * @returns number of successfully read sample points |
1138 | * @see SetPos(), CreateDecompressionBuffer() |
1139 | */ |
1140 | file_offset_t Sample::Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer) { |
1141 | if (SampleCount == 0) return 0; |
1142 | if (!Compressed) { |
1143 | if (BitDepth == 24) { |
1144 | return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize; |
1145 | } |
1146 | 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 | } |
1152 | else { |
1153 | if (this->SamplePos >= this->SamplesTotal) return 0; |
1154 | //TODO: efficiency: maybe we should test for an average compression rate |
1155 | file_offset_t assumedsize = GuessSize(SampleCount), |
1156 | remainingbytes = 0, // remaining bytes in the local buffer |
1157 | remainingsamples = SampleCount, |
1158 | copysamples, skipsamples, |
1159 | currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read() |
1160 | this->FrameOffset = 0; |
1161 | |
1162 | 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 | } |
1171 | |
1172 | unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart; |
1173 | int16_t* pDst = static_cast<int16_t*>(pBuffer); |
1174 | uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer); |
1175 | remainingbytes = pCkData->Read(pSrc, assumedsize, 1); |
1176 | |
1177 | while (remainingsamples && remainingbytes) { |
1178 | file_offset_t framesamples = SamplesPerFrame; |
1179 | file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset; |
1180 | |
1181 | 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 | } |
1197 | } |
1198 | else { |
1199 | framebytes = bytesPerFrame[mode_l] + 1; |
1200 | nextFrameOffset = bytesPerFrameNoHdr[mode_l]; |
1201 | if (remainingbytes < framebytes) { |
1202 | framesamples = SamplesInLastFrame; |
1203 | } |
1204 | } |
1205 | |
1206 | // determine how many samples in this frame to skip and read |
1207 | 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 | } |
1217 | else { |
1218 | // 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 | copysamples = remainingsamples; |
1222 | 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 | pCkData->SetPos(remainingbytes, RIFF::stream_backward); |
1237 | } |
1238 | } |
1239 | else remainingbytes = 0; |
1240 | |
1241 | currentframeoffset -= skipsamples; |
1242 | |
1243 | 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 | |
1252 | if (Channels == 2) { // Stereo |
1253 | const unsigned char* const param_r = pSrc; |
1254 | if (mode_r != 2) pSrc += 12; |
1255 | |
1256 | Decompress24(mode_l, param_l, 6, pSrc, pDst24, |
1257 | skipsamples, copysamples, TruncatedBits); |
1258 | Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3, |
1259 | skipsamples, copysamples, TruncatedBits); |
1260 | pDst24 += copysamples * 6; |
1261 | } |
1262 | else { // Mono |
1263 | Decompress24(mode_l, param_l, 3, pSrc, pDst24, |
1264 | skipsamples, copysamples, TruncatedBits); |
1265 | pDst24 += copysamples * 3; |
1266 | } |
1267 | } |
1268 | else { // 16 bit |
1269 | if (mode_l) pSrc += 4; |
1270 | |
1271 | 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 | 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 | skipsamples, copysamples); |
1280 | pDst += copysamples << 1; |
1281 | } |
1282 | else { // Mono |
1283 | step = 2 - mode_l; |
1284 | Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples); |
1285 | pDst += copysamples; |
1286 | } |
1287 | } |
1288 | pSrc += nextFrameOffset; |
1289 | } |
1290 | |
1291 | // 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 | remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1); |
1297 | pSrc = (unsigned char*) pDecompressionBuffer->pStart; |
1298 | } |
1299 | } // while |
1300 | |
1301 | this->SamplePos += (SampleCount - remainingsamples); |
1302 | if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal; |
1303 | return (SampleCount - remainingsamples); |
1304 | } |
1305 | } |
1306 | |
1307 | /** @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 | * 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 | * @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 | file_offset_t Sample::Write(void* pBuffer, file_offset_t SampleCount) { |
1330 | if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)"); |
1331 | |
1332 | // if this is the first write in this sample, reset the |
1333 | // checksum calculator |
1334 | if (pCkData->GetPos() == 0) { |
1335 | __resetCRC(crc); |
1336 | } |
1337 | if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small"); |
1338 | file_offset_t res; |
1339 | 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 | __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc); |
1346 | |
1347 | // if this is the last write, update the checksum chunk in the |
1348 | // file |
1349 | if (pCkData->GetPos() == pCkData->GetSize()) { |
1350 | __finalizeCRC(crc); |
1351 | File* pFile = static_cast<File*>(GetParent()); |
1352 | pFile->SetSampleChecksum(this, crc); |
1353 | } |
1354 | return res; |
1355 | } |
1356 | |
1357 | /** |
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 | buffer_t Sample::CreateDecompressionBuffer(file_offset_t MaxReadSize) { |
1374 | buffer_t result; |
1375 | const double worstCaseHeaderOverhead = |
1376 | (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0; |
1377 | result.Size = (file_offset_t) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead); |
1378 | 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 | /** |
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 | /** |
1412 | * 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 | * 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 | * @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 | * @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 | * @see GetWaveDataCRC32Checksum() |
1451 | */ |
1452 | bool Sample::VerifyWaveData(uint32_t* pActually) { |
1453 | //File* pFile = static_cast<File*>(GetParent()); |
1454 | uint32_t crc = CalculateWaveDataChecksum(); |
1455 | if (pActually) *pActually = crc; |
1456 | return crc == this->crc; |
1457 | } |
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 | __finalizeCRC(crc); |
1474 | return crc; |
1475 | } |
1476 | |
1477 | Sample::~Sample() { |
1478 | Instances--; |
1479 | if (!Instances && InternalDecompressionBuffer.Size) { |
1480 | delete[] (unsigned char*) InternalDecompressionBuffer.pStart; |
1481 | InternalDecompressionBuffer.pStart = NULL; |
1482 | InternalDecompressionBuffer.Size = 0; |
1483 | } |
1484 | if (FrameTable) delete[] FrameTable; |
1485 | if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; |
1486 | } |
1487 | |
1488 | |
1489 | |
1490 | // *************** DimensionRegion *************** |
1491 | // * |
1492 | |
1493 | size_t DimensionRegion::Instances = 0; |
1494 | DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL; |
1495 | |
1496 | DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) { |
1497 | Instances++; |
1498 | |
1499 | pSample = NULL; |
1500 | pRegion = pParent; |
1501 | |
1502 | if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4); |
1503 | else memset(&Crossfade, 0, 4); |
1504 | |
1505 | if (!pVelocityTables) pVelocityTables = new VelocityTableMap; |
1506 | |
1507 | RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA); |
1508 | if (_3ewa) { // if '3ewa' chunk exists |
1509 | _3ewa->SetPos(0); |
1510 | |
1511 | _3ewa->ReadInt32(); // unknown, always == chunk size ? |
1512 | 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 | : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */ |
1621 | _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 | if (_3ewa->RemainingBytes() >= 8) { |
1657 | _3ewa->Read(DimensionUpperLimits, 1, 8); |
1658 | } else { |
1659 | memset(DimensionUpperLimits, 0, 8); |
1660 | } |
1661 | } 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 | EG1Decay1 = 0.005; |
1671 | EG1Sustain = 1000; |
1672 | EG1Release = 0.3; |
1673 | 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 | EG2Decay1 = 0.005; |
1688 | EG2Sustain = 1000; |
1689 | EG2Release = 60; |
1690 | LFO2ControlDepth = 0; |
1691 | LFO2Frequency = 1.0; |
1692 | LFO2InternalDepth = 0; |
1693 | EG1Decay2 = 0.0; |
1694 | EG1InfiniteSustain = true; |
1695 | EG1PreAttack = 0; |
1696 | EG2Decay2 = 0.0; |
1697 | EG2InfiniteSustain = true; |
1698 | EG2PreAttack = 0; |
1699 | 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 | memset(DimensionUpperLimits, 127, 8); |
1742 | } |
1743 | |
1744 | // chunk for own format extensions, these will *NOT* work with Gigasampler/GigaStudio ! |
1745 | RIFF::Chunk* lsde = _3ewl->GetSubChunk(CHUNK_ID_LSDE); |
1746 | if (lsde) { // format extension for EG behavior options |
1747 | lsde->SetPos(0); |
1748 | |
1749 | eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options }; |
1750 | for (int i = 0; i < 2; ++i) { // NOTE: we reserved a 3rd byte for a potential future EG3 option |
1751 | 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 | } |
1759 | // 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 | 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 | // 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 | |
1792 | pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve, |
1793 | VelocityResponseDepth, |
1794 | VelocityResponseCurveScaling); |
1795 | |
1796 | pVelocityReleaseTable = GetReleaseVelocityTable( |
1797 | ReleaseVelocityResponseCurve, |
1798 | ReleaseVelocityResponseDepth |
1799 | ); |
1800 | |
1801 | pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, |
1802 | VCFVelocityDynamicRange, |
1803 | VCFVelocityScale, |
1804 | VCFCutoffController); |
1805 | |
1806 | SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360)); |
1807 | VelocityTable = 0; |
1808 | } |
1809 | |
1810 | /* |
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 | //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method |
1817 | *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 | |
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 | 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 | // 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 | gig::Sample* pOriginalSample = pSample; |
1863 | gig::Region* pOriginalRegion = pRegion; |
1864 | |
1865 | //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 | |
1869 | // restore members that shall not be altered |
1870 | pParentList = p; // restore the chunk pointer |
1871 | pRegion = pOriginalRegion; |
1872 | |
1873 | // only take the raw sample reference reference if the |
1874 | // 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 | |
1883 | // 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 | void DimensionRegion::serialize(Serialization::Archive* archive) { |
1897 | // 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 | 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 | SRLZ(LFO1WaveForm); |
1917 | SRLZ(LFO1Frequency); |
1918 | SRLZ(LFO1Phase); |
1919 | 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 | SRLZ(LFO2WaveForm); |
1937 | SRLZ(LFO2Frequency); |
1938 | SRLZ(LFO2Phase); |
1939 | SRLZ(LFO2InternalDepth); |
1940 | SRLZ(LFO2ControlDepth); |
1941 | SRLZ(LFO2Controller); |
1942 | SRLZ(LFO2FlipPhase); |
1943 | SRLZ(LFO2Sync); |
1944 | SRLZ(EG3Attack); |
1945 | SRLZ(EG3Depth); |
1946 | SRLZ(LFO3WaveForm); |
1947 | SRLZ(LFO3Frequency); |
1948 | SRLZ(LFO3Phase); |
1949 | SRLZ(LFO3InternalDepth); |
1950 | SRLZ(LFO3ControlDepth); |
1951 | SRLZ(LFO3Controller); |
1952 | SRLZ(LFO3FlipPhase); |
1953 | 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 | SRLZ(EG1Options); |
1987 | SRLZ(EG2Options); |
1988 | SRLZ(SustainReleaseTrigger); |
1989 | SRLZ(NoNoteOffReleaseTrigger); |
1990 | |
1991 | // derived attributes from DLS::Sampler |
1992 | SRLZ(FineTune); |
1993 | SRLZ(Gain); |
1994 | } |
1995 | |
1996 | /** |
1997 | * 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 | * 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 | * |
2012 | * @param pProgress - callback function for progress notification |
2013 | */ |
2014 | void DimensionRegion::UpdateChunks(progress_t* pProgress) { |
2015 | // first update base class's chunk |
2016 | DLS::Sampler::UpdateChunks(pProgress); |
2017 | |
2018 | 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 | // make sure '3ewa' chunk exists |
2026 | RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA); |
2027 | if (!_3ewa) { |
2028 | File* pFile = (File*) GetParent()->GetParent()->GetParent(); |
2029 | bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2; |
2030 | _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, versiongt2 ? 148 : 140); |
2031 | } |
2032 | pData = (uint8_t*) _3ewa->LoadChunkData(); |
2033 | |
2034 | // update '3ewa' chunk with DimensionRegion's current settings |
2035 | |
2036 | const uint32_t chunksize = (uint32_t) _3ewa->GetNewSize(); |
2037 | store32(&pData[0], chunksize); // unknown, always chunk size? |
2038 | |
2039 | const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency); |
2040 | store32(&pData[4], lfo3freq); |
2041 | |
2042 | const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack); |
2043 | store32(&pData[8], eg3attack); |
2044 | |
2045 | // next 2 bytes unknown |
2046 | |
2047 | store16(&pData[14], LFO1InternalDepth); |
2048 | |
2049 | // next 2 bytes unknown |
2050 | |
2051 | store16(&pData[18], LFO3InternalDepth); |
2052 | |
2053 | // next 2 bytes unknown |
2054 | |
2055 | store16(&pData[22], LFO1ControlDepth); |
2056 | |
2057 | // next 2 bytes unknown |
2058 | |
2059 | store16(&pData[26], LFO3ControlDepth); |
2060 | |
2061 | const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack); |
2062 | store32(&pData[28], eg1attack); |
2063 | |
2064 | const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1); |
2065 | store32(&pData[32], eg1decay1); |
2066 | |
2067 | // next 2 bytes unknown |
2068 | |
2069 | store16(&pData[38], EG1Sustain); |
2070 | |
2071 | const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release); |
2072 | store32(&pData[40], eg1release); |
2073 | |
2074 | const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller); |
2075 | pData[44] = eg1ctl; |
2076 | |
2077 | const uint8_t eg1ctrloptions = |
2078 | (EG1ControllerInvert ? 0x01 : 0x00) | |
2079 | GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) | |
2080 | GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) | |
2081 | GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence); |
2082 | pData[45] = eg1ctrloptions; |
2083 | |
2084 | const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller); |
2085 | pData[46] = eg2ctl; |
2086 | |
2087 | const uint8_t eg2ctrloptions = |
2088 | (EG2ControllerInvert ? 0x01 : 0x00) | |
2089 | GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) | |
2090 | GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) | |
2091 | GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence); |
2092 | pData[47] = eg2ctrloptions; |
2093 | |
2094 | const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency); |
2095 | store32(&pData[48], lfo1freq); |
2096 | |
2097 | const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack); |
2098 | store32(&pData[52], eg2attack); |
2099 | |
2100 | const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1); |
2101 | store32(&pData[56], eg2decay1); |
2102 | |
2103 | // next 2 bytes unknown |
2104 | |
2105 | store16(&pData[62], EG2Sustain); |
2106 | |
2107 | const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release); |
2108 | store32(&pData[64], eg2release); |
2109 | |
2110 | // next 2 bytes unknown |
2111 | |
2112 | store16(&pData[70], LFO2ControlDepth); |
2113 | |
2114 | const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency); |
2115 | store32(&pData[72], lfo2freq); |
2116 | |
2117 | // next 2 bytes unknown |
2118 | |
2119 | store16(&pData[78], LFO2InternalDepth); |
2120 | |
2121 | const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2); |
2122 | store32(&pData[80], eg1decay2); |
2123 | |
2124 | // next 2 bytes unknown |
2125 | |
2126 | store16(&pData[86], EG1PreAttack); |
2127 | |
2128 | const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2); |
2129 | store32(&pData[88], eg2decay2); |
2130 | |
2131 | // next 2 bytes unknown |
2132 | |
2133 | store16(&pData[94], EG2PreAttack); |
2134 | |
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 | pData[96] = velocityresponse; |
2152 | } |
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 | pData[97] = releasevelocityresponse; |
2171 | } |
2172 | |
2173 | pData[98] = VelocityResponseCurveScaling; |
2174 | |
2175 | pData[99] = AttenuationControllerThreshold; |
2176 | |
2177 | // next 4 bytes unknown |
2178 | |
2179 | store16(&pData[104], SampleStartOffset); |
2180 | |
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 | pData[108] = pitchTrackDimensionBypass; |
2199 | } |
2200 | |
2201 | const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit |
2202 | pData[109] = pan; |
2203 | |
2204 | const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00; |
2205 | pData[110] = selfmask; |
2206 | |
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 | pData[112] = lfo3ctrl; |
2215 | } |
2216 | |
2217 | const uint8_t attenctl = EncodeLeverageController(AttenuationController); |
2218 | pData[113] = attenctl; |
2219 | |
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 | pData[114] = lfo2ctrl; |
2226 | } |
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 | pData[115] = lfo1ctrl; |
2235 | } |
2236 | |
2237 | const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth |
2238 | : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */ |
2239 | store16(&pData[116], eg3depth); |
2240 | |
2241 | // next 2 bytes unknown |
2242 | |
2243 | const uint8_t channeloffset = ChannelOffset * 4; |
2244 | pData[120] = channeloffset; |
2245 | |
2246 | { |
2247 | uint8_t regoptions = 0; |
2248 | if (MSDecode) regoptions |= 0x01; // bit 0 |
2249 | if (SustainDefeat) regoptions |= 0x02; // bit 1 |
2250 | pData[121] = regoptions; |
2251 | } |
2252 | |
2253 | // next 2 bytes unknown |
2254 | |
2255 | pData[124] = VelocityUpperLimit; |
2256 | |
2257 | // next 3 bytes unknown |
2258 | |
2259 | pData[128] = ReleaseTriggerDecay; |
2260 | |
2261 | // next 2 bytes unknown |
2262 | |
2263 | const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7 |
2264 | pData[131] = eg1hold; |
2265 | |
2266 | const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */ |
2267 | (VCFCutoff & 0x7f); /* lower 7 bits */ |
2268 | pData[132] = vcfcutoff; |
2269 | |
2270 | pData[133] = VCFCutoffController; |
2271 | |
2272 | const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */ |
2273 | (VCFVelocityScale & 0x7f); /* lower 7 bits */ |
2274 | pData[134] = vcfvelscale; |
2275 | |
2276 | // next byte unknown |
2277 | |
2278 | const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */ |
2279 | (VCFResonance & 0x7f); /* lower 7 bits */ |
2280 | pData[136] = vcfresonance; |
2281 | |
2282 | const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */ |
2283 | (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */ |
2284 | pData[137] = vcfbreakpoint; |
2285 | |
2286 | const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 + |
2287 | VCFVelocityCurve * 5; |
2288 | pData[138] = vcfvelocity; |
2289 | |
2290 | const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType; |
2291 | pData[139] = vcftype; |
2292 | |
2293 | if (chunksize >= 148) { |
2294 | memcpy(&pData[140], DimensionUpperLimits, 8); |
2295 | } |
2296 | |
2297 | // chunk for own format extensions, these will *NOT* work with |
2298 | // Gigasampler/GigaStudio ! |
2299 | RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE); |
2300 | 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 | } |
2312 | if (lsde) { |
2313 | if (lsde->GetNewSize() < lsdeSize) |
2314 | lsde->Resize(lsdeSize); |
2315 | // format extension for EG behavior options |
2316 | unsigned char* pData = (unsigned char*) lsde->LoadChunkData(); |
2317 | eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options }; |
2318 | for (int i = 0; i < 2; ++i) { // NOTE: we reserved the 3rd byte for a potential future EG3 option |
2319 | 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 | // format extension for release trigger options |
2327 | pData[3] = static_cast<uint8_t>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 0); |
2328 | // 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 | } |
2347 | } |
2348 | |
2349 | /** |
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 | 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 | // 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 | // 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 | double* table; |
2439 | uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling; |
2440 | if (pVelocityTables->count(tableKey)) { // if key exists |
2441 | table = (*pVelocityTables)[tableKey]; |
2442 | } |
2443 | else { |
2444 | table = CreateVelocityTable(curveType, depth, scaling); |
2445 | (*pVelocityTables)[tableKey] = table; // put the new table into the tables map |
2446 | } |
2447 | return table; |
2448 | } |
2449 | |
2450 | Region* DimensionRegion::GetParent() const { |
2451 | return pRegion; |
2452 | } |
2453 | |
2454 | // 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 | 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 | |
2477 | // 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 | |
2571 | // 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 | // unknown controller type |
2812 | default: |
2813 | 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 | } |
2818 | return decodedcontroller; |
2819 | } |
2820 | |
2821 | // see above (diagnostic push not supported prior GCC 4.6) |
2822 | //#pragma GCC diagnostic pop |
2823 | |
2824 | 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 | |
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 | default: |
3093 | throw gig::Exception("leverage controller number is not supported by the gig format"); |
3094 | } |
3095 | break; |
3096 | default: |
3097 | throw gig::Exception("Unknown leverage controller type."); |
3098 | } |
3099 | return encodedcontroller; |
3100 | } |
3101 | |
3102 | 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 | if (VelocityTable) delete[] VelocityTable; |
3116 | } |
3117 | |
3118 | /** |
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 | * @param MIDIKeyVelocity MIDI velocity value of the triggered key (between 0 and 127) |
3127 | * @returns amplitude factor (between 0.0 and 1.0) |
3128 | */ |
3129 | double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) { |
3130 | return pVelocityAttenuationTable[MIDIKeyVelocity]; |
3131 | } |
3132 | |
3133 | double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) { |
3134 | return pVelocityReleaseTable[MIDIKeyVelocity]; |
3135 | } |
3136 | |
3137 | double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) { |
3138 | return pVelocityCutoffTable[MIDIKeyVelocity]; |
3139 | } |
3140 | |
3141 | /** |
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 | double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) { |
3232 | |
3233 | // line-segment approximations of the 15 velocity curves |
3234 | |
3235 | // linear |
3236 | const int lin0[] = { 1, 1, 127, 127 }; |
3237 | const int lin1[] = { 1, 21, 127, 127 }; |
3238 |