libgig  4.1.0
gig.cpp
1 /***************************************************************************
2  * *
3  * libgig - C++ cross-platform Gigasampler format file access library *
4  * *
5  * Copyright (C) 2003-2017 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 
36 #define GIG_FILE_EXT_VERSION 2
37 
43 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
44 
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 
259  inline static void __resetCRC(uint32_t& crc) {
260  crc = 0xffffffff;
261  }
262 
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 
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;
370 
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  uint16_t iSampleGroup = pCk3gix->ReadInt16();
416  pGroup = pFile->GetGroup(iSampleGroup);
417  } else { // '3gix' chunk missing
418  // by default assigned to that mandatory "Default Group"
419  pGroup = pFile->GetGroup(0);
420  }
421 
422  pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
423  if (pCkSmpl) {
424  Manufacturer = pCkSmpl->ReadInt32();
425  Product = pCkSmpl->ReadInt32();
426  SamplePeriod = pCkSmpl->ReadInt32();
427  MIDIUnityNote = pCkSmpl->ReadInt32();
428  FineTune = pCkSmpl->ReadInt32();
429  pCkSmpl->Read(&SMPTEFormat, 1, 4);
430  SMPTEOffset = pCkSmpl->ReadInt32();
431  Loops = pCkSmpl->ReadInt32();
432  pCkSmpl->ReadInt32(); // manufByt
433  LoopID = pCkSmpl->ReadInt32();
434  pCkSmpl->Read(&LoopType, 1, 4);
435  LoopStart = pCkSmpl->ReadInt32();
436  LoopEnd = pCkSmpl->ReadInt32();
437  LoopFraction = pCkSmpl->ReadInt32();
438  LoopPlayCount = pCkSmpl->ReadInt32();
439  } else { // 'smpl' chunk missing
440  // use default values
441  Manufacturer = 0;
442  Product = 0;
443  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
444  MIDIUnityNote = 60;
445  FineTune = 0;
447  SMPTEOffset = 0;
448  Loops = 0;
449  LoopID = 0;
451  LoopStart = 0;
452  LoopEnd = 0;
453  LoopFraction = 0;
454  LoopPlayCount = 0;
455  }
456 
457  FrameTable = NULL;
458  SamplePos = 0;
459  RAMCache.Size = 0;
460  RAMCache.pStart = NULL;
462 
463  if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
464 
465  RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
466  Compressed = ewav;
467  Dithered = false;
468  TruncatedBits = 0;
469  if (Compressed) {
470  uint32_t version = ewav->ReadInt32();
471  if (version == 3 && BitDepth == 24) {
472  Dithered = ewav->ReadInt32();
473  ewav->SetPos(Channels == 2 ? 84 : 64);
474  TruncatedBits = ewav->ReadInt32();
475  }
476  ScanCompressedSample();
477  }
478 
479  // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
481  InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
482  InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE;
483  }
484  FrameOffset = 0; // just for streaming compressed samples
485 
486  LoopSize = LoopEnd - LoopStart + 1;
487  }
488 
504  void Sample::CopyAssignMeta(const Sample* orig) {
505  // handle base classes
507 
508  // handle actual own attributes of this class
509  Manufacturer = orig->Manufacturer;
510  Product = orig->Product;
511  SamplePeriod = orig->SamplePeriod;
513  FineTune = orig->FineTune;
514  SMPTEFormat = orig->SMPTEFormat;
515  SMPTEOffset = orig->SMPTEOffset;
516  Loops = orig->Loops;
517  LoopID = orig->LoopID;
518  LoopType = orig->LoopType;
519  LoopStart = orig->LoopStart;
520  LoopEnd = orig->LoopEnd;
521  LoopSize = orig->LoopSize;
522  LoopFraction = orig->LoopFraction;
524 
525  // schedule resizing this sample to the given sample's size
526  Resize(orig->GetSize());
527  }
528 
540  void Sample::CopyAssignWave(const Sample* orig) {
541  const int iReadAtOnce = 32*1024;
542  char* buf = new char[iReadAtOnce * orig->FrameSize];
543  Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
544  file_offset_t restorePos = pOrig->GetPos();
545  pOrig->SetPos(0);
546  SetPos(0);
547  for (file_offset_t n = pOrig->Read(buf, iReadAtOnce); n;
548  n = pOrig->Read(buf, iReadAtOnce))
549  {
550  Write(buf, n);
551  }
552  pOrig->SetPos(restorePos);
553  delete [] buf;
554  }
555 
568  void Sample::UpdateChunks(progress_t* pProgress) {
569  // first update base class's chunks
570  DLS::Sample::UpdateChunks(pProgress);
571 
572  // make sure 'smpl' chunk exists
573  pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
574  if (!pCkSmpl) {
575  pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
576  memset(pCkSmpl->LoadChunkData(), 0, 60);
577  }
578  // update 'smpl' chunk
579  uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
580  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
581  store32(&pData[0], Manufacturer);
582  store32(&pData[4], Product);
583  store32(&pData[8], SamplePeriod);
584  store32(&pData[12], MIDIUnityNote);
585  store32(&pData[16], FineTune);
586  store32(&pData[20], SMPTEFormat);
587  store32(&pData[24], SMPTEOffset);
588  store32(&pData[28], Loops);
589 
590  // we skip 'manufByt' for now (4 bytes)
591 
592  store32(&pData[36], LoopID);
593  store32(&pData[40], LoopType);
594  store32(&pData[44], LoopStart);
595  store32(&pData[48], LoopEnd);
596  store32(&pData[52], LoopFraction);
597  store32(&pData[56], LoopPlayCount);
598 
599  // make sure '3gix' chunk exists
600  pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
601  if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
602  // determine appropriate sample group index (to be stored in chunk)
603  uint16_t iSampleGroup = 0; // 0 refers to default sample group
604  File* pFile = static_cast<File*>(pParent);
605  if (pFile->pGroups) {
606  std::list<Group*>::iterator iter = pFile->pGroups->begin();
607  std::list<Group*>::iterator end = pFile->pGroups->end();
608  for (int i = 0; iter != end; i++, iter++) {
609  if (*iter == pGroup) {
610  iSampleGroup = i;
611  break; // found
612  }
613  }
614  }
615  // update '3gix' chunk
616  pData = (uint8_t*) pCk3gix->LoadChunkData();
617  store16(&pData[0], iSampleGroup);
618 
619  // if the library user toggled the "Compressed" attribute from true to
620  // false, then the EWAV chunk associated with compressed samples needs
621  // to be deleted
622  RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
623  if (ewav && !Compressed) {
624  pWaveList->DeleteSubChunk(ewav);
625  }
626  }
627 
629  void Sample::ScanCompressedSample() {
630  //TODO: we have to add some more scans here (e.g. determine compression rate)
631  this->SamplesTotal = 0;
632  std::list<file_offset_t> frameOffsets;
633 
634  SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
635  WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
636 
637  // Scanning
638  pCkData->SetPos(0);
639  if (Channels == 2) { // Stereo
640  for (int i = 0 ; ; i++) {
641  // for 24 bit samples every 8:th frame offset is
642  // stored, to save some memory
643  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
644 
645  const int mode_l = pCkData->ReadUint8();
646  const int mode_r = pCkData->ReadUint8();
647  if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
648  const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
649 
650  if (pCkData->RemainingBytes() <= frameSize) {
652  ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
653  (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
655  break;
656  }
658  pCkData->SetPos(frameSize, RIFF::stream_curpos);
659  }
660  }
661  else { // Mono
662  for (int i = 0 ; ; i++) {
663  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
664 
665  const int mode = pCkData->ReadUint8();
666  if (mode > 5) throw gig::Exception("Unknown compression mode");
667  const file_offset_t frameSize = bytesPerFrame[mode];
668 
669  if (pCkData->RemainingBytes() <= frameSize) {
671  ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
673  break;
674  }
676  pCkData->SetPos(frameSize, RIFF::stream_curpos);
677  }
678  }
679  pCkData->SetPos(0);
680 
681  // Build the frames table (which is used for fast resolving of a frame's chunk offset)
682  if (FrameTable) delete[] FrameTable;
683  FrameTable = new file_offset_t[frameOffsets.size()];
684  std::list<file_offset_t>::iterator end = frameOffsets.end();
685  std::list<file_offset_t>::iterator iter = frameOffsets.begin();
686  for (int i = 0; iter != end; i++, iter++) {
687  FrameTable[i] = *iter;
688  }
689  }
690 
701  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
702  }
703 
726  buffer_t Sample::LoadSampleData(file_offset_t SampleCount) {
727  return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
728  }
729 
750  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
751  }
752 
785  buffer_t Sample::LoadSampleDataWithNullSamplesExtension(file_offset_t SampleCount, uint NullSamplesCount) {
786  if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
787  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
788  file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
789  SetPos(0); // reset read position to begin of sample
790  RAMCache.pStart = new int8_t[allocationsize];
791  RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
792  RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
793  // fill the remaining buffer space with silence samples
794  memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
795  return GetCache();
796  }
797 
809  // return a copy of the buffer_t structure
810  buffer_t result;
811  result.Size = this->RAMCache.Size;
812  result.pStart = this->RAMCache.pStart;
814  return result;
815  }
816 
824  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
825  RAMCache.pStart = NULL;
826  RAMCache.Size = 0;
828  }
829 
860  void Sample::Resize(file_offset_t NewSize) {
861  if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
862  DLS::Sample::Resize(NewSize);
863  }
864 
886  file_offset_t Sample::SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence) {
887  if (Compressed) {
888  switch (Whence) {
889  case RIFF::stream_curpos:
890  this->SamplePos += SampleCount;
891  break;
892  case RIFF::stream_end:
893  this->SamplePos = this->SamplesTotal - 1 - SampleCount;
894  break;
895  case RIFF::stream_backward:
896  this->SamplePos -= SampleCount;
897  break;
898  case RIFF::stream_start: default:
899  this->SamplePos = SampleCount;
900  break;
901  }
902  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
903 
904  file_offset_t frame = this->SamplePos / 2048; // to which frame to jump
905  this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
906  pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
907  return this->SamplePos;
908  }
909  else { // not compressed
910  file_offset_t orderedBytes = SampleCount * this->FrameSize;
911  file_offset_t result = pCkData->SetPos(orderedBytes, Whence);
912  return (result == orderedBytes) ? SampleCount
913  : result / this->FrameSize;
914  }
915  }
916 
920  file_offset_t Sample::GetPos() const {
921  if (Compressed) return SamplePos;
922  else return pCkData->GetPos() / FrameSize;
923  }
924 
959  file_offset_t Sample::ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState,
960  DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
961  file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
962  uint8_t* pDst = (uint8_t*) pBuffer;
963 
964  SetPos(pPlaybackState->position); // recover position from the last time
965 
966  if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
967 
968  const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
969  const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
970 
971  if (GetPos() <= loopEnd) {
972  switch (loop.LoopType) {
973 
974  case loop_type_bidirectional: { //TODO: not tested yet!
975  do {
976  // if not endless loop check if max. number of loop cycles have been passed
977  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
978 
979  if (!pPlaybackState->reverse) { // forward playback
980  do {
981  samplestoloopend = loopEnd - GetPos();
982  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
983  samplestoread -= readsamples;
984  totalreadsamples += readsamples;
985  if (readsamples == samplestoloopend) {
986  pPlaybackState->reverse = true;
987  break;
988  }
989  } while (samplestoread && readsamples);
990  }
991  else { // backward playback
992 
993  // as we can only read forward from disk, we have to
994  // determine the end position within the loop first,
995  // read forward from that 'end' and finally after
996  // reading, swap all sample frames so it reflects
997  // backward playback
998 
999  file_offset_t swapareastart = totalreadsamples;
1000  file_offset_t loopoffset = GetPos() - loop.LoopStart;
1001  file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
1002  file_offset_t reverseplaybackend = GetPos() - samplestoreadinloop;
1003 
1004  SetPos(reverseplaybackend);
1005 
1006  // read samples for backward playback
1007  do {
1008  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
1009  samplestoreadinloop -= readsamples;
1010  samplestoread -= readsamples;
1011  totalreadsamples += readsamples;
1012  } while (samplestoreadinloop && readsamples);
1013 
1014  SetPos(reverseplaybackend); // pretend we really read backwards
1015 
1016  if (reverseplaybackend == loop.LoopStart) {
1017  pPlaybackState->loop_cycles_left--;
1018  pPlaybackState->reverse = false;
1019  }
1020 
1021  // reverse the sample frames for backward playback
1022  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!
1023  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1024  }
1025  } while (samplestoread && readsamples);
1026  break;
1027  }
1028 
1029  case loop_type_backward: { // TODO: not tested yet!
1030  // forward playback (not entered the loop yet)
1031  if (!pPlaybackState->reverse) do {
1032  samplestoloopend = loopEnd - GetPos();
1033  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1034  samplestoread -= readsamples;
1035  totalreadsamples += readsamples;
1036  if (readsamples == samplestoloopend) {
1037  pPlaybackState->reverse = true;
1038  break;
1039  }
1040  } while (samplestoread && readsamples);
1041 
1042  if (!samplestoread) break;
1043 
1044  // as we can only read forward from disk, we have to
1045  // determine the end position within the loop first,
1046  // read forward from that 'end' and finally after
1047  // reading, swap all sample frames so it reflects
1048  // backward playback
1049 
1050  file_offset_t swapareastart = totalreadsamples;
1051  file_offset_t loopoffset = GetPos() - loop.LoopStart;
1052  file_offset_t samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
1053  : samplestoread;
1054  file_offset_t reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
1055 
1056  SetPos(reverseplaybackend);
1057 
1058  // read samples for backward playback
1059  do {
1060  // if not endless loop check if max. number of loop cycles have been passed
1061  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1062  samplestoloopend = loopEnd - GetPos();
1063  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1064  samplestoreadinloop -= readsamples;
1065  samplestoread -= readsamples;
1066  totalreadsamples += readsamples;
1067  if (readsamples == samplestoloopend) {
1068  pPlaybackState->loop_cycles_left--;
1069  SetPos(loop.LoopStart);
1070  }
1071  } while (samplestoreadinloop && readsamples);
1072 
1073  SetPos(reverseplaybackend); // pretend we really read backwards
1074 
1075  // reverse the sample frames for backward playback
1076  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1077  break;
1078  }
1079 
1080  default: case loop_type_normal: {
1081  do {
1082  // if not endless loop check if max. number of loop cycles have been passed
1083  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1084  samplestoloopend = loopEnd - GetPos();
1085  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1086  samplestoread -= readsamples;
1087  totalreadsamples += readsamples;
1088  if (readsamples == samplestoloopend) {
1089  pPlaybackState->loop_cycles_left--;
1090  SetPos(loop.LoopStart);
1091  }
1092  } while (samplestoread && readsamples);
1093  break;
1094  }
1095  }
1096  }
1097  }
1098 
1099  // read on without looping
1100  if (samplestoread) do {
1101  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
1102  samplestoread -= readsamples;
1103  totalreadsamples += readsamples;
1104  } while (readsamples && samplestoread);
1105 
1106  // store current position
1107  pPlaybackState->position = GetPos();
1108 
1109  return totalreadsamples;
1110  }
1111 
1134  file_offset_t Sample::Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer) {
1135  if (SampleCount == 0) return 0;
1136  if (!Compressed) {
1137  if (BitDepth == 24) {
1138  return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1139  }
1140  else { // 16 bit
1141  // (pCkData->Read does endian correction)
1142  return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
1143  : pCkData->Read(pBuffer, SampleCount, 2);
1144  }
1145  }
1146  else {
1147  if (this->SamplePos >= this->SamplesTotal) return 0;
1148  //TODO: efficiency: maybe we should test for an average compression rate
1149  file_offset_t assumedsize = GuessSize(SampleCount),
1150  remainingbytes = 0, // remaining bytes in the local buffer
1151  remainingsamples = SampleCount,
1152  copysamples, skipsamples,
1153  currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
1154  this->FrameOffset = 0;
1155 
1156  buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
1157 
1158  // if decompression buffer too small, then reduce amount of samples to read
1159  if (pDecompressionBuffer->Size < assumedsize) {
1160  std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1161  SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1162  remainingsamples = SampleCount;
1163  assumedsize = GuessSize(SampleCount);
1164  }
1165 
1166  unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1167  int16_t* pDst = static_cast<int16_t*>(pBuffer);
1168  uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1169  remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1170 
1171  while (remainingsamples && remainingbytes) {
1172  file_offset_t framesamples = SamplesPerFrame;
1173  file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1174 
1175  int mode_l = *pSrc++, mode_r = 0;
1176 
1177  if (Channels == 2) {
1178  mode_r = *pSrc++;
1179  framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1180  rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1181  nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1182  if (remainingbytes < framebytes) { // last frame in sample
1183  framesamples = SamplesInLastFrame;
1184  if (mode_l == 4 && (framesamples & 1)) {
1185  rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1186  }
1187  else {
1188  rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1189  }
1190  }
1191  }
1192  else {
1193  framebytes = bytesPerFrame[mode_l] + 1;
1194  nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1195  if (remainingbytes < framebytes) {
1196  framesamples = SamplesInLastFrame;
1197  }
1198  }
1199 
1200  // determine how many samples in this frame to skip and read
1201  if (currentframeoffset + remainingsamples >= framesamples) {
1202  if (currentframeoffset <= framesamples) {
1203  copysamples = framesamples - currentframeoffset;
1204  skipsamples = currentframeoffset;
1205  }
1206  else {
1207  copysamples = 0;
1208  skipsamples = framesamples;
1209  }
1210  }
1211  else {
1212  // This frame has enough data for pBuffer, but not
1213  // all of the frame is needed. Set file position
1214  // to start of this frame for next call to Read.
1215  copysamples = remainingsamples;
1216  skipsamples = currentframeoffset;
1217  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1218  this->FrameOffset = currentframeoffset + copysamples;
1219  }
1220  remainingsamples -= copysamples;
1221 
1222  if (remainingbytes > framebytes) {
1223  remainingbytes -= framebytes;
1224  if (remainingsamples == 0 &&
1225  currentframeoffset + copysamples == framesamples) {
1226  // This frame has enough data for pBuffer, and
1227  // all of the frame is needed. Set file
1228  // position to start of next frame for next
1229  // call to Read. FrameOffset is 0.
1230  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1231  }
1232  }
1233  else remainingbytes = 0;
1234 
1235  currentframeoffset -= skipsamples;
1236 
1237  if (copysamples == 0) {
1238  // skip this frame
1239  pSrc += framebytes - Channels;
1240  }
1241  else {
1242  const unsigned char* const param_l = pSrc;
1243  if (BitDepth == 24) {
1244  if (mode_l != 2) pSrc += 12;
1245 
1246  if (Channels == 2) { // Stereo
1247  const unsigned char* const param_r = pSrc;
1248  if (mode_r != 2) pSrc += 12;
1249 
1250  Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1251  skipsamples, copysamples, TruncatedBits);
1252  Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1253  skipsamples, copysamples, TruncatedBits);
1254  pDst24 += copysamples * 6;
1255  }
1256  else { // Mono
1257  Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1258  skipsamples, copysamples, TruncatedBits);
1259  pDst24 += copysamples * 3;
1260  }
1261  }
1262  else { // 16 bit
1263  if (mode_l) pSrc += 4;
1264 
1265  int step;
1266  if (Channels == 2) { // Stereo
1267  const unsigned char* const param_r = pSrc;
1268  if (mode_r) pSrc += 4;
1269 
1270  step = (2 - mode_l) + (2 - mode_r);
1271  Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1272  Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1273  skipsamples, copysamples);
1274  pDst += copysamples << 1;
1275  }
1276  else { // Mono
1277  step = 2 - mode_l;
1278  Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1279  pDst += copysamples;
1280  }
1281  }
1282  pSrc += nextFrameOffset;
1283  }
1284 
1285  // reload from disk to local buffer if needed
1286  if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1287  assumedsize = GuessSize(remainingsamples);
1288  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1289  if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1290  remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1291  pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1292  }
1293  } // while
1294 
1295  this->SamplePos += (SampleCount - remainingsamples);
1296  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1297  return (SampleCount - remainingsamples);
1298  }
1299  }
1300 
1323  file_offset_t Sample::Write(void* pBuffer, file_offset_t SampleCount) {
1324  if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1325 
1326  // if this is the first write in this sample, reset the
1327  // checksum calculator
1328  if (pCkData->GetPos() == 0) {
1329  __resetCRC(crc);
1330  }
1331  if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1332  file_offset_t res;
1333  if (BitDepth == 24) {
1334  res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1335  } else { // 16 bit
1336  res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1337  : pCkData->Write(pBuffer, SampleCount, 2);
1338  }
1339  __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1340 
1341  // if this is the last write, update the checksum chunk in the
1342  // file
1343  if (pCkData->GetPos() == pCkData->GetSize()) {
1344  __finalizeCRC(crc);
1345  File* pFile = static_cast<File*>(GetParent());
1346  pFile->SetSampleChecksum(this, crc);
1347  }
1348  return res;
1349  }
1350 
1367  buffer_t Sample::CreateDecompressionBuffer(file_offset_t MaxReadSize) {
1368  buffer_t result;
1369  const double worstCaseHeaderOverhead =
1370  (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1371  result.Size = (file_offset_t) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1372  result.pStart = new int8_t[result.Size];
1373  result.NullExtensionSize = 0;
1374  return result;
1375  }
1376 
1384  void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1385  if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1386  delete[] (int8_t*) DecompressionBuffer.pStart;
1387  DecompressionBuffer.pStart = NULL;
1388  DecompressionBuffer.Size = 0;
1389  DecompressionBuffer.NullExtensionSize = 0;
1390  }
1391  }
1392 
1402  return pGroup;
1403  }
1404 
1418  return crc;
1419  }
1420 
1446  bool Sample::VerifyWaveData(uint32_t* pActually) {
1447  //File* pFile = static_cast<File*>(GetParent());
1448  uint32_t crc = CalculateWaveDataChecksum();
1449  if (pActually) *pActually = crc;
1450  return crc == this->crc;
1451  }
1452 
1453  uint32_t Sample::CalculateWaveDataChecksum() {
1454  const size_t sz = 20*1024; // 20kB buffer size
1455  std::vector<uint8_t> buffer(sz);
1456  buffer.resize(sz);
1457 
1458  const size_t n = sz / FrameSize;
1459  SetPos(0);
1460  uint32_t crc = 0;
1461  __resetCRC(crc);
1462  while (true) {
1463  file_offset_t nRead = Read(&buffer[0], n);
1464  if (nRead <= 0) break;
1465  __calculateCRC(&buffer[0], nRead * FrameSize, crc);
1466  }
1467  __finalizeCRC(crc);
1468  return crc;
1469  }
1470 
1472  Instances--;
1474  delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1477  }
1478  if (FrameTable) delete[] FrameTable;
1479  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1480  }
1481 
1482 
1483 
1484 // *************** DimensionRegion ***************
1485 // *
1486 
1487  size_t DimensionRegion::Instances = 0;
1488  DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1489 
1490  DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1491  Instances++;
1492 
1493  pSample = NULL;
1494  pRegion = pParent;
1495 
1496  if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1497  else memset(&Crossfade, 0, 4);
1498 
1499  if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1500 
1501  RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1502  if (_3ewa) { // if '3ewa' chunk exists
1503  _3ewa->ReadInt32(); // unknown, always == chunk size ?
1504  LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1505  EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1506  _3ewa->ReadInt16(); // unknown
1507  LFO1InternalDepth = _3ewa->ReadUint16();
1508  _3ewa->ReadInt16(); // unknown
1509  LFO3InternalDepth = _3ewa->ReadInt16();
1510  _3ewa->ReadInt16(); // unknown
1511  LFO1ControlDepth = _3ewa->ReadUint16();
1512  _3ewa->ReadInt16(); // unknown
1513  LFO3ControlDepth = _3ewa->ReadInt16();
1514  EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1515  EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1516  _3ewa->ReadInt16(); // unknown
1517  EG1Sustain = _3ewa->ReadUint16();
1518  EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1519  EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1520  uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1521  EG1ControllerInvert = eg1ctrloptions & 0x01;
1522  EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1523  EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1524  EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1525  EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1526  uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1527  EG2ControllerInvert = eg2ctrloptions & 0x01;
1528  EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1529  EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1530  EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1531  LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1532  EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1533  EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1534  _3ewa->ReadInt16(); // unknown
1535  EG2Sustain = _3ewa->ReadUint16();
1536  EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1537  _3ewa->ReadInt16(); // unknown
1538  LFO2ControlDepth = _3ewa->ReadUint16();
1539  LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1540  _3ewa->ReadInt16(); // unknown
1541  LFO2InternalDepth = _3ewa->ReadUint16();
1542  int32_t eg1decay2 = _3ewa->ReadInt32();
1543  EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1544  EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1545  _3ewa->ReadInt16(); // unknown
1546  EG1PreAttack = _3ewa->ReadUint16();
1547  int32_t eg2decay2 = _3ewa->ReadInt32();
1548  EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1549  EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1550  _3ewa->ReadInt16(); // unknown
1551  EG2PreAttack = _3ewa->ReadUint16();
1552  uint8_t velocityresponse = _3ewa->ReadUint8();
1553  if (velocityresponse < 5) {
1554  VelocityResponseCurve = curve_type_nonlinear;
1555  VelocityResponseDepth = velocityresponse;
1556  } else if (velocityresponse < 10) {
1557  VelocityResponseCurve = curve_type_linear;
1558  VelocityResponseDepth = velocityresponse - 5;
1559  } else if (velocityresponse < 15) {
1560  VelocityResponseCurve = curve_type_special;
1561  VelocityResponseDepth = velocityresponse - 10;
1562  } else {
1563  VelocityResponseCurve = curve_type_unknown;
1564  VelocityResponseDepth = 0;
1565  }
1566  uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1567  if (releasevelocityresponse < 5) {
1568  ReleaseVelocityResponseCurve = curve_type_nonlinear;
1569  ReleaseVelocityResponseDepth = releasevelocityresponse;
1570  } else if (releasevelocityresponse < 10) {
1571  ReleaseVelocityResponseCurve = curve_type_linear;
1572  ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1573  } else if (releasevelocityresponse < 15) {
1574  ReleaseVelocityResponseCurve = curve_type_special;
1575  ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1576  } else {
1577  ReleaseVelocityResponseCurve = curve_type_unknown;
1578  ReleaseVelocityResponseDepth = 0;
1579  }
1580  VelocityResponseCurveScaling = _3ewa->ReadUint8();
1581  AttenuationControllerThreshold = _3ewa->ReadInt8();
1582  _3ewa->ReadInt32(); // unknown
1583  SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1584  _3ewa->ReadInt16(); // unknown
1585  uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1586  PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1587  if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1588  else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1589  else DimensionBypass = dim_bypass_ctrl_none;
1590  uint8_t pan = _3ewa->ReadUint8();
1591  Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1592  SelfMask = _3ewa->ReadInt8() & 0x01;
1593  _3ewa->ReadInt8(); // unknown
1594  uint8_t lfo3ctrl = _3ewa->ReadUint8();
1595  LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1596  LFO3Sync = lfo3ctrl & 0x20; // bit 5
1597  InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1598  AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1599  uint8_t lfo2ctrl = _3ewa->ReadUint8();
1600  LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1601  LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1602  LFO2Sync = lfo2ctrl & 0x20; // bit 5
1603  bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1604  uint8_t lfo1ctrl = _3ewa->ReadUint8();
1605  LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1606  LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1607  LFO1Sync = lfo1ctrl & 0x40; // bit 6
1608  VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1610  uint16_t eg3depth = _3ewa->ReadUint16();
1611  EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1612  : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1613  _3ewa->ReadInt16(); // unknown
1614  ChannelOffset = _3ewa->ReadUint8() / 4;
1615  uint8_t regoptions = _3ewa->ReadUint8();
1616  MSDecode = regoptions & 0x01; // bit 0
1617  SustainDefeat = regoptions & 0x02; // bit 1
1618  _3ewa->ReadInt16(); // unknown
1619  VelocityUpperLimit = _3ewa->ReadInt8();
1620  _3ewa->ReadInt8(); // unknown
1621  _3ewa->ReadInt16(); // unknown
1622  ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1623  _3ewa->ReadInt8(); // unknown
1624  _3ewa->ReadInt8(); // unknown
1625  EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1626  uint8_t vcfcutoff = _3ewa->ReadUint8();
1627  VCFEnabled = vcfcutoff & 0x80; // bit 7
1628  VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1629  VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1630  uint8_t vcfvelscale = _3ewa->ReadUint8();
1631  VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1632  VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1633  _3ewa->ReadInt8(); // unknown
1634  uint8_t vcfresonance = _3ewa->ReadUint8();
1635  VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1636  VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1637  uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1638  VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1639  VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1640  uint8_t vcfvelocity = _3ewa->ReadUint8();
1641  VCFVelocityDynamicRange = vcfvelocity % 5;
1642  VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1643  VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1644  if (VCFType == vcf_type_lowpass) {
1645  if (lfo3ctrl & 0x40) // bit 6
1646  VCFType = vcf_type_lowpassturbo;
1647  }
1648  if (_3ewa->RemainingBytes() >= 8) {
1649  _3ewa->Read(DimensionUpperLimits, 1, 8);
1650  } else {
1651  memset(DimensionUpperLimits, 0, 8);
1652  }
1653  } else { // '3ewa' chunk does not exist yet
1654  // use default values
1655  LFO3Frequency = 1.0;
1656  EG3Attack = 0.0;
1657  LFO1InternalDepth = 0;
1658  LFO3InternalDepth = 0;
1659  LFO1ControlDepth = 0;
1660  LFO3ControlDepth = 0;
1661  EG1Attack = 0.0;
1662  EG1Decay1 = 0.005;
1663  EG1Sustain = 1000;
1664  EG1Release = 0.3;
1665  EG1Controller.type = eg1_ctrl_t::type_none;
1666  EG1Controller.controller_number = 0;
1667  EG1ControllerInvert = false;
1668  EG1ControllerAttackInfluence = 0;
1669  EG1ControllerDecayInfluence = 0;
1670  EG1ControllerReleaseInfluence = 0;
1671  EG2Controller.type = eg2_ctrl_t::type_none;
1672  EG2Controller.controller_number = 0;
1673  EG2ControllerInvert = false;
1674  EG2ControllerAttackInfluence = 0;
1675  EG2ControllerDecayInfluence = 0;
1676  EG2ControllerReleaseInfluence = 0;
1677  LFO1Frequency = 1.0;
1678  EG2Attack = 0.0;
1679  EG2Decay1 = 0.005;
1680  EG2Sustain = 1000;
1681  EG2Release = 60;
1682  LFO2ControlDepth = 0;
1683  LFO2Frequency = 1.0;
1684  LFO2InternalDepth = 0;
1685  EG1Decay2 = 0.0;
1686  EG1InfiniteSustain = true;
1687  EG1PreAttack = 0;
1688  EG2Decay2 = 0.0;
1689  EG2InfiniteSustain = true;
1690  EG2PreAttack = 0;
1691  VelocityResponseCurve = curve_type_nonlinear;
1692  VelocityResponseDepth = 3;
1693  ReleaseVelocityResponseCurve = curve_type_nonlinear;
1694  ReleaseVelocityResponseDepth = 3;
1695  VelocityResponseCurveScaling = 32;
1696  AttenuationControllerThreshold = 0;
1697  SampleStartOffset = 0;
1698  PitchTrack = true;
1699  DimensionBypass = dim_bypass_ctrl_none;
1700  Pan = 0;
1701  SelfMask = true;
1702  LFO3Controller = lfo3_ctrl_modwheel;
1703  LFO3Sync = false;
1704  InvertAttenuationController = false;
1705  AttenuationController.type = attenuation_ctrl_t::type_none;
1706  AttenuationController.controller_number = 0;
1707  LFO2Controller = lfo2_ctrl_internal;
1708  LFO2FlipPhase = false;
1709  LFO2Sync = false;
1710  LFO1Controller = lfo1_ctrl_internal;
1711  LFO1FlipPhase = false;
1712  LFO1Sync = false;
1713  VCFResonanceController = vcf_res_ctrl_none;
1714  EG3Depth = 0;
1715  ChannelOffset = 0;
1716  MSDecode = false;
1717  SustainDefeat = false;
1718  VelocityUpperLimit = 0;
1719  ReleaseTriggerDecay = 0;
1720  EG1Hold = false;
1721  VCFEnabled = false;
1722  VCFCutoff = 0;
1723  VCFCutoffController = vcf_cutoff_ctrl_none;
1724  VCFCutoffControllerInvert = false;
1725  VCFVelocityScale = 0;
1726  VCFResonance = 0;
1727  VCFResonanceDynamic = false;
1728  VCFKeyboardTracking = false;
1729  VCFKeyboardTrackingBreakpoint = 0;
1730  VCFVelocityDynamicRange = 0x04;
1731  VCFVelocityCurve = curve_type_linear;
1732  VCFType = vcf_type_lowpass;
1733  memset(DimensionUpperLimits, 127, 8);
1734  }
1735  // format extension for EG behavior options, these will *NOT* work with
1736  // Gigasampler/GigaStudio !
1737  RIFF::Chunk* lsde = _3ewl->GetSubChunk(CHUNK_ID_LSDE);
1738  if (lsde) {
1739  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1740  for (int i = 0; i < 2; ++i) {
1741  unsigned char byte = lsde->ReadUint8();
1742  pEGOpts[i]->AttackCancel = byte & 1;
1743  pEGOpts[i]->AttackHoldCancel = byte & (1 << 1);
1744  pEGOpts[i]->Decay1Cancel = byte & (1 << 2);
1745  pEGOpts[i]->Decay2Cancel = byte & (1 << 3);
1746  pEGOpts[i]->ReleaseCancel = byte & (1 << 4);
1747  }
1748  }
1749 
1750  pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1751  VelocityResponseDepth,
1752  VelocityResponseCurveScaling);
1753 
1754  pVelocityReleaseTable = GetReleaseVelocityTable(
1755  ReleaseVelocityResponseCurve,
1756  ReleaseVelocityResponseDepth
1757  );
1758 
1759  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1760  VCFVelocityDynamicRange,
1761  VCFVelocityScale,
1762  VCFCutoffController);
1763 
1764  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1765  VelocityTable = 0;
1766  }
1767 
1768  /*
1769  * Constructs a DimensionRegion by copying all parameters from
1770  * another DimensionRegion
1771  */
1772  DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1773  Instances++;
1774  //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1775  *this = src; // default memberwise shallow copy of all parameters
1776  pParentList = _3ewl; // restore the chunk pointer
1777 
1778  // deep copy of owned structures
1779  if (src.VelocityTable) {
1780  VelocityTable = new uint8_t[128];
1781  for (int k = 0 ; k < 128 ; k++)
1782  VelocityTable[k] = src.VelocityTable[k];
1783  }
1784  if (src.pSampleLoops) {
1785  pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1786  for (int k = 0 ; k < src.SampleLoops ; k++)
1787  pSampleLoops[k] = src.pSampleLoops[k];
1788  }
1789  }
1790 
1801  CopyAssign(orig, NULL);
1802  }
1803 
1812  void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1813  // delete all allocated data first
1814  if (VelocityTable) delete [] VelocityTable;
1815  if (pSampleLoops) delete [] pSampleLoops;
1816 
1817  // backup parent list pointer
1818  RIFF::List* p = pParentList;
1819 
1820  gig::Sample* pOriginalSample = pSample;
1821  gig::Region* pOriginalRegion = pRegion;
1822 
1823  //NOTE: copy code copied from assignment constructor above, see comment there as well
1824 
1825  *this = *orig; // default memberwise shallow copy of all parameters
1826 
1827  // restore members that shall not be altered
1828  pParentList = p; // restore the chunk pointer
1829  pRegion = pOriginalRegion;
1830 
1831  // only take the raw sample reference reference if the
1832  // two DimensionRegion objects are part of the same file
1833  if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1834  pSample = pOriginalSample;
1835  }
1836 
1837  if (mSamples && mSamples->count(orig->pSample)) {
1838  pSample = mSamples->find(orig->pSample)->second;
1839  }
1840 
1841  // deep copy of owned structures
1842  if (orig->VelocityTable) {
1843  VelocityTable = new uint8_t[128];
1844  for (int k = 0 ; k < 128 ; k++)
1845  VelocityTable[k] = orig->VelocityTable[k];
1846  }
1847  if (orig->pSampleLoops) {
1849  for (int k = 0 ; k < orig->SampleLoops ; k++)
1850  pSampleLoops[k] = orig->pSampleLoops[k];
1851  }
1852  }
1853 
1854  void DimensionRegion::serialize(Serialization::Archive* archive) {
1855  // in case this class will become backward incompatible one day,
1856  // then set a version and minimum version for this class like:
1857  //archive->setVersion(*this, 2);
1858  //archive->setMinVersion(*this, 1);
1859 
1860  SRLZ(VelocityUpperLimit);
1861  SRLZ(EG1PreAttack);
1862  SRLZ(EG1Attack);
1863  SRLZ(EG1Decay1);
1864  SRLZ(EG1Decay2);
1865  SRLZ(EG1InfiniteSustain);
1866  SRLZ(EG1Sustain);
1867  SRLZ(EG1Release);
1868  SRLZ(EG1Hold);
1869  SRLZ(EG1Controller);
1870  SRLZ(EG1ControllerInvert);
1874  SRLZ(LFO1Frequency);
1875  SRLZ(LFO1InternalDepth);
1876  SRLZ(LFO1ControlDepth);
1877  SRLZ(LFO1Controller);
1878  SRLZ(LFO1FlipPhase);
1879  SRLZ(LFO1Sync);
1880  SRLZ(EG2PreAttack);
1881  SRLZ(EG2Attack);
1882  SRLZ(EG2Decay1);
1883  SRLZ(EG2Decay2);
1884  SRLZ(EG2InfiniteSustain);
1885  SRLZ(EG2Sustain);
1886  SRLZ(EG2Release);
1887  SRLZ(EG2Controller);
1888  SRLZ(EG2ControllerInvert);
1892  SRLZ(LFO2Frequency);
1893  SRLZ(LFO2InternalDepth);
1894  SRLZ(LFO2ControlDepth);
1895  SRLZ(LFO2Controller);
1896  SRLZ(LFO2FlipPhase);
1897  SRLZ(LFO2Sync);
1898  SRLZ(EG3Attack);
1899  SRLZ(EG3Depth);
1900  SRLZ(LFO3Frequency);
1901  SRLZ(LFO3InternalDepth);
1902  SRLZ(LFO3ControlDepth);
1903  SRLZ(LFO3Controller);
1904  SRLZ(LFO3Sync);
1905  SRLZ(VCFEnabled);
1906  SRLZ(VCFType);
1907  SRLZ(VCFCutoffController);
1909  SRLZ(VCFCutoff);
1910  SRLZ(VCFVelocityCurve);
1911  SRLZ(VCFVelocityScale);
1913  SRLZ(VCFResonance);
1914  SRLZ(VCFResonanceDynamic);
1915  SRLZ(VCFResonanceController);
1916  SRLZ(VCFKeyboardTracking);
1918  SRLZ(VelocityResponseCurve);
1919  SRLZ(VelocityResponseDepth);
1923  SRLZ(ReleaseTriggerDecay);
1924  SRLZ(Crossfade);
1925  SRLZ(PitchTrack);
1926  SRLZ(DimensionBypass);
1927  SRLZ(Pan);
1928  SRLZ(SelfMask);
1929  SRLZ(AttenuationController);
1932  SRLZ(ChannelOffset);
1933  SRLZ(SustainDefeat);
1934  SRLZ(MSDecode);
1935  //SRLZ(SampleStartOffset);
1936  SRLZ(SampleAttenuation);
1937  SRLZ(EG1Options);
1938  SRLZ(EG2Options);
1939 
1940  // derived attributes from DLS::Sampler
1941  SRLZ(FineTune);
1942  SRLZ(Gain);
1943  }
1944 
1949  void DimensionRegion::SetGain(int32_t gain) {
1950  DLS::Sampler::SetGain(gain);
1951  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1952  }
1953 
1964  // first update base class's chunk
1965  DLS::Sampler::UpdateChunks(pProgress);
1966 
1967  RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1968  uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1969  pData[12] = Crossfade.in_start;
1970  pData[13] = Crossfade.in_end;
1971  pData[14] = Crossfade.out_start;
1972  pData[15] = Crossfade.out_end;
1973 
1974  // make sure '3ewa' chunk exists
1975  RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1976  if (!_3ewa) {
1977  File* pFile = (File*) GetParent()->GetParent()->GetParent();
1978  bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1979  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1980  }
1981  pData = (uint8_t*) _3ewa->LoadChunkData();
1982 
1983  // update '3ewa' chunk with DimensionRegion's current settings
1984 
1985  const uint32_t chunksize = (uint32_t) _3ewa->GetNewSize();
1986  store32(&pData[0], chunksize); // unknown, always chunk size?
1987 
1988  const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1989  store32(&pData[4], lfo3freq);
1990 
1991  const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1992  store32(&pData[8], eg3attack);
1993 
1994  // next 2 bytes unknown
1995 
1996  store16(&pData[14], LFO1InternalDepth);
1997 
1998  // next 2 bytes unknown
1999 
2000  store16(&pData[18], LFO3InternalDepth);
2001 
2002  // next 2 bytes unknown
2003 
2004  store16(&pData[22], LFO1ControlDepth);
2005 
2006  // next 2 bytes unknown
2007 
2008  store16(&pData[26], LFO3ControlDepth);
2009 
2010  const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
2011  store32(&pData[28], eg1attack);
2012 
2013  const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
2014  store32(&pData[32], eg1decay1);
2015 
2016  // next 2 bytes unknown
2017 
2018  store16(&pData[38], EG1Sustain);
2019 
2020  const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
2021  store32(&pData[40], eg1release);
2022 
2023  const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
2024  pData[44] = eg1ctl;
2025 
2026  const uint8_t eg1ctrloptions =
2027  (EG1ControllerInvert ? 0x01 : 0x00) |
2028  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2029  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2030  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2031  pData[45] = eg1ctrloptions;
2032 
2033  const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2034  pData[46] = eg2ctl;
2035 
2036  const uint8_t eg2ctrloptions =
2037  (EG2ControllerInvert ? 0x01 : 0x00) |
2038  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2039  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2040  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
2041  pData[47] = eg2ctrloptions;
2042 
2043  const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
2044  store32(&pData[48], lfo1freq);
2045 
2046  const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
2047  store32(&pData[52], eg2attack);
2048 
2049  const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
2050  store32(&pData[56], eg2decay1);
2051 
2052  // next 2 bytes unknown
2053 
2054  store16(&pData[62], EG2Sustain);
2055 
2056  const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2057  store32(&pData[64], eg2release);
2058 
2059  // next 2 bytes unknown
2060 
2061  store16(&pData[70], LFO2ControlDepth);
2062 
2063  const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2064  store32(&pData[72], lfo2freq);
2065 
2066  // next 2 bytes unknown
2067 
2068  store16(&pData[78], LFO2InternalDepth);
2069 
2070  const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2071  store32(&pData[80], eg1decay2);
2072 
2073  // next 2 bytes unknown
2074 
2075  store16(&pData[86], EG1PreAttack);
2076 
2077  const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2078  store32(&pData[88], eg2decay2);
2079 
2080  // next 2 bytes unknown
2081 
2082  store16(&pData[94], EG2PreAttack);
2083 
2084  {
2085  if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
2086  uint8_t velocityresponse = VelocityResponseDepth;
2087  switch (VelocityResponseCurve) {
2088  case curve_type_nonlinear:
2089  break;
2090  case curve_type_linear:
2091  velocityresponse += 5;
2092  break;
2093  case curve_type_special:
2094  velocityresponse += 10;
2095  break;
2096  case curve_type_unknown:
2097  default:
2098  throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2099  }
2100  pData[96] = velocityresponse;
2101  }
2102 
2103  {
2104  if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
2105  uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2106  switch (ReleaseVelocityResponseCurve) {
2107  case curve_type_nonlinear:
2108  break;
2109  case curve_type_linear:
2110  releasevelocityresponse += 5;
2111  break;
2112  case curve_type_special:
2113  releasevelocityresponse += 10;
2114  break;
2115  case curve_type_unknown:
2116  default:
2117  throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2118  }
2119  pData[97] = releasevelocityresponse;
2120  }
2121 
2122  pData[98] = VelocityResponseCurveScaling;
2123 
2124  pData[99] = AttenuationControllerThreshold;
2125 
2126  // next 4 bytes unknown
2127 
2128  store16(&pData[104], SampleStartOffset);
2129 
2130  // next 2 bytes unknown
2131 
2132  {
2133  uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2134  switch (DimensionBypass) {
2135  case dim_bypass_ctrl_94:
2136  pitchTrackDimensionBypass |= 0x10;
2137  break;
2138  case dim_bypass_ctrl_95:
2139  pitchTrackDimensionBypass |= 0x20;
2140  break;
2141  case dim_bypass_ctrl_none:
2142  //FIXME: should we set anything here?
2143  break;
2144  default:
2145  throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2146  }
2147  pData[108] = pitchTrackDimensionBypass;
2148  }
2149 
2150  const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
2151  pData[109] = pan;
2152 
2153  const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
2154  pData[110] = selfmask;
2155 
2156  // next byte unknown
2157 
2158  {
2159  uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
2160  if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
2161  if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
2162  if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
2163  pData[112] = lfo3ctrl;
2164  }
2165 
2166  const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2167  pData[113] = attenctl;
2168 
2169  {
2170  uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
2171  if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
2172  if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
2173  if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
2174  pData[114] = lfo2ctrl;
2175  }
2176 
2177  {
2178  uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
2179  if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
2180  if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
2182  lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2183  pData[115] = lfo1ctrl;
2184  }
2185 
2186  const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2187  : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
2188  store16(&pData[116], eg3depth);
2189 
2190  // next 2 bytes unknown
2191 
2192  const uint8_t channeloffset = ChannelOffset * 4;
2193  pData[120] = channeloffset;
2194 
2195  {
2196  uint8_t regoptions = 0;
2197  if (MSDecode) regoptions |= 0x01; // bit 0
2198  if (SustainDefeat) regoptions |= 0x02; // bit 1
2199  pData[121] = regoptions;
2200  }
2201 
2202  // next 2 bytes unknown
2203 
2204  pData[124] = VelocityUpperLimit;
2205 
2206  // next 3 bytes unknown
2207 
2208  pData[128] = ReleaseTriggerDecay;
2209 
2210  // next 2 bytes unknown
2211 
2212  const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
2213  pData[131] = eg1hold;
2214 
2215  const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
2216  (VCFCutoff & 0x7f); /* lower 7 bits */
2217  pData[132] = vcfcutoff;
2218 
2219  pData[133] = VCFCutoffController;
2220 
2221  const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
2222  (VCFVelocityScale & 0x7f); /* lower 7 bits */
2223  pData[134] = vcfvelscale;
2224 
2225  // next byte unknown
2226 
2227  const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
2228  (VCFResonance & 0x7f); /* lower 7 bits */
2229  pData[136] = vcfresonance;
2230 
2231  const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2232  (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2233  pData[137] = vcfbreakpoint;
2234 
2235  const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2236  VCFVelocityCurve * 5;
2237  pData[138] = vcfvelocity;
2238 
2239  const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2240  pData[139] = vcftype;
2241 
2242  if (chunksize >= 148) {
2243  memcpy(&pData[140], DimensionUpperLimits, 8);
2244  }
2245 
2246  // format extension for EG behavior options, these will *NOT* work with
2247  // Gigasampler/GigaStudio !
2248  RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2249  if (!lsde) {
2250  // only add this "LSDE" chunk if the EG options do not match the
2251  // default EG behavior
2252  eg_opt_t defaultOpt;
2253  if (memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||
2254  memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)))
2255  {
2256  lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, 2);
2257  // move LSDE chunk to the end of parent list
2258  pParentList->MoveSubChunk(lsde, (RIFF::Chunk*)NULL);
2259  }
2260  }
2261  if (lsde) {
2262  unsigned char* pData = (unsigned char*) lsde->LoadChunkData();
2263  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
2264  for (int i = 0; i < 2; ++i) {
2265  pData[i] =
2266  (pEGOpts[i]->AttackCancel ? 1 : 0) |
2267  (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2268  (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2269  (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2270  (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2271  }
2272  }
2273  }
2274 
2275  double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2276  curve_type_t curveType = releaseVelocityResponseCurve;
2277  uint8_t depth = releaseVelocityResponseDepth;
2278  // this models a strange behaviour or bug in GSt: two of the
2279  // velocity response curves for release time are not used even
2280  // if specified, instead another curve is chosen.
2281  if ((curveType == curve_type_nonlinear && depth == 0) ||
2282  (curveType == curve_type_special && depth == 4)) {
2283  curveType = curve_type_nonlinear;
2284  depth = 3;
2285  }
2286  return GetVelocityTable(curveType, depth, 0);
2287  }
2288 
2289  double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2290  uint8_t vcfVelocityDynamicRange,
2291  uint8_t vcfVelocityScale,
2292  vcf_cutoff_ctrl_t vcfCutoffController)
2293  {
2294  curve_type_t curveType = vcfVelocityCurve;
2295  uint8_t depth = vcfVelocityDynamicRange;
2296  // even stranger GSt: two of the velocity response curves for
2297  // filter cutoff are not used, instead another special curve
2298  // is chosen. This curve is not used anywhere else.
2299  if ((curveType == curve_type_nonlinear && depth == 0) ||
2300  (curveType == curve_type_special && depth == 4)) {
2301  curveType = curve_type_special;
2302  depth = 5;
2303  }
2304  return GetVelocityTable(curveType, depth,
2305  (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2306  ? vcfVelocityScale : 0);
2307  }
2308 
2309  // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
2310  double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2311  {
2312  // sanity check input parameters
2313  // (fallback to some default parameters on ill input)
2314  switch (curveType) {
2315  case curve_type_nonlinear:
2316  case curve_type_linear:
2317  if (depth > 4) {
2318  printf("Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2319  depth = 0;
2320  scaling = 0;
2321  }
2322  break;
2323  case curve_type_special:
2324  if (depth > 5) {
2325  printf("Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2326  depth = 0;
2327  scaling = 0;
2328  }
2329  break;
2330  case curve_type_unknown:
2331  default:
2332  printf("Warning: Unknown velocity curve type (0x%x).\n", curveType);
2333  curveType = curve_type_linear;
2334  depth = 0;
2335  scaling = 0;
2336  break;
2337  }
2338 
2339  double* table;
2340  uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2341  if (pVelocityTables->count(tableKey)) { // if key exists
2342  table = (*pVelocityTables)[tableKey];
2343  }
2344  else {
2345  table = CreateVelocityTable(curveType, depth, scaling);
2346  (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
2347  }
2348  return table;
2349  }
2350 
2351  Region* DimensionRegion::GetParent() const {
2352  return pRegion;
2353  }
2354 
2355 // show error if some _lev_ctrl_* enum entry is not listed in the following function
2356 // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2357 // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2358 //#pragma GCC diagnostic push
2359 //#pragma GCC diagnostic error "-Wswitch"
2360 
2361  leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2362  leverage_ctrl_t decodedcontroller;
2363  switch (EncodedController) {
2364  // special controller
2365  case _lev_ctrl_none:
2366  decodedcontroller.type = leverage_ctrl_t::type_none;
2367  decodedcontroller.controller_number = 0;
2368  break;
2369  case _lev_ctrl_velocity:
2370  decodedcontroller.type = leverage_ctrl_t::type_velocity;
2371  decodedcontroller.controller_number = 0;
2372  break;
2373  case _lev_ctrl_channelaftertouch:
2374  decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
2375  decodedcontroller.controller_number = 0;
2376  break;
2377 
2378  // ordinary MIDI control change controller
2379  case _lev_ctrl_modwheel:
2380  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2381  decodedcontroller.controller_number = 1;
2382  break;
2383  case _lev_ctrl_breath:
2384  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2385  decodedcontroller.controller_number = 2;
2386  break;
2387  case _lev_ctrl_foot:
2388  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2389  decodedcontroller.controller_number = 4;
2390  break;
2391  case _lev_ctrl_effect1:
2392  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2393  decodedcontroller.controller_number = 12;
2394  break;
2395  case _lev_ctrl_effect2:
2396  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2397  decodedcontroller.controller_number = 13;
2398  break;
2399  case _lev_ctrl_genpurpose1:
2400  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2401  decodedcontroller.controller_number = 16;
2402  break;
2403  case _lev_ctrl_genpurpose2:
2404  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2405  decodedcontroller.controller_number = 17;
2406  break;
2407  case _lev_ctrl_genpurpose3:
2408  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2409  decodedcontroller.controller_number = 18;
2410  break;
2411  case _lev_ctrl_genpurpose4:
2412  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2413  decodedcontroller.controller_number = 19;
2414  break;
2415  case _lev_ctrl_portamentotime:
2416  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2417  decodedcontroller.controller_number = 5;
2418  break;
2419  case _lev_ctrl_sustainpedal:
2420  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2421  decodedcontroller.controller_number = 64;
2422  break;
2423  case _lev_ctrl_portamento:
2424  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2425  decodedcontroller.controller_number = 65;
2426  break;
2427  case _lev_ctrl_sostenutopedal:
2428  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2429  decodedcontroller.controller_number = 66;
2430  break;
2431  case _lev_ctrl_softpedal:
2432  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2433  decodedcontroller.controller_number = 67;
2434  break;
2435  case _lev_ctrl_genpurpose5:
2436  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2437  decodedcontroller.controller_number = 80;
2438  break;
2439  case _lev_ctrl_genpurpose6:
2440  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2441  decodedcontroller.controller_number = 81;
2442  break;
2443  case _lev_ctrl_genpurpose7:
2444  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2445  decodedcontroller.controller_number = 82;
2446  break;
2447  case _lev_ctrl_genpurpose8:
2448  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2449  decodedcontroller.controller_number = 83;
2450  break;
2451  case _lev_ctrl_effect1depth:
2452  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2453  decodedcontroller.controller_number = 91;
2454  break;
2455  case _lev_ctrl_effect2depth:
2456  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2457  decodedcontroller.controller_number = 92;
2458  break;
2459  case _lev_ctrl_effect3depth:
2460  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2461  decodedcontroller.controller_number = 93;
2462  break;
2463  case _lev_ctrl_effect4depth:
2464  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2465  decodedcontroller.controller_number = 94;
2466  break;
2467  case _lev_ctrl_effect5depth:
2468  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2469  decodedcontroller.controller_number = 95;
2470  break;
2471 
2472  // format extension (these controllers are so far only supported by
2473  // LinuxSampler & gigedit) they will *NOT* work with
2474  // Gigasampler/GigaStudio !
2475  case _lev_ctrl_CC3_EXT:
2476  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2477  decodedcontroller.controller_number = 3;
2478  break;
2479  case _lev_ctrl_CC6_EXT:
2480  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2481  decodedcontroller.controller_number = 6;
2482  break;
2483  case _lev_ctrl_CC7_EXT:
2484  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2485  decodedcontroller.controller_number = 7;
2486  break;
2487  case _lev_ctrl_CC8_EXT:
2488  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2489  decodedcontroller.controller_number = 8;
2490  break;
2491  case _lev_ctrl_CC9_EXT:
2492  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2493  decodedcontroller.controller_number = 9;
2494  break;
2495  case _lev_ctrl_CC10_EXT:
2496  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2497  decodedcontroller.controller_number = 10;
2498  break;
2499  case _lev_ctrl_CC11_EXT:
2500  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2501  decodedcontroller.controller_number = 11;
2502  break;
2503  case _lev_ctrl_CC14_EXT:
2504  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2505  decodedcontroller.controller_number = 14;
2506  break;
2507  case _lev_ctrl_CC15_EXT:
2508  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2509  decodedcontroller.controller_number = 15;
2510  break;
2511  case _lev_ctrl_CC20_EXT:
2512  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2513  decodedcontroller.controller_number = 20;
2514  break;
2515  case _lev_ctrl_CC21_EXT:
2516  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2517  decodedcontroller.controller_number = 21;
2518  break;
2519  case _lev_ctrl_CC22_EXT:
2520  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2521  decodedcontroller.controller_number = 22;
2522  break;
2523  case _lev_ctrl_CC23_EXT:
2524  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2525  decodedcontroller.controller_number = 23;
2526  break;
2527  case _lev_ctrl_CC24_EXT:
2528  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2529  decodedcontroller.controller_number = 24;
2530  break;
2531  case _lev_ctrl_CC25_EXT:
2532  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2533  decodedcontroller.controller_number = 25;
2534  break;
2535  case _lev_ctrl_CC26_EXT:
2536  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2537  decodedcontroller.controller_number = 26;
2538  break;
2539  case _lev_ctrl_CC27_EXT:
2540  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2541  decodedcontroller.controller_number = 27;
2542  break;
2543  case _lev_ctrl_CC28_EXT:
2544  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2545  decodedcontroller.controller_number = 28;
2546  break;
2547  case _lev_ctrl_CC29_EXT:
2548  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2549  decodedcontroller.controller_number = 29;
2550  break;
2551  case _lev_ctrl_CC30_EXT:
2552  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2553  decodedcontroller.controller_number = 30;
2554  break;
2555  case _lev_ctrl_CC31_EXT:
2556  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2557  decodedcontroller.controller_number = 31;
2558  break;
2559  case _lev_ctrl_CC68_EXT:
2560  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2561  decodedcontroller.controller_number = 68;
2562  break;
2563  case _lev_ctrl_CC69_EXT:
2564  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2565  decodedcontroller.controller_number = 69;
2566  break;
2567  case _lev_ctrl_CC70_EXT:
2568  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2569  decodedcontroller.controller_number = 70;
2570  break;
2571  case _lev_ctrl_CC71_EXT:
2572  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2573  decodedcontroller.controller_number = 71;
2574  break;
2575  case _lev_ctrl_CC72_EXT:
2576  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2577  decodedcontroller.controller_number = 72;
2578  break;
2579  case _lev_ctrl_CC73_EXT:
2580  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2581  decodedcontroller.controller_number = 73;
2582  break;
2583  case _lev_ctrl_CC74_EXT:
2584  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2585  decodedcontroller.controller_number = 74;
2586  break;
2587  case _lev_ctrl_CC75_EXT:
2588  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2589  decodedcontroller.controller_number = 75;
2590  break;
2591  case _lev_ctrl_CC76_EXT:
2592  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2593  decodedcontroller.controller_number = 76;
2594  break;
2595  case _lev_ctrl_CC77_EXT:
2596  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2597  decodedcontroller.controller_number = 77;
2598  break;
2599  case _lev_ctrl_CC78_EXT:
2600  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2601  decodedcontroller.controller_number = 78;
2602  break;
2603  case _lev_ctrl_CC79_EXT:
2604  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2605  decodedcontroller.controller_number = 79;
2606  break;
2607  case _lev_ctrl_CC84_EXT:
2608  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2609  decodedcontroller.controller_number = 84;
2610  break;
2611  case _lev_ctrl_CC85_EXT:
2612  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2613  decodedcontroller.controller_number = 85;
2614  break;
2615  case _lev_ctrl_CC86_EXT:
2616  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2617  decodedcontroller.controller_number = 86;
2618  break;
2619  case _lev_ctrl_CC87_EXT:
2620  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2621  decodedcontroller.controller_number = 87;
2622  break;
2623  case _lev_ctrl_CC89_EXT:
2624  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2625  decodedcontroller.controller_number = 89;
2626  break;
2627  case _lev_ctrl_CC90_EXT:
2628  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2629  decodedcontroller.controller_number = 90;
2630  break;
2631  case _lev_ctrl_CC96_EXT:
2632  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2633  decodedcontroller.controller_number = 96;
2634  break;
2635  case _lev_ctrl_CC97_EXT:
2636  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2637  decodedcontroller.controller_number = 97;
2638  break;
2639  case _lev_ctrl_CC102_EXT:
2640  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2641  decodedcontroller.controller_number = 102;
2642  break;
2643  case _lev_ctrl_CC103_EXT:
2644  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2645  decodedcontroller.controller_number = 103;
2646  break;
2647  case _lev_ctrl_CC104_EXT:
2648  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2649  decodedcontroller.controller_number = 104;
2650  break;
2651  case _lev_ctrl_CC105_EXT:
2652  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2653  decodedcontroller.controller_number = 105;
2654  break;
2655  case _lev_ctrl_CC106_EXT:
2656  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2657  decodedcontroller.controller_number = 106;
2658  break;
2659  case _lev_ctrl_CC107_EXT:
2660  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2661  decodedcontroller.controller_number = 107;
2662  break;
2663  case _lev_ctrl_CC108_EXT:
2664  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2665  decodedcontroller.controller_number = 108;
2666  break;
2667  case _lev_ctrl_CC109_EXT:
2668  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2669  decodedcontroller.controller_number = 109;
2670  break;
2671  case _lev_ctrl_CC110_EXT:
2672  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2673  decodedcontroller.controller_number = 110;
2674  break;
2675  case _lev_ctrl_CC111_EXT:
2676  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2677  decodedcontroller.controller_number = 111;
2678  break;
2679  case _lev_ctrl_CC112_EXT:
2680  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2681  decodedcontroller.controller_number = 112;
2682  break;
2683  case _lev_ctrl_CC113_EXT:
2684  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2685  decodedcontroller.controller_number = 113;
2686  break;
2687  case _lev_ctrl_CC114_EXT:
2688  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2689  decodedcontroller.controller_number = 114;
2690  break;
2691  case _lev_ctrl_CC115_EXT:
2692  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2693  decodedcontroller.controller_number = 115;
2694  break;
2695  case _lev_ctrl_CC116_EXT:
2696  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2697  decodedcontroller.controller_number = 116;
2698  break;
2699  case _lev_ctrl_CC117_EXT:
2700  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2701  decodedcontroller.controller_number = 117;
2702  break;
2703  case _lev_ctrl_CC118_EXT:
2704  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2705  decodedcontroller.controller_number = 118;
2706  break;
2707  case _lev_ctrl_CC119_EXT:
2708  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2709  decodedcontroller.controller_number = 119;
2710  break;
2711 
2712  // unknown controller type
2713  default:
2714  decodedcontroller.type = leverage_ctrl_t::type_none;
2715  decodedcontroller.controller_number = 0;
2716  printf("Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2717  break;
2718  }
2719  return decodedcontroller;
2720  }
2721 
2722 // see above (diagnostic push not supported prior GCC 4.6)
2723 //#pragma GCC diagnostic pop
2724 
2725  DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2726  _lev_ctrl_t encodedcontroller;
2727  switch (DecodedController.type) {
2728  // special controller
2730  encodedcontroller = _lev_ctrl_none;
2731  break;
2732  case leverage_ctrl_t::type_velocity:
2733  encodedcontroller = _lev_ctrl_velocity;
2734  break;
2735  case leverage_ctrl_t::type_channelaftertouch:
2736  encodedcontroller = _lev_ctrl_channelaftertouch;
2737  break;
2738 
2739  // ordinary MIDI control change controller
2740  case leverage_ctrl_t::type_controlchange:
2741  switch (DecodedController.controller_number) {
2742  case 1:
2743  encodedcontroller = _lev_ctrl_modwheel;
2744  break;
2745  case 2:
2746  encodedcontroller = _lev_ctrl_breath;
2747  break;
2748  case 4:
2749  encodedcontroller = _lev_ctrl_foot;
2750  break;
2751  case 12:
2752  encodedcontroller = _lev_ctrl_effect1;
2753  break;
2754  case 13:
2755  encodedcontroller = _lev_ctrl_effect2;
2756  break;
2757  case 16:
2758  encodedcontroller = _lev_ctrl_genpurpose1;
2759  break;
2760  case 17:
2761  encodedcontroller = _lev_ctrl_genpurpose2;
2762  break;
2763  case 18:
2764  encodedcontroller = _lev_ctrl_genpurpose3;
2765  break;
2766  case 19:
2767  encodedcontroller = _lev_ctrl_genpurpose4;
2768  break;
2769  case 5:
2770  encodedcontroller = _lev_ctrl_portamentotime;
2771  break;
2772  case 64:
2773  encodedcontroller = _lev_ctrl_sustainpedal;
2774  break;
2775  case 65:
2776  encodedcontroller = _lev_ctrl_portamento;
2777  break;
2778  case 66:
2779  encodedcontroller = _lev_ctrl_sostenutopedal;
2780  break;
2781  case 67:
2782  encodedcontroller = _lev_ctrl_softpedal;
2783  break;
2784  case 80:
2785  encodedcontroller = _lev_ctrl_genpurpose5;
2786  break;
2787  case 81:
2788  encodedcontroller = _lev_ctrl_genpurpose6;
2789  break;
2790  case 82:
2791  encodedcontroller = _lev_ctrl_genpurpose7;
2792  break;
2793  case 83:
2794  encodedcontroller = _lev_ctrl_genpurpose8;
2795  break;
2796  case 91:
2797  encodedcontroller = _lev_ctrl_effect1depth;
2798  break;
2799  case 92:
2800  encodedcontroller = _lev_ctrl_effect2depth;
2801  break;
2802  case 93:
2803  encodedcontroller = _lev_ctrl_effect3depth;
2804  break;
2805  case 94:
2806  encodedcontroller = _lev_ctrl_effect4depth;
2807  break;
2808  case 95:
2809  encodedcontroller = _lev_ctrl_effect5depth;
2810  break;
2811 
2812  // format extension (these controllers are so far only
2813  // supported by LinuxSampler & gigedit) they will *NOT*
2814  // work with Gigasampler/GigaStudio !
2815  case 3:
2816  encodedcontroller = _lev_ctrl_CC3_EXT;
2817  break;
2818  case 6:
2819  encodedcontroller = _lev_ctrl_CC6_EXT;
2820  break;
2821  case 7:
2822  encodedcontroller = _lev_ctrl_CC7_EXT;
2823  break;
2824  case 8:
2825  encodedcontroller = _lev_ctrl_CC8_EXT;
2826  break;
2827  case 9:
2828  encodedcontroller = _lev_ctrl_CC9_EXT;
2829  break;
2830  case 10:
2831  encodedcontroller = _lev_ctrl_CC10_EXT;
2832  break;
2833  case 11:
2834  encodedcontroller = _lev_ctrl_CC11_EXT;
2835  break;
2836  case 14:
2837  encodedcontroller = _lev_ctrl_CC14_EXT;
2838  break;
2839  case 15:
2840  encodedcontroller = _lev_ctrl_CC15_EXT;
2841  break;
2842  case 20:
2843  encodedcontroller = _lev_ctrl_CC20_EXT;
2844  break;
2845  case 21:
2846  encodedcontroller = _lev_ctrl_CC21_EXT;
2847  break;
2848  case 22:
2849  encodedcontroller = _lev_ctrl_CC22_EXT;
2850  break;
2851  case 23:
2852  encodedcontroller = _lev_ctrl_CC23_EXT;
2853  break;
2854  case 24:
2855  encodedcontroller = _lev_ctrl_CC24_EXT;
2856  break;
2857  case 25:
2858  encodedcontroller = _lev_ctrl_CC25_EXT;
2859  break;
2860  case 26:
2861  encodedcontroller = _lev_ctrl_CC26_EXT;
2862  break;
2863  case 27:
2864  encodedcontroller = _lev_ctrl_CC27_EXT;
2865  break;
2866  case 28:
2867  encodedcontroller = _lev_ctrl_CC28_EXT;
2868  break;
2869  case 29:
2870  encodedcontroller = _lev_ctrl_CC29_EXT;
2871  break;
2872  case 30:
2873  encodedcontroller = _lev_ctrl_CC30_EXT;
2874  break;
2875  case 31:
2876  encodedcontroller = _lev_ctrl_CC31_EXT;
2877  break;
2878  case 68:
2879  encodedcontroller = _lev_ctrl_CC68_EXT;
2880  break;
2881  case 69:
2882  encodedcontroller = _lev_ctrl_CC69_EXT;
2883  break;
2884  case 70:
2885  encodedcontroller = _lev_ctrl_CC70_EXT;
2886  break;
2887  case 71:
2888  encodedcontroller = _lev_ctrl_CC71_EXT;
2889  break;
2890  case 72:
2891  encodedcontroller = _lev_ctrl_CC72_EXT;
2892  break;
2893  case 73:
2894  encodedcontroller = _lev_ctrl_CC73_EXT;
2895  break;
2896  case 74:
2897  encodedcontroller = _lev_ctrl_CC74_EXT;
2898  break;
2899  case 75:
2900  encodedcontroller = _lev_ctrl_CC75_EXT;
2901  break;
2902  case 76:
2903  encodedcontroller = _lev_ctrl_CC76_EXT;
2904  break;
2905  case 77:
2906  encodedcontroller = _lev_ctrl_CC77_EXT;
2907  break;
2908  case 78:
2909  encodedcontroller = _lev_ctrl_CC78_EXT;
2910  break;
2911  case 79:
2912  encodedcontroller = _lev_ctrl_CC79_EXT;
2913  break;
2914  case 84:
2915  encodedcontroller = _lev_ctrl_CC84_EXT;
2916  break;
2917  case 85:
2918  encodedcontroller = _lev_ctrl_CC85_EXT;
2919  break;
2920  case 86:
2921  encodedcontroller = _lev_ctrl_CC86_EXT;
2922  break;
2923  case 87:
2924  encodedcontroller = _lev_ctrl_CC87_EXT;
2925  break;
2926  case 89:
2927  encodedcontroller = _lev_ctrl_CC89_EXT;
2928  break;
2929  case 90:
2930  encodedcontroller = _lev_ctrl_CC90_EXT;
2931  break;
2932  case 96:
2933  encodedcontroller = _lev_ctrl_CC96_EXT;
2934  break;
2935  case 97:
2936  encodedcontroller = _lev_ctrl_CC97_EXT;
2937  break;
2938  case 102:
2939  encodedcontroller = _lev_ctrl_CC102_EXT;
2940  break;
2941  case 103:
2942  encodedcontroller = _lev_ctrl_CC103_EXT;
2943  break;
2944  case 104:
2945  encodedcontroller = _lev_ctrl_CC104_EXT;
2946  break;
2947  case 105:
2948  encodedcontroller = _lev_ctrl_CC105_EXT;
2949  break;
2950  case 106:
2951  encodedcontroller = _lev_ctrl_CC106_EXT;
2952  break;
2953  case 107:
2954  encodedcontroller = _lev_ctrl_CC107_EXT;
2955  break;
2956  case 108:
2957  encodedcontroller = _lev_ctrl_CC108_EXT;
2958  break;
2959  case 109:
2960  encodedcontroller = _lev_ctrl_CC109_EXT;
2961  break;
2962  case 110:
2963  encodedcontroller = _lev_ctrl_CC110_EXT;
2964  break;
2965  case 111:
2966  encodedcontroller = _lev_ctrl_CC111_EXT;
2967  break;
2968  case 112:
2969  encodedcontroller = _lev_ctrl_CC112_EXT;
2970  break;
2971  case 113:
2972  encodedcontroller = _lev_ctrl_CC113_EXT;
2973  break;
2974  case 114:
2975  encodedcontroller = _lev_ctrl_CC114_EXT;
2976  break;
2977  case 115:
2978  encodedcontroller = _lev_ctrl_CC115_EXT;
2979  break;
2980  case 116:
2981  encodedcontroller = _lev_ctrl_CC116_EXT;
2982  break;
2983  case 117:
2984  encodedcontroller = _lev_ctrl_CC117_EXT;
2985  break;
2986  case 118:
2987  encodedcontroller = _lev_ctrl_CC118_EXT;
2988  break;
2989  case 119:
2990  encodedcontroller = _lev_ctrl_CC119_EXT;
2991  break;
2992 
2993  default:
2994  throw gig::Exception("leverage controller number is not supported by the gig format");
2995  }
2996  break;
2997  default:
2998  throw gig::Exception("Unknown leverage controller type.");
2999  }
3000  return encodedcontroller;
3001  }
3002 
3003  DimensionRegion::~DimensionRegion() {
3004  Instances--;
3005  if (!Instances) {
3006  // delete the velocity->volume tables
3007  VelocityTableMap::iterator iter;
3008  for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3009  double* pTable = iter->second;
3010  if (pTable) delete[] pTable;
3011  }
3012  pVelocityTables->clear();
3013  delete pVelocityTables;
3014  pVelocityTables = NULL;
3015  }
3016  if (VelocityTable) delete[] VelocityTable;
3017  }
3018 
3030  double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
3031  return pVelocityAttenuationTable[MIDIKeyVelocity];
3032  }
3033 
3034  double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3035  return pVelocityReleaseTable[MIDIKeyVelocity];
3036  }
3037 
3038  double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3039  return pVelocityCutoffTable[MIDIKeyVelocity];
3040  }
3041 
3047  pVelocityAttenuationTable =
3048  GetVelocityTable(
3050  );
3051  VelocityResponseCurve = curve;
3052  }
3053 
3059  pVelocityAttenuationTable =
3060  GetVelocityTable(
3062  );
3063  VelocityResponseDepth = depth;
3064  }
3065 
3071  pVelocityAttenuationTable =
3072  GetVelocityTable(
3074  );
3075  VelocityResponseCurveScaling = scaling;
3076  }
3077 
3083  pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3085  }
3086 
3092  pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3094  }
3095 
3100  void DimensionRegion::SetVCFCutoffController(vcf_cutoff_ctrl_t controller) {
3101  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3102  VCFCutoffController = controller;
3103  }
3104 
3109  void DimensionRegion::SetVCFVelocityCurve(curve_type_t curve) {
3110  pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3111  VCFVelocityCurve = curve;
3112  }
3113 
3119  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3120  VCFVelocityDynamicRange = range;
3121  }
3122 
3128  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3129  VCFVelocityScale = scaling;
3130  }
3131 
3132  double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3133 
3134  // line-segment approximations of the 15 velocity curves
3135 
3136  // linear
3137  const int lin0[] = { 1, 1, 127, 127 };
3138  const int lin1[] = { 1, 21, 127, 127 };
3139  const int lin2[] = { 1, 45, 127, 127 };
3140  const int lin3[] = { 1, 74, 127, 127 };
3141  const int lin4[] = { 1, 127, 127, 127 };
3142 
3143  // non-linear
3144  const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3145  const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3146  127, 127 };
3147  const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3148  127, 127 };
3149  const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3150  127, 127 };
3151  const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3152 
3153  // special
3154  const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3155  113, 127, 127, 127 };
3156  const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3157  118, 127, 127, 127 };
3158  const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3159  85, 90, 91, 127, 127, 127 };
3160  const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3161  117, 127, 127, 127 };
3162  const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3163  127, 127 };
3164 
3165  // this is only used by the VCF velocity curve
3166  const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3167  91, 127, 127, 127 };
3168 
3169  const int* const curves[] = { non0, non1, non2, non3, non4,
3170  lin0, lin1, lin2, lin3, lin4,
3171  spe0, spe1, spe2, spe3, spe4, spe5 };
3172 
3173  double* const table = new double[128];
3174 
3175  const int* curve = curves[curveType * 5 + depth];
3176  const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
3177 
3178  table[0] = 0;
3179  for (int x = 1 ; x < 128 ; x++) {
3180 
3181  if (x > curve[2]) curve += 2;
3182  double y = curve[1] + (x - curve[0]) *
3183  (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3184  y = y / 127;
3185 
3186  // Scale up for s > 20, down for s < 20. When
3187  // down-scaling, the curve still ends at 1.0.
3188  if (s < 20 && y >= 0.5)
3189  y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3190  else
3191  y = y * (s / 20.0);
3192  if (y > 1) y = 1;
3193 
3194  table[x] = y;
3195  }
3196  return table;
3197  }
3198 
3199 
3200 // *************** Region ***************
3201 // *
3202 
3203  Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
3204  // Initialization
3205  Dimensions = 0;
3206  for (int i = 0; i < 256; i++) {
3207  pDimensionRegions[i] = NULL;
3208  }
3209  Layers = 1;
3210  File* file = (File*) GetParent()->GetParent();
3211  int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
3212 
3213  // Actual Loading
3214 
3215  if (!file->GetAutoLoad()) return;
3216 
3217  LoadDimensionRegions(rgnList);
3218 
3219  RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
3220  if (_3lnk) {
3221  DimensionRegions = _3lnk->ReadUint32();
3222  for (int i = 0; i < dimensionBits; i++) {
3223  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
3224  uint8_t bits = _3lnk->ReadUint8();
3225  _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
3226  _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
3227  uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
3228  if (dimension == dimension_none) { // inactive dimension
3229  pDimensionDefinitions[i].dimension = dimension_none;
3230  pDimensionDefinitions[i].bits = 0;
3231  pDimensionDefinitions[i].zones = 0;
3232  pDimensionDefinitions[i].split_type = split_type_bit;
3233  pDimensionDefinitions[i].zone_size = 0;
3234  }
3235  else { // active dimension
3236  pDimensionDefinitions[i].dimension = dimension;
3237  pDimensionDefinitions[i].bits = bits;
3238  pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
3239  pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3240  pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3241  Dimensions++;
3242 
3243  // if this is a layer dimension, remember the amount of layers
3244  if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
3245  }
3246  _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
3247  }
3248  for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3249 
3250  // if there's a velocity dimension and custom velocity zone splits are used,
3251  // update the VelocityTables in the dimension regions
3252  UpdateVelocityTable();
3253 
3254  // jump to start of the wave pool indices (if not already there)
3255  if (file->pVersion && file->pVersion->major == 3)
3256  _3lnk->SetPos(68); // version 3 has a different 3lnk structure
3257  else
3258  _3lnk->SetPos(44);
3259 
3260  // load sample references (if auto loading is enabled)
3261  if (file->GetAutoLoad()) {
3262  for (uint i = 0; i < DimensionRegions; i++) {
3263  uint32_t wavepoolindex = _3lnk->ReadUint32();
3264  if (file->pWavePoolTable && pDimensionRegions[i])
3265  pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3266  }
3267  GetSample(); // load global region sample reference
3268  }
3269  } else {
3270  DimensionRegions = 0;
3271  for (int i = 0 ; i < 8 ; i++) {
3272  pDimensionDefinitions[i].dimension = dimension_none;
3273  pDimensionDefinitions[i].bits = 0;
3274  pDimensionDefinitions[i].zones = 0;
3275  }
3276  }
3277 
3278  // make sure there is at least one dimension region
3279  if (!DimensionRegions) {
3280  RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
3281  if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
3282  RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
3283  pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
3284  DimensionRegions = 1;
3285  }
3286  }
3287 
3299  // in the gig format we don't care about the Region's sample reference
3300  // but we still have to provide some existing one to not corrupt the
3301  // file, so to avoid the latter we simply always assign the sample of
3302  // the first dimension region of this region
3303  pSample = pDimensionRegions[0]->pSample;
3304 
3305  // first update base class's chunks
3306  DLS::Region::UpdateChunks(pProgress);
3307 
3308  // update dimension region's chunks
3309  for (int i = 0; i < DimensionRegions; i++) {
3310  pDimensionRegions[i]->UpdateChunks(pProgress);
3311  }
3312 
3313  File* pFile = (File*) GetParent()->GetParent();
3314  bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
3315  const int iMaxDimensions = version3 ? 8 : 5;
3316  const int iMaxDimensionRegions = version3 ? 256 : 32;
3317 
3318  // make sure '3lnk' chunk exists
3319  RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3320  if (!_3lnk) {
3321  const int _3lnkChunkSize = version3 ? 1092 : 172;
3322  _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3323  memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3324 
3325  // move 3prg to last position
3326  pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (RIFF::Chunk*)NULL);
3327  }
3328 
3329  // update dimension definitions in '3lnk' chunk
3330  uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3331  store32(&pData[0], DimensionRegions);
3332  int shift = 0;
3333  for (int i = 0; i < iMaxDimensions; i++) {
3334  pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3335  pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3336  pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3337  pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3338  pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3339  // next 3 bytes unknown, always zero?
3340 
3341  shift += pDimensionDefinitions[i].bits;
3342  }
3343 
3344  // update wave pool table in '3lnk' chunk
3345  const int iWavePoolOffset = version3 ? 68 : 44;
3346  for (uint i = 0; i < iMaxDimensionRegions; i++) {
3347  int iWaveIndex = -1;
3348  if (i < DimensionRegions) {
3349  if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
3350  File::SampleList::iterator iter = pFile->pSamples->begin();
3351  File::SampleList::iterator end = pFile->pSamples->end();
3352  for (int index = 0; iter != end; ++iter, ++index) {
3353  if (*iter == pDimensionRegions[i]->pSample) {
3354  iWaveIndex = index;
3355  break;
3356  }
3357  }
3358  }
3359  store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3360  }
3361  }
3362 
3363  void Region::LoadDimensionRegions(RIFF::List* rgn) {
3364  RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
3365  if (_3prg) {
3366  int dimensionRegionNr = 0;
3367  RIFF::List* _3ewl = _3prg->GetFirstSubList();
3368  while (_3ewl) {
3369  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3370  pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3371  dimensionRegionNr++;
3372  }
3373  _3ewl = _3prg->GetNextSubList();
3374  }
3375  if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
3376  }
3377  }
3378 
3379  void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3380  // update KeyRange struct and make sure regions are in correct order
3381  DLS::Region::SetKeyRange(Low, High);
3382  // update Region key table for fast lookup
3383  ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3384  }
3385 
3386  void Region::UpdateVelocityTable() {
3387  // get velocity dimension's index
3388  int veldim = -1;
3389  for (int i = 0 ; i < Dimensions ; i++) {
3390  if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3391  veldim = i;
3392  break;
3393  }
3394  }
3395  if (veldim == -1) return;
3396 
3397  int step = 1;
3398  for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3399  int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3400 
3401  // loop through all dimension regions for all dimensions except the velocity dimension
3402  int dim[8] = { 0 };
3403  for (int i = 0 ; i < DimensionRegions ; i++) {
3404  const int end = i + step * pDimensionDefinitions[veldim].zones;
3405 
3406  // create a velocity table for all cases where the velocity zone is zero
3407  if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3408  pDimensionRegions[i]->VelocityUpperLimit) {
3409  // create the velocity table
3410  uint8_t* table = pDimensionRegions[i]->VelocityTable;
3411  if (!table) {
3412  table = new uint8_t[128];
3413  pDimensionRegions[i]->VelocityTable = table;
3414  }
3415  int tableidx = 0;
3416  int velocityZone = 0;
3417  if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
3418  for (int k = i ; k < end ; k += step) {
3419  DimensionRegion *d = pDimensionRegions[k];
3420  for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3421  velocityZone++;
3422  }
3423  } else { // gig2
3424  for (int k = i ; k < end ; k += step) {
3425  DimensionRegion *d = pDimensionRegions[k];
3426  for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3427  velocityZone++;
3428  }
3429  }
3430  } else {
3431  if (pDimensionRegions[i]->VelocityTable) {
3432  delete[] pDimensionRegions[i]->VelocityTable;
3434  }
3435  }
3436 
3437  // jump to the next case where the velocity zone is zero
3438  int j;
3439  int shift = 0;
3440  for (j = 0 ; j < Dimensions ; j++) {
3441  if (j == veldim) i += skipveldim; // skip velocity dimension
3442  else {
3443  dim[j]++;
3444  if (dim[j] < pDimensionDefinitions[j].zones) break;
3445  else {
3446  // skip unused dimension regions
3447  dim[j] = 0;
3448  i += ((1 << pDimensionDefinitions[j].bits) -
3449  pDimensionDefinitions[j].zones) << shift;
3450  }
3451  }
3452  shift += pDimensionDefinitions[j].bits;
3453  }
3454  if (j == Dimensions) break;
3455  }
3456  }
3457 
3474  // some initial sanity checks of the given dimension definition
3475  if (pDimDef->zones < 2)
3476  throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3477  if (pDimDef->bits < 1)
3478  throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3479  if (pDimDef->dimension == dimension_samplechannel) {
3480  if (pDimDef->zones != 2)
3481  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3482  if (pDimDef->bits != 1)
3483  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3484  }
3485 
3486  // check if max. amount of dimensions reached
3487  File* file = (File*) GetParent()->GetParent();
3488  const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
3489  if (Dimensions >= iMaxDimensions)
3490  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
3491  // check if max. amount of dimension bits reached
3492  int iCurrentBits = 0;
3493  for (int i = 0; i < Dimensions; i++)
3494  iCurrentBits += pDimensionDefinitions[i].bits;
3495  if (iCurrentBits >= iMaxDimensions)
3496  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
3497  const int iNewBits = iCurrentBits + pDimDef->bits;
3498  if (iNewBits > iMaxDimensions)
3499  throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
3500  // check if there's already a dimensions of the same type
3501  for (int i = 0; i < Dimensions; i++)
3502  if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3503  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3504 
3505  // pos is where the new dimension should be placed, normally
3506  // last in list, except for the samplechannel dimension which
3507  // has to be first in list
3508  int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3509  int bitpos = 0;
3510  for (int i = 0 ; i < pos ; i++)
3511  bitpos += pDimensionDefinitions[i].bits;
3512 
3513  // make room for the new dimension
3514  for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3515  for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3516  for (int j = Dimensions ; j > pos ; j--) {
3519  }
3520  }
3521 
3522  // assign definition of new dimension
3523  pDimensionDefinitions[pos] = *pDimDef;
3524 
3525  // auto correct certain dimension definition fields (where possible)
3527  __resolveSplitType(pDimensionDefinitions[pos].dimension);
3529  __resolveZoneSize(pDimensionDefinitions[pos]);
3530 
3531  // create new dimension region(s) for this new dimension, and make
3532  // sure that the dimension regions are placed correctly in both the
3533  // RIFF list and the pDimensionRegions array
3534  RIFF::Chunk* moveTo = NULL;
3535  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3536  for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3537  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3538  pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3539  }
3540  for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3541  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3542  RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3543  if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3544  // create a new dimension region and copy all parameter values from
3545  // an existing dimension region
3546  pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3547  new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3548 
3549  DimensionRegions++;
3550  }
3551  }
3552  moveTo = pDimensionRegions[i]->pParentList;
3553  }
3554 
3555  // initialize the upper limits for this dimension
3556  int mask = (1 << bitpos) - 1;
3557  for (int z = 0 ; z < pDimDef->zones ; z++) {
3558  uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3559  for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3560  pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3561  (z << bitpos) |
3562  (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3563  }
3564  }
3565 
3566  Dimensions++;
3567 
3568  // if this is a layer dimension, update 'Layers' attribute
3569  if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
3570 
3571  UpdateVelocityTable();
3572  }
3573 
3586  // get dimension's index
3587  int iDimensionNr = -1;
3588  for (int i = 0; i < Dimensions; i++) {
3589  if (&pDimensionDefinitions[i] == pDimDef) {
3590  iDimensionNr = i;
3591  break;
3592  }
3593  }
3594  if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
3595 
3596  // get amount of bits below the dimension to delete
3597  int iLowerBits = 0;
3598  for (int i = 0; i < iDimensionNr; i++)
3599  iLowerBits += pDimensionDefinitions[i].bits;
3600 
3601  // get amount ot bits above the dimension to delete
3602  int iUpperBits = 0;
3603  for (int i = iDimensionNr + 1; i < Dimensions; i++)
3604  iUpperBits += pDimensionDefinitions[i].bits;
3605 
3606  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3607 
3608  // delete dimension regions which belong to the given dimension
3609  // (that is where the dimension's bit > 0)
3610  for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3611  for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3612  for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3613  int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3614  iObsoleteBit << iLowerBits |
3615  iLowerBit;
3616 
3617  _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3618  delete pDimensionRegions[iToDelete];
3619  pDimensionRegions[iToDelete] = NULL;
3620  DimensionRegions--;
3621  }
3622  }
3623  }
3624 
3625  // defrag pDimensionRegions array
3626  // (that is remove the NULL spaces within the pDimensionRegions array)
3627  for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3628  if (!pDimensionRegions[iTo]) {
3629  if (iFrom <= iTo) iFrom = iTo + 1;
3630  while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3631  if (iFrom < 256 && pDimensionRegions[iFrom]) {
3632  pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3633  pDimensionRegions[iFrom] = NULL;
3634  }
3635  }
3636  }
3637 
3638  // remove the this dimension from the upper limits arrays
3639  for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3641  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3642  d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3643  }
3644  d->DimensionUpperLimits[Dimensions - 1] = 127;
3645  }
3646 
3647  // 'remove' dimension definition
3648  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3650  }
3654 
3655  Dimensions--;
3656 
3657  // if this was a layer dimension, update 'Layers' attribute
3658  if (pDimDef->dimension == dimension_layer) Layers = 1;
3659  }
3660 
3675  void Region::DeleteDimensionZone(dimension_t type, int zone) {
3676  dimension_def_t* oldDef = GetDimensionDefinition(type);
3677  if (!oldDef)
3678  throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3679  if (oldDef->zones <= 2)
3680  throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3681  if (zone < 0 || zone >= oldDef->zones)
3682  throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3683 
3684  const int newZoneSize = oldDef->zones - 1;
3685 
3686  // create a temporary Region which just acts as a temporary copy
3687  // container and will be deleted at the end of this function and will
3688  // also not be visible through the API during this process
3689  gig::Region* tempRgn = NULL;
3690  {
3691  // adding these temporary chunks is probably not even necessary
3692  Instrument* instr = static_cast<Instrument*>(GetParent());
3693  RIFF::List* pCkInstrument = instr->pCkInstrument;
3694  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3695  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3696  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3697  tempRgn = new Region(instr, rgn);
3698  }
3699 
3700  // copy this region's dimensions (with already the dimension split size
3701  // requested by the arguments of this method call) to the temporary
3702  // region, and don't use Region::CopyAssign() here for this task, since
3703  // it would also alter fast lookup helper variables here and there
3704  dimension_def_t newDef;
3705  for (int i = 0; i < Dimensions; ++i) {
3706  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3707  // is this the dimension requested by the method arguments? ...
3708  if (def.dimension == type) { // ... if yes, decrement zone amount by one
3709  def.zones = newZoneSize;
3710  if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3711  newDef = def;
3712  }
3713  tempRgn->AddDimension(&def);
3714  }
3715 
3716  // find the dimension index in the tempRegion which is the dimension
3717  // type passed to this method (paranoidly expecting different order)
3718  int tempReducedDimensionIndex = -1;
3719  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3720  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3721  tempReducedDimensionIndex = d;
3722  break;
3723  }
3724  }
3725 
3726  // copy dimension regions from this region to the temporary region
3727  for (int iDst = 0; iDst < 256; ++iDst) {
3728  DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3729  if (!dstDimRgn) continue;
3730  std::map<dimension_t,int> dimCase;
3731  bool isValidZone = true;
3732  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3733  const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3734  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3735  (iDst >> baseBits) & ((1 << dstBits) - 1);
3736  baseBits += dstBits;
3737  // there are also DimensionRegion objects of unused zones, skip them
3738  if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3739  isValidZone = false;
3740  break;
3741  }
3742  }
3743  if (!isValidZone) continue;
3744  // a bit paranoid: cope with the chance that the dimensions would
3745  // have different order in source and destination regions
3746  const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3747  if (dimCase[type] >= zone) dimCase[type]++;
3748  DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3749  dstDimRgn->CopyAssign(srcDimRgn);
3750  // if this is the upper most zone of the dimension passed to this
3751  // method, then correct (raise) its upper limit to 127
3752  if (newDef.split_type == split_type_normal && isLastZone)
3753  dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3754  }
3755 
3756  // now tempRegion's dimensions and DimensionRegions basically reflect
3757  // what we wanted to get for this actual Region here, so we now just
3758  // delete and recreate the dimension in question with the new amount
3759  // zones and then copy back from tempRegion
3760  DeleteDimension(oldDef);
3761  AddDimension(&newDef);
3762  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3763  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3764  if (!srcDimRgn) continue;
3765  std::map<dimension_t,int> dimCase;
3766  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3767  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3768  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3769  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3770  baseBits += srcBits;
3771  }
3772  // a bit paranoid: cope with the chance that the dimensions would
3773  // have different order in source and destination regions
3774  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3775  if (!dstDimRgn) continue;
3776  dstDimRgn->CopyAssign(srcDimRgn);
3777  }
3778 
3779  // delete temporary region
3780  delete tempRgn;
3781 
3782  UpdateVelocityTable();
3783  }
3784 
3799  void Region::SplitDimensionZone(dimension_t type, int zone) {
3800  dimension_def_t* oldDef = GetDimensionDefinition(type);
3801  if (!oldDef)
3802  throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3803  if (zone < 0 || zone >= oldDef->zones)
3804  throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3805 
3806  const int newZoneSize = oldDef->zones + 1;
3807 
3808  // create a temporary Region which just acts as a temporary copy
3809  // container and will be deleted at the end of this function and will
3810  // also not be visible through the API during this process
3811  gig::Region* tempRgn = NULL;
3812  {
3813  // adding these temporary chunks is probably not even necessary
3814  Instrument* instr = static_cast<Instrument*>(GetParent());
3815  RIFF::List* pCkInstrument = instr->pCkInstrument;
3816  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3817  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3818  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3819  tempRgn = new Region(instr, rgn);
3820  }
3821 
3822  // copy this region's dimensions (with already the dimension split size
3823  // requested by the arguments of this method call) to the temporary
3824  // region, and don't use Region::CopyAssign() here for this task, since
3825  // it would also alter fast lookup helper variables here and there
3826  dimension_def_t newDef;
3827  for (int i = 0; i < Dimensions; ++i) {
3828  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3829  // is this the dimension requested by the method arguments? ...
3830  if (def.dimension == type) { // ... if yes, increment zone amount by one
3831  def.zones = newZoneSize;
3832  if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3833  newDef = def;
3834  }
3835  tempRgn->AddDimension(&def);
3836  }
3837 
3838  // find the dimension index in the tempRegion which is the dimension
3839  // type passed to this method (paranoidly expecting different order)
3840  int tempIncreasedDimensionIndex = -1;
3841  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3842  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3843  tempIncreasedDimensionIndex = d;
3844  break;
3845  }
3846  }
3847 
3848  // copy dimension regions from this region to the temporary region
3849  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3850  DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
3851  if (!srcDimRgn) continue;
3852  std::map<dimension_t,int> dimCase;
3853  bool isValidZone = true;
3854  for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
3855  const int srcBits = pDimensionDefinitions[d].bits;
3856  dimCase[pDimensionDefinitions[d].dimension] =
3857  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3858  // there are also DimensionRegion objects for unused zones, skip them
3859  if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
3860  isValidZone = false;
3861  break;
3862  }
3863  baseBits += srcBits;
3864  }
3865  if (!isValidZone) continue;
3866  // a bit paranoid: cope with the chance that the dimensions would
3867  // have different order in source and destination regions
3868  if (dimCase[type] > zone) dimCase[type]++;
3869  DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3870  dstDimRgn->CopyAssign(srcDimRgn);
3871  // if this is the requested zone to be splitted, then also copy
3872  // the source DimensionRegion to the newly created target zone
3873  // and set the old zones upper limit lower
3874  if (dimCase[type] == zone) {
3875  // lower old zones upper limit
3876  if (newDef.split_type == split_type_normal) {
3877  const int high =
3878  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
3879  int low = 0;
3880  if (zone > 0) {
3881  std::map<dimension_t,int> lowerCase = dimCase;
3882  lowerCase[type]--;
3883  DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
3884  low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
3885  }
3886  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
3887  }
3888  // fill the newly created zone of the divided zone as well
3889  dimCase[type]++;
3890  dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3891  dstDimRgn->CopyAssign(srcDimRgn);
3892  }
3893  }
3894 
3895  // now tempRegion's dimensions and DimensionRegions basically reflect
3896  // what we wanted to get for this actual Region here, so we now just
3897  // delete and recreate the dimension in question with the new amount
3898  // zones and then copy back from tempRegion
3899  DeleteDimension(oldDef);
3900  AddDimension(&newDef);
3901  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3902  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3903  if (!srcDimRgn) continue;
3904  std::map<dimension_t,int> dimCase;
3905  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3906  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3907  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3908  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3909  baseBits += srcBits;
3910  }
3911  // a bit paranoid: cope with the chance that the dimensions would
3912  // have different order in source and destination regions
3913  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3914  if (!dstDimRgn) continue;
3915  dstDimRgn->CopyAssign(srcDimRgn);
3916  }
3917 
3918  // delete temporary region
3919  delete tempRgn;
3920 
3921  UpdateVelocityTable();
3922  }
3923 
3938  void Region::SetDimensionType(dimension_t oldType, dimension_t newType) {
3939  if (oldType == newType) return;
3940  dimension_def_t* def = GetDimensionDefinition(oldType);
3941  if (!def)
3942  throw gig::Exception("No dimension with provided old dimension type exists on this region");
3943  if (newType == dimension_samplechannel && def->zones != 2)
3944  throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
3945  if (GetDimensionDefinition(newType))
3946  throw gig::Exception("There is already a dimension with requested new dimension type on this region");
3947  def->dimension = newType;
3948  def->split_type = __resolveSplitType(newType);
3949  }
3950 
3951  DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
3952  uint8_t bits[8] = {};
3953  for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3954  it != DimCase.end(); ++it)
3955  {
3956  for (int d = 0; d < Dimensions; ++d) {
3957  if (pDimensionDefinitions[d].dimension == it->first) {
3958  bits[d] = it->second;
3959  goto nextDimCaseSlice;
3960  }
3961  }
3962  assert(false); // do crash ... too harsh maybe ? ignore it instead ?
3963  nextDimCaseSlice:
3964  ; // noop
3965  }
3966  return GetDimensionRegionByBit(bits);
3967  }
3968 
3979  for (int i = 0; i < Dimensions; ++i)
3980  if (pDimensionDefinitions[i].dimension == type)
3981  return &pDimensionDefinitions[i];
3982  return NULL;
3983  }
3984 
3986  for (int i = 0; i < 256; i++) {
3987  if (pDimensionRegions[i]) delete pDimensionRegions[i];
3988  }
3989  }
3990 
4010  uint8_t bits;
4011  int veldim = -1;
4012  int velbitpos = 0;
4013  int bitpos = 0;
4014  int dimregidx = 0;
4015  for (uint i = 0; i < Dimensions; i++) {
4016  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4017  // the velocity dimension must be handled after the other dimensions
4018  veldim = i;
4019  velbitpos = bitpos;
4020  } else {
4021  switch (pDimensionDefinitions[i].split_type) {
4022  case split_type_normal:
4023  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4024  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4025  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4026  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4027  }
4028  } else {
4029  // gig2: evenly sized zones
4030  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4031  }
4032  break;
4033  case split_type_bit: // the value is already the sought dimension bit number
4034  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4035  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4036  break;
4037  }
4038  dimregidx |= bits << bitpos;
4039  }
4040  bitpos += pDimensionDefinitions[i].bits;
4041  }
4042  DimensionRegion* dimreg = pDimensionRegions[dimregidx & 255];
4043  if (!dimreg) return NULL;
4044  if (veldim != -1) {
4045  // (dimreg is now the dimension region for the lowest velocity)
4046  if (dimreg->VelocityTable) // custom defined zone ranges
4047  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4048  else // normal split type
4049  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4050 
4051  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4052  dimregidx |= (bits & limiter_mask) << velbitpos;
4053  dimreg = pDimensionRegions[dimregidx & 255];
4054  }
4055  return dimreg;
4056  }
4057 
4058  int Region::GetDimensionRegionIndexByValue(const uint DimValues[8]) {
4059  uint8_t bits;
4060  int veldim = -1;
4061  int velbitpos = 0;
4062  int bitpos = 0;
4063  int dimregidx = 0;
4064  for (uint i = 0; i < Dimensions; i++) {
4065  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4066  // the velocity dimension must be handled after the other dimensions
4067  veldim = i;
4068  velbitpos = bitpos;
4069  } else {
4070  switch (pDimensionDefinitions[i].split_type) {
4071  case split_type_normal:
4072  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4073  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4074  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4075  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4076  }
4077  } else {
4078  // gig2: evenly sized zones
4079  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4080  }
4081  break;
4082  case split_type_bit: // the value is already the sought dimension bit number
4083  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4084  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4085  break;
4086  }
4087  dimregidx |= bits << bitpos;
4088  }
4089  bitpos += pDimensionDefinitions[i].bits;
4090  }
4091  dimregidx &= 255;
4092  DimensionRegion* dimreg = pDimensionRegions[dimregidx];
4093  if (!dimreg) return -1;
4094  if (veldim != -1) {
4095  // (dimreg is now the dimension region for the lowest velocity)
4096  if (dimreg->VelocityTable) // custom defined zone ranges
4097  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4098  else // normal split type
4099  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4100 
4101  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4102  dimregidx |= (bits & limiter_mask) << velbitpos;
4103  dimregidx &= 255;
4104  }
4105  return dimregidx;
4106  }
4107 
4119  return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4120  << pDimensionDefinitions[5].bits | DimBits[5])
4121  << pDimensionDefinitions[4].bits | DimBits[4])
4122  << pDimensionDefinitions[3].bits | DimBits[3])
4123  << pDimensionDefinitions[2].bits | DimBits[2])
4124  << pDimensionDefinitions[1].bits | DimBits[1])
4125  << pDimensionDefinitions[0].bits | DimBits[0]];
4126  }
4127 
4138  if (pSample) return static_cast<gig::Sample*>(pSample);
4139  else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4140  }
4141 
4142  Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
4143  if ((int32_t)WavePoolTableIndex == -1) return NULL;
4144  File* file = (File*) GetParent()->GetParent();
4145  if (!file->pWavePoolTable) return NULL;
4146  if (WavePoolTableIndex + 1 > file->WavePoolCount) return NULL;
4147  // for new files or files >= 2 GB use 64 bit wave pool offsets
4148  if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
4149  // use 64 bit wave pool offsets (treating this as large file)
4150  uint64_t soughtoffset =
4151  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4152  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4153  Sample* sample = file->GetFirstSample(pProgress);
4154  while (sample) {
4155  if (sample->ullWavePoolOffset == soughtoffset)
4156  return static_cast<gig::Sample*>(sample);
4157  sample = file->GetNextSample();
4158  }
4159  } else {
4160  // use extension files and 32 bit wave pool offsets
4161  file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4162  file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4163  Sample* sample = file->GetFirstSample(pProgress);
4164  while (sample) {
4165  if (sample->ullWavePoolOffset == soughtoffset &&
4166  sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
4167  sample = file->GetNextSample();
4168  }
4169  }
4170  return NULL;
4171  }
4172 
4182  void Region::CopyAssign(const Region* orig) {
4183  CopyAssign(orig, NULL);
4184  }
4185 
4193  void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
4194  // handle base classes
4196 
4197  if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
4198  pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
4199  }
4200 
4201  // handle own member variables
4202  for (int i = Dimensions - 1; i >= 0; --i) {
4204  }
4205  Layers = 0; // just to be sure
4206  for (int i = 0; i < orig->Dimensions; i++) {
4207  // we need to copy the dim definition here, to avoid the compiler
4208  // complaining about const-ness issue
4209  dimension_def_t def = orig->pDimensionDefinitions[i];
4210  AddDimension(&def);
4211  }
4212  for (int i = 0; i < 256; i++) {
4213  if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
4215  orig->pDimensionRegions[i],
4216  mSamples
4217  );
4218  }
4219  }
4220  Layers = orig->Layers;
4221  }
4222 
4223 
4224 // *************** MidiRule ***************
4225 // *
4226 
4227  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
4228  _3ewg->SetPos(36);
4229  Triggers = _3ewg->ReadUint8();
4230  _3ewg->SetPos(40);
4231  ControllerNumber = _3ewg->ReadUint8();
4232  _3ewg->SetPos(46);
4233  for (int i = 0 ; i < Triggers ; i++) {
4234  pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
4235  pTriggers[i].Descending = _3ewg->ReadUint8();
4236  pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
4237  pTriggers[i].Key = _3ewg->ReadUint8();
4238  pTriggers[i].NoteOff = _3ewg->ReadUint8();
4239  pTriggers[i].Velocity = _3ewg->ReadUint8();
4240  pTriggers[i].OverridePedal = _3ewg->ReadUint8();
4241  _3ewg->ReadUint8();
4242  }
4243  }
4244 
4245  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4246  ControllerNumber(0),
4247  Triggers(0) {
4248  }
4249 
4250  void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
4251  pData[32] = 4;
4252  pData[33] = 16;
4253  pData[36] = Triggers;
4254  pData[40] = ControllerNumber;
4255  for (int i = 0 ; i < Triggers ; i++) {
4256  pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4257  pData[47 + i * 8] = pTriggers[i].Descending;
4258  pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4259  pData[49 + i * 8] = pTriggers[i].Key;
4260  pData[50 + i * 8] = pTriggers[i].NoteOff;
4261  pData[51 + i * 8] = pTriggers[i].Velocity;
4262  pData[52 + i * 8] = pTriggers[i].OverridePedal;
4263  }
4264  }
4265 
4266  MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
4267  _3ewg->SetPos(36);
4268  LegatoSamples = _3ewg->ReadUint8(); // always 12
4269  _3ewg->SetPos(40);
4270  BypassUseController = _3ewg->ReadUint8();
4271  BypassKey = _3ewg->ReadUint8();
4272  BypassController = _3ewg->ReadUint8();
4273  ThresholdTime = _3ewg->ReadUint16();
4274  _3ewg->ReadInt16();
4275  ReleaseTime = _3ewg->ReadUint16();
4276  _3ewg->ReadInt16();
4277  KeyRange.low = _3ewg->ReadUint8();
4278  KeyRange.high = _3ewg->ReadUint8();
4279  _3ewg->SetPos(64);
4280  ReleaseTriggerKey = _3ewg->ReadUint8();
4281  AltSustain1Key = _3ewg->ReadUint8();
4282  AltSustain2Key = _3ewg->ReadUint8();
4283  }
4284 
4285  MidiRuleLegato::MidiRuleLegato() :
4286  LegatoSamples(12),
4287  BypassUseController(false),
4288  BypassKey(0),
4289  BypassController(1),
4290  ThresholdTime(20),
4291  ReleaseTime(20),
4292  ReleaseTriggerKey(0),
4293  AltSustain1Key(0),
4294  AltSustain2Key(0)
4295  {
4296  KeyRange.low = KeyRange.high = 0;
4297  }
4298 
4299  void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
4300  pData[32] = 0;
4301  pData[33] = 16;
4302  pData[36] = LegatoSamples;
4303  pData[40] = BypassUseController;
4304  pData[41] = BypassKey;
4305  pData[42] = BypassController;
4306  store16(&pData[43], ThresholdTime);
4307  store16(&pData[47], ReleaseTime);
4308  pData[51] = KeyRange.low;
4309  pData[52] = KeyRange.high;
4310  pData[64] = ReleaseTriggerKey;
4311  pData[65] = AltSustain1Key;
4312  pData[66] = AltSustain2Key;
4313  }
4314 
4315  MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
4316  _3ewg->SetPos(36);
4317  Articulations = _3ewg->ReadUint8();
4318  int flags = _3ewg->ReadUint8();
4319  Polyphonic = flags & 8;
4320  Chained = flags & 4;
4321  Selector = (flags & 2) ? selector_controller :
4322  (flags & 1) ? selector_key_switch : selector_none;
4323  Patterns = _3ewg->ReadUint8();
4324  _3ewg->ReadUint8(); // chosen row
4325  _3ewg->ReadUint8(); // unknown
4326  _3ewg->ReadUint8(); // unknown
4327  _3ewg->ReadUint8(); // unknown
4328  KeySwitchRange.low = _3ewg->ReadUint8();
4329  KeySwitchRange.high = _3ewg->ReadUint8();
4330  Controller = _3ewg->ReadUint8();
4331  PlayRange.low = _3ewg->ReadUint8();
4332  PlayRange.high = _3ewg->ReadUint8();
4333 
4334  int n = std::min(int(Articulations), 32);
4335  for (int i = 0 ; i < n ; i++) {
4336  _3ewg->ReadString(pArticulations[i], 32);
4337  }
4338  _3ewg->SetPos(1072);
4339  n = std::min(int(Patterns), 32);
4340  for (int i = 0 ; i < n ; i++) {
4341  _3ewg->ReadString(pPatterns[i].Name, 16);
4342  pPatterns[i].Size = _3ewg->ReadUint8();
4343  _3ewg->Read(&pPatterns[i][0], 1, 32);
4344  }
4345  }
4346 
4347  MidiRuleAlternator::MidiRuleAlternator() :
4348  Articulations(0),
4349  Patterns(0),
4350  Selector(selector_none),
4351  Controller(0),
4352  Polyphonic(false),
4353  Chained(false)
4354  {
4355  PlayRange.low = PlayRange.high = 0;
4356  KeySwitchRange.low = KeySwitchRange.high = 0;
4357  }
4358 
4359  void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
4360  pData[32] = 3;
4361  pData[33] = 16;
4362  pData[36] = Articulations;
4363  pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4364  (Selector == selector_controller ? 2 :
4365  (Selector == selector_key_switch ? 1 : 0));
4366  pData[38] = Patterns;
4367 
4368  pData[43] = KeySwitchRange.low;
4369  pData[44] = KeySwitchRange.high;
4370  pData[45] = Controller;
4371  pData[46] = PlayRange.low;
4372  pData[47] = PlayRange.high;
4373 
4374  char* str = reinterpret_cast<char*>(pData);
4375  int pos = 48;
4376  int n = std::min(int(Articulations), 32);
4377  for (int i = 0 ; i < n ; i++, pos += 32) {
4378  strncpy(&str[pos], pArticulations[i].c_str(), 32);
4379  }
4380 
4381  pos = 1072;
4382  n = std::min(int(Patterns), 32);
4383  for (int i = 0 ; i < n ; i++, pos += 49) {
4384  strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4385  pData[pos + 16] = pPatterns[i].Size;
4386  memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4387  }
4388  }
4389 
4390 // *************** Script ***************
4391 // *
4392 
4393  Script::Script(ScriptGroup* group, RIFF::Chunk* ckScri) {
4394  pGroup = group;
4395  pChunk = ckScri;
4396  if (ckScri) { // object is loaded from file ...
4397  // read header
4398  uint32_t headerSize = ckScri->ReadUint32();
4399  Compression = (Compression_t) ckScri->ReadUint32();
4400  Encoding = (Encoding_t) ckScri->ReadUint32();
4401  Language = (Language_t) ckScri->ReadUint32();
4402  Bypass = (Language_t) ckScri->ReadUint32() & 1;
4403  crc = ckScri->ReadUint32();
4404  uint32_t nameSize = ckScri->ReadUint32();
4405  Name.resize(nameSize, ' ');
4406  for (int i = 0; i < nameSize; ++i)
4407  Name[i] = ckScri->ReadUint8();
4408  // to handle potential future extensions of the header
4409  ckScri->SetPos(sizeof(int32_t) + headerSize);
4410  // read actual script data
4411  uint32_t scriptSize = uint32_t(ckScri->GetSize() - ckScri->GetPos());
4412  data.resize(scriptSize);
4413  for (int i = 0; i < scriptSize; ++i)
4414  data[i] = ckScri->ReadUint8();
4415  } else { // this is a new script object, so just initialize it as such ...
4419  Bypass = false;
4420  crc = 0;
4421  Name = "Unnamed Script";
4422  }
4423  }
4424 
4425  Script::~Script() {
4426  }
4427 
4432  String s;
4433  s.resize(data.size(), ' ');
4434  memcpy(&s[0], &data[0], data.size());
4435  return s;
4436  }
4437 
4444  void Script::SetScriptAsText(const String& text) {
4445  data.resize(text.size());
4446  memcpy(&data[0], &text[0], text.size());
4447  }
4448 
4459  // recalculate CRC32 check sum
4460  __resetCRC(crc);
4461  __calculateCRC(&data[0], data.size(), crc);
4462  __finalizeCRC(crc);
4463  // make sure chunk exists and has the required size
4464  const file_offset_t chunkSize = (file_offset_t) 7*sizeof(int32_t) + Name.size() + data.size();
4465  if (!pChunk) pChunk = pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4466  else pChunk->Resize(chunkSize);
4467  // fill the chunk data to be written to disk
4468  uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4469  int pos = 0;
4470  store32(&pData[pos], uint32_t(6*sizeof(int32_t) + Name.size())); // total header size
4471  pos += sizeof(int32_t);
4472  store32(&pData[pos], Compression);
4473  pos += sizeof(int32_t);
4474  store32(&pData[pos], Encoding);
4475  pos += sizeof(int32_t);
4476  store32(&pData[pos], Language);
4477  pos += sizeof(int32_t);
4478  store32(&pData[pos], Bypass ? 1 : 0);
4479  pos += sizeof(int32_t);
4480  store32(&pData[pos], crc);
4481  pos += sizeof(int32_t);
4482  store32(&pData[pos], (uint32_t) Name.size());
4483  pos += sizeof(int32_t);
4484  for (int i = 0; i < Name.size(); ++i, ++pos)
4485  pData[pos] = Name[i];
4486  for (int i = 0; i < data.size(); ++i, ++pos)
4487  pData[pos] = data[i];
4488  }
4489 
4497  if (this->pGroup == pGroup) return;
4498  if (pChunk)
4499  pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4500  this->pGroup = pGroup;
4501  }
4502 
4510  return pGroup;
4511  }
4512 
4520  void Script::CopyAssign(const Script* orig) {
4521  Name = orig->Name;
4522  Compression = orig->Compression;
4523  Encoding = orig->Encoding;
4524  Language = orig->Language;
4525  Bypass = orig->Bypass;
4526  data = orig->data;
4527  }
4528 
4529  void Script::RemoveAllScriptReferences() {
4530  File* pFile = pGroup->pFile;
4531  for (int i = 0; pFile->GetInstrument(i); ++i) {
4532  Instrument* instr = pFile->GetInstrument(i);
4533  instr->RemoveScript(this);
4534  }
4535  }
4536 
4537 // *************** ScriptGroup ***************
4538 // *
4539 
4540  ScriptGroup::ScriptGroup(File* file, RIFF::List* lstRTIS) {
4541  pFile = file;
4542  pList = lstRTIS;
4543  pScripts = NULL;
4544  if (lstRTIS) {
4545  RIFF::Chunk* ckName = lstRTIS->GetSubChunk(CHUNK_ID_LSNM);
4546  ::LoadString(ckName, Name);
4547  } else {
4548  Name = "Default Group";
4549  }
4550  }
4551 
4552  ScriptGroup::~ScriptGroup() {
4553  if (pScripts) {
4554  std::list<Script*>::iterator iter = pScripts->begin();
4555  std::list<Script*>::iterator end = pScripts->end();
4556  while (iter != end) {
4557  delete *iter;
4558  ++iter;
4559  }
4560  delete pScripts;
4561  }
4562  }
4563 
4574  if (pScripts) {
4575  if (!pList)
4576  pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4577 
4578  // now store the name of this group as <LSNM> chunk as subchunk of the <RTIS> list chunk
4579  ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String("Unnamed Group"), true, 64);
4580 
4581  for (std::list<Script*>::iterator it = pScripts->begin();
4582  it != pScripts->end(); ++it)
4583  {
4584  (*it)->UpdateChunks(pProgress);
4585  }
4586  }
4587  }
4588 
4597  if (!pScripts) LoadScripts();
4598  std::list<Script*>::iterator it = pScripts->begin();
4599  for (uint i = 0; it != pScripts->end(); ++i, ++it)
4600  if (i == index) return *it;
4601  return NULL;
4602  }
4603 
4616  if (!pScripts) LoadScripts();
4617  Script* pScript = new Script(this, NULL);
4618  pScripts->push_back(pScript);
4619  return pScript;
4620  }
4621 
4633  if (!pScripts) LoadScripts();
4634  std::list<Script*>::iterator iter =
4635  find(pScripts->begin(), pScripts->end(), pScript);
4636  if (iter == pScripts->end())
4637  throw gig::Exception("Could not delete script, could not find given script");
4638  pScripts->erase(iter);
4639  pScript->RemoveAllScriptReferences();
4640  if (pScript->pChunk)
4641  pScript->pChunk->GetParent()->DeleteSubChunk(pScript->pChunk);
4642  delete pScript;
4643  }
4644 
4645  void ScriptGroup::LoadScripts() {
4646  if (pScripts) return;
4647  pScripts = new std::list<Script*>;
4648  if (!pList) return;
4649 
4650  for (RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4651  ck = pList->GetNextSubChunk())
4652  {
4653  if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4654  pScripts->push_back(new Script(this, ck));
4655  }
4656  }
4657  }
4658 
4659 // *************** Instrument ***************
4660 // *
4661 
4662  Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
4663  static const DLS::Info::string_length_t fixedStringLengths[] = {
4664  { CHUNK_ID_INAM, 64 },
4665  { CHUNK_ID_ISFT, 12 },
4666  { 0, 0 }
4667  };
4668  pInfo->SetFixedStringLengths(fixedStringLengths);
4669 
4670  // Initialization
4671  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4672  EffectSend = 0;
4673  Attenuation = 0;
4674  FineTune = 0;
4675  PitchbendRange = 2;
4676  PianoReleaseMode = false;
4677  DimensionKeyRange.low = 0;
4678  DimensionKeyRange.high = 0;
4679  pMidiRules = new MidiRule*[3];
4680  pMidiRules[0] = NULL;
4681  pScriptRefs = NULL;
4682 
4683  // Loading
4684  RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
4685  if (lart) {
4686  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4687  if (_3ewg) {
4688  EffectSend = _3ewg->ReadUint16();
4689  Attenuation = _3ewg->ReadInt32();
4690  FineTune = _3ewg->ReadInt16();
4691  PitchbendRange = _3ewg->ReadInt16();
4692  uint8_t dimkeystart = _3ewg->ReadUint8();
4693  PianoReleaseMode = dimkeystart & 0x01;
4694  DimensionKeyRange.low = dimkeystart >> 1;
4695  DimensionKeyRange.high = _3ewg->ReadUint8();
4696 
4697  if (_3ewg->GetSize() > 32) {
4698  // read MIDI rules
4699  int i = 0;
4700  _3ewg->SetPos(32);
4701  uint8_t id1 = _3ewg->ReadUint8();
4702  uint8_t id2 = _3ewg->ReadUint8();
4703 
4704  if (id2 == 16) {
4705  if (id1 == 4) {
4706  pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4707  } else if (id1 == 0) {
4708  pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4709  } else if (id1 == 3) {
4710  pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4711  } else {
4712  pMidiRules[i++] = new MidiRuleUnknown;
4713  }
4714  }
4715  else if (id1 != 0 || id2 != 0) {
4716  pMidiRules[i++] = new MidiRuleUnknown;
4717  }
4718  //TODO: all the other types of rules
4719 
4720  pMidiRules[i] = NULL;
4721  }
4722  }
4723  }
4724 
4725  if (pFile->GetAutoLoad()) {
4726  if (!pRegions) pRegions = new RegionList;
4727  RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
4728  if (lrgn) {
4729  RIFF::List* rgn = lrgn->GetFirstSubList();
4730  while (rgn) {
4731  if (rgn->GetListType() == LIST_TYPE_RGN) {
4732  __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
4733  pRegions->push_back(new Region(this, rgn));
4734  }
4735  rgn = lrgn->GetNextSubList();
4736  }
4737  // Creating Region Key Table for fast lookup
4738  UpdateRegionKeyTable();
4739  }
4740  }
4741 
4742  // own gig format extensions
4743  RIFF::List* lst3LS = insList->GetSubList(LIST_TYPE_3LS);
4744  if (lst3LS) {
4745  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4746  if (ckSCSL) {
4747  int headerSize = ckSCSL->ReadUint32();
4748  int slotCount = ckSCSL->ReadUint32();
4749  if (slotCount) {
4750  int slotSize = ckSCSL->ReadUint32();
4751  ckSCSL->SetPos(headerSize); // in case of future header extensions
4752  int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions
4753  for (int i = 0; i < slotCount; ++i) {
4754  _ScriptPooolEntry e;
4755  e.fileOffset = ckSCSL->ReadUint32();
4756  e.bypass = ckSCSL->ReadUint32() & 1;
4757  if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions
4758  scriptPoolFileOffsets.push_back(e);
4759  }
4760  }
4761  }
4762  }
4763 
4764  __notify_progress(pProgress, 1.0f); // notify done
4765  }
4766 
4767  void Instrument::UpdateRegionKeyTable() {
4768  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4769  RegionList::iterator iter = pRegions->begin();
4770  RegionList::iterator end = pRegions->end();
4771  for (; iter != end; ++iter) {
4772  gig::Region* pRegion = static_cast<gig::Region*>(*iter);
4773  const int low = std::max(int(pRegion->KeyRange.low), 0);
4774  const int high = std::min(int(pRegion->KeyRange.high), 127);
4775  for (int iKey = low; iKey <= high; iKey++) {
4776  RegionKeyTable[iKey] = pRegion;
4777  }
4778  }
4779  }
4780 
4782  for (int i = 0 ; pMidiRules[i] ; i++) {
4783  delete pMidiRules[i];
4784  }
4785  delete[] pMidiRules;
4786  if (pScriptRefs) delete pScriptRefs;
4787  }
4788 
4800  // first update base classes' chunks
4801  DLS::Instrument::UpdateChunks(pProgress);
4802 
4803  // update Regions' chunks
4804  {
4805  RegionList::iterator iter = pRegions->begin();
4806  RegionList::iterator end = pRegions->end();
4807  for (; iter != end; ++iter)
4808  (*iter)->UpdateChunks(pProgress);
4809  }
4810 
4811  // make sure 'lart' RIFF list chunk exists
4812  RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
4813  if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
4814  // make sure '3ewg' RIFF chunk exists
4815  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4816  if (!_3ewg) {
4817  File* pFile = (File*) GetParent();
4818 
4819  // 3ewg is bigger in gig3, as it includes the iMIDI rules
4820  int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
4821  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
4822  memset(_3ewg->LoadChunkData(), 0, size);
4823  }
4824  // update '3ewg' RIFF chunk
4825  uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
4826  store16(&pData[0], EffectSend);
4827  store32(&pData[2], Attenuation);
4828  store16(&pData[6], FineTune);
4829  store16(&pData[8], PitchbendRange);
4830  const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4831  DimensionKeyRange.low << 1;
4832  pData[10] = dimkeystart;
4833  pData[11] = DimensionKeyRange.high;
4834 
4835  if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
4836  pData[32] = 0;
4837  pData[33] = 0;
4838  } else {
4839  for (int i = 0 ; pMidiRules[i] ; i++) {
4840  pMidiRules[i]->UpdateChunks(pData);
4841  }
4842  }
4843 
4844  // own gig format extensions
4845  if (ScriptSlotCount()) {
4846  // make sure we have converted the original loaded script file
4847  // offsets into valid Script object pointers
4848  LoadScripts();
4849 
4850  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4851  if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS);
4852  const int slotCount = (int) pScriptRefs->size();
4853  const int headerSize = 3 * sizeof(uint32_t);
4854  const int slotSize = 2 * sizeof(uint32_t);
4855  const int totalChunkSize = headerSize + slotCount * slotSize;
4856  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4857  if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
4858  else ckSCSL->Resize(totalChunkSize);
4859  uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData();
4860  int pos = 0;
4861  store32(&pData[pos], headerSize);
4862  pos += sizeof(uint32_t);
4863  store32(&pData[pos], slotCount);
4864  pos += sizeof(uint32_t);
4865  store32(&pData[pos], slotSize);
4866  pos += sizeof(uint32_t);
4867  for (int i = 0; i < slotCount; ++i) {
4868  // arbitrary value, the actual file offset will be updated in
4869  // UpdateScriptFileOffsets() after the file has been resized
4870  int bogusFileOffset = 0;
4871  store32(&pData[pos], bogusFileOffset);
4872  pos += sizeof(uint32_t);
4873  store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
4874  pos += sizeof(uint32_t);
4875  }
4876  } else {
4877  // no script slots, so get rid of any LS custom RIFF chunks (if any)
4878  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4879  if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS);
4880  }
4881  }
4882 
4883  void Instrument::UpdateScriptFileOffsets() {
4884  // own gig format extensions
4885  if (pScriptRefs && pScriptRefs->size() > 0) {
4886  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4887  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4888  const int slotCount = (int) pScriptRefs->size();
4889  const int headerSize = 3 * sizeof(uint32_t);
4890  ckSCSL->SetPos(headerSize);
4891  for (int i = 0; i < slotCount; ++i) {
4892  uint32_t fileOffset = uint32_t(
4893  (*pScriptRefs)[i].script->pChunk->GetFilePos() -
4894  (*pScriptRefs)[i].script->pChunk->GetPos() -
4895  CHUNK_HEADER_SIZE(ckSCSL->GetFile()->GetFileOffsetSize())
4896  );
4897  ckSCSL->WriteUint32(&fileOffset);
4898  // jump over flags entry (containing the bypass flag)
4899  ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos);
4900  }
4901  }
4902  }
4903 
4911  Region* Instrument::GetRegion(unsigned int Key) {
4912  if (!pRegions || pRegions->empty() || Key > 127) return NULL;
4913  return RegionKeyTable[Key];
4914 
4915  /*for (int i = 0; i < Regions; i++) {
4916  if (Key <= pRegions[i]->KeyRange.high &&
4917  Key >= pRegions[i]->KeyRange.low) return pRegions[i];
4918  }
4919  return NULL;*/
4920  }
4921 
4930  if (!pRegions) return NULL;
4931  RegionsIterator = pRegions->begin();
4932  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4933  }
4934 
4944  if (!pRegions) return NULL;
4945  RegionsIterator++;
4946  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4947  }
4948 
4949  Region* Instrument::AddRegion() {
4950  // create new Region object (and its RIFF chunks)
4951  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
4952  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
4953  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
4954  Region* pNewRegion = new Region(this, rgn);
4955  pRegions->push_back(pNewRegion);
4956  Regions = (uint32_t) pRegions->size();
4957  // update Region key table for fast lookup
4958  UpdateRegionKeyTable();
4959  // done
4960  return pNewRegion;
4961  }
4962 
4963  void Instrument::DeleteRegion(Region* pRegion) {
4964  if (!pRegions) return;
4965  DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
4966  // update Region key table for fast lookup
4967  UpdateRegionKeyTable();
4968  }
4969 
4998  if (dst && GetParent() != dst->GetParent())
4999  throw Exception(
5000  "gig::Instrument::MoveTo() can only be used for moving within "
5001  "the same gig file."
5002  );
5003 
5004  File* pFile = (File*) GetParent();
5005 
5006  // move this instrument within the instrument list
5007  {
5008  File::InstrumentList& list = *pFile->pInstruments;
5009 
5010  File::InstrumentList::iterator itFrom =
5011  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(this));
5012 
5013  File::InstrumentList::iterator itTo =
5014  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(dst));
5015 
5016  list.splice(itTo, list, itFrom);
5017  }
5018 
5019  // move the instrument's actual list RIFF chunk appropriately
5020  RIFF::List* lstCkInstruments = pFile->pRIFF->GetSubList(LIST_TYPE_LINS);
5021  lstCkInstruments->MoveSubChunk(
5022  this->pCkInstrument,
5023  (RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5024  );
5025  }
5026 
5038  return pMidiRules[i];
5039  }
5040 
5047  delete pMidiRules[0];
5049  pMidiRules[0] = r;
5050  pMidiRules[1] = 0;
5051  return r;
5052  }
5053 
5060  delete pMidiRules[0];
5061  MidiRuleLegato* r = new MidiRuleLegato;
5062  pMidiRules[0] = r;
5063  pMidiRules[1] = 0;
5064  return r;
5065  }
5066 
5073  delete pMidiRules[0];
5075  pMidiRules[0] = r;
5076  pMidiRules[1] = 0;
5077  return r;
5078  }
5079 
5086  delete pMidiRules[i];
5087  pMidiRules[i] = 0;
5088  }
5089 
5090  void Instrument::LoadScripts() {
5091  if (pScriptRefs) return;
5092  pScriptRefs = new std::vector<_ScriptPooolRef>;
5093  if (scriptPoolFileOffsets.empty()) return;
5094  File* pFile = (File*) GetParent();
5095  for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5096  uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5097  for (uint i = 0; pFile->GetScriptGroup(i); ++i) {
5098  ScriptGroup* group = pFile->GetScriptGroup(i);
5099  for (uint s = 0; group->GetScript(s); ++s) {
5100  Script* script = group->GetScript(s);
5101  if (script->pChunk) {
5102  uint32_t offset = uint32_t(
5103  script->pChunk->GetFilePos() -
5104  script->pChunk->GetPos() -
5105  CHUNK_HEADER_SIZE(script->pChunk->GetFile()->GetFileOffsetSize())
5106  );
5107  if (offset == soughtOffset)
5108  {
5109  _ScriptPooolRef ref;
5110  ref.script = script;
5111  ref.bypass = scriptPoolFileOffsets[k].bypass;
5112  pScriptRefs->push_back(ref);
5113  break;
5114  }
5115  }
5116  }
5117  }
5118  }
5119  // we don't need that anymore
5120  scriptPoolFileOffsets.clear();
5121  }
5122 
5136  LoadScripts();
5137  if (index >= pScriptRefs->size()) return NULL;
5138  return pScriptRefs->at(index).script;
5139  }
5140 
5176  void Instrument::AddScriptSlot(Script* pScript, bool bypass) {
5177  LoadScripts();
5178  _ScriptPooolRef ref = { pScript, bypass };
5179  pScriptRefs->push_back(ref);
5180  }
5181 
5196  void Instrument::SwapScriptSlots(uint index1, uint index2) {
5197  LoadScripts();
5198  if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5199  return;
5200  _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5201  (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5202  (*pScriptRefs)[index2] = tmp;
5203  }
5204 
5211  void Instrument::RemoveScriptSlot(uint index) {
5212  LoadScripts();
5213  if (index >= pScriptRefs->size()) return;
5214  pScriptRefs->erase( pScriptRefs->begin() + index );
5215  }
5216 
5230  LoadScripts();
5231  for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5232  if ((*pScriptRefs)[i].script == pScript) {
5233  pScriptRefs->erase( pScriptRefs->begin() + i );
5234  }
5235  }
5236  }
5237 
5253  return uint(pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size());
5254  }
5255 
5273  if (index >= ScriptSlotCount()) return false;
5274  return pScriptRefs ? pScriptRefs->at(index).bypass
5275  : scriptPoolFileOffsets.at(index).bypass;
5276 
5277  }
5278 
5292  void Instrument::SetScriptSlotBypassed(uint index, bool bBypass) {
5293  if (index >= ScriptSlotCount()) return;
5294  if (pScriptRefs)
5295  pScriptRefs->at(index).bypass = bBypass;
5296  else
5297  scriptPoolFileOffsets.at(index).bypass = bBypass;
5298  }
5299 
5310  CopyAssign(orig, NULL);
5311  }
5312 
5321  void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
5322  // handle base class
5323  // (without copying DLS region stuff)
5324  DLS::Instrument::CopyAssignCore(orig);
5325 
5326  // handle own member variables
5327  Attenuation = orig->Attenuation;
5328  EffectSend = orig->EffectSend;
5329  FineTune = orig->FineTune;
5331  PianoReleaseMode = orig->PianoReleaseMode;
5333  scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5334  pScriptRefs = orig->pScriptRefs;
5335 
5336  // free old midi rules
5337  for (int i = 0 ; pMidiRules[i] ; i++) {
5338  delete pMidiRules[i];
5339  }
5340  //TODO: MIDI rule copying
5341  pMidiRules[0] = NULL;
5342 
5343  // delete all old regions
5344  while (Regions) DeleteRegion(GetFirstRegion());
5345  // create new regions and copy them from original
5346  {
5347  RegionList::const_iterator it = orig->pRegions->begin();
5348  for (int i = 0; i < orig->Regions; ++i, ++it) {
5349  Region* dstRgn = AddRegion();
5350  //NOTE: Region does semi-deep copy !
5351  dstRgn->CopyAssign(
5352  static_cast<gig::Region*>(*it),
5353  mSamples
5354  );
5355  }
5356  }
5357 
5358  UpdateRegionKeyTable();
5359  }
5360 
5361 
5362 // *************** Group ***************
5363 // *
5364 
5371  Group::Group(File* file, RIFF::Chunk* ck3gnm) {
5372  pFile = file;
5373  pNameChunk = ck3gnm;
5374  ::LoadString(pNameChunk, Name);
5375  }
5376 
5377  Group::~Group() {
5378  // remove the chunk associated with this group (if any)
5379  if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
5380  }
5381 
5392  void Group::UpdateChunks(progress_t* pProgress) {
5393  // make sure <3gri> and <3gnl> list chunks exist
5394  RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
5395  if (!_3gri) {
5396  _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
5397  pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
5398  }
5399  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
5400  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
5401 
5402  if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
5403  // v3 has a fixed list of 128 strings, find a free one
5404  for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
5405  if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
5406  pNameChunk = ck;
5407  break;
5408  }
5409  }
5410  }
5411 
5412  // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
5413  ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
5414  }
5415 
5428  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5429  for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
5430  if (pSample->GetGroup() == this) return pSample;
5431  }
5432  return NULL;
5433  }
5434 
5446  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5447  for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
5448  if (pSample->GetGroup() == this) return pSample;
5449  }
5450  return NULL;
5451  }
5452 
5456  void Group::AddSample(Sample* pSample) {
5457  pSample->pGroup = this;
5458  }
5459 
5467  // get "that" other group first
5468  Group* pOtherGroup = NULL;
5469  for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
5470  if (pOtherGroup != this) break;
5471  }
5472  if (!pOtherGroup) throw Exception(
5473  "Could not move samples to another group, since there is no "
5474  "other Group. This is a bug, report it!"
5475  );
5476  // now move all samples of this group to the other group
5477  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
5478  pOtherGroup->AddSample(pSample);
5479  }
5480  }
5481 
5482 
5483 
5484 // *************** File ***************
5485 // *
5486 
5489  0, 2, 19980628 & 0xffff, 19980628 >> 16
5490  };
5491 
5494  0, 3, 20030331 & 0xffff, 20030331 >> 16
5495  };
5496 
5497  static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
5498  { CHUNK_ID_IARL, 256 },
5499  { CHUNK_ID_IART, 128 },
5500  { CHUNK_ID_ICMS, 128 },
5501  { CHUNK_ID_ICMT, 1024 },
5502  { CHUNK_ID_ICOP, 128 },
5503  { CHUNK_ID_ICRD, 128 },
5504  { CHUNK_ID_IENG, 128 },
5505  { CHUNK_ID_IGNR, 128 },
5506  { CHUNK_ID_IKEY, 128 },
5507  { CHUNK_ID_IMED, 128 },
5508  { CHUNK_ID_INAM, 128 },
5509  { CHUNK_ID_IPRD, 128 },
5510  { CHUNK_ID_ISBJ, 128 },
5511  { CHUNK_ID_ISFT, 128 },
5512  { CHUNK_ID_ISRC, 128 },
5513  { CHUNK_ID_ISRF, 128 },
5514  { CHUNK_ID_ITCH, 128 },
5515  { 0, 0 }
5516  };
5517 
5518  File::File() : DLS::File() {
5519  bAutoLoad = true;
5520  *pVersion = VERSION_3;
5521  pGroups = NULL;
5522  pScriptGroups = NULL;
5523  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5524  pInfo->ArchivalLocation = String(256, ' ');
5525 
5526  // add some mandatory chunks to get the file chunks in right
5527  // order (INFO chunk will be moved to first position later)
5528  pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
5529  pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
5530  pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
5531 
5532  GenerateDLSID();
5533  }
5534 
5535  File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
5536  bAutoLoad = true;
5537  pGroups = NULL;
5538  pScriptGroups = NULL;
5539  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5540  }
5541 
5542  File::~File() {
5543  if (pGroups) {
5544  std::list<Group*>::iterator iter = pGroups->begin();
5545  std::list<Group*>::iterator end = pGroups->end();
5546  while (iter != end) {
5547  delete *iter;
5548  ++iter;
5549  }
5550  delete pGroups;
5551  }
5552  if (pScriptGroups) {
5553  std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
5554  std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
5555  while (iter != end) {
5556  delete *iter;
5557  ++iter;
5558  }
5559  delete pScriptGroups;
5560  }
5561  }
5562 
5564  if (!pSamples) LoadSamples(pProgress);
5565  if (!pSamples) return NULL;
5566  SamplesIterator = pSamples->begin();
5567  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5568  }
5569 
5571  if (!pSamples) return NULL;
5572  SamplesIterator++;
5573  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5574  }
5575 
5581  Sample* File::GetSample(uint index) {
5582  if (!pSamples) LoadSamples();
5583  if (!pSamples) return NULL;
5584  DLS::File::SampleList::iterator it = pSamples->begin();
5585  for (int i = 0; i < index; ++i) {
5586  ++it;
5587  if (it == pSamples->end()) return NULL;
5588  }
5589  if (it == pSamples->end()) return NULL;
5590  return static_cast<gig::Sample*>( *it );
5591  }
5592 
5601  if (!pSamples) LoadSamples();
5603  RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
5604  // create new Sample object and its respective 'wave' list chunk
5605  RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
5606  Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
5607 
5608  // add mandatory chunks to get the chunks in right order
5609  wave->AddSubChunk(CHUNK_ID_FMT, 16);
5610  wave->AddSubList(LIST_TYPE_INFO);
5611 
5612  pSamples->push_back(pSample);
5613  return pSample;
5614  }
5615 
5625  void File::DeleteSample(Sample* pSample) {
5626  if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
5627  SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
5628  if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
5629  if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
5630  pSamples->erase(iter);
5631  delete pSample;
5632 
5633  SampleList::iterator tmp = SamplesIterator;
5634  // remove all references to the sample
5635  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
5636  instrument = GetNextInstrument()) {
5637  for (Region* region = instrument->GetFirstRegion() ; region ;
5638  region = instrument->GetNextRegion()) {
5639 
5640  if (region->GetSample() == pSample) region->SetSample(NULL);
5641 
5642  for (int i = 0 ; i < region->DimensionRegions ; i++) {
5643  gig::DimensionRegion *d = region->pDimensionRegions[i];
5644  if (d->pSample == pSample) d->pSample = NULL;
5645  }
5646  }
5647  }
5648  SamplesIterator = tmp; // restore iterator
5649  }
5650 
5651  void File::LoadSamples() {
5652  LoadSamples(NULL);
5653  }
5654 
5655  void File::LoadSamples(progress_t* pProgress) {
5656  // Groups must be loaded before samples, because samples will try
5657  // to resolve the group they belong to
5658  if (!pGroups) LoadGroups();
5659 
5660  if (!pSamples) pSamples = new SampleList;
5661 
5662  RIFF::File* file = pRIFF;
5663 
5664  // just for progress calculation
5665  int iSampleIndex = 0;
5666  int iTotalSamples = WavePoolCount;
5667 
5668  // check if samples should be loaded from extension files
5669  // (only for old gig files < 2 GB)
5670  int lastFileNo = 0;
5671  if (!file->IsNew() && !(file->GetCurrentFileSize() >> 31)) {
5672  for (int i = 0 ; i < WavePoolCount ; i++) {
5673  if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
5674  }
5675  }
5676  String name(pRIFF->GetFileName());
5677  int nameLen = (int) name.length();
5678  char suffix[6];
5679  if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
5680 
5681  for (int fileNo = 0 ; ; ) {
5682  RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
5683  if (wvpl) {
5684  file_offset_t wvplFileOffset = wvpl->GetFilePos();
5685  RIFF::List* wave = wvpl->GetFirstSubList();
5686  while (wave) {
5687  if (wave->GetListType() == LIST_TYPE_WAVE) {
5688  // notify current progress
5689  const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
5690  __notify_progress(pProgress, subprogress);
5691 
5692  file_offset_t waveFileOffset = wave->GetFilePos();
5693  pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo, iSampleIndex));
5694 
5695  iSampleIndex++;
5696  }
5697  wave = wvpl->GetNextSubList();
5698  }
5699 
5700  if (fileNo == lastFileNo) break;
5701 
5702  // open extension file (*.gx01, *.gx02, ...)
5703  fileNo++;
5704  sprintf(suffix, ".gx%02d", fileNo);
5705  name.replace(nameLen, 5, suffix);
5706  file = new RIFF::File(name);
5707  ExtensionFiles.push_back(file);
5708  } else break;
5709  }
5710 
5711  __notify_progress(pProgress, 1.0); // notify done
5712  }
5713 
5715  if (!pInstruments) LoadInstruments();
5716  if (!pInstruments) return NULL;
5717  InstrumentsIterator = pInstruments->begin();
5718  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5719  }
5720 
5722  if (!pInstruments) return NULL;
5723  InstrumentsIterator++;
5724  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5725  }
5726 
5734  Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
5735  if (!pInstruments) {
5736  // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
5737 
5738  // sample loading subtask
5739  progress_t subprogress;
5740  __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
5741  __notify_progress(&subprogress, 0.0f);
5742  if (GetAutoLoad())
5743  GetFirstSample(&subprogress); // now force all samples to be loaded
5744  __notify_progress(&subprogress, 1.0f);
5745 
5746  // instrument loading subtask
5747  if (pProgress && pProgress->callback) {
5748  subprogress.__range_min = subprogress.__range_max;
5749  subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
5750  }
5751  __notify_progress(&subprogress, 0.0f);
5752  LoadInstruments(&subprogress);
5753  __notify_progress(&subprogress, 1.0f);
5754  }
5755  if (!pInstruments) return NULL;
5756  InstrumentsIterator = pInstruments->begin();
5757  for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
5758  if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
5759  InstrumentsIterator++;
5760  }
5761  return NULL;
5762  }
5763 
5772  if (!pInstruments) LoadInstruments();
5774  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
5775  RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
5776 
5777  // add mandatory chunks to get the chunks in right order
5778  lstInstr->AddSubList(LIST_TYPE_INFO);
5779  lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
5780 
5781  Instrument* pInstrument = new Instrument(this, lstInstr);
5782  pInstrument->GenerateDLSID();
5783 
5784  lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
5785 
5786  // this string is needed for the gig to be loadable in GSt:
5787  pInstrument->pInfo->Software = "Endless Wave";
5788 
5789  pInstruments->push_back(pInstrument);
5790  return pInstrument;
5791  }
5792 
5809  Instrument* instr = AddInstrument();
5810  instr->CopyAssign(orig);
5811  return instr;
5812  }
5813 
5825  void File::AddContentOf(File* pFile) {
5826  static int iCallCount = -1;
5827  iCallCount++;
5828  std::map<Group*,Group*> mGroups;
5829  std::map<Sample*,Sample*> mSamples;
5830 
5831  // clone sample groups
5832  for (int i = 0; pFile->GetGroup(i); ++i) {
5833  Group* g = AddGroup();
5834  g->Name =
5835  "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
5836  mGroups[pFile->GetGroup(i)] = g;
5837  }
5838 
5839  // clone samples (not waveform data here yet)
5840  for (int i = 0; pFile->GetSample(i); ++i) {
5841  Sample* s = AddSample();
5842  s->CopyAssignMeta(pFile->GetSample(i));
5843  mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
5844  mSamples[pFile->GetSample(i)] = s;
5845  }
5846 
5847  // clone script groups and their scripts
5848  for (int iGroup = 0; pFile->GetScriptGroup(iGroup); ++iGroup) {
5849  ScriptGroup* sg = pFile->GetScriptGroup(iGroup);
5850  ScriptGroup* dg = AddScriptGroup();
5851  dg->Name = "COPY" + ToString(iCallCount) + "_" + sg->Name;
5852  for (int iScript = 0; sg->GetScript(iScript); ++iScript) {
5853  Script* ss = sg->GetScript(iScript);
5854  Script* ds = dg->AddScript();
5855  ds->CopyAssign(ss);
5856  }
5857  }
5858 
5859  //BUG: For some reason this method only works with this additional
5860  // Save() call in between here.
5861  //
5862  // Important: The correct one of the 2 Save() methods has to be called
5863  // here, depending on whether the file is completely new or has been
5864  // saved to disk already, otherwise it will result in data corruption.
5865  if (pRIFF->IsNew())
5866  Save(GetFileName());
5867  else
5868  Save();
5869 
5870  // clone instruments
5871  // (passing the crosslink table here for the cloned samples)
5872  for (int i = 0; pFile->GetInstrument(i); ++i) {
5873  Instrument* instr = AddInstrument();
5874  instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
5875  }
5876 
5877  // Mandatory: file needs to be saved to disk at this point, so this
5878  // file has the correct size and data layout for writing the samples'
5879  // waveform data to disk.
5880  Save();
5881 
5882  // clone samples' waveform data
5883  // (using direct read & write disk streaming)
5884  for (int i = 0; pFile->GetSample(i); ++i) {
5885  mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
5886  }
5887  }
5888 
5897  void File::DeleteInstrument(Instrument* pInstrument) {
5898  if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
5899  InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
5900  if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
5901  pInstruments->erase(iter);
5902  delete pInstrument;
5903  }
5904 
5905  void File::LoadInstruments() {
5906  LoadInstruments(NULL);
5907  }
5908 
5909  void File::LoadInstruments(progress_t* pProgress) {
5910  if (!pInstruments) pInstruments = new InstrumentList;
5911  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
5912  if (lstInstruments) {
5913  int iInstrumentIndex = 0;
5914  RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
5915  while (lstInstr) {
5916  if (lstInstr->GetListType() == LIST_TYPE_INS) {
5917  // notify current progress
5918  const float localProgress = (float) iInstrumentIndex / (float) Instruments;
5919  __notify_progress(pProgress, localProgress);
5920 
5921  // divide local progress into subprogress for loading current Instrument
5922  progress_t subprogress;
5923  __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
5924 
5925  pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
5926 
5927  iInstrumentIndex++;
5928  }
5929  lstInstr = lstInstruments->GetNextSubList();
5930  }
5931  __notify_progress(pProgress, 1.0); // notify done
5932  }
5933  }
5934 
5938  void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
5939  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
5940  if (!_3crc) return;
5941 
5942  // get the index of the sample
5943  int iWaveIndex = GetWaveTableIndexOf(pSample);
5944  if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
5945 
5946  // write the CRC-32 checksum to disk
5947  _3crc->SetPos(iWaveIndex * 8);
5948  uint32_t one = 1;
5949  _3crc->WriteUint32(&one); // always 1
5950  _3crc->WriteUint32(&crc);
5951  }
5952 
5953  uint32_t File::GetSampleChecksum(Sample* pSample) {
5954  // get the index of the sample
5955  int iWaveIndex = GetWaveTableIndexOf(pSample);
5956  if (iWaveIndex < 0) throw gig::Exception("Could not retrieve reference crc of sample, could not resolve sample's wave table index");
5957 
5958  return GetSampleChecksumByIndex(iWaveIndex);
5959  }
5960 
5961  uint32_t File::GetSampleChecksumByIndex(int index) {
5962  if (index < 0) throw gig::Exception("Could not retrieve reference crc of sample, invalid wave pool index of sample");
5963 
5964  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
5965  if (!_3crc) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
5966  uint8_t* pData = (uint8_t*) _3crc->LoadChunkData();
5967  if (!pData) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
5968 
5969  // read the CRC-32 checksum directly from disk
5970  size_t pos = index * 8;
5971  if (pos + 8 > _3crc->GetNewSize())
5972  throw gig::Exception("Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
5973 
5974  uint32_t one = load32(&pData[pos]); // always 1
5975  if (one != 1)
5976  throw gig::Exception("Could not retrieve reference crc of sample, because reference checksum table is damaged");
5977 
5978  return load32(&pData[pos+4]);
5979  }
5980 
5981  int File::GetWaveTableIndexOf(gig::Sample* pSample) {
5982  if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
5983  File::SampleList::iterator iter = pSamples->begin();
5984  File::SampleList::iterator end = pSamples->end();
5985  for (int index = 0; iter != end; ++iter, ++index)
5986  if (*iter == pSample)
5987  return index;
5988  return -1;
5989  }
5990 
5998  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
5999  if (!_3crc) return false;
6000  if (_3crc->GetNewSize() <= 0) return false;
6001  if (_3crc->GetNewSize() % 8) return false;
6002  if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
6003  if (_3crc->GetNewSize() != pSamples->size() * 8) return false;
6004 
6005  const file_offset_t n = _3crc->GetNewSize() / 8;
6006 
6007  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6008  if (!pData) return false;
6009 
6010  for (file_offset_t i = 0; i < n; ++i) {
6011  uint32_t one = pData[i*2];
6012  if (one != 1) return false;
6013  }
6014 
6015  return true;
6016  }
6017 
6035  // make sure sample chunks were scanned
6036  if (!pSamples) GetFirstSample();
6037 
6038  bool bRequiresSave = false;
6039 
6040  // make sure "3CRC" chunk exists with required size
6041  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6042  if (!_3crc) {
6043  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6044  // the order of einf and 3crc is not the same in v2 and v3
6045  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6046  if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
6047  bRequiresSave = true;
6048  } else if (_3crc->GetNewSize() != pSamples->size() * 8) {
6049  _3crc->Resize(pSamples->size() * 8);
6050  bRequiresSave = true;
6051  }
6052 
6053  if (bRequiresSave) { // refill CRC table for all samples in RAM ...
6054  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6055  {
6056  File::SampleList::iterator iter = pSamples->begin();
6057  File::SampleList::iterator end = pSamples->end();
6058  for (; iter != end; ++iter) {
6059  gig::Sample* pSample = (gig::Sample*) *iter;
6060  int index = GetWaveTableIndexOf(pSample);
6061  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6062  pData[index*2] = 1; // always 1
6063  pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6064  }
6065  }
6066  } else { // no file structure changes necessary, so directly write to disk and we are done ...
6067  // make sure file is in write mode
6068  pRIFF->SetMode(RIFF::stream_mode_read_write);
6069  {
6070  File::SampleList::iterator iter = pSamples->begin();
6071  File::SampleList::iterator end = pSamples->end();
6072  for (; iter != end; ++iter) {
6073  gig::Sample* pSample = (gig::Sample*) *iter;
6074  int index = GetWaveTableIndexOf(pSample);
6075  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6076  pSample->crc = pSample->CalculateWaveDataChecksum();
6077  SetSampleChecksum(pSample, pSample->crc);
6078  }
6079  }
6080  }
6081 
6082  return bRequiresSave;
6083  }
6084 
6086  if (!pGroups) LoadGroups();
6087  // there must always be at least one group
6088  GroupsIterator = pGroups->begin();
6089  return *GroupsIterator;
6090  }
6091 
6093  if (!pGroups) return NULL;
6094  ++GroupsIterator;
6095  return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6096  }
6097 
6104  Group* File::GetGroup(uint index) {
6105  if (!pGroups) LoadGroups();
6106  GroupsIterator = pGroups->begin();
6107  for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
6108  if (i == index) return *GroupsIterator;
6109  ++GroupsIterator;
6110  }
6111  return NULL;
6112  }
6113 
6124  Group* File::GetGroup(String name) {
6125  if (!pGroups) LoadGroups();
6126  GroupsIterator = pGroups->begin();
6127  for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
6128  if ((*GroupsIterator)->Name == name) return *GroupsIterator;
6129  return NULL;
6130  }
6131 
6132  Group* File::AddGroup() {
6133  if (!pGroups) LoadGroups();
6134  // there must always be at least one group
6136  Group* pGroup = new Group(this, NULL);
6137  pGroups->push_back(pGroup);
6138  return pGroup;
6139  }
6140 
6150  void File::DeleteGroup(Group* pGroup) {
6151  if (!pGroups) LoadGroups();
6152  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6153  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6154  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6155  // delete all members of this group
6156  for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
6157  DeleteSample(pSample);
6158  }
6159  // now delete this group object
6160  pGroups->erase(iter);
6161  delete pGroup;
6162  }
6163 
6175  if (!pGroups) LoadGroups();
6176  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6177  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6178  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6179  // move all members of this group to another group
6180  pGroup->MoveAll();
6181  pGroups->erase(iter);
6182  delete pGroup;
6183  }
6184 
6185  void File::LoadGroups() {
6186  if (!pGroups) pGroups = new std::list<Group*>;
6187  // try to read defined groups from file
6188  RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
6189  if (lst3gri) {
6190  RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
6191  if (lst3gnl) {
6192  RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
6193  while (ck) {
6194  if (ck->GetChunkID() == CHUNK_ID_3GNM) {
6195  if (pVersion && pVersion->major == 3 &&
6196  strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
6197 
6198  pGroups->push_back(new Group(this, ck));
6199  }
6200  ck = lst3gnl->GetNextSubChunk();
6201  }
6202  }
6203  }
6204  // if there were no group(s), create at least the mandatory default group
6205  if (!pGroups->size()) {
6206  Group* pGroup = new Group(this, NULL);
6207  pGroup->Name = "Default Group";
6208  pGroups->push_back(pGroup);
6209  }
6210  }
6211 
6220  if (!pScriptGroups) LoadScriptGroups();
6221  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6222  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6223  if (i == index) return *it;
6224  return NULL;
6225  }
6226 
6235  ScriptGroup* File::GetScriptGroup(const String& name) {
6236  if (!pScriptGroups) LoadScriptGroups();
6237  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6238  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6239  if ((*it)->Name == name) return *it;
6240  return NULL;
6241  }
6242 
6252  if (!pScriptGroups) LoadScriptGroups();
6253  ScriptGroup* pScriptGroup = new ScriptGroup(this, NULL);
6254  pScriptGroups->push_back(pScriptGroup);
6255  return pScriptGroup;
6256  }
6257 
6270  void File::DeleteScriptGroup(ScriptGroup* pScriptGroup) {
6271  if (!pScriptGroups) LoadScriptGroups();
6272  std::list<ScriptGroup*>::iterator iter =
6273  find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
6274  if (iter == pScriptGroups->end())
6275  throw gig::Exception("Could not delete script group, could not find given script group");
6276  pScriptGroups->erase(iter);
6277  for (int i = 0; pScriptGroup->GetScript(i); ++i)
6278  pScriptGroup->DeleteScript(pScriptGroup->GetScript(i));
6279  if (pScriptGroup->pList)
6280  pScriptGroup->pList->GetParent()->DeleteSubChunk(pScriptGroup->pList);
6281  delete pScriptGroup;
6282  }
6283 
6284  void File::LoadScriptGroups() {
6285  if (pScriptGroups) return;
6286  pScriptGroups = new std::list<ScriptGroup*>;
6287  RIFF::List* lstLS = pRIFF->GetSubList(LIST_TYPE_3LS);
6288  if (lstLS) {
6289  for (RIFF::List* lst = lstLS->GetFirstSubList(); lst;
6290  lst = lstLS->GetNextSubList())
6291  {
6292  if (lst->GetListType() == LIST_TYPE_RTIS) {
6293  pScriptGroups->push_back(new ScriptGroup(this, lst));
6294  }
6295  }
6296  }
6297  }
6298 
6310  void File::UpdateChunks(progress_t* pProgress) {
6311  bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
6312 
6313  // update own gig format extension chunks
6314  // (not part of the GigaStudio 4 format)
6315  RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);
6316  if (!lst3LS) {
6317  lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
6318  }
6319  // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
6320  // location of <3LS > is irrelevant, however it should be located
6321  // before the actual wave data
6322  RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
6323  pRIFF->MoveSubChunk(lst3LS, ckPTBL);
6324 
6325  // This must be performed before writing the chunks for instruments,
6326  // because the instruments' script slots will write the file offsets
6327  // of the respective instrument script chunk as reference.
6328  if (pScriptGroups) {
6329  // Update instrument script (group) chunks.
6330  for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6331  it != pScriptGroups->end(); ++it)
6332  {
6333  (*it)->UpdateChunks(pProgress);
6334  }
6335  }
6336 
6337  // in case no libgig custom format data was added, then remove the
6338  // custom "3LS " chunk again
6339  if (!lst3LS->CountSubChunks()) {
6340  pRIFF->DeleteSubChunk(lst3LS);
6341  lst3LS = NULL;
6342  }
6343 
6344  // first update base class's chunks
6345  DLS::File::UpdateChunks(pProgress);
6346 
6347  if (newFile) {
6348  // INFO was added by Resource::UpdateChunks - make sure it
6349  // is placed first in file
6350  RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
6351  RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
6352  if (first != info) {
6353  pRIFF->MoveSubChunk(info, first);
6354  }
6355  }
6356 
6357  // update group's chunks
6358  if (pGroups) {
6359  // make sure '3gri' and '3gnl' list chunks exist
6360  // (before updating the Group chunks)
6361  RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
6362  if (!_3gri) {
6363  _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
6364  pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
6365  }
6366  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
6367  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
6368 
6369  // v3: make sure the file has 128 3gnm chunks
6370  // (before updating the Group chunks)
6371  if (pVersion && pVersion->major == 3) {
6372  RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
6373  for (int i = 0 ; i < 128 ; i++) {
6374  if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
6375  if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
6376  }
6377  }
6378 
6379  std::list<Group*>::iterator iter = pGroups->begin();
6380  std::list<Group*>::iterator end = pGroups->end();
6381  for (; iter != end; ++iter) {
6382  (*iter)->UpdateChunks(pProgress);
6383  }
6384  }
6385 
6386  // update einf chunk
6387 
6388  // The einf chunk contains statistics about the gig file, such
6389  // as the number of regions and samples used by each
6390  // instrument. It is divided in equally sized parts, where the
6391  // first part contains information about the whole gig file,
6392  // and the rest of the parts map to each instrument in the
6393  // file.
6394  //
6395  // At the end of each part there is a bit map of each sample
6396  // in the file, where a set bit means that the sample is used
6397  // by the file/instrument.
6398  //
6399  // Note that there are several fields with unknown use. These
6400  // are set to zero.
6401 
6402  int sublen = int(pSamples->size() / 8 + 49);
6403  int einfSize = (Instruments + 1) * sublen;
6404 
6405  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6406  if (einf) {
6407  if (einf->GetSize() != einfSize) {
6408  einf->Resize(einfSize);
6409  memset(einf->LoadChunkData(), 0, einfSize);
6410  }
6411  } else if (newFile) {
6412  einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
6413  }
6414  if (einf) {
6415  uint8_t* pData = (uint8_t*) einf->LoadChunkData();
6416 
6417  std::map<gig::Sample*,int> sampleMap;
6418  int sampleIdx = 0;
6419  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
6420  sampleMap[pSample] = sampleIdx++;
6421  }
6422 
6423  int totnbusedsamples = 0;
6424  int totnbusedchannels = 0;
6425  int totnbregions = 0;
6426  int totnbdimregions = 0;
6427  int totnbloops = 0;
6428  int instrumentIdx = 0;
6429 
6430  memset(&pData[48], 0, sublen - 48);
6431 
6432  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
6433  instrument = GetNextInstrument()) {
6434  int nbusedsamples = 0;
6435  int nbusedchannels = 0;
6436  int nbdimregions = 0;
6437  int nbloops = 0;
6438 
6439  memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
6440 
6441  for (Region* region = instrument->GetFirstRegion() ; region ;
6442  region = instrument->GetNextRegion()) {
6443  for (int i = 0 ; i < region->DimensionRegions ; i++) {
6444  gig::DimensionRegion *d = region->pDimensionRegions[i];
6445  if (d->pSample) {
6446  int sampleIdx = sampleMap[d->pSample];
6447  int byte = 48 + sampleIdx / 8;
6448  int bit = 1 << (sampleIdx & 7);
6449  if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
6450  pData[(instrumentIdx + 1) * sublen + byte] |= bit;
6451  nbusedsamples++;
6452  nbusedchannels += d->pSample->Channels;
6453 
6454  if ((pData[byte] & bit) == 0) {
6455  pData[byte] |= bit;
6456  totnbusedsamples++;
6457  totnbusedchannels += d->pSample->Channels;
6458  }
6459  }
6460  }
6461  if (d->SampleLoops) nbloops++;
6462  }
6463  nbdimregions += region->DimensionRegions;
6464  }
6465  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6466  // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
6467  store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
6468  store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
6469  store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
6470  store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
6471  store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
6472  store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
6473  // next 8 bytes unknown
6474  store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
6475  store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
6476  // next 4 bytes unknown
6477 
6478  totnbregions += instrument->Regions;
6479  totnbdimregions += nbdimregions;
6480  totnbloops += nbloops;
6481  instrumentIdx++;
6482  }
6483  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6484  // store32(&pData[0], sublen);
6485  store32(&pData[4], totnbusedchannels);
6486  store32(&pData[8], totnbusedsamples);
6487  store32(&pData[12], Instruments);
6488  store32(&pData[16], totnbregions);
6489  store32(&pData[20], totnbdimregions);
6490  store32(&pData[24], totnbloops);
6491  // next 8 bytes unknown
6492  // next 4 bytes unknown, not always 0
6493  store32(&pData[40], (uint32_t) pSamples->size());
6494  // next 4 bytes unknown
6495  }
6496 
6497  // update 3crc chunk
6498 
6499  // The 3crc chunk contains CRC-32 checksums for the
6500  // samples. When saving a gig file to disk, we first update the 3CRC
6501  // chunk here (in RAM) with the old crc values which we read from the
6502  // 3CRC chunk when we opened the file (available with gig::Sample::crc
6503  // member variable). This step is required, because samples might have
6504  // been deleted by the user since the file was opened, which in turn
6505  // changes the order of the (i.e. old) checksums within the 3crc chunk.
6506  // If a sample was conciously modified by the user (that is if
6507  // Sample::Write() was called later on) then Sample::Write() will just
6508  // update the respective individual checksum(s) directly on disk and
6509  // leaves all other sample checksums untouched.
6510 
6511  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6512  if (_3crc) {
6513  _3crc->Resize(pSamples->size() * 8);
6514  } else /*if (newFile)*/ {
6515  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6516  // the order of einf and 3crc is not the same in v2 and v3
6517  if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
6518  }
6519  { // must be performed in RAM here ...
6520  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6521  if (pData) {
6522  File::SampleList::iterator iter = pSamples->begin();
6523  File::SampleList::iterator end = pSamples->end();
6524  for (int index = 0; iter != end; ++iter, ++index) {
6525  gig::Sample* pSample = (gig::Sample*) *iter;
6526  pData[index*2] = 1; // always 1
6527  pData[index*2+1] = pSample->crc;
6528  }
6529  }
6530  }
6531  }
6532 
6535 
6536  for (Instrument* instrument = GetFirstInstrument(); instrument;
6537  instrument = GetNextInstrument())
6538  {
6539  instrument->UpdateScriptFileOffsets();
6540  }
6541  }
6542 
6558  void File::SetAutoLoad(bool b) {
6559  bAutoLoad = b;
6560  }
6561 
6567  return bAutoLoad;
6568  }
6569 
6570 
6571 
6572 // *************** Exception ***************
6573 // *
6574 
6575  Exception::Exception() : DLS::Exception() {
6576  }
6577 
6578  Exception::Exception(String format, ...) : DLS::Exception() {
6579  va_list arg;
6580  va_start(arg, format);
6581  Message = assemble(format, arg);
6582  va_end(arg);
6583  }
6584 
6585  Exception::Exception(String format, va_list arg) : DLS::Exception() {
6586  Message = assemble(format, arg);
6587  }
6588 
6589  void Exception::PrintMessage() {
6590  std::cout << "gig::Exception: " << Message << std::endl;
6591  }
6592 
6593 
6594 // *************** functions ***************
6595 // *
6596 
6602  String libraryName() {
6603  return PACKAGE;
6604  }
6605 
6610  String libraryVersion() {
6611  return VERSION;
6612  }
6613 
6614 } // namespace gig
range_t KeySwitchRange
Key range for key switch selector.
Definition: gig.h:1047
file_offset_t WriteUint32(uint32_t *pData, file_offset_t WordCount=1)
Writes WordCount number of 32 Bit unsigned integer words from the buffer pointed by pData to the chun...
Definition: RIFF.cpp:684
bool LFO2FlipPhase
Inverts phase of the filter cutoff LFO wave.
Definition: gig.h:509
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
Definition: gig.cpp:4444
void AddContentOf(File *pFile)
Add content of another existing file.
Definition: gig.cpp:5825
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
Definition: gig.cpp:5466
bool IsNew() const
Returns true if this file has been created new from scratch and has not been stored to disk yet...
Definition: RIFF.cpp:2092
dim_bypass_ctrl_t DimensionBypass
If defined, the MIDI controller can switch on/off the dimension in realtime.
Definition: gig.h:543
~Instrument()
Destructor.
Definition: gig.cpp:4781
file_offset_t position
Current position within the sample.
Definition: gig.h:378
Encapsulates articulation informations of a dimension region.
Definition: gig.h:468
dimension_none
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
Definition: gig.h:319
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
Definition: gig.h:1201
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
Definition: DLS.h:373
uint8_t VCFVelocityScale
(0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defi...
Definition: gig.h:526
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
Definition: gig.cpp:3938
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Definition: gig.h:379
uint8_t AltSustain2Key
Key triggering a second set of alternate sustain samples.
Definition: gig.h:999
Destination container for serialization, and source container for deserialization.
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
Definition: gig.h:785
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Definition: DLS.h:468
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
Definition: gig.cpp:4911
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
Definition: gig.cpp:5456
String GetScriptAsText()
Returns the current script (i.e.
Definition: gig.cpp:4431
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
Definition: gig.h:787
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
Definition: gig.cpp:5072
split_type_normal split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:330
vcf_res_ctrl_none
Defines how the filter resonance is controlled by.
Definition: gig.h:226
Sample * AddSample()
Add a new sample.
Definition: gig.cpp:5600
file_offset_t SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence=RIFF::stream_start)
Sets the position within the sample (in sample points, not in bytes).
Definition: gig.cpp:886
bool VCFEnabled
If filter should be used.
Definition: gig.h:520
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
Definition: gig.cpp:3473
file_offset_t ReadUint16(uint16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit unsigned integer words and copies it into the buffer pointed by pDat...
Definition: RIFF.cpp:572
stream_whence_t
File stream position dependent to these relations.
Definition: RIFF.h:165
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Definition: gig.h:743
uint8_t BypassKey
Key to be used to bypass the sustain note.
Definition: gig.h:992
uint16_t LFO1ControlDepth
Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents).
Definition: gig.h:488
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
Definition: RIFF.cpp:1116
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
Definition: gig.h:790
Group of Gigasampler samples.
Definition: gig.h:1266
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
Definition: DLS.h:233
uint8_t VCFVelocityDynamicRange
0x04 = lowest, 0x00 = highest .
Definition: gig.h:527
String Name
Stores the name of this Group.
Definition: gig.h:1268
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index)...
Definition: gig.cpp:4118
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Definition: gig.h:1199
double EG1Release
Release time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:479
uint8_t Triggers
Number of triggers.
Definition: gig.h:950
Defines behavior options for envelope generators (gig format extension).
Definition: gig.h:406
vcf_type_t VCFType
Defines the general filter characteristic (lowpass, highpass, bandpass, etc.).
Definition: gig.h:521
Script * AddScript()
Add new instrument script.
Definition: gig.cpp:4615
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order...
Definition: DLS.cpp:1078
void __ensureMandatoryChunksExist()
Checks if all (for DLS) mandatory chunks exist, if not they will be created.
Definition: DLS.cpp:1871
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Definition: gig.h:751
Instrument * AddInstrument()
Add a new instrument definition.
Definition: gig.cpp:5771
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
Definition: RIFF.h:225
Script * GetScript(uint index)
Get instrument script.
Definition: gig.cpp:4596
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:748
lfo1_ctrl_t LFO1Controller
MIDI Controller which controls sample amplitude LFO.
Definition: gig.h:489
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: DLS.cpp:1514
uint8_t low
Low value of range.
Definition: gig.h:102
void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Definition: gig.cpp:4573
uint16_t SampleStartOffset
Number of samples the sample start should be moved (0 - 2000).
Definition: gig.h:552
MIDI rule for triggering notes by control change events.
Definition: gig.h:947
file_offset_t ReadInt32(int32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:609
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
Definition: DLS.cpp:1175
NKSP stands for "Is Not KSP" (default). Refer to the NKSP Reference Manual for details about this scr...
Definition: gig.h:1109
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
Definition: RIFF.h:205
curve_type_nonlinear
Defines the shape of a function graph.
Definition: gig.h:149
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
Definition: gig.h:789
file_offset_t Size
Size of the actual data in the buffer in bytes.
Definition: gig.h:109
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
Definition: gig.cpp:5176
bool EG1Hold
If true, Decay1 stage should be postponed until the sample reached the sample loop start...
Definition: gig.h:480
range_t PlayRange
Key range of the playable keys in the instrument.
Definition: gig.h:1025
uint16_t ThresholdTime
Maximum time (ms) between two notes that should be played legato.
Definition: gig.h:994
static size_t Instances
Number of instances of class Sample.
Definition: gig.h:782
uint8_t VelocityResponseCurveScaling
0 - 127 (usually you don&#39;t have to interpret this parameter, use GetVelocityAttenuation() instead)...
Definition: gig.h:536
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Definition: gig.cpp:1401
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5714
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
Definition: RIFF.cpp:663
file_offset_t GetSize() const
Returns sample size.
Definition: DLS.cpp:858
Region * RegionKeyTable[128]
fast lookup for the corresponding Region of a MIDI key
Definition: gig.h:1231
uint8_t ReleaseTriggerKey
Key triggering release samples.
Definition: gig.h:997
bool VCFKeyboardTracking
If true: VCF cutoff frequence will be dependend to the note key position relative to the defined brea...
Definition: gig.h:531
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
Definition: gig.cpp:540
lfo2_ctrl_internal
Defines how LFO2 is controlled by.
Definition: gig.h:183
uint32_t crc
Reflects CRC-32 checksum of the raw sample data at the last time when the sample&#39;s raw wave form data...
Definition: gig.h:795
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
Definition: DLS.h:399
uint8_t Controller
CC number for controller selector.
Definition: gig.h:1048
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3127
Defines Region information of a Gigasampler/GigaStudio instrument.
Definition: gig.h:850
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise)...
Definition: DLS.h:404
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
Definition: gig.h:753
uint8_t ReleaseTriggerDecay
0 - 8
Definition: gig.h:539
lfo3_ctrl_t LFO3Controller
MIDI Controller which controls the sample pitch LFO.
Definition: gig.h:517
lfo1_ctrl_internal
Defines how LFO1 is controlled by.
Definition: gig.h:195
bool Chained
If all patterns should be chained together.
Definition: gig.h:1051
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it&#39;s original sample rate...
Definition: gig.h:742
uint8_t ControllerNumber
MIDI controller number.
Definition: gig.h:949
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
Definition: RIFF.cpp:1090
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Definition: RIFF.cpp:1342
uint8_t ChannelOffset
Audio output where the audio signal of the dimension region should be routed to (0 - 9)...
Definition: gig.h:549
Defines Sample Loop Points.
Definition: DLS.h:231
uint8_t VCFResonance
Firm internal filter resonance weight.
Definition: gig.h:528
Standard 8 bit US ASCII character encoding (default).
Definition: gig.h:1103
bool VCFResonanceDynamic
If true: Increases the resonance Q according to changes of controllers that actually control the VCF ...
Definition: gig.h:529
Language_t Language
Programming language and dialect the script is written in.
Definition: gig.h:1115
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
Definition: gig.cpp:5085
unsigned int Dimensions
Number of defined dimensions, do not alter!
Definition: gig.h:852
vcf_cutoff_ctrl_t VCFCutoffController
Specifies which external controller has influence on the filter cutoff frequency. ...
Definition: gig.h:522
file_offset_t loop_cycles_left
How many times the loop has still to be passed, this value will be decremented with each loop cycle...
Definition: gig.h:380
bool VerifySampleChecksumTable()
Checks whether the file&#39;s "3CRC" chunk was damaged.
Definition: gig.cpp:5997
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
Definition: gig.cpp:5046
double EG1Decay1
Decay time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:475
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
Definition: RIFF.cpp:1151
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it&#39;s articulation d...
Definition: gig.cpp:4009
lfo2_ctrl_t LFO2Controller
MIDI Controlle which controls the filter cutoff LFO.
Definition: gig.h:508
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used...
Definition: gig.h:1113
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction...
Definition: gig.h:756
Region * GetFirstRegion()
Returns the first Region of the instrument.
Definition: gig.cpp:4929
String libraryVersion()
Returns version of this C++ library.
Definition: gig.cpp:6610
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set...
Definition: gig.h:470
uint8_t ReleaseVelocityResponseDepth
Dynamic range of release velocity affecting envelope time (0 - 4).
Definition: gig.h:538
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File...
Definition: gig.h:1404
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:749
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
Definition: gig.cpp:4458
void GenerateDLSID()
Generates a new DLSID for the resource.
Definition: DLS.cpp:495
uint8_t in_end
End position of fade in.
Definition: gig.h:368
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3100
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Definition: gig.h:1322
Sample * pSample
Points to the Sample which is assigned to the dimension region.
Definition: gig.h:471
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used...
Definition: DLS.h:405
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:700
uint16_t ReleaseTime
Release time.
Definition: gig.h:995
List * GetParent() const
Returns pointer to the chunk&#39;s parent list chunk.
Definition: RIFF.h:224
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:749
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
Definition: gig.cpp:6092
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3109
double EG2Decay1
Decay time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:495
uint8_t EG1ControllerAttackInfluence
Amount EG1 Controller has influence on the EG1 Attack time (0 - 3, where 0 means off).
Definition: gig.h:483
String pArticulations[32]
Names of the articulations.
Definition: gig.h:1023
Compression_t
Definition: gig.h:1105
void SetAutoLoad(bool b)
Enable / disable automatic loading.
Definition: gig.cpp:6558
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
Definition: gig.cpp:5037
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
Definition: gig.h:744
uint16_t low
Low value of range.
Definition: DLS.h:207
double SampleAttenuation
Sample volume (calculated from DLS::Sampler::Gain)
Definition: gig.h:553
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
Definition: gig.h:411
RIFF List Chunk.
Definition: RIFF.h:294
double EG1Decay2
Only if EG1InfiniteSustain == false: 2nd decay stage time of the sample amplitude EG (0...
Definition: gig.h:476
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
Definition: DLS.cpp:296
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
Definition: gig.cpp:5229
uint8_t BypassController
Controller to be used to bypass the sustain note.
Definition: gig.h:993
attenuation_ctrl_t AttenuationController
MIDI Controller which has influence on the volume level of the sample (or entire sample group)...
Definition: gig.h:546
file_offset_t Read(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
Definition: RIFF.cpp:318
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
Definition: gig.h:783
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Definition: gig.cpp:1384
Pointer address and size of a buffer.
Definition: gig.h:107
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:409
uint8_t in_start
Start position of fade in.
Definition: gig.h:367
uint8_t Patterns
Number of alternator patterns.
Definition: gig.h:1027
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
Definition: gig.h:334
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument...
Definition: gig.h:1116
range_t KeyRange
Key range for legato notes.
Definition: gig.h:996
bool EG2ControllerInvert
Invert values coming from defined EG2 controller.
Definition: gig.h:501
uint8_t Articulations
Number of articulations in the instrument.
Definition: gig.h:1022
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
Definition: gig.cpp:6085
file_offset_t SetPos(file_offset_t Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes)...
Definition: RIFF.cpp:224
eg_opt_t EG2Options
[gig extension]: Behavior options which should be used for envelope generator 2 (filter cutoff EG)...
Definition: gig.h:556
Group * GetGroup(uint index)
Returns the group with the given index.
Definition: gig.cpp:6104
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
Definition: gig.h:1112
uint32_t DimensionRegions
Total number of DimensionRegions this Region contains, do not alter!
Definition: gig.h:854
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
Definition: gig.cpp:5808
uint ScriptSlotCount() const
Instrument&#39;s amount of script slots.
Definition: gig.cpp:5252
bool MSDecode
Gigastudio flag: defines if Mid Side Recordings should be decoded.
Definition: gig.h:551
bool EG1InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released...
Definition: gig.h:477
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors...
Definition: gig.h:754
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
Definition: gig.cpp:823
uint32_t SampleLoops
Reflects the number of sample loops.
Definition: DLS.h:372
virtual void Save(const String &Path, progress_t *pProgress=NULL)
Save changes to another file.
Definition: DLS.cpp:1803
uint16_t LFO2InternalDepth
Firm pitch of the filter cutoff LFO (0 - 1200 cents).
Definition: gig.h:506
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
Definition: gig.cpp:3675
void Resize(file_offset_t NewSize)
Resize sample.
Definition: DLS.cpp:891
uint16_t LFO1InternalDepth
Firm pitch of the sample amplitude LFO (0 - 1200 cents).
Definition: gig.h:487
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
Definition: gig.cpp:1367
float zone_size
Intended for internal usage: reflects the size of each zone (128/zones) for normal split types only...
Definition: gig.h:338
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: gig.cpp:6533
void Resize(file_offset_t NewSize)
Resize sample.
Definition: gig.cpp:860
bool PitchTrack
If true: sample will be pitched according to the key position (this will be disabled for drums for ex...
Definition: gig.h:542
Encoding_t
Definition: gig.h:1102
uint16_t high
High value of range.
Definition: DLS.h:208
uint64_t file_offset_t
Type used by libgig for handling file positioning during file I/O tasks.
Definition: RIFF.h:148
bool BypassUseController
If a controller should be used to bypass the sustain note.
Definition: gig.h:991
float __range_min
Only for internal usage, do not modify!
Definition: RIFF.h:208
unsigned int Layers
Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there i...
Definition: gig.h:856
void * pStart
Points to the beginning of the buffer.
Definition: gig.h:108
file_offset_t ReadUint32(uint32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
Definition: RIFF.cpp:646
bool EG2InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released...
Definition: gig.h:497
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Definition: gig.h:784
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
Definition: RIFF.cpp:1071
struct gig::MidiRuleAlternator::pattern_t pPatterns[32]
A pattern is a sequence of articulation numbers.
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Definition: gig.cpp:920
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
Definition: RIFF.cpp:1133
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
Definition: gig.cpp:5059
uint8_t EG2ControllerAttackInfluence
Amount EG2 Controller has influence on the EG2 Attack time (0 - 3, where 0 means off).
Definition: gig.h:502
bool SelfMask
If true: high velocity notes will stop low velocity notes at the same note, with that you can save vo...
Definition: gig.h:545
int16_t LFO3ControlDepth
Controller depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:516
void RemoveScriptSlot(uint index)
Remove script slot.
Definition: gig.cpp:5211
double EG3Attack
Attack time of the sample pitch EG (0.000 - 10.000s).
Definition: gig.h:512
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Definition: gig.cpp:3585
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5721
uint8_t LegatoSamples
Number of legato samples per key in each direction (always 12)
Definition: gig.h:990
uint8_t out_end
End postition of fade out.
Definition: gig.h:370
void DeleteGroupOnly(Group *pGroup)
Delete a group.
Definition: gig.cpp:6174
double EG2Attack
Attack time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:494
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
Definition: DLS.h:403
bool InvertAttenuationController
Inverts the values coming from the defined Attenuation Controller.
Definition: gig.h:547
vcf_cutoff_ctrl_none
Defines how the filter cutoff frequency is controlled by.
Definition: gig.h:214
double LFO1Frequency
Frequency of the sample amplitude LFO (0.10 - 10.00 Hz).
Definition: gig.h:486
Ordinary RIFF Chunk.
Definition: RIFF.h:218
uint32_t LoopID
Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (only...
Definition: gig.h:747
type_none
Defines possible controllers.
Definition: gig.h:246
bool LFO1FlipPhase
Inverts phase of the sample amplitude LFO wave.
Definition: gig.h:490
uint8_t AltSustain1Key
Key triggering alternate sustain samples.
Definition: gig.h:998
void DeleteSample(Sample *pSample)
Delete a sample.
Definition: gig.cpp:5625
int16_t FineTune
in cents
Definition: gig.h:1198
bool LFO3Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:518
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
Definition: gig.cpp:5272
loop_type_normal
Standard types of sample loops.
Definition: gig.h:126
double LFO3Frequency
Frequency of the sample pitch LFO (0.10 - 10.00 Hz).
Definition: gig.h:514
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file...
Definition: RIFF.cpp:2207
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
Definition: gig.h:1323
uint32_t LoopLength
Length of the looping area (in sample points).
Definition: DLS.h:235
ScriptGroup * AddScriptGroup()
Add new instrument script group.
Definition: gig.cpp:6251
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
Definition: gig.h:855
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field...
Definition: gig.h:740
bool LFO1Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:491
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
Definition: RIFF.h:222
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
Definition: gig.cpp:6219
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
Definition: RIFF.cpp:256
~Sample()
Destructor.
Definition: gig.cpp:1471
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file&#39;s checksum table with those n...
Definition: gig.cpp:6034
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Definition: gig.cpp:5938
Sample * GetNextSample()
Returns the next Sample of the Group.
Definition: gig.cpp:5445
uint8_t EG2ControllerReleaseInfluence
Amount EG2 Controller has influence on the EG2 Release time (0 - 3, where 0 means off)...
Definition: gig.h:504
Used for indicating the progress of a certain task.
Definition: RIFF.h:204
file_offset_t ReadAndLoop(void *pBuffer, file_offset_t SampleCount, playback_state_t *pPlaybackState, DimensionRegion *pDimRgn, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the position stored in pPlaybackState into the buffer ...
Definition: gig.cpp:959
uint16_t EG2PreAttack
Preattack value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:493
file_offset_t Write(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Writes WordCount number of data words with given WordSize from the buffer pointed by pData...
Definition: RIFF.cpp:388
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
Definition: gig.h:746
bool LFO2Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:510
uint32_t GetListType() const
Returns unsigned integer representation of the list&#39;s ID.
Definition: RIFF.h:298
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
Definition: gig.h:745
file_offset_t ReadInt8(int8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:461
uint32_t GetWaveDataCRC32Checksum()
Returns the CRC-32 checksum of the sample&#39;s raw wave form data at the time when this sample&#39;s wave fo...
Definition: gig.cpp:1417
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it&#39;s in the gig) ...
Definition: gig.h:792
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Definition: gig.cpp:3799
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: gig.cpp:5563
bool EG1ControllerInvert
Invert values coming from defined EG1 controller.
Definition: gig.h:482
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: DLS.cpp:1309
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0, int index=-1)
Constructor.
Definition: gig.cpp:390
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL...
Definition: DLS.h:500
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
Definition: gig.cpp:5897
uint16_t LFO2ControlDepth
Controller depth influencing filter cutoff LFO pitch (0 - 1200).
Definition: gig.h:507
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
Definition: DLS.h:234
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
Definition: gig.cpp:5392
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:408
String Name
Name of this script group. For example to be displayed in an instrument editor.
Definition: gig.h:1150
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame...
Definition: gig.h:786
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
Definition: gig.cpp:1323
int16_t EG3Depth
Depth of the sample pitch EG (-1200 - +1200).
Definition: gig.h:513
bool GetAutoLoad()
Returns whether automatic loading is enabled.
Definition: gig.cpp:6566
uint8_t VCFKeyboardTrackingBreakpoint
See VCFKeyboardTracking (0 - 127).
Definition: gig.h:532
eg2_ctrl_t EG2Controller
MIDI Controller which has influence on filter cutoff EG parameters (attack, decay, release).
Definition: gig.h:500
void * LoadChunkData()
Load chunk body into RAM.
Definition: RIFF.cpp:809
bool VCFCutoffControllerInvert
Inverts values coming from the defined cutoff controller.
Definition: gig.h:523
file_offset_t NullExtensionSize
The buffer might be bigger than the actual data, if that&#39;s the case that unused space at the end of t...
Definition: gig.h:110
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
Definition: gig.cpp:4182
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
Definition: gig.cpp:5196
double EG2Release
Release time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:499
uint8_t EG1ControllerReleaseInfluence
Amount EG1 Controller has influence on the EG1 Release time (0 - 3, where 0 means off)...
Definition: gig.h:485
uint8_t EG2ControllerDecayInfluence
Amount EG2 Controller has influence on the EG2 Decay time (0 - 3, where 0 means off).
Definition: gig.h:503
~Region()
Destructor.
Definition: gig.cpp:3985
bool Polyphonic
If alternator should step forward only when all notes are off.
Definition: gig.h:1050
Abstract base class for all MIDI rules.
Definition: gig.h:926
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
Definition: gig.cpp:4509
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3070
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file&#39;s current instruments, samples, groups and settings to the respective RIFF chu...
Definition: gig.cpp:6310
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
Definition: gig.h:788
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:750
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:407
curve_type_t ReleaseVelocityResponseCurve
Defines a transformation curve to the incoming release veloctiy values affecting envelope times...
Definition: gig.h:537
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension&#39;s controller and number of...
Definition: gig.h:853
uint8_t zones
Number of zones the dimension has.
Definition: gig.h:336
vcf_type_lowpass
Defines which frequencies are filtered by the VCF.
Definition: gig.h:351
uint8_t AttenuationControllerThreshold
0-127
Definition: gig.h:548
buffer_t GetCache()
Returns current cached sample points.
Definition: gig.cpp:808
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3118
void Resize(file_offset_t NewSize)
Resize chunk.
Definition: RIFF.cpp:880
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
Definition: gig.h:737
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value...
Definition: gig.cpp:1949
RIFF File.
Definition: RIFF.h:344
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Definition: RIFF.cpp:1323
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
Definition: gig.cpp:5371
file_offset_t Read(void *pBuffer, file_offset_t SampleCount, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
Definition: gig.cpp:1134
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
Definition: DLS.cpp:596
int16_t LFO3InternalDepth
Firm depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:515
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
Definition: gig.cpp:1963
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
Definition: DLS.h:319
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
Definition: gig.cpp:5570
double EG2Decay2
Only if EG2InfiniteSustain == false: 2nd stage decay time of the filter cutoff EG (0...
Definition: gig.h:496
file_offset_t GetNewSize() const
New chunk size if it was modified with Resize(), otherwise value returned will be equal to GetSize()...
Definition: RIFF.h:226
int32_t Attenuation
in dB
Definition: gig.h:1196
Encapsulates sample waves used for playback.
Definition: DLS.h:396
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: gig.cpp:4799
type_t type
Controller type.
Definition: gig.h:248
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
Definition: gig.h:249
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
Definition: gig.h:587
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
Definition: RIFF.cpp:1275
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
Definition: DLS.h:400
curve_type_t VelocityResponseCurve
Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don&#39;t...
Definition: gig.h:534
File * GetFile() const
Returns pointer to the chunk&#39;s File object.
Definition: RIFF.h:223
uint16_t EG1Sustain
Sustain value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:478
Sample * GetSample(uint index)
Returns Sample object of index.
Definition: gig.cpp:5581
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Definition: RIFF.cpp:1191
String GetFileName()
File name of this DLS file.
Definition: DLS.cpp:1678
Real-time instrument script (gig format extension).
Definition: gig.h:1100
bool SetMode(stream_mode_t NewMode)
Change file access mode.
Definition: RIFF.cpp:1737
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3058
smpte_format_no_offset
Society of Motion Pictures and Television E time format.
Definition: gig.h:138
Gigasampler/GigaStudio specific classes and definitions.
Definition: gig.h:94
float __range_max
Only for internal usage, do not modify!
Definition: RIFF.h:209
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
Definition: gig.h:554
virtual void CopyAssign(const DimensionRegion *orig)
Make a (semi) deep copy of the DimensionRegion object given by orig and assign it to this object...
Definition: gig.cpp:1800
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks. ...
Definition: gig.cpp:3298
uint8_t VelocityResponseDepth
Dynamic range of velocity affecting amplitude (0 - 4) (usually you don&#39;t have to interpret this param...
Definition: gig.h:535
uint32_t LoopFraction
The fractional value specifies a fraction of a sample at which to loop. This allows a loop to be fine...
Definition: gig.h:752
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0, 4 or 6)
Definition: gig.h:755
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
Definition: gig.cpp:5734
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
Definition: DLS.cpp:769
Group of instrument scripts (gig format extension).
Definition: gig.h:1148
file_offset_t GetFilePos() const
Current, actual offset of chunk data body start in file.
Definition: RIFF.h:228
Language_t
Definition: gig.h:1108
int8_t Pan
Panorama / Balance (-64..0..63 <-> left..middle..right)
Definition: gig.h:544
Provides convenient access to Gigasampler/GigaStudio .gig files.
Definition: gig.h:1320
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
Definition: gig.cpp:4496
MIDI rule for instruments with legato samples.
Definition: gig.h:988
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3091
range_t KeyRange
Definition: DLS.h:433
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: DLS.cpp:970
Sample * GetFirstSample()
Returns the first Sample of this Group.
Definition: gig.cpp:5427
dimension_def_t * GetDimensionDefinition(dimension_t type)
Searches in the current Region for a dimension of the given dimension type and returns the precise co...
Definition: gig.cpp:3978
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample&#39;s raw audio wave data.
Definition: gig.cpp:1446
file_offset_t GetCurrentFileSize() const
Returns the current size of this file (in bytes) as it is currently yet stored on disk...
Definition: RIFF.cpp:2114
uint16_t EG2Sustain
Sustain value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:498
uint32_t Instruments
Reflects the number of available Instrument objects.
Definition: DLS.h:501
Provides all neccessary information for the synthesis of a DLS Instrument.
Definition: DLS.h:461
Provides access to a Gigasampler/GigaStudio instrument.
Definition: gig.h:1183
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
Definition: gig.cpp:5292
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Definition: gig.cpp:6150
bool SustainDefeat
If true: Sustain pedal will not hold a note.
Definition: gig.h:550
Encoding_t Encoding
Format the script&#39;s source code text is encoded with.
Definition: gig.h:1114
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
Definition: gig.h:791
virtual void CopyAssign(const Instrument *orig)
Make a (semi) deep copy of the Instrument object given by orig and assign it to this object...
Definition: gig.cpp:5309
String libraryName()
Returns the name of this C++ library.
Definition: gig.cpp:6602
int32_t Gain
Definition: DLS.h:369
Quadtuple version number ("major.minor.release.build").
Definition: DLS.h:111
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:410
void MoveTo(Instrument *dst)
Move this instrument at the position before.
Definition: gig.cpp:4997
double LFO2Frequency
Frequency of the filter cutoff LFO (0.10 - 10.00 Hz).
Definition: gig.h:505
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Definition: gig.h:741
uint16_t EG1PreAttack
Preattack value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:473
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
Definition: gig.cpp:5135
void CopyAssign(const Script *orig)
Make a (semi) deep copy of the Script object given by orig and assign it to this object.
Definition: gig.cpp:4520
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
Definition: gig.h:335
file_offset_t GetPos() const
Position within the chunk data body (starting with 0).
Definition: RIFF.h:227
selector_t Selector
Method by which pattern is chosen.
Definition: gig.h:1046
uint8_t out_start
Start position of fade out.
Definition: gig.h:369
uint8_t VCFCutoff
Max. cutoff frequency.
Definition: gig.h:524
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order...
Definition: gig.cpp:3379
DLS specific classes and definitions.
Definition: DLS.h:104
eg_opt_t EG1Options
[gig extension]: Behavior options which should be used for envelope generator 1 (volume amplitude EG)...
Definition: gig.h:555
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
Definition: DLS.h:348
uint32_t Manufacturer
Specifies the MIDI Manufacturer&#39;s Association (MMA) Manufacturer code for the sampler intended to rec...
Definition: gig.h:739
uint8_t high
High value of range.
Definition: gig.h:103
file_offset_t ReadInt16(int16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:535
MIDI rule to automatically cycle through specified sequences of different articulations.
Definition: gig.h:1020
Reflects the current playback state for a sample.
Definition: gig.h:377
General dimension definition.
Definition: gig.h:333
void CopyAssignMeta(const Sample *orig)
Make a (semi) deep copy of the Sample object given by orig (without the actual waveform data) and ass...
Definition: gig.cpp:504
eg1_ctrl_t EG1Controller
MIDI Controller which has influence on sample amplitude EG parameters (attack, decay, release).
Definition: gig.h:481
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:337
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
Definition: DLS.cpp:1113
void DeleteScript(Script *pScript)
Delete an instrument script.
Definition: gig.cpp:4632
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: gig.cpp:568
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3082
vcf_res_ctrl_t VCFResonanceController
Specifies which external controller has influence on the filter resonance Q.
Definition: gig.h:530
Is not compressed at all (default).
Definition: gig.h:1106
curve_type_t VCFVelocityCurve
Defines a transformation curve for the incoming velocity values, affecting the VCF.
Definition: gig.h:525
file_offset_t ReadUint8(uint8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:498
uint8_t EG1ControllerDecayInfluence
Amount EG1 Controller has influence on the EG1 Decay time (0 - 3, where 0 means off).
Definition: gig.h:484
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Definition: RIFF.cpp:1173
Defines Region information of an Instrument.
Definition: DLS.h:431
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Definition: gig.cpp:3030
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
Definition: gig.cpp:4137
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3046
double EG1Attack
Attack time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:474
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Definition: RIFF.cpp:1253
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Definition: gig.cpp:6270
Region * GetNextRegion()
Returns the next Region of the instrument.
Definition: gig.cpp:4943
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file&#39;s current instruments, samples and settings to the respective RIFF chunks...
Definition: DLS.cpp:1698
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: DLS.cpp:1862