libgig  4.4.1
gig.cpp
1 /***************************************************************************
2  * *
3  * libgig - C++ cross-platform Gigasampler format file access library *
4  * *
5  * Copyright (C) 2003-2021 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
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  pCk3gix->SetPos(0);
416 
417  uint16_t iSampleGroup = pCk3gix->ReadInt16();
418  pGroup = pFile->GetGroup(iSampleGroup);
419  } else { // '3gix' chunk missing
420  // by default assigned to that mandatory "Default Group"
421  pGroup = pFile->GetGroup(0);
422  }
423 
424  pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
425  if (pCkSmpl) {
426  pCkSmpl->SetPos(0);
427 
428  Manufacturer = pCkSmpl->ReadInt32();
429  Product = pCkSmpl->ReadInt32();
430  SamplePeriod = pCkSmpl->ReadInt32();
431  MIDIUnityNote = pCkSmpl->ReadInt32();
432  FineTune = pCkSmpl->ReadInt32();
433  pCkSmpl->Read(&SMPTEFormat, 1, 4);
434  SMPTEOffset = pCkSmpl->ReadInt32();
435  Loops = pCkSmpl->ReadInt32();
436  pCkSmpl->ReadInt32(); // manufByt
437  LoopID = pCkSmpl->ReadInt32();
438  pCkSmpl->Read(&LoopType, 1, 4);
439  LoopStart = pCkSmpl->ReadInt32();
440  LoopEnd = pCkSmpl->ReadInt32();
441  LoopFraction = pCkSmpl->ReadInt32();
442  LoopPlayCount = pCkSmpl->ReadInt32();
443  } else { // 'smpl' chunk missing
444  // use default values
445  Manufacturer = 0;
446  Product = 0;
447  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
448  MIDIUnityNote = 60;
449  FineTune = 0;
451  SMPTEOffset = 0;
452  Loops = 0;
453  LoopID = 0;
455  LoopStart = 0;
456  LoopEnd = 0;
457  LoopFraction = 0;
458  LoopPlayCount = 0;
459  }
460 
461  FrameTable = NULL;
462  SamplePos = 0;
463  RAMCache.Size = 0;
464  RAMCache.pStart = NULL;
466 
467  if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
468 
469  RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
470  Compressed = ewav;
471  Dithered = false;
472  TruncatedBits = 0;
473  if (Compressed) {
474  ewav->SetPos(0);
475 
476  uint32_t version = ewav->ReadInt32();
477  if (version > 2 && BitDepth == 24) {
478  Dithered = ewav->ReadInt32();
479  ewav->SetPos(Channels == 2 ? 84 : 64);
480  TruncatedBits = ewav->ReadInt32();
481  }
482  ScanCompressedSample();
483  }
484 
485  // we use a buffer for decompression only
487  InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE];
488  InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE;
489  }
490  FrameOffset = 0; // just for streaming compressed samples
491 
492  LoopSize = LoopEnd - LoopStart + 1;
493  }
494 
510  void Sample::CopyAssignMeta(const Sample* orig) {
511  // handle base classes
513 
514  // handle actual own attributes of this class
515  Manufacturer = orig->Manufacturer;
516  Product = orig->Product;
517  SamplePeriod = orig->SamplePeriod;
519  FineTune = orig->FineTune;
520  SMPTEFormat = orig->SMPTEFormat;
521  SMPTEOffset = orig->SMPTEOffset;
522  Loops = orig->Loops;
523  LoopID = orig->LoopID;
524  LoopType = orig->LoopType;
525  LoopStart = orig->LoopStart;
526  LoopEnd = orig->LoopEnd;
527  LoopSize = orig->LoopSize;
528  LoopFraction = orig->LoopFraction;
530 
531  // schedule resizing this sample to the given sample's size
532  Resize(orig->GetSize());
533  }
534 
546  void Sample::CopyAssignWave(const Sample* orig) {
547  const int iReadAtOnce = 32*1024;
548  char* buf = new char[iReadAtOnce * orig->FrameSize];
549  Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
550  file_offset_t restorePos = pOrig->GetPos();
551  pOrig->SetPos(0);
552  SetPos(0);
553  for (file_offset_t n = pOrig->Read(buf, iReadAtOnce); n;
554  n = pOrig->Read(buf, iReadAtOnce))
555  {
556  Write(buf, n);
557  }
558  pOrig->SetPos(restorePos);
559  delete [] buf;
560  }
561 
574  void Sample::UpdateChunks(progress_t* pProgress) {
575  // first update base class's chunks
576  DLS::Sample::UpdateChunks(pProgress);
577 
578  // make sure 'smpl' chunk exists
579  pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL);
580  if (!pCkSmpl) {
581  pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
582  memset(pCkSmpl->LoadChunkData(), 0, 60);
583  }
584  // update 'smpl' chunk
585  uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
586  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
587  store32(&pData[0], Manufacturer);
588  store32(&pData[4], Product);
589  store32(&pData[8], SamplePeriod);
590  store32(&pData[12], MIDIUnityNote);
591  store32(&pData[16], FineTune);
592  store32(&pData[20], SMPTEFormat);
593  store32(&pData[24], SMPTEOffset);
594  store32(&pData[28], Loops);
595 
596  // we skip 'manufByt' for now (4 bytes)
597 
598  store32(&pData[36], LoopID);
599  store32(&pData[40], LoopType);
600  store32(&pData[44], LoopStart);
601  store32(&pData[48], LoopEnd);
602  store32(&pData[52], LoopFraction);
603  store32(&pData[56], LoopPlayCount);
604 
605  // make sure '3gix' chunk exists
606  pCk3gix = pWaveList->GetSubChunk(CHUNK_ID_3GIX);
607  if (!pCk3gix) pCk3gix = pWaveList->AddSubChunk(CHUNK_ID_3GIX, 4);
608  // determine appropriate sample group index (to be stored in chunk)
609  uint16_t iSampleGroup = 0; // 0 refers to default sample group
610  File* pFile = static_cast<File*>(pParent);
611  if (pFile->pGroups) {
612  std::vector<Group*>::iterator iter = pFile->pGroups->begin();
613  std::vector<Group*>::iterator end = pFile->pGroups->end();
614  for (int i = 0; iter != end; i++, iter++) {
615  if (*iter == pGroup) {
616  iSampleGroup = i;
617  break; // found
618  }
619  }
620  }
621  // update '3gix' chunk
622  pData = (uint8_t*) pCk3gix->LoadChunkData();
623  store16(&pData[0], iSampleGroup);
624 
625  // if the library user toggled the "Compressed" attribute from true to
626  // false, then the EWAV chunk associated with compressed samples needs
627  // to be deleted
628  RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
629  if (ewav && !Compressed) {
630  pWaveList->DeleteSubChunk(ewav);
631  }
632  }
633 
635  void Sample::ScanCompressedSample() {
636  //TODO: we have to add some more scans here (e.g. determine compression rate)
637  this->SamplesTotal = 0;
638  std::list<file_offset_t> frameOffsets;
639 
640  SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
641  WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
642 
643  // Scanning
644  pCkData->SetPos(0);
645  if (Channels == 2) { // Stereo
646  for (int i = 0 ; ; i++) {
647  // for 24 bit samples every 8:th frame offset is
648  // stored, to save some memory
649  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
650 
651  const int mode_l = pCkData->ReadUint8();
652  const int mode_r = pCkData->ReadUint8();
653  if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
654  const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
655 
656  if (pCkData->RemainingBytes() <= frameSize) {
658  ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
659  (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
661  break;
662  }
664  pCkData->SetPos(frameSize, RIFF::stream_curpos);
665  }
666  }
667  else { // Mono
668  for (int i = 0 ; ; i++) {
669  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
670 
671  const int mode = pCkData->ReadUint8();
672  if (mode > 5) throw gig::Exception("Unknown compression mode");
673  const file_offset_t frameSize = bytesPerFrame[mode];
674 
675  if (pCkData->RemainingBytes() <= frameSize) {
677  ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
679  break;
680  }
682  pCkData->SetPos(frameSize, RIFF::stream_curpos);
683  }
684  }
685  pCkData->SetPos(0);
686 
687  // Build the frames table (which is used for fast resolving of a frame's chunk offset)
688  if (FrameTable) delete[] FrameTable;
689  FrameTable = new file_offset_t[frameOffsets.size()];
690  std::list<file_offset_t>::iterator end = frameOffsets.end();
691  std::list<file_offset_t>::iterator iter = frameOffsets.begin();
692  for (int i = 0; iter != end; i++, iter++) {
693  FrameTable[i] = *iter;
694  }
695  }
696 
707  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
708  }
709 
732  buffer_t Sample::LoadSampleData(file_offset_t SampleCount) {
733  return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
734  }
735 
756  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
757  }
758 
791  buffer_t Sample::LoadSampleDataWithNullSamplesExtension(file_offset_t SampleCount, uint NullSamplesCount) {
792  if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
793  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
794  file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
795  SetPos(0); // reset read position to begin of sample
796  RAMCache.pStart = new int8_t[allocationsize];
797  RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
798  RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
799  // fill the remaining buffer space with silence samples
800  memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
801  return GetCache();
802  }
803 
815  // return a copy of the buffer_t structure
816  buffer_t result;
817  result.Size = this->RAMCache.Size;
818  result.pStart = this->RAMCache.pStart;
820  return result;
821  }
822 
830  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
831  RAMCache.pStart = NULL;
832  RAMCache.Size = 0;
834  }
835 
866  void Sample::Resize(file_offset_t NewSize) {
867  if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
868  DLS::Sample::Resize(NewSize);
869  }
870 
892  file_offset_t Sample::SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence) {
893  if (Compressed) {
894  switch (Whence) {
895  case RIFF::stream_curpos:
896  this->SamplePos += SampleCount;
897  break;
898  case RIFF::stream_end:
899  this->SamplePos = this->SamplesTotal - 1 - SampleCount;
900  break;
901  case RIFF::stream_backward:
902  this->SamplePos -= SampleCount;
903  break;
904  case RIFF::stream_start: default:
905  this->SamplePos = SampleCount;
906  break;
907  }
908  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
909 
910  file_offset_t frame = this->SamplePos / 2048; // to which frame to jump
911  this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
912  pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
913  return this->SamplePos;
914  }
915  else { // not compressed
916  file_offset_t orderedBytes = SampleCount * this->FrameSize;
917  file_offset_t result = pCkData->SetPos(orderedBytes, Whence);
918  return (result == orderedBytes) ? SampleCount
919  : result / this->FrameSize;
920  }
921  }
922 
926  file_offset_t Sample::GetPos() const {
927  if (Compressed) return SamplePos;
928  else return pCkData->GetPos() / FrameSize;
929  }
930 
965  file_offset_t Sample::ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState,
966  DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
967  file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
968  uint8_t* pDst = (uint8_t*) pBuffer;
969 
970  SetPos(pPlaybackState->position); // recover position from the last time
971 
972  if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
973 
974  const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
975  const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
976 
977  if (GetPos() <= loopEnd) {
978  switch (loop.LoopType) {
979 
980  case loop_type_bidirectional: { //TODO: not tested yet!
981  do {
982  // if not endless loop check if max. number of loop cycles have been passed
983  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
984 
985  if (!pPlaybackState->reverse) { // forward playback
986  do {
987  samplestoloopend = loopEnd - GetPos();
988  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
989  samplestoread -= readsamples;
990  totalreadsamples += readsamples;
991  if (readsamples == samplestoloopend) {
992  pPlaybackState->reverse = true;
993  break;
994  }
995  } while (samplestoread && readsamples);
996  }
997  else { // backward playback
998 
999  // as we can only read forward from disk, we have to
1000  // determine the end position within the loop first,
1001  // read forward from that 'end' and finally after
1002  // reading, swap all sample frames so it reflects
1003  // backward playback
1004 
1005  file_offset_t swapareastart = totalreadsamples;
1006  file_offset_t loopoffset = GetPos() - loop.LoopStart;
1007  file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
1008  file_offset_t reverseplaybackend = GetPos() - samplestoreadinloop;
1009 
1010  SetPos(reverseplaybackend);
1011 
1012  // read samples for backward playback
1013  do {
1014  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
1015  samplestoreadinloop -= readsamples;
1016  samplestoread -= readsamples;
1017  totalreadsamples += readsamples;
1018  } while (samplestoreadinloop && readsamples);
1019 
1020  SetPos(reverseplaybackend); // pretend we really read backwards
1021 
1022  if (reverseplaybackend == loop.LoopStart) {
1023  pPlaybackState->loop_cycles_left--;
1024  pPlaybackState->reverse = false;
1025  }
1026 
1027  // reverse the sample frames for backward playback
1028  if (totalreadsamples > swapareastart) //FIXME: this if() is just a crash workaround for now (#102), but totalreadsamples <= swapareastart should never be the case, so there's probably still a bug above!
1029  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1030  }
1031  } while (samplestoread && readsamples);
1032  break;
1033  }
1034 
1035  case loop_type_backward: { // TODO: not tested yet!
1036  // forward playback (not entered the loop yet)
1037  if (!pPlaybackState->reverse) do {
1038  samplestoloopend = loopEnd - GetPos();
1039  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1040  samplestoread -= readsamples;
1041  totalreadsamples += readsamples;
1042  if (readsamples == samplestoloopend) {
1043  pPlaybackState->reverse = true;
1044  break;
1045  }
1046  } while (samplestoread && readsamples);
1047 
1048  if (!samplestoread) break;
1049 
1050  // as we can only read forward from disk, we have to
1051  // determine the end position within the loop first,
1052  // read forward from that 'end' and finally after
1053  // reading, swap all sample frames so it reflects
1054  // backward playback
1055 
1056  file_offset_t swapareastart = totalreadsamples;
1057  file_offset_t loopoffset = GetPos() - loop.LoopStart;
1058  file_offset_t samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
1059  : samplestoread;
1060  file_offset_t reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
1061 
1062  SetPos(reverseplaybackend);
1063 
1064  // read samples for backward playback
1065  do {
1066  // if not endless loop check if max. number of loop cycles have been passed
1067  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1068  samplestoloopend = loopEnd - GetPos();
1069  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1070  samplestoreadinloop -= readsamples;
1071  samplestoread -= readsamples;
1072  totalreadsamples += readsamples;
1073  if (readsamples == samplestoloopend) {
1074  pPlaybackState->loop_cycles_left--;
1075  SetPos(loop.LoopStart);
1076  }
1077  } while (samplestoreadinloop && readsamples);
1078 
1079  SetPos(reverseplaybackend); // pretend we really read backwards
1080 
1081  // reverse the sample frames for backward playback
1082  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1083  break;
1084  }
1085 
1086  default: case loop_type_normal: {
1087  do {
1088  // if not endless loop check if max. number of loop cycles have been passed
1089  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1090  samplestoloopend = loopEnd - GetPos();
1091  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1092  samplestoread -= readsamples;
1093  totalreadsamples += readsamples;
1094  if (readsamples == samplestoloopend) {
1095  pPlaybackState->loop_cycles_left--;
1096  SetPos(loop.LoopStart);
1097  }
1098  } while (samplestoread && readsamples);
1099  break;
1100  }
1101  }
1102  }
1103  }
1104 
1105  // read on without looping
1106  if (samplestoread) do {
1107  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
1108  samplestoread -= readsamples;
1109  totalreadsamples += readsamples;
1110  } while (readsamples && samplestoread);
1111 
1112  // store current position
1113  pPlaybackState->position = GetPos();
1114 
1115  return totalreadsamples;
1116  }
1117 
1140  file_offset_t Sample::Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer) {
1141  if (SampleCount == 0) return 0;
1142  if (!Compressed) {
1143  if (BitDepth == 24) {
1144  return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1145  }
1146  else { // 16 bit
1147  // (pCkData->Read does endian correction)
1148  return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
1149  : pCkData->Read(pBuffer, SampleCount, 2);
1150  }
1151  }
1152  else {
1153  if (this->SamplePos >= this->SamplesTotal) return 0;
1154  //TODO: efficiency: maybe we should test for an average compression rate
1155  file_offset_t assumedsize = GuessSize(SampleCount),
1156  remainingbytes = 0, // remaining bytes in the local buffer
1157  remainingsamples = SampleCount,
1158  copysamples, skipsamples,
1159  currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
1160  this->FrameOffset = 0;
1161 
1162  buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
1163 
1164  // if decompression buffer too small, then reduce amount of samples to read
1165  if (pDecompressionBuffer->Size < assumedsize) {
1166  std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1167  SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1168  remainingsamples = SampleCount;
1169  assumedsize = GuessSize(SampleCount);
1170  }
1171 
1172  unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1173  int16_t* pDst = static_cast<int16_t*>(pBuffer);
1174  uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1175  remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1176 
1177  while (remainingsamples && remainingbytes) {
1178  file_offset_t framesamples = SamplesPerFrame;
1179  file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1180 
1181  int mode_l = *pSrc++, mode_r = 0;
1182 
1183  if (Channels == 2) {
1184  mode_r = *pSrc++;
1185  framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1186  rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1187  nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1188  if (remainingbytes < framebytes) { // last frame in sample
1189  framesamples = SamplesInLastFrame;
1190  if (mode_l == 4 && (framesamples & 1)) {
1191  rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1192  }
1193  else {
1194  rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1195  }
1196  }
1197  }
1198  else {
1199  framebytes = bytesPerFrame[mode_l] + 1;
1200  nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1201  if (remainingbytes < framebytes) {
1202  framesamples = SamplesInLastFrame;
1203  }
1204  }
1205 
1206  // determine how many samples in this frame to skip and read
1207  if (currentframeoffset + remainingsamples >= framesamples) {
1208  if (currentframeoffset <= framesamples) {
1209  copysamples = framesamples - currentframeoffset;
1210  skipsamples = currentframeoffset;
1211  }
1212  else {
1213  copysamples = 0;
1214  skipsamples = framesamples;
1215  }
1216  }
1217  else {
1218  // This frame has enough data for pBuffer, but not
1219  // all of the frame is needed. Set file position
1220  // to start of this frame for next call to Read.
1221  copysamples = remainingsamples;
1222  skipsamples = currentframeoffset;
1223  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1224  this->FrameOffset = currentframeoffset + copysamples;
1225  }
1226  remainingsamples -= copysamples;
1227 
1228  if (remainingbytes > framebytes) {
1229  remainingbytes -= framebytes;
1230  if (remainingsamples == 0 &&
1231  currentframeoffset + copysamples == framesamples) {
1232  // This frame has enough data for pBuffer, and
1233  // all of the frame is needed. Set file
1234  // position to start of next frame for next
1235  // call to Read. FrameOffset is 0.
1236  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1237  }
1238  }
1239  else remainingbytes = 0;
1240 
1241  currentframeoffset -= skipsamples;
1242 
1243  if (copysamples == 0) {
1244  // skip this frame
1245  pSrc += framebytes - Channels;
1246  }
1247  else {
1248  const unsigned char* const param_l = pSrc;
1249  if (BitDepth == 24) {
1250  if (mode_l != 2) pSrc += 12;
1251 
1252  if (Channels == 2) { // Stereo
1253  const unsigned char* const param_r = pSrc;
1254  if (mode_r != 2) pSrc += 12;
1255 
1256  Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1257  skipsamples, copysamples, TruncatedBits);
1258  Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1259  skipsamples, copysamples, TruncatedBits);
1260  pDst24 += copysamples * 6;
1261  }
1262  else { // Mono
1263  Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1264  skipsamples, copysamples, TruncatedBits);
1265  pDst24 += copysamples * 3;
1266  }
1267  }
1268  else { // 16 bit
1269  if (mode_l) pSrc += 4;
1270 
1271  int step;
1272  if (Channels == 2) { // Stereo
1273  const unsigned char* const param_r = pSrc;
1274  if (mode_r) pSrc += 4;
1275 
1276  step = (2 - mode_l) + (2 - mode_r);
1277  Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1278  Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1279  skipsamples, copysamples);
1280  pDst += copysamples << 1;
1281  }
1282  else { // Mono
1283  step = 2 - mode_l;
1284  Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1285  pDst += copysamples;
1286  }
1287  }
1288  pSrc += nextFrameOffset;
1289  }
1290 
1291  // reload from disk to local buffer if needed
1292  if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1293  assumedsize = GuessSize(remainingsamples);
1294  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1295  if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1296  remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1297  pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1298  }
1299  } // while
1300 
1301  this->SamplePos += (SampleCount - remainingsamples);
1302  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1303  return (SampleCount - remainingsamples);
1304  }
1305  }
1306 
1329  file_offset_t Sample::Write(void* pBuffer, file_offset_t SampleCount) {
1330  if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1331 
1332  // if this is the first write in this sample, reset the
1333  // checksum calculator
1334  if (pCkData->GetPos() == 0) {
1335  __resetCRC(crc);
1336  }
1337  if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1338  file_offset_t res;
1339  if (BitDepth == 24) {
1340  res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1341  } else { // 16 bit
1342  res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1343  : pCkData->Write(pBuffer, SampleCount, 2);
1344  }
1345  __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1346 
1347  // if this is the last write, update the checksum chunk in the
1348  // file
1349  if (pCkData->GetPos() == std::min(pCkData->GetSize(), pCkData->GetNewSize())) {
1350  __finalizeCRC(crc);
1351  File* pFile = static_cast<File*>(GetParent());
1352  pFile->SetSampleChecksum(this, crc);
1353  }
1354  return res;
1355  }
1356 
1373  buffer_t Sample::CreateDecompressionBuffer(file_offset_t MaxReadSize) {
1374  buffer_t result;
1375  const double worstCaseHeaderOverhead =
1376  (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1377  result.Size = (file_offset_t) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1378  result.pStart = new int8_t[result.Size];
1379  result.NullExtensionSize = 0;
1380  return result;
1381  }
1382 
1390  void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1391  if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1392  delete[] (int8_t*) DecompressionBuffer.pStart;
1393  DecompressionBuffer.pStart = NULL;
1394  DecompressionBuffer.Size = 0;
1395  DecompressionBuffer.NullExtensionSize = 0;
1396  }
1397  }
1398 
1408  return pGroup;
1409  }
1410 
1424  return crc;
1425  }
1426 
1452  bool Sample::VerifyWaveData(uint32_t* pActually) {
1453  //File* pFile = static_cast<File*>(GetParent());
1454  uint32_t crc = CalculateWaveDataChecksum();
1455  if (pActually) *pActually = crc;
1456  return crc == this->crc;
1457  }
1458 
1459  uint32_t Sample::CalculateWaveDataChecksum() {
1460  const size_t sz = 20*1024; // 20kB buffer size
1461  std::vector<uint8_t> buffer(sz);
1462  buffer.resize(sz);
1463 
1464  const size_t n = sz / FrameSize;
1465  SetPos(0);
1466  uint32_t crc = 0;
1467  __resetCRC(crc);
1468  while (true) {
1469  file_offset_t nRead = Read(&buffer[0], n);
1470  if (nRead <= 0) break;
1471  __calculateCRC(&buffer[0], nRead * FrameSize, crc);
1472  }
1473  __finalizeCRC(crc);
1474  return crc;
1475  }
1476 
1478  Instances--;
1480  delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1483  }
1484  if (FrameTable) delete[] FrameTable;
1485  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1486  }
1487 
1488 
1489 
1490 // *************** DimensionRegion ***************
1491 // *
1492 
1493  size_t DimensionRegion::Instances = 0;
1494  DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1495 
1496  DimensionRegion::DimensionRegion(Region* pParent, RIFF::List* _3ewl) : DLS::Sampler(_3ewl) {
1497  Instances++;
1498 
1499  pSample = NULL;
1500  pRegion = pParent;
1501 
1502  if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1503  else memset(&Crossfade, 0, 4);
1504 
1505  if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1506 
1507  RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1508  if (_3ewa) { // if '3ewa' chunk exists
1509  _3ewa->SetPos(0);
1510 
1511  _3ewa->ReadInt32(); // unknown, always == chunk size ?
1512  LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1513  EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1514  _3ewa->ReadInt16(); // unknown
1515  LFO1InternalDepth = _3ewa->ReadUint16();
1516  _3ewa->ReadInt16(); // unknown
1517  LFO3InternalDepth = _3ewa->ReadInt16();
1518  _3ewa->ReadInt16(); // unknown
1519  LFO1ControlDepth = _3ewa->ReadUint16();
1520  _3ewa->ReadInt16(); // unknown
1521  LFO3ControlDepth = _3ewa->ReadInt16();
1522  EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1523  EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1524  _3ewa->ReadInt16(); // unknown
1525  EG1Sustain = _3ewa->ReadUint16();
1526  EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1527  EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1528  uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1529  EG1ControllerInvert = eg1ctrloptions & 0x01;
1530  EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1531  EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1532  EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1533  EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1534  uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1535  EG2ControllerInvert = eg2ctrloptions & 0x01;
1536  EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1537  EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1538  EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1539  LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1540  EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1541  EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1542  _3ewa->ReadInt16(); // unknown
1543  EG2Sustain = _3ewa->ReadUint16();
1544  EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1545  _3ewa->ReadInt16(); // unknown
1546  LFO2ControlDepth = _3ewa->ReadUint16();
1547  LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1548  _3ewa->ReadInt16(); // unknown
1549  LFO2InternalDepth = _3ewa->ReadUint16();
1550  int32_t eg1decay2 = _3ewa->ReadInt32();
1551  EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1552  EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1553  _3ewa->ReadInt16(); // unknown
1554  EG1PreAttack = _3ewa->ReadUint16();
1555  int32_t eg2decay2 = _3ewa->ReadInt32();
1556  EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1557  EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1558  _3ewa->ReadInt16(); // unknown
1559  EG2PreAttack = _3ewa->ReadUint16();
1560  uint8_t velocityresponse = _3ewa->ReadUint8();
1561  if (velocityresponse < 5) {
1562  VelocityResponseCurve = curve_type_nonlinear;
1563  VelocityResponseDepth = velocityresponse;
1564  } else if (velocityresponse < 10) {
1565  VelocityResponseCurve = curve_type_linear;
1566  VelocityResponseDepth = velocityresponse - 5;
1567  } else if (velocityresponse < 15) {
1568  VelocityResponseCurve = curve_type_special;
1569  VelocityResponseDepth = velocityresponse - 10;
1570  } else {
1571  VelocityResponseCurve = curve_type_unknown;
1572  VelocityResponseDepth = 0;
1573  }
1574  uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1575  if (releasevelocityresponse < 5) {
1576  ReleaseVelocityResponseCurve = curve_type_nonlinear;
1577  ReleaseVelocityResponseDepth = releasevelocityresponse;
1578  } else if (releasevelocityresponse < 10) {
1579  ReleaseVelocityResponseCurve = curve_type_linear;
1580  ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1581  } else if (releasevelocityresponse < 15) {
1582  ReleaseVelocityResponseCurve = curve_type_special;
1583  ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1584  } else {
1585  ReleaseVelocityResponseCurve = curve_type_unknown;
1586  ReleaseVelocityResponseDepth = 0;
1587  }
1588  VelocityResponseCurveScaling = _3ewa->ReadUint8();
1589  AttenuationControllerThreshold = _3ewa->ReadInt8();
1590  _3ewa->ReadInt32(); // unknown
1591  SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1592  _3ewa->ReadInt16(); // unknown
1593  uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1594  PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1595  if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1596  else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1597  else DimensionBypass = dim_bypass_ctrl_none;
1598  uint8_t pan = _3ewa->ReadUint8();
1599  Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1600  SelfMask = _3ewa->ReadInt8() & 0x01;
1601  _3ewa->ReadInt8(); // unknown
1602  uint8_t lfo3ctrl = _3ewa->ReadUint8();
1603  LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1604  LFO3Sync = lfo3ctrl & 0x20; // bit 5
1605  InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1606  AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1607  uint8_t lfo2ctrl = _3ewa->ReadUint8();
1608  LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1609  LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1610  LFO2Sync = lfo2ctrl & 0x20; // bit 5
1611  bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1612  uint8_t lfo1ctrl = _3ewa->ReadUint8();
1613  LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1614  LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1615  LFO1Sync = lfo1ctrl & 0x40; // bit 6
1616  VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1618  uint16_t eg3depth = _3ewa->ReadUint16();
1619  EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1620  : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1621  _3ewa->ReadInt16(); // unknown
1622  ChannelOffset = _3ewa->ReadUint8() / 4;
1623  uint8_t regoptions = _3ewa->ReadUint8();
1624  MSDecode = regoptions & 0x01; // bit 0
1625  SustainDefeat = regoptions & 0x02; // bit 1
1626  _3ewa->ReadInt16(); // unknown
1627  VelocityUpperLimit = _3ewa->ReadInt8();
1628  _3ewa->ReadInt8(); // unknown
1629  _3ewa->ReadInt16(); // unknown
1630  ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1631  _3ewa->ReadInt8(); // unknown
1632  _3ewa->ReadInt8(); // unknown
1633  EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1634  uint8_t vcfcutoff = _3ewa->ReadUint8();
1635  VCFEnabled = vcfcutoff & 0x80; // bit 7
1636  VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1637  VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1638  uint8_t vcfvelscale = _3ewa->ReadUint8();
1639  VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1640  VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1641  _3ewa->ReadInt8(); // unknown
1642  uint8_t vcfresonance = _3ewa->ReadUint8();
1643  VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1644  VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1645  uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1646  VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1647  VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1648  uint8_t vcfvelocity = _3ewa->ReadUint8();
1649  VCFVelocityDynamicRange = vcfvelocity % 5;
1650  VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1651  VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1652  if (VCFType == vcf_type_lowpass) {
1653  if (lfo3ctrl & 0x40) // bit 6
1654  VCFType = vcf_type_lowpassturbo;
1655  }
1656  if (_3ewa->RemainingBytes() >= 8) {
1657  _3ewa->Read(DimensionUpperLimits, 1, 8);
1658  } else {
1659  memset(DimensionUpperLimits, 0, 8);
1660  }
1661  } else { // '3ewa' chunk does not exist yet
1662  // use default values
1663  LFO3Frequency = 1.0;
1664  EG3Attack = 0.0;
1665  LFO1InternalDepth = 0;
1666  LFO3InternalDepth = 0;
1667  LFO1ControlDepth = 0;
1668  LFO3ControlDepth = 0;
1669  EG1Attack = 0.0;
1670  EG1Decay1 = 0.005;
1671  EG1Sustain = 1000;
1672  EG1Release = 0.3;
1673  EG1Controller.type = eg1_ctrl_t::type_none;
1674  EG1Controller.controller_number = 0;
1675  EG1ControllerInvert = false;
1676  EG1ControllerAttackInfluence = 0;
1677  EG1ControllerDecayInfluence = 0;
1678  EG1ControllerReleaseInfluence = 0;
1679  EG2Controller.type = eg2_ctrl_t::type_none;
1680  EG2Controller.controller_number = 0;
1681  EG2ControllerInvert = false;
1682  EG2ControllerAttackInfluence = 0;
1683  EG2ControllerDecayInfluence = 0;
1684  EG2ControllerReleaseInfluence = 0;
1685  LFO1Frequency = 1.0;
1686  EG2Attack = 0.0;
1687  EG2Decay1 = 0.005;
1688  EG2Sustain = 1000;
1689  EG2Release = 60;
1690  LFO2ControlDepth = 0;
1691  LFO2Frequency = 1.0;
1692  LFO2InternalDepth = 0;
1693  EG1Decay2 = 0.0;
1694  EG1InfiniteSustain = true;
1695  EG1PreAttack = 0;
1696  EG2Decay2 = 0.0;
1697  EG2InfiniteSustain = true;
1698  EG2PreAttack = 0;
1699  VelocityResponseCurve = curve_type_nonlinear;
1700  VelocityResponseDepth = 3;
1701  ReleaseVelocityResponseCurve = curve_type_nonlinear;
1702  ReleaseVelocityResponseDepth = 3;
1703  VelocityResponseCurveScaling = 32;
1704  AttenuationControllerThreshold = 0;
1705  SampleStartOffset = 0;
1706  PitchTrack = true;
1707  DimensionBypass = dim_bypass_ctrl_none;
1708  Pan = 0;
1709  SelfMask = true;
1710  LFO3Controller = lfo3_ctrl_modwheel;
1711  LFO3Sync = false;
1712  InvertAttenuationController = false;
1713  AttenuationController.type = attenuation_ctrl_t::type_none;
1714  AttenuationController.controller_number = 0;
1715  LFO2Controller = lfo2_ctrl_internal;
1716  LFO2FlipPhase = false;
1717  LFO2Sync = false;
1718  LFO1Controller = lfo1_ctrl_internal;
1719  LFO1FlipPhase = false;
1720  LFO1Sync = false;
1721  VCFResonanceController = vcf_res_ctrl_none;
1722  EG3Depth = 0;
1723  ChannelOffset = 0;
1724  MSDecode = false;
1725  SustainDefeat = false;
1726  VelocityUpperLimit = 0;
1727  ReleaseTriggerDecay = 0;
1728  EG1Hold = false;
1729  VCFEnabled = false;
1730  VCFCutoff = 0;
1731  VCFCutoffController = vcf_cutoff_ctrl_none;
1732  VCFCutoffControllerInvert = false;
1733  VCFVelocityScale = 0;
1734  VCFResonance = 0;
1735  VCFResonanceDynamic = false;
1736  VCFKeyboardTracking = false;
1737  VCFKeyboardTrackingBreakpoint = 0;
1738  VCFVelocityDynamicRange = 0x04;
1739  VCFVelocityCurve = curve_type_linear;
1740  VCFType = vcf_type_lowpass;
1741  memset(DimensionUpperLimits, 127, 8);
1742  }
1743 
1744  // chunk for own format extensions, these will *NOT* work with Gigasampler/GigaStudio !
1745  RIFF::Chunk* lsde = _3ewl->GetSubChunk(CHUNK_ID_LSDE);
1746  if (lsde) { // format extension for EG behavior options
1747  lsde->SetPos(0);
1748 
1749  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1750  for (int i = 0; i < 2; ++i) { // NOTE: we reserved a 3rd byte for a potential future EG3 option
1751  unsigned char byte = lsde->ReadUint8();
1752  pEGOpts[i]->AttackCancel = byte & 1;
1753  pEGOpts[i]->AttackHoldCancel = byte & (1 << 1);
1754  pEGOpts[i]->Decay1Cancel = byte & (1 << 2);
1755  pEGOpts[i]->Decay2Cancel = byte & (1 << 3);
1756  pEGOpts[i]->ReleaseCancel = byte & (1 << 4);
1757  }
1758  }
1759  // format extension for sustain pedal up effect on release trigger samples
1760  if (lsde && lsde->GetSize() > 3) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
1761  lsde->SetPos(3);
1762  uint8_t byte = lsde->ReadUint8();
1763  SustainReleaseTrigger = static_cast<sust_rel_trg_t>(byte & 0x03);
1764  NoNoteOffReleaseTrigger = byte >> 7;
1765  } else {
1766  SustainReleaseTrigger = sust_rel_trg_none;
1767  NoNoteOffReleaseTrigger = false;
1768  }
1769  // format extension for LFOs' wave form, phase displacement and for
1770  // LFO3's flip phase
1771  if (lsde && lsde->GetSize() > 4) {
1772  lsde->SetPos(4);
1773  LFO1WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1774  LFO2WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1775  LFO3WaveForm = static_cast<lfo_wave_t>( lsde->ReadUint16() );
1776  lsde->ReadUint16(); // unused 16 bits, reserved for potential future use
1777  LFO1Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1778  LFO2Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1779  LFO3Phase = (double) GIG_EXP_DECODE( lsde->ReadInt32() );
1780  const uint32_t flags = lsde->ReadInt32();
1781  LFO3FlipPhase = flags & 1;
1782  } else {
1783  LFO1WaveForm = lfo_wave_sine;
1784  LFO2WaveForm = lfo_wave_sine;
1785  LFO3WaveForm = lfo_wave_sine;
1786  LFO1Phase = 0.0;
1787  LFO2Phase = 0.0;
1788  LFO3Phase = 0.0;
1789  LFO3FlipPhase = false;
1790  }
1791 
1792  pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1793  VelocityResponseDepth,
1794  VelocityResponseCurveScaling);
1795 
1796  pVelocityReleaseTable = GetReleaseVelocityTable(
1797  ReleaseVelocityResponseCurve,
1798  ReleaseVelocityResponseDepth
1799  );
1800 
1801  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1802  VCFVelocityDynamicRange,
1803  VCFVelocityScale,
1804  VCFCutoffController);
1805 
1806  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1807  VelocityTable = 0;
1808  }
1809 
1810  /*
1811  * Constructs a DimensionRegion by copying all parameters from
1812  * another DimensionRegion
1813  */
1814  DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1815  Instances++;
1816  //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1817  *this = src; // default memberwise shallow copy of all parameters
1818  pParentList = _3ewl; // restore the chunk pointer
1819 
1820  // deep copy of owned structures
1821  if (src.VelocityTable) {
1822  VelocityTable = new uint8_t[128];
1823  for (int k = 0 ; k < 128 ; k++)
1824  VelocityTable[k] = src.VelocityTable[k];
1825  }
1826  if (src.pSampleLoops) {
1827  pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1828  for (int k = 0 ; k < src.SampleLoops ; k++)
1829  pSampleLoops[k] = src.pSampleLoops[k];
1830  }
1831  }
1832 
1843  CopyAssign(orig, NULL);
1844  }
1845 
1854  void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1855  // delete all allocated data first
1856  if (VelocityTable) delete [] VelocityTable;
1857  if (pSampleLoops) delete [] pSampleLoops;
1858 
1859  // backup parent list pointer
1860  RIFF::List* p = pParentList;
1861 
1862  gig::Sample* pOriginalSample = pSample;
1863  gig::Region* pOriginalRegion = pRegion;
1864 
1865  //NOTE: copy code copied from assignment constructor above, see comment there as well
1866 
1867  *this = *orig; // default memberwise shallow copy of all parameters
1868 
1869  // restore members that shall not be altered
1870  pParentList = p; // restore the chunk pointer
1871  pRegion = pOriginalRegion;
1872 
1873  // only take the raw sample reference reference if the
1874  // two DimensionRegion objects are part of the same file
1875  if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1876  pSample = pOriginalSample;
1877  }
1878 
1879  if (mSamples && mSamples->count(orig->pSample)) {
1880  pSample = mSamples->find(orig->pSample)->second;
1881  }
1882 
1883  // deep copy of owned structures
1884  if (orig->VelocityTable) {
1885  VelocityTable = new uint8_t[128];
1886  for (int k = 0 ; k < 128 ; k++)
1887  VelocityTable[k] = orig->VelocityTable[k];
1888  }
1889  if (orig->pSampleLoops) {
1890  pSampleLoops = new DLS::sample_loop_t[orig->SampleLoops];
1891  for (int k = 0 ; k < orig->SampleLoops ; k++)
1892  pSampleLoops[k] = orig->pSampleLoops[k];
1893  }
1894  }
1895 
1896  void DimensionRegion::serialize(Serialization::Archive* archive) {
1897  // in case this class will become backward incompatible one day,
1898  // then set a version and minimum version for this class like:
1899  //archive->setVersion(*this, 2);
1900  //archive->setMinVersion(*this, 1);
1901 
1902  SRLZ(VelocityUpperLimit);
1903  SRLZ(EG1PreAttack);
1904  SRLZ(EG1Attack);
1905  SRLZ(EG1Decay1);
1906  SRLZ(EG1Decay2);
1907  SRLZ(EG1InfiniteSustain);
1908  SRLZ(EG1Sustain);
1909  SRLZ(EG1Release);
1910  SRLZ(EG1Hold);
1911  SRLZ(EG1Controller);
1912  SRLZ(EG1ControllerInvert);
1913  SRLZ(EG1ControllerAttackInfluence);
1914  SRLZ(EG1ControllerDecayInfluence);
1915  SRLZ(EG1ControllerReleaseInfluence);
1916  SRLZ(LFO1WaveForm);
1917  SRLZ(LFO1Frequency);
1918  SRLZ(LFO1Phase);
1919  SRLZ(LFO1InternalDepth);
1920  SRLZ(LFO1ControlDepth);
1921  SRLZ(LFO1Controller);
1922  SRLZ(LFO1FlipPhase);
1923  SRLZ(LFO1Sync);
1924  SRLZ(EG2PreAttack);
1925  SRLZ(EG2Attack);
1926  SRLZ(EG2Decay1);
1927  SRLZ(EG2Decay2);
1928  SRLZ(EG2InfiniteSustain);
1929  SRLZ(EG2Sustain);
1930  SRLZ(EG2Release);
1931  SRLZ(EG2Controller);
1932  SRLZ(EG2ControllerInvert);
1933  SRLZ(EG2ControllerAttackInfluence);
1934  SRLZ(EG2ControllerDecayInfluence);
1935  SRLZ(EG2ControllerReleaseInfluence);
1936  SRLZ(LFO2WaveForm);
1937  SRLZ(LFO2Frequency);
1938  SRLZ(LFO2Phase);
1939  SRLZ(LFO2InternalDepth);
1940  SRLZ(LFO2ControlDepth);
1941  SRLZ(LFO2Controller);
1942  SRLZ(LFO2FlipPhase);
1943  SRLZ(LFO2Sync);
1944  SRLZ(EG3Attack);
1945  SRLZ(EG3Depth);
1946  SRLZ(LFO3WaveForm);
1947  SRLZ(LFO3Frequency);
1948  SRLZ(LFO3Phase);
1949  SRLZ(LFO3InternalDepth);
1950  SRLZ(LFO3ControlDepth);
1951  SRLZ(LFO3Controller);
1952  SRLZ(LFO3FlipPhase);
1953  SRLZ(LFO3Sync);
1954  SRLZ(VCFEnabled);
1955  SRLZ(VCFType);
1956  SRLZ(VCFCutoffController);
1957  SRLZ(VCFCutoffControllerInvert);
1958  SRLZ(VCFCutoff);
1959  SRLZ(VCFVelocityCurve);
1960  SRLZ(VCFVelocityScale);
1961  SRLZ(VCFVelocityDynamicRange);
1962  SRLZ(VCFResonance);
1963  SRLZ(VCFResonanceDynamic);
1964  SRLZ(VCFResonanceController);
1965  SRLZ(VCFKeyboardTracking);
1966  SRLZ(VCFKeyboardTrackingBreakpoint);
1967  SRLZ(VelocityResponseCurve);
1968  SRLZ(VelocityResponseDepth);
1969  SRLZ(VelocityResponseCurveScaling);
1970  SRLZ(ReleaseVelocityResponseCurve);
1971  SRLZ(ReleaseVelocityResponseDepth);
1972  SRLZ(ReleaseTriggerDecay);
1973  SRLZ(Crossfade);
1974  SRLZ(PitchTrack);
1975  SRLZ(DimensionBypass);
1976  SRLZ(Pan);
1977  SRLZ(SelfMask);
1978  SRLZ(AttenuationController);
1979  SRLZ(InvertAttenuationController);
1980  SRLZ(AttenuationControllerThreshold);
1981  SRLZ(ChannelOffset);
1982  SRLZ(SustainDefeat);
1983  SRLZ(MSDecode);
1984  //SRLZ(SampleStartOffset);
1985  SRLZ(SampleAttenuation);
1986  SRLZ(EG1Options);
1987  SRLZ(EG2Options);
1988  SRLZ(SustainReleaseTrigger);
1989  SRLZ(NoNoteOffReleaseTrigger);
1990 
1991  // derived attributes from DLS::Sampler
1992  SRLZ(FineTune);
1993  SRLZ(Gain);
1994  }
1995 
2000  void DimensionRegion::SetGain(int32_t gain) {
2001  DLS::Sampler::SetGain(gain);
2002  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
2003  }
2004 
2015  // first update base class's chunk
2016  DLS::Sampler::UpdateChunks(pProgress);
2017 
2018  RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
2019  uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
2020  pData[12] = Crossfade.in_start;
2021  pData[13] = Crossfade.in_end;
2022  pData[14] = Crossfade.out_start;
2023  pData[15] = Crossfade.out_end;
2024 
2025  // make sure '3ewa' chunk exists
2026  RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
2027  if (!_3ewa) {
2028  File* pFile = (File*) GetParent()->GetParent()->GetParent();
2029  bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
2030  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, versiongt2 ? 148 : 140);
2031  }
2032  pData = (uint8_t*) _3ewa->LoadChunkData();
2033 
2034  // update '3ewa' chunk with DimensionRegion's current settings
2035 
2036  const uint32_t chunksize = (uint32_t) _3ewa->GetNewSize();
2037  store32(&pData[0], chunksize); // unknown, always chunk size?
2038 
2039  const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
2040  store32(&pData[4], lfo3freq);
2041 
2042  const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
2043  store32(&pData[8], eg3attack);
2044 
2045  // next 2 bytes unknown
2046 
2047  store16(&pData[14], LFO1InternalDepth);
2048 
2049  // next 2 bytes unknown
2050 
2051  store16(&pData[18], LFO3InternalDepth);
2052 
2053  // next 2 bytes unknown
2054 
2055  store16(&pData[22], LFO1ControlDepth);
2056 
2057  // next 2 bytes unknown
2058 
2059  store16(&pData[26], LFO3ControlDepth);
2060 
2061  const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
2062  store32(&pData[28], eg1attack);
2063 
2064  const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
2065  store32(&pData[32], eg1decay1);
2066 
2067  // next 2 bytes unknown
2068 
2069  store16(&pData[38], EG1Sustain);
2070 
2071  const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
2072  store32(&pData[40], eg1release);
2073 
2074  const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
2075  pData[44] = eg1ctl;
2076 
2077  const uint8_t eg1ctrloptions =
2078  (EG1ControllerInvert ? 0x01 : 0x00) |
2079  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2080  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2081  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2082  pData[45] = eg1ctrloptions;
2083 
2084  const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2085  pData[46] = eg2ctl;
2086 
2087  const uint8_t eg2ctrloptions =
2088  (EG2ControllerInvert ? 0x01 : 0x00) |
2089  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2090  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2091  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
2092  pData[47] = eg2ctrloptions;
2093 
2094  const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
2095  store32(&pData[48], lfo1freq);
2096 
2097  const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
2098  store32(&pData[52], eg2attack);
2099 
2100  const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
2101  store32(&pData[56], eg2decay1);
2102 
2103  // next 2 bytes unknown
2104 
2105  store16(&pData[62], EG2Sustain);
2106 
2107  const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2108  store32(&pData[64], eg2release);
2109 
2110  // next 2 bytes unknown
2111 
2112  store16(&pData[70], LFO2ControlDepth);
2113 
2114  const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2115  store32(&pData[72], lfo2freq);
2116 
2117  // next 2 bytes unknown
2118 
2119  store16(&pData[78], LFO2InternalDepth);
2120 
2121  const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2122  store32(&pData[80], eg1decay2);
2123 
2124  // next 2 bytes unknown
2125 
2126  store16(&pData[86], EG1PreAttack);
2127 
2128  const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2129  store32(&pData[88], eg2decay2);
2130 
2131  // next 2 bytes unknown
2132 
2133  store16(&pData[94], EG2PreAttack);
2134 
2135  {
2136  if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
2137  uint8_t velocityresponse = VelocityResponseDepth;
2138  switch (VelocityResponseCurve) {
2139  case curve_type_nonlinear:
2140  break;
2141  case curve_type_linear:
2142  velocityresponse += 5;
2143  break;
2144  case curve_type_special:
2145  velocityresponse += 10;
2146  break;
2147  case curve_type_unknown:
2148  default:
2149  throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2150  }
2151  pData[96] = velocityresponse;
2152  }
2153 
2154  {
2155  if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
2156  uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2157  switch (ReleaseVelocityResponseCurve) {
2158  case curve_type_nonlinear:
2159  break;
2160  case curve_type_linear:
2161  releasevelocityresponse += 5;
2162  break;
2163  case curve_type_special:
2164  releasevelocityresponse += 10;
2165  break;
2166  case curve_type_unknown:
2167  default:
2168  throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2169  }
2170  pData[97] = releasevelocityresponse;
2171  }
2172 
2173  pData[98] = VelocityResponseCurveScaling;
2174 
2175  pData[99] = AttenuationControllerThreshold;
2176 
2177  // next 4 bytes unknown
2178 
2179  store16(&pData[104], SampleStartOffset);
2180 
2181  // next 2 bytes unknown
2182 
2183  {
2184  uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2185  switch (DimensionBypass) {
2186  case dim_bypass_ctrl_94:
2187  pitchTrackDimensionBypass |= 0x10;
2188  break;
2189  case dim_bypass_ctrl_95:
2190  pitchTrackDimensionBypass |= 0x20;
2191  break;
2192  case dim_bypass_ctrl_none:
2193  //FIXME: should we set anything here?
2194  break;
2195  default:
2196  throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2197  }
2198  pData[108] = pitchTrackDimensionBypass;
2199  }
2200 
2201  const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
2202  pData[109] = pan;
2203 
2204  const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
2205  pData[110] = selfmask;
2206 
2207  // next byte unknown
2208 
2209  {
2210  uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
2211  if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
2212  if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
2213  if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
2214  pData[112] = lfo3ctrl;
2215  }
2216 
2217  const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2218  pData[113] = attenctl;
2219 
2220  {
2221  uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
2222  if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
2223  if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
2224  if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
2225  pData[114] = lfo2ctrl;
2226  }
2227 
2228  {
2229  uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
2230  if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
2231  if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
2232  if (VCFResonanceController != vcf_res_ctrl_none)
2233  lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2234  pData[115] = lfo1ctrl;
2235  }
2236 
2237  const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2238  : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
2239  store16(&pData[116], eg3depth);
2240 
2241  // next 2 bytes unknown
2242 
2243  const uint8_t channeloffset = ChannelOffset * 4;
2244  pData[120] = channeloffset;
2245 
2246  {
2247  uint8_t regoptions = 0;
2248  if (MSDecode) regoptions |= 0x01; // bit 0
2249  if (SustainDefeat) regoptions |= 0x02; // bit 1
2250  pData[121] = regoptions;
2251  }
2252 
2253  // next 2 bytes unknown
2254 
2255  pData[124] = VelocityUpperLimit;
2256 
2257  // next 3 bytes unknown
2258 
2259  pData[128] = ReleaseTriggerDecay;
2260 
2261  // next 2 bytes unknown
2262 
2263  const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
2264  pData[131] = eg1hold;
2265 
2266  const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
2267  (VCFCutoff & 0x7f); /* lower 7 bits */
2268  pData[132] = vcfcutoff;
2269 
2270  pData[133] = VCFCutoffController;
2271 
2272  const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
2273  (VCFVelocityScale & 0x7f); /* lower 7 bits */
2274  pData[134] = vcfvelscale;
2275 
2276  // next byte unknown
2277 
2278  const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
2279  (VCFResonance & 0x7f); /* lower 7 bits */
2280  pData[136] = vcfresonance;
2281 
2282  const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2283  (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2284  pData[137] = vcfbreakpoint;
2285 
2286  const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2287  VCFVelocityCurve * 5;
2288  pData[138] = vcfvelocity;
2289 
2290  const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2291  pData[139] = vcftype;
2292 
2293  if (chunksize >= 148) {
2294  memcpy(&pData[140], DimensionUpperLimits, 8);
2295  }
2296 
2297  // chunk for own format extensions, these will *NOT* work with
2298  // Gigasampler/GigaStudio !
2299  RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2300  const int lsdeSize =
2301  3 /* EG cancel options */ +
2302  1 /* sustain pedal up on release trigger option */ +
2303  8 /* LFOs' wave forms */ + 12 /* LFOs' phase */ + 4 /* flags (LFO3FlipPhase) */;
2304  if (!lsde && UsesAnyGigFormatExtension()) {
2305  // only add this "LSDE" chunk if there is some (format extension)
2306  // setting effective that would require our "LSDE" format extension
2307  // chunk to be stored
2308  lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2309  // move LSDE chunk to the end of parent list
2310  pParentList->MoveSubChunk(lsde, (RIFF::Chunk*)NULL);
2311  }
2312  if (lsde) {
2313  if (lsde->GetNewSize() < lsdeSize)
2314  lsde->Resize(lsdeSize);
2315  // format extension for EG behavior options
2316  unsigned char* pData = (unsigned char*) lsde->LoadChunkData();
2317  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
2318  for (int i = 0; i < 2; ++i) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
2319  pData[i] =
2320  (pEGOpts[i]->AttackCancel ? 1 : 0) |
2321  (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2322  (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2323  (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2324  (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2325  }
2326  // format extension for release trigger options
2327  pData[3] = static_cast<uint8_t>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 0);
2328  // format extension for LFOs' wave form, phase displacement and for
2329  // LFO3's flip phase
2330  store16(&pData[4], LFO1WaveForm);
2331  store16(&pData[6], LFO2WaveForm);
2332  store16(&pData[8], LFO3WaveForm);
2333  //NOTE: 16 bits reserved here for potential future use !
2334  const int32_t lfo1Phase = (int32_t) GIG_EXP_ENCODE(LFO1Phase);
2335  const int32_t lfo2Phase = (int32_t) GIG_EXP_ENCODE(LFO2Phase);
2336  const int32_t lfo3Phase = (int32_t) GIG_EXP_ENCODE(LFO3Phase);
2337  store32(&pData[12], lfo1Phase);
2338  store32(&pData[16], lfo2Phase);
2339  store32(&pData[20], lfo3Phase);
2340  const int32_t flags = LFO3FlipPhase ? 1 : 0;
2341  store32(&pData[24], flags);
2342 
2343  // compile time sanity check: is our last store access here
2344  // consistent with the initial lsdeSize value assignment?
2345  static_assert(lsdeSize == 28, "Inconsistency in assumed 'LSDE' RIFF chunk size");
2346  }
2347  }
2348 
2364  bool DimensionRegion::UsesAnyGigFormatExtension() const {
2365  eg_opt_t defaultOpt;
2366  return memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||
2367  memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)) ||
2368  SustainReleaseTrigger || NoNoteOffReleaseTrigger ||
2369  LFO1WaveForm || LFO2WaveForm || LFO3WaveForm ||
2370  LFO1Phase || LFO2Phase || LFO3Phase ||
2371  LFO3FlipPhase;
2372  }
2373 
2374  double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2375  curve_type_t curveType = releaseVelocityResponseCurve;
2376  uint8_t depth = releaseVelocityResponseDepth;
2377  // this models a strange behaviour or bug in GSt: two of the
2378  // velocity response curves for release time are not used even
2379  // if specified, instead another curve is chosen.
2380  if ((curveType == curve_type_nonlinear && depth == 0) ||
2381  (curveType == curve_type_special && depth == 4)) {
2382  curveType = curve_type_nonlinear;
2383  depth = 3;
2384  }
2385  return GetVelocityTable(curveType, depth, 0);
2386  }
2387 
2388  double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2389  uint8_t vcfVelocityDynamicRange,
2390  uint8_t vcfVelocityScale,
2391  vcf_cutoff_ctrl_t vcfCutoffController)
2392  {
2393  curve_type_t curveType = vcfVelocityCurve;
2394  uint8_t depth = vcfVelocityDynamicRange;
2395  // even stranger GSt: two of the velocity response curves for
2396  // filter cutoff are not used, instead another special curve
2397  // is chosen. This curve is not used anywhere else.
2398  if ((curveType == curve_type_nonlinear && depth == 0) ||
2399  (curveType == curve_type_special && depth == 4)) {
2400  curveType = curve_type_special;
2401  depth = 5;
2402  }
2403  return GetVelocityTable(curveType, depth,
2404  (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2405  ? vcfVelocityScale : 0);
2406  }
2407 
2408  // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
2409  double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2410  {
2411  // sanity check input parameters
2412  // (fallback to some default parameters on ill input)
2413  switch (curveType) {
2414  case curve_type_nonlinear:
2415  case curve_type_linear:
2416  if (depth > 4) {
2417  printf("Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2418  depth = 0;
2419  scaling = 0;
2420  }
2421  break;
2422  case curve_type_special:
2423  if (depth > 5) {
2424  printf("Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2425  depth = 0;
2426  scaling = 0;
2427  }
2428  break;
2429  case curve_type_unknown:
2430  default:
2431  printf("Warning: Unknown velocity curve type (0x%x).\n", curveType);
2432  curveType = curve_type_linear;
2433  depth = 0;
2434  scaling = 0;
2435  break;
2436  }
2437 
2438  double* table;
2439  uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2440  if (pVelocityTables->count(tableKey)) { // if key exists
2441  table = (*pVelocityTables)[tableKey];
2442  }
2443  else {
2444  table = CreateVelocityTable(curveType, depth, scaling);
2445  (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
2446  }
2447  return table;
2448  }
2449 
2450  Region* DimensionRegion::GetParent() const {
2451  return pRegion;
2452  }
2453 
2454 // show error if some _lev_ctrl_* enum entry is not listed in the following function
2455 // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2456 // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2457 //#pragma GCC diagnostic push
2458 //#pragma GCC diagnostic error "-Wswitch"
2459 
2460  leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2461  leverage_ctrl_t decodedcontroller;
2462  switch (EncodedController) {
2463  // special controller
2464  case _lev_ctrl_none:
2465  decodedcontroller.type = leverage_ctrl_t::type_none;
2466  decodedcontroller.controller_number = 0;
2467  break;
2468  case _lev_ctrl_velocity:
2469  decodedcontroller.type = leverage_ctrl_t::type_velocity;
2470  decodedcontroller.controller_number = 0;
2471  break;
2472  case _lev_ctrl_channelaftertouch:
2473  decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
2474  decodedcontroller.controller_number = 0;
2475  break;
2476 
2477  // ordinary MIDI control change controller
2478  case _lev_ctrl_modwheel:
2479  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2480  decodedcontroller.controller_number = 1;
2481  break;
2482  case _lev_ctrl_breath:
2483  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2484  decodedcontroller.controller_number = 2;
2485  break;
2486  case _lev_ctrl_foot:
2487  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2488  decodedcontroller.controller_number = 4;
2489  break;
2490  case _lev_ctrl_effect1:
2491  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2492  decodedcontroller.controller_number = 12;
2493  break;
2494  case _lev_ctrl_effect2:
2495  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2496  decodedcontroller.controller_number = 13;
2497  break;
2498  case _lev_ctrl_genpurpose1:
2499  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2500  decodedcontroller.controller_number = 16;
2501  break;
2502  case _lev_ctrl_genpurpose2:
2503  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2504  decodedcontroller.controller_number = 17;
2505  break;
2506  case _lev_ctrl_genpurpose3:
2507  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2508  decodedcontroller.controller_number = 18;
2509  break;
2510  case _lev_ctrl_genpurpose4:
2511  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2512  decodedcontroller.controller_number = 19;
2513  break;
2514  case _lev_ctrl_portamentotime:
2515  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2516  decodedcontroller.controller_number = 5;
2517  break;
2518  case _lev_ctrl_sustainpedal:
2519  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2520  decodedcontroller.controller_number = 64;
2521  break;
2522  case _lev_ctrl_portamento:
2523  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2524  decodedcontroller.controller_number = 65;
2525  break;
2526  case _lev_ctrl_sostenutopedal:
2527  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2528  decodedcontroller.controller_number = 66;
2529  break;
2530  case _lev_ctrl_softpedal:
2531  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2532  decodedcontroller.controller_number = 67;
2533  break;
2534  case _lev_ctrl_genpurpose5:
2535  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2536  decodedcontroller.controller_number = 80;
2537  break;
2538  case _lev_ctrl_genpurpose6:
2539  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2540  decodedcontroller.controller_number = 81;
2541  break;
2542  case _lev_ctrl_genpurpose7:
2543  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2544  decodedcontroller.controller_number = 82;
2545  break;
2546  case _lev_ctrl_genpurpose8:
2547  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2548  decodedcontroller.controller_number = 83;
2549  break;
2550  case _lev_ctrl_effect1depth:
2551  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2552  decodedcontroller.controller_number = 91;
2553  break;
2554  case _lev_ctrl_effect2depth:
2555  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2556  decodedcontroller.controller_number = 92;
2557  break;
2558  case _lev_ctrl_effect3depth:
2559  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2560  decodedcontroller.controller_number = 93;
2561  break;
2562  case _lev_ctrl_effect4depth:
2563  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2564  decodedcontroller.controller_number = 94;
2565  break;
2566  case _lev_ctrl_effect5depth:
2567  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2568  decodedcontroller.controller_number = 95;
2569  break;
2570 
2571  // format extension (these controllers are so far only supported by
2572  // LinuxSampler & gigedit) they will *NOT* work with
2573  // Gigasampler/GigaStudio !
2574  case _lev_ctrl_CC3_EXT:
2575  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2576  decodedcontroller.controller_number = 3;
2577  break;
2578  case _lev_ctrl_CC6_EXT:
2579  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2580  decodedcontroller.controller_number = 6;
2581  break;
2582  case _lev_ctrl_CC7_EXT:
2583  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2584  decodedcontroller.controller_number = 7;
2585  break;
2586  case _lev_ctrl_CC8_EXT:
2587  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2588  decodedcontroller.controller_number = 8;
2589  break;
2590  case _lev_ctrl_CC9_EXT:
2591  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2592  decodedcontroller.controller_number = 9;
2593  break;
2594  case _lev_ctrl_CC10_EXT:
2595  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2596  decodedcontroller.controller_number = 10;
2597  break;
2598  case _lev_ctrl_CC11_EXT:
2599  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2600  decodedcontroller.controller_number = 11;
2601  break;
2602  case _lev_ctrl_CC14_EXT:
2603  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2604  decodedcontroller.controller_number = 14;
2605  break;
2606  case _lev_ctrl_CC15_EXT:
2607  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2608  decodedcontroller.controller_number = 15;
2609  break;
2610  case _lev_ctrl_CC20_EXT:
2611  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2612  decodedcontroller.controller_number = 20;
2613  break;
2614  case _lev_ctrl_CC21_EXT:
2615  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2616  decodedcontroller.controller_number = 21;
2617  break;
2618  case _lev_ctrl_CC22_EXT:
2619  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2620  decodedcontroller.controller_number = 22;
2621  break;
2622  case _lev_ctrl_CC23_EXT:
2623  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2624  decodedcontroller.controller_number = 23;
2625  break;
2626  case _lev_ctrl_CC24_EXT:
2627  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2628  decodedcontroller.controller_number = 24;
2629  break;
2630  case _lev_ctrl_CC25_EXT:
2631  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2632  decodedcontroller.controller_number = 25;
2633  break;
2634  case _lev_ctrl_CC26_EXT:
2635  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2636  decodedcontroller.controller_number = 26;
2637  break;
2638  case _lev_ctrl_CC27_EXT:
2639  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2640  decodedcontroller.controller_number = 27;
2641  break;
2642  case _lev_ctrl_CC28_EXT:
2643  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2644  decodedcontroller.controller_number = 28;
2645  break;
2646  case _lev_ctrl_CC29_EXT:
2647  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2648  decodedcontroller.controller_number = 29;
2649  break;
2650  case _lev_ctrl_CC30_EXT:
2651  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2652  decodedcontroller.controller_number = 30;
2653  break;
2654  case _lev_ctrl_CC31_EXT:
2655  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2656  decodedcontroller.controller_number = 31;
2657  break;
2658  case _lev_ctrl_CC68_EXT:
2659  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2660  decodedcontroller.controller_number = 68;
2661  break;
2662  case _lev_ctrl_CC69_EXT:
2663  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2664  decodedcontroller.controller_number = 69;
2665  break;
2666  case _lev_ctrl_CC70_EXT:
2667  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2668  decodedcontroller.controller_number = 70;
2669  break;
2670  case _lev_ctrl_CC71_EXT:
2671  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2672  decodedcontroller.controller_number = 71;
2673  break;
2674  case _lev_ctrl_CC72_EXT:
2675  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2676  decodedcontroller.controller_number = 72;
2677  break;
2678  case _lev_ctrl_CC73_EXT:
2679  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2680  decodedcontroller.controller_number = 73;
2681  break;
2682  case _lev_ctrl_CC74_EXT:
2683  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2684  decodedcontroller.controller_number = 74;
2685  break;
2686  case _lev_ctrl_CC75_EXT:
2687  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2688  decodedcontroller.controller_number = 75;
2689  break;
2690  case _lev_ctrl_CC76_EXT:
2691  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2692  decodedcontroller.controller_number = 76;
2693  break;
2694  case _lev_ctrl_CC77_EXT:
2695  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2696  decodedcontroller.controller_number = 77;
2697  break;
2698  case _lev_ctrl_CC78_EXT:
2699  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2700  decodedcontroller.controller_number = 78;
2701  break;
2702  case _lev_ctrl_CC79_EXT:
2703  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2704  decodedcontroller.controller_number = 79;
2705  break;
2706  case _lev_ctrl_CC84_EXT:
2707  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2708  decodedcontroller.controller_number = 84;
2709  break;
2710  case _lev_ctrl_CC85_EXT:
2711  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2712  decodedcontroller.controller_number = 85;
2713  break;
2714  case _lev_ctrl_CC86_EXT:
2715  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2716  decodedcontroller.controller_number = 86;
2717  break;
2718  case _lev_ctrl_CC87_EXT:
2719  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2720  decodedcontroller.controller_number = 87;
2721  break;
2722  case _lev_ctrl_CC89_EXT:
2723  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2724  decodedcontroller.controller_number = 89;
2725  break;
2726  case _lev_ctrl_CC90_EXT:
2727  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2728  decodedcontroller.controller_number = 90;
2729  break;
2730  case _lev_ctrl_CC96_EXT:
2731  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2732  decodedcontroller.controller_number = 96;
2733  break;
2734  case _lev_ctrl_CC97_EXT:
2735  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2736  decodedcontroller.controller_number = 97;
2737  break;
2738  case _lev_ctrl_CC102_EXT:
2739  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2740  decodedcontroller.controller_number = 102;
2741  break;
2742  case _lev_ctrl_CC103_EXT:
2743  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2744  decodedcontroller.controller_number = 103;
2745  break;
2746  case _lev_ctrl_CC104_EXT:
2747  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2748  decodedcontroller.controller_number = 104;
2749  break;
2750  case _lev_ctrl_CC105_EXT:
2751  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2752  decodedcontroller.controller_number = 105;
2753  break;
2754  case _lev_ctrl_CC106_EXT:
2755  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2756  decodedcontroller.controller_number = 106;
2757  break;
2758  case _lev_ctrl_CC107_EXT:
2759  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2760  decodedcontroller.controller_number = 107;
2761  break;
2762  case _lev_ctrl_CC108_EXT:
2763  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2764  decodedcontroller.controller_number = 108;
2765  break;
2766  case _lev_ctrl_CC109_EXT:
2767  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2768  decodedcontroller.controller_number = 109;
2769  break;
2770  case _lev_ctrl_CC110_EXT:
2771  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2772  decodedcontroller.controller_number = 110;
2773  break;
2774  case _lev_ctrl_CC111_EXT:
2775  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2776  decodedcontroller.controller_number = 111;
2777  break;
2778  case _lev_ctrl_CC112_EXT:
2779  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2780  decodedcontroller.controller_number = 112;
2781  break;
2782  case _lev_ctrl_CC113_EXT:
2783  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2784  decodedcontroller.controller_number = 113;
2785  break;
2786  case _lev_ctrl_CC114_EXT:
2787  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2788  decodedcontroller.controller_number = 114;
2789  break;
2790  case _lev_ctrl_CC115_EXT:
2791  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2792  decodedcontroller.controller_number = 115;
2793  break;
2794  case _lev_ctrl_CC116_EXT:
2795  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2796  decodedcontroller.controller_number = 116;
2797  break;
2798  case _lev_ctrl_CC117_EXT:
2799  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2800  decodedcontroller.controller_number = 117;
2801  break;
2802  case _lev_ctrl_CC118_EXT:
2803  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2804  decodedcontroller.controller_number = 118;
2805  break;
2806  case _lev_ctrl_CC119_EXT:
2807  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2808  decodedcontroller.controller_number = 119;
2809  break;
2810 
2811  // unknown controller type
2812  default:
2813  decodedcontroller.type = leverage_ctrl_t::type_none;
2814  decodedcontroller.controller_number = 0;
2815  printf("Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2816  break;
2817  }
2818  return decodedcontroller;
2819  }
2820 
2821 // see above (diagnostic push not supported prior GCC 4.6)
2822 //#pragma GCC diagnostic pop
2823 
2824  DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2825  _lev_ctrl_t encodedcontroller;
2826  switch (DecodedController.type) {
2827  // special controller
2829  encodedcontroller = _lev_ctrl_none;
2830  break;
2832  encodedcontroller = _lev_ctrl_velocity;
2833  break;
2835  encodedcontroller = _lev_ctrl_channelaftertouch;
2836  break;
2837 
2838  // ordinary MIDI control change controller
2840  switch (DecodedController.controller_number) {
2841  case 1:
2842  encodedcontroller = _lev_ctrl_modwheel;
2843  break;
2844  case 2:
2845  encodedcontroller = _lev_ctrl_breath;
2846  break;
2847  case 4:
2848  encodedcontroller = _lev_ctrl_foot;
2849  break;
2850  case 12:
2851  encodedcontroller = _lev_ctrl_effect1;
2852  break;
2853  case 13:
2854  encodedcontroller = _lev_ctrl_effect2;
2855  break;
2856  case 16:
2857  encodedcontroller = _lev_ctrl_genpurpose1;
2858  break;
2859  case 17:
2860  encodedcontroller = _lev_ctrl_genpurpose2;
2861  break;
2862  case 18:
2863  encodedcontroller = _lev_ctrl_genpurpose3;
2864  break;
2865  case 19:
2866  encodedcontroller = _lev_ctrl_genpurpose4;
2867  break;
2868  case 5:
2869  encodedcontroller = _lev_ctrl_portamentotime;
2870  break;
2871  case 64:
2872  encodedcontroller = _lev_ctrl_sustainpedal;
2873  break;
2874  case 65:
2875  encodedcontroller = _lev_ctrl_portamento;
2876  break;
2877  case 66:
2878  encodedcontroller = _lev_ctrl_sostenutopedal;
2879  break;
2880  case 67:
2881  encodedcontroller = _lev_ctrl_softpedal;
2882  break;
2883  case 80:
2884  encodedcontroller = _lev_ctrl_genpurpose5;
2885  break;
2886  case 81:
2887  encodedcontroller = _lev_ctrl_genpurpose6;
2888  break;
2889  case 82:
2890  encodedcontroller = _lev_ctrl_genpurpose7;
2891  break;
2892  case 83:
2893  encodedcontroller = _lev_ctrl_genpurpose8;
2894  break;
2895  case 91:
2896  encodedcontroller = _lev_ctrl_effect1depth;
2897  break;
2898  case 92:
2899  encodedcontroller = _lev_ctrl_effect2depth;
2900  break;
2901  case 93:
2902  encodedcontroller = _lev_ctrl_effect3depth;
2903  break;
2904  case 94:
2905  encodedcontroller = _lev_ctrl_effect4depth;
2906  break;
2907  case 95:
2908  encodedcontroller = _lev_ctrl_effect5depth;
2909  break;
2910 
2911  // format extension (these controllers are so far only
2912  // supported by LinuxSampler & gigedit) they will *NOT*
2913  // work with Gigasampler/GigaStudio !
2914  case 3:
2915  encodedcontroller = _lev_ctrl_CC3_EXT;
2916  break;
2917  case 6:
2918  encodedcontroller = _lev_ctrl_CC6_EXT;
2919  break;
2920  case 7:
2921  encodedcontroller = _lev_ctrl_CC7_EXT;
2922  break;
2923  case 8:
2924  encodedcontroller = _lev_ctrl_CC8_EXT;
2925  break;
2926  case 9:
2927  encodedcontroller = _lev_ctrl_CC9_EXT;
2928  break;
2929  case 10:
2930  encodedcontroller = _lev_ctrl_CC10_EXT;
2931  break;
2932  case 11:
2933  encodedcontroller = _lev_ctrl_CC11_EXT;
2934  break;
2935  case 14:
2936  encodedcontroller = _lev_ctrl_CC14_EXT;
2937  break;
2938  case 15:
2939  encodedcontroller = _lev_ctrl_CC15_EXT;
2940  break;
2941  case 20:
2942  encodedcontroller = _lev_ctrl_CC20_EXT;
2943  break;
2944  case 21:
2945  encodedcontroller = _lev_ctrl_CC21_EXT;
2946  break;
2947  case 22:
2948  encodedcontroller = _lev_ctrl_CC22_EXT;
2949  break;
2950  case 23:
2951  encodedcontroller = _lev_ctrl_CC23_EXT;
2952  break;
2953  case 24:
2954  encodedcontroller = _lev_ctrl_CC24_EXT;
2955  break;
2956  case 25:
2957  encodedcontroller = _lev_ctrl_CC25_EXT;
2958  break;
2959  case 26:
2960  encodedcontroller = _lev_ctrl_CC26_EXT;
2961  break;
2962  case 27:
2963  encodedcontroller = _lev_ctrl_CC27_EXT;
2964  break;
2965  case 28:
2966  encodedcontroller = _lev_ctrl_CC28_EXT;
2967  break;
2968  case 29:
2969  encodedcontroller = _lev_ctrl_CC29_EXT;
2970  break;
2971  case 30:
2972  encodedcontroller = _lev_ctrl_CC30_EXT;
2973  break;
2974  case 31:
2975  encodedcontroller = _lev_ctrl_CC31_EXT;
2976  break;
2977  case 68:
2978  encodedcontroller = _lev_ctrl_CC68_EXT;
2979  break;
2980  case 69:
2981  encodedcontroller = _lev_ctrl_CC69_EXT;
2982  break;
2983  case 70:
2984  encodedcontroller = _lev_ctrl_CC70_EXT;
2985  break;
2986  case 71:
2987  encodedcontroller = _lev_ctrl_CC71_EXT;
2988  break;
2989  case 72:
2990  encodedcontroller = _lev_ctrl_CC72_EXT;
2991  break;
2992  case 73:
2993  encodedcontroller = _lev_ctrl_CC73_EXT;
2994  break;
2995  case 74:
2996  encodedcontroller = _lev_ctrl_CC74_EXT;
2997  break;
2998  case 75:
2999  encodedcontroller = _lev_ctrl_CC75_EXT;
3000  break;
3001  case 76:
3002  encodedcontroller = _lev_ctrl_CC76_EXT;
3003  break;
3004  case 77:
3005  encodedcontroller = _lev_ctrl_CC77_EXT;
3006  break;
3007  case 78:
3008  encodedcontroller = _lev_ctrl_CC78_EXT;
3009  break;
3010  case 79:
3011  encodedcontroller = _lev_ctrl_CC79_EXT;
3012  break;
3013  case 84:
3014  encodedcontroller = _lev_ctrl_CC84_EXT;
3015  break;
3016  case 85:
3017  encodedcontroller = _lev_ctrl_CC85_EXT;
3018  break;
3019  case 86:
3020  encodedcontroller = _lev_ctrl_CC86_EXT;
3021  break;
3022  case 87:
3023  encodedcontroller = _lev_ctrl_CC87_EXT;
3024  break;
3025  case 89:
3026  encodedcontroller = _lev_ctrl_CC89_EXT;
3027  break;
3028  case 90:
3029  encodedcontroller = _lev_ctrl_CC90_EXT;
3030  break;
3031  case 96:
3032  encodedcontroller = _lev_ctrl_CC96_EXT;
3033  break;
3034  case 97:
3035  encodedcontroller = _lev_ctrl_CC97_EXT;
3036  break;
3037  case 102:
3038  encodedcontroller = _lev_ctrl_CC102_EXT;
3039  break;
3040  case 103:
3041  encodedcontroller = _lev_ctrl_CC103_EXT;
3042  break;
3043  case 104:
3044  encodedcontroller = _lev_ctrl_CC104_EXT;
3045  break;
3046  case 105:
3047  encodedcontroller = _lev_ctrl_CC105_EXT;
3048  break;
3049  case 106:
3050  encodedcontroller = _lev_ctrl_CC106_EXT;
3051  break;
3052  case 107:
3053  encodedcontroller = _lev_ctrl_CC107_EXT;
3054  break;
3055  case 108:
3056  encodedcontroller = _lev_ctrl_CC108_EXT;
3057  break;
3058  case 109:
3059  encodedcontroller = _lev_ctrl_CC109_EXT;
3060  break;
3061  case 110:
3062  encodedcontroller = _lev_ctrl_CC110_EXT;
3063  break;
3064  case 111:
3065  encodedcontroller = _lev_ctrl_CC111_EXT;
3066  break;
3067  case 112:
3068  encodedcontroller = _lev_ctrl_CC112_EXT;
3069  break;
3070  case 113:
3071  encodedcontroller = _lev_ctrl_CC113_EXT;
3072  break;
3073  case 114:
3074  encodedcontroller = _lev_ctrl_CC114_EXT;
3075  break;
3076  case 115:
3077  encodedcontroller = _lev_ctrl_CC115_EXT;
3078  break;
3079  case 116:
3080  encodedcontroller = _lev_ctrl_CC116_EXT;
3081  break;
3082  case 117:
3083  encodedcontroller = _lev_ctrl_CC117_EXT;
3084  break;
3085  case 118:
3086  encodedcontroller = _lev_ctrl_CC118_EXT;
3087  break;
3088  case 119:
3089  encodedcontroller = _lev_ctrl_CC119_EXT;
3090  break;
3091 
3092  default:
3093  throw gig::Exception("leverage controller number is not supported by the gig format");
3094  }
3095  break;
3096  default:
3097  throw gig::Exception("Unknown leverage controller type.");
3098  }
3099  return encodedcontroller;
3100  }
3101 
3102  DimensionRegion::~DimensionRegion() {
3103  Instances--;
3104  if (!Instances) {
3105  // delete the velocity->volume tables
3106  VelocityTableMap::iterator iter;
3107  for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3108  double* pTable = iter->second;
3109  if (pTable) delete[] pTable;
3110  }
3111  pVelocityTables->clear();
3112  delete pVelocityTables;
3113  pVelocityTables = NULL;
3114  }
3115  if (VelocityTable) delete[] VelocityTable;
3116  }
3117 
3129  double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
3130  return pVelocityAttenuationTable[MIDIKeyVelocity];
3131  }
3132 
3133  double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3134  return pVelocityReleaseTable[MIDIKeyVelocity];
3135  }
3136 
3137  double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3138  return pVelocityCutoffTable[MIDIKeyVelocity];
3139  }
3140 
3146  pVelocityAttenuationTable =
3147  GetVelocityTable(
3148  curve, VelocityResponseDepth, VelocityResponseCurveScaling
3149  );
3150  VelocityResponseCurve = curve;
3151  }
3152 
3158  pVelocityAttenuationTable =
3159  GetVelocityTable(
3160  VelocityResponseCurve, depth, VelocityResponseCurveScaling
3161  );
3162  VelocityResponseDepth = depth;
3163  }
3164 
3170  pVelocityAttenuationTable =
3171  GetVelocityTable(
3172  VelocityResponseCurve, VelocityResponseDepth, scaling
3173  );
3174  VelocityResponseCurveScaling = scaling;
3175  }
3176 
3182  pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3183  ReleaseVelocityResponseCurve = curve;
3184  }
3185 
3191  pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3192  ReleaseVelocityResponseDepth = depth;
3193  }
3194 
3200  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3201  VCFCutoffController = controller;
3202  }
3203 
3209  pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3210  VCFVelocityCurve = curve;
3211  }
3212 
3218  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3219  VCFVelocityDynamicRange = range;
3220  }
3221 
3227  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3228  VCFVelocityScale = scaling;
3229  }
3230 
3231  double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3232 
3233  // line-segment approximations of the 15 velocity curves
3234 
3235  // linear
3236  const int lin0[] = { 1, 1, 127, 127 };
3237  const int lin1[] = { 1, 21, 127, 127 };
3238  const int lin2[] = { 1, 45, 127, 127 };
3239  const int lin3[] = { 1, 74, 127, 127 };
3240  const int lin4[] = { 1, 127, 127, 127 };
3241 
3242  // non-linear
3243  const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3244  const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3245  127, 127 };
3246  const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3247  127, 127 };
3248  const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3249  127, 127 };
3250  const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3251 
3252  // special
3253  const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3254  113, 127, 127, 127 };
3255  const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3256  118, 127, 127, 127 };
3257  const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3258  85, 90, 91, 127, 127, 127 };
3259  const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3260  117, 127, 127, 127 };
3261  const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3262  127, 127 };
3263 
3264  // this is only used by the VCF velocity curve
3265  const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3266  91, 127, 127, 127 };
3267 
3268  const int* const curves[] = { non0, non1, non2, non3, non4,
3269  lin0, lin1, lin2, lin3, lin4,
3270  spe0, spe1, spe2, spe3, spe4, spe5 };
3271 
3272  double* const table = new double[128];
3273 
3274  const int* curve = curves[curveType * 5 + depth];
3275  const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
3276 
3277  table[0] = 0;
3278  for (int x = 1 ; x < 128 ; x++) {
3279 
3280  if (x > curve[2]) curve += 2;
3281  double y = curve[1] + (x - curve[0]) *
3282  (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3283  y = y / 127;
3284 
3285  // Scale up for s > 20, down for s < 20. When
3286  // down-scaling, the curve still ends at 1.0.
3287  if (s < 20 && y >= 0.5)
3288  y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3289  else
3290  y = y * (s / 20.0);
3291  if (y > 1) y = 1;
3292 
3293  table[x] = y;
3294  }
3295  return table;
3296  }
3297 
3298 
3299 // *************** Region ***************
3300 // *
3301 
3302  Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
3303  // Initialization
3304  Dimensions = 0;
3305  for (int i = 0; i < 256; i++) {
3306  pDimensionRegions[i] = NULL;
3307  }
3308  Layers = 1;
3309  File* file = (File*) GetParent()->GetParent();
3310  int dimensionBits = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3311 
3312  // Actual Loading
3313 
3314  if (!file->GetAutoLoad()) return;
3315 
3316  LoadDimensionRegions(rgnList);
3317 
3318  RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
3319  if (_3lnk) {
3320  _3lnk->SetPos(0);
3321 
3322  DimensionRegions = _3lnk->ReadUint32();
3323  for (int i = 0; i < dimensionBits; i++) {
3324  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
3325  uint8_t bits = _3lnk->ReadUint8();
3326  _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
3327  _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
3328  uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
3329  if (dimension == dimension_none) { // inactive dimension
3330  pDimensionDefinitions[i].dimension = dimension_none;
3331  pDimensionDefinitions[i].bits = 0;
3332  pDimensionDefinitions[i].zones = 0;
3333  pDimensionDefinitions[i].split_type = split_type_bit;
3334  pDimensionDefinitions[i].zone_size = 0;
3335  }
3336  else { // active dimension
3337  pDimensionDefinitions[i].dimension = dimension;
3338  pDimensionDefinitions[i].bits = bits;
3339  pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
3340  pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3341  pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3342  Dimensions++;
3343 
3344  // if this is a layer dimension, remember the amount of layers
3345  if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
3346  }
3347  _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
3348  }
3349  for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3350 
3351  // if there's a velocity dimension and custom velocity zone splits are used,
3352  // update the VelocityTables in the dimension regions
3353  UpdateVelocityTable();
3354 
3355  // jump to start of the wave pool indices (if not already there)
3356  if (file->pVersion && file->pVersion->major > 2)
3357  _3lnk->SetPos(68); // version 3 has a different 3lnk structure
3358  else
3359  _3lnk->SetPos(44);
3360 
3361  // load sample references (if auto loading is enabled)
3362  if (file->GetAutoLoad()) {
3363  for (uint i = 0; i < DimensionRegions; i++) {
3364  uint32_t wavepoolindex = _3lnk->ReadUint32();
3365  if (file->pWavePoolTable && pDimensionRegions[i])
3366  pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3367  }
3368  GetSample(); // load global region sample reference
3369  }
3370  } else {
3371  DimensionRegions = 0;
3372  for (int i = 0 ; i < 8 ; i++) {
3373  pDimensionDefinitions[i].dimension = dimension_none;
3374  pDimensionDefinitions[i].bits = 0;
3375  pDimensionDefinitions[i].zones = 0;
3376  }
3377  }
3378 
3379  // make sure there is at least one dimension region
3380  if (!DimensionRegions) {
3381  RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
3382  if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
3383  RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
3384  pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
3385  DimensionRegions = 1;
3386  }
3387  }
3388 
3400  // in the gig format we don't care about the Region's sample reference
3401  // but we still have to provide some existing one to not corrupt the
3402  // file, so to avoid the latter we simply always assign the sample of
3403  // the first dimension region of this region
3404  pSample = pDimensionRegions[0]->pSample;
3405 
3406  // first update base class's chunks
3407  DLS::Region::UpdateChunks(pProgress);
3408 
3409  // update dimension region's chunks
3410  for (int i = 0; i < DimensionRegions; i++) {
3411  pDimensionRegions[i]->UpdateChunks(pProgress);
3412  }
3413 
3414  File* pFile = (File*) GetParent()->GetParent();
3415  const bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
3416  const int iMaxDimensions = versiongt2 ? 8 : 5;
3417  const int iMaxDimensionRegions = versiongt2 ? 256 : 32;
3418 
3419  // make sure '3lnk' chunk exists
3420  RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3421  if (!_3lnk) {
3422  const int _3lnkChunkSize = versiongt2 ? 1092 : 172;
3423  _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3424  memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3425 
3426  // move 3prg to last position
3427  pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (RIFF::Chunk*)NULL);
3428  }
3429 
3430  // update dimension definitions in '3lnk' chunk
3431  uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3432  store32(&pData[0], DimensionRegions);
3433  int shift = 0;
3434  for (int i = 0; i < iMaxDimensions; i++) {
3435  pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3436  pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3437  pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3438  pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3439  pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3440  // next 3 bytes unknown, always zero?
3441 
3442  shift += pDimensionDefinitions[i].bits;
3443  }
3444 
3445  // update wave pool table in '3lnk' chunk
3446  const int iWavePoolOffset = versiongt2 ? 68 : 44;
3447  for (uint i = 0; i < iMaxDimensionRegions; i++) {
3448  int iWaveIndex = -1;
3449  if (i < DimensionRegions) {
3450  if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
3451  File::SampleList::iterator iter = pFile->pSamples->begin();
3452  File::SampleList::iterator end = pFile->pSamples->end();
3453  for (int index = 0; iter != end; ++iter, ++index) {
3454  if (*iter == pDimensionRegions[i]->pSample) {
3455  iWaveIndex = index;
3456  break;
3457  }
3458  }
3459  }
3460  store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3461  }
3462 
3463  // The following chunks are just added for compatibility with the
3464  // GigaStudio software, which would show a warning if these were
3465  // missing. However currently these chunks don't cover any useful
3466  // data. So if this gig file uses any of our own gig format
3467  // extensions which would cause this gig file to be unloadable
3468  // with GSt software anyway, then just skip these GSt compatibility
3469  // chunks here as well.
3470  if (versiongt2 && !UsesAnyGigFormatExtension()) {
3471  // add 3dnm list which always seems to be empty
3472  RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM);
3473  if (!_3dnm) _3dnm = pCkRegion->AddSubList(LIST_TYPE_3DNM);
3474 
3475  // add 3ddp chunk which always seems to have 16 bytes of 0xFF
3476  RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP);
3477  if (!_3ddp) _3ddp = pCkRegion->AddSubChunk(CHUNK_ID_3DDP, 16);
3478  uint8_t* pData = (uint8_t*) _3ddp->LoadChunkData();
3479  for (int i = 0; i < 16; i += 4) {
3480  store32(&pData[i], 0xFFFFFFFF);
3481  }
3482 
3483  // move 3dnm and 3ddp to the end of the region list
3484  pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3DNM), (RIFF::Chunk*)NULL);
3485  pCkRegion->MoveSubChunk(pCkRegion->GetSubChunk(CHUNK_ID_3DDP), (RIFF::Chunk*)NULL);
3486  } else {
3487  // this is intended for the user switching from GSt >= 3 version
3488  // back to an older format version, delete GSt3 chunks ...
3489  RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM);
3490  if (_3dnm) pCkRegion->DeleteSubChunk(_3dnm);
3491 
3492  RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP);
3493  if (_3ddp) pCkRegion->DeleteSubChunk(_3ddp);
3494  }
3495  }
3496 
3497  void Region::LoadDimensionRegions(RIFF::List* rgn) {
3498  RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
3499  if (_3prg) {
3500  int dimensionRegionNr = 0;
3501  size_t i = 0;
3502  for (RIFF::List* _3ewl = _3prg->GetSubListAt(i); _3ewl;
3503  _3ewl = _3prg->GetSubListAt(++i))
3504  {
3505  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3506  pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3507  dimensionRegionNr++;
3508  }
3509  }
3510  if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
3511  }
3512  }
3513 
3514  void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3515  // update KeyRange struct and make sure regions are in correct order
3516  DLS::Region::SetKeyRange(Low, High);
3517  // update Region key table for fast lookup
3518  ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3519  }
3520 
3521  void Region::UpdateVelocityTable() {
3522  // get velocity dimension's index
3523  int veldim = -1;
3524  for (int i = 0 ; i < Dimensions ; i++) {
3525  if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3526  veldim = i;
3527  break;
3528  }
3529  }
3530  if (veldim == -1) return;
3531 
3532  int step = 1;
3533  for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3534  int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3535 
3536  // loop through all dimension regions for all dimensions except the velocity dimension
3537  int dim[8] = { 0 };
3538  for (int i = 0 ; i < DimensionRegions ; i++) {
3539  const int end = i + step * pDimensionDefinitions[veldim].zones;
3540 
3541  // create a velocity table for all cases where the velocity zone is zero
3542  if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3543  pDimensionRegions[i]->VelocityUpperLimit) {
3544  // create the velocity table
3545  uint8_t* table = pDimensionRegions[i]->VelocityTable;
3546  if (!table) {
3547  table = new uint8_t[128];
3548  pDimensionRegions[i]->VelocityTable = table;
3549  }
3550  int tableidx = 0;
3551  int velocityZone = 0;
3552  if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
3553  for (int k = i ; k < end ; k += step) {
3554  DimensionRegion *d = pDimensionRegions[k];
3555  for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3556  velocityZone++;
3557  }
3558  } else { // gig2
3559  for (int k = i ; k < end ; k += step) {
3560  DimensionRegion *d = pDimensionRegions[k];
3561  for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3562  velocityZone++;
3563  }
3564  }
3565  } else {
3566  if (pDimensionRegions[i]->VelocityTable) {
3567  delete[] pDimensionRegions[i]->VelocityTable;
3568  pDimensionRegions[i]->VelocityTable = 0;
3569  }
3570  }
3571 
3572  // jump to the next case where the velocity zone is zero
3573  int j;
3574  int shift = 0;
3575  for (j = 0 ; j < Dimensions ; j++) {
3576  if (j == veldim) i += skipveldim; // skip velocity dimension
3577  else {
3578  dim[j]++;
3579  if (dim[j] < pDimensionDefinitions[j].zones) break;
3580  else {
3581  // skip unused dimension regions
3582  dim[j] = 0;
3583  i += ((1 << pDimensionDefinitions[j].bits) -
3584  pDimensionDefinitions[j].zones) << shift;
3585  }
3586  }
3587  shift += pDimensionDefinitions[j].bits;
3588  }
3589  if (j == Dimensions) break;
3590  }
3591  }
3592 
3609  // some initial sanity checks of the given dimension definition
3610  if (pDimDef->zones < 2)
3611  throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3612  if (pDimDef->bits < 1)
3613  throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3614  if (pDimDef->dimension == dimension_samplechannel) {
3615  if (pDimDef->zones != 2)
3616  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3617  if (pDimDef->bits != 1)
3618  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3619  }
3620 
3621  // check if max. amount of dimensions reached
3622  File* file = (File*) GetParent()->GetParent();
3623  const int iMaxDimensions = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3624  if (Dimensions >= iMaxDimensions)
3625  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
3626  // check if max. amount of dimension bits reached
3627  int iCurrentBits = 0;
3628  for (int i = 0; i < Dimensions; i++)
3629  iCurrentBits += pDimensionDefinitions[i].bits;
3630  if (iCurrentBits >= iMaxDimensions)
3631  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
3632  const int iNewBits = iCurrentBits + pDimDef->bits;
3633  if (iNewBits > iMaxDimensions)
3634  throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
3635  // check if there's already a dimensions of the same type
3636  for (int i = 0; i < Dimensions; i++)
3637  if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3638  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3639 
3640  // pos is where the new dimension should be placed, normally
3641  // last in list, except for the samplechannel dimension which
3642  // has to be first in list
3643  int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3644  int bitpos = 0;
3645  for (int i = 0 ; i < pos ; i++)
3646  bitpos += pDimensionDefinitions[i].bits;
3647 
3648  // make room for the new dimension
3649  for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3650  for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3651  for (int j = Dimensions ; j > pos ; j--) {
3652  pDimensionRegions[i]->DimensionUpperLimits[j] =
3653  pDimensionRegions[i]->DimensionUpperLimits[j - 1];
3654  }
3655  }
3656 
3657  // assign definition of new dimension
3658  pDimensionDefinitions[pos] = *pDimDef;
3659 
3660  // auto correct certain dimension definition fields (where possible)
3661  pDimensionDefinitions[pos].split_type =
3662  __resolveSplitType(pDimensionDefinitions[pos].dimension);
3663  pDimensionDefinitions[pos].zone_size =
3664  __resolveZoneSize(pDimensionDefinitions[pos]);
3665 
3666  // create new dimension region(s) for this new dimension, and make
3667  // sure that the dimension regions are placed correctly in both the
3668  // RIFF list and the pDimensionRegions array
3669  RIFF::Chunk* moveTo = NULL;
3670  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3671  for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3672  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3673  pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3674  }
3675  for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3676  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3677  RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3678  if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3679  // create a new dimension region and copy all parameter values from
3680  // an existing dimension region
3681  pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3682  new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3683 
3684  DimensionRegions++;
3685  }
3686  }
3687  moveTo = pDimensionRegions[i]->pParentList;
3688  }
3689 
3690  // initialize the upper limits for this dimension
3691  int mask = (1 << bitpos) - 1;
3692  for (int z = 0 ; z < pDimDef->zones ; z++) {
3693  uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3694  for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3695  pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3696  (z << bitpos) |
3697  (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3698  }
3699  }
3700 
3701  Dimensions++;
3702 
3703  // if this is a layer dimension, update 'Layers' attribute
3704  if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
3705 
3706  UpdateVelocityTable();
3707  }
3708 
3721  // get dimension's index
3722  int iDimensionNr = -1;
3723  for (int i = 0; i < Dimensions; i++) {
3724  if (&pDimensionDefinitions[i] == pDimDef) {
3725  iDimensionNr = i;
3726  break;
3727  }
3728  }
3729  if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
3730 
3731  // get amount of bits below the dimension to delete
3732  int iLowerBits = 0;
3733  for (int i = 0; i < iDimensionNr; i++)
3734  iLowerBits += pDimensionDefinitions[i].bits;
3735 
3736  // get amount ot bits above the dimension to delete
3737  int iUpperBits = 0;
3738  for (int i = iDimensionNr + 1; i < Dimensions; i++)
3739  iUpperBits += pDimensionDefinitions[i].bits;
3740 
3741  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3742 
3743  // delete dimension regions which belong to the given dimension
3744  // (that is where the dimension's bit > 0)
3745  for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3746  for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3747  for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3748  int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3749  iObsoleteBit << iLowerBits |
3750  iLowerBit;
3751 
3752  _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3753  delete pDimensionRegions[iToDelete];
3754  pDimensionRegions[iToDelete] = NULL;
3755  DimensionRegions--;
3756  }
3757  }
3758  }
3759 
3760  // defrag pDimensionRegions array
3761  // (that is remove the NULL spaces within the pDimensionRegions array)
3762  for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3763  if (!pDimensionRegions[iTo]) {
3764  if (iFrom <= iTo) iFrom = iTo + 1;
3765  while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3766  if (iFrom < 256 && pDimensionRegions[iFrom]) {
3767  pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3768  pDimensionRegions[iFrom] = NULL;
3769  }
3770  }
3771  }
3772 
3773  // remove the this dimension from the upper limits arrays
3774  for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3775  DimensionRegion* d = pDimensionRegions[j];
3776  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3777  d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3778  }
3779  d->DimensionUpperLimits[Dimensions - 1] = 127;
3780  }
3781 
3782  // 'remove' dimension definition
3783  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3784  pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
3785  }
3786  pDimensionDefinitions[Dimensions - 1].dimension = dimension_none;
3787  pDimensionDefinitions[Dimensions - 1].bits = 0;
3788  pDimensionDefinitions[Dimensions - 1].zones = 0;
3789 
3790  Dimensions--;
3791 
3792  // if this was a layer dimension, update 'Layers' attribute
3793  if (pDimDef->dimension == dimension_layer) Layers = 1;
3794  }
3795 
3811  if (!Dimensions)
3812  throw gig::Exception("Could not delete dimension zone, because there is no dimension at all.");
3813  dimension_def_t* oldDef = GetDimensionDefinition(type);
3814  if (!oldDef)
3815  throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3816  if (oldDef->zones <= 2)
3817  throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3818  if (zone < 0 || zone >= oldDef->zones)
3819  throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3820 
3821  const int newZoneSize = oldDef->zones - 1;
3822 
3823  // create a temporary Region which just acts as a temporary copy
3824  // container and will be deleted at the end of this function and will
3825  // also not be visible through the API during this process
3826  gig::Region* tempRgn = NULL;
3827  {
3828  // adding these temporary chunks is probably not even necessary
3829  Instrument* instr = static_cast<Instrument*>(GetParent());
3830  RIFF::List* pCkInstrument = instr->pCkInstrument;
3831  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3832  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3833  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3834  tempRgn = new Region(instr, rgn);
3835  }
3836 
3837  // copy this region's dimensions (with already the dimension split size
3838  // requested by the arguments of this method call) to the temporary
3839  // region, and don't use Region::CopyAssign() here for this task, since
3840  // it would also alter fast lookup helper variables here and there
3841  dimension_def_t newDef = {};
3842  for (int i = 0; i < Dimensions; ++i) {
3843  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3844  // is this the dimension requested by the method arguments? ...
3845  if (def.dimension == type) { // ... if yes, decrement zone amount by one
3846  def.zones = newZoneSize;
3847  if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3848  newDef = def;
3849  }
3850  tempRgn->AddDimension(&def);
3851  }
3852  // silence clang sanitizer warning
3853  if (newDef.dimension == dimension_none)
3854  throw gig::Exception("Unexpected internal failure resolving dimension in DeleteDimensionZone() [this is a bug].");
3855 
3856  // find the dimension index in the tempRegion which is the dimension
3857  // type passed to this method (paranoidly expecting different order)
3858  int tempReducedDimensionIndex = -1;
3859  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3860  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3861  tempReducedDimensionIndex = d;
3862  break;
3863  }
3864  }
3865 
3866  // copy dimension regions from this region to the temporary region
3867  for (int iDst = 0; iDst < 256; ++iDst) {
3868  DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3869  if (!dstDimRgn) continue;
3870  std::map<dimension_t,int> dimCase;
3871  bool isValidZone = true;
3872  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3873  const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3874  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3875  (iDst >> baseBits) & ((1 << dstBits) - 1);
3876  baseBits += dstBits;
3877  // there are also DimensionRegion objects of unused zones, skip them
3878  if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3879  isValidZone = false;
3880  break;
3881  }
3882  }
3883  if (!isValidZone) continue;
3884  // a bit paranoid: cope with the chance that the dimensions would
3885  // have different order in source and destination regions
3886  const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3887  if (dimCase[type] >= zone) dimCase[type]++;
3888  DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3889  dstDimRgn->CopyAssign(srcDimRgn);
3890  // if this is the upper most zone of the dimension passed to this
3891  // method, then correct (raise) its upper limit to 127
3892  if (newDef.split_type == split_type_normal && isLastZone)
3893  dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3894  }
3895 
3896  // now tempRegion's dimensions and DimensionRegions basically reflect
3897  // what we wanted to get for this actual Region here, so we now just
3898  // delete and recreate the dimension in question with the new amount
3899  // zones and then copy back from tempRegion. we're actually deleting and
3900  // recreating all dimensions here, to avoid altering the precise order
3901  // of the dimensions (which would not be an error per se, but it would
3902  // cause usability issues with instrument editors)
3903  {
3904  std::vector<dimension_def_t> oldDefs;
3905  for (int i = 0; i < Dimensions; ++i)
3906  oldDefs.push_back(pDimensionDefinitions[i]); // copy, don't reference
3907  for (int i = Dimensions - 1; i >= 0; --i)
3908  DeleteDimension(&pDimensionDefinitions[i]);
3909  for (int i = 0; i < oldDefs.size(); ++i) {
3910  dimension_def_t& def = oldDefs[i];
3911  AddDimension(
3912  (def.dimension == newDef.dimension) ? &newDef : &def
3913  );
3914  }
3915  }
3916  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3917  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3918  if (!srcDimRgn) continue;
3919  std::map<dimension_t,int> dimCase;
3920  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3921  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3922  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3923  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3924  baseBits += srcBits;
3925  }
3926  // a bit paranoid: cope with the chance that the dimensions would
3927  // have different order in source and destination regions
3928  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3929  if (!dstDimRgn) continue;
3930  dstDimRgn->CopyAssign(srcDimRgn);
3931  }
3932 
3933  // delete temporary region
3934  tempRgn->DeleteChunks();
3935  delete tempRgn;
3936 
3937  UpdateVelocityTable();
3938  }
3939 
3955  if (!Dimensions)
3956  throw gig::Exception("Could not split dimension zone, because there is no dimension at all.");
3957  dimension_def_t* oldDef = GetDimensionDefinition(type);
3958  if (!oldDef)
3959  throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3960  if (zone < 0 || zone >= oldDef->zones)
3961  throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3962 
3963  const int newZoneSize = oldDef->zones + 1;
3964 
3965  // create a temporary Region which just acts as a temporary copy
3966  // container and will be deleted at the end of this function and will
3967  // also not be visible through the API during this process
3968  gig::Region* tempRgn = NULL;
3969  {
3970  // adding these temporary chunks is probably not even necessary
3971  Instrument* instr = static_cast<Instrument*>(GetParent());
3972  RIFF::List* pCkInstrument = instr->pCkInstrument;
3973  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3974  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3975  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3976  tempRgn = new Region(instr, rgn);
3977  }
3978 
3979  // copy this region's dimensions (with already the dimension split size
3980  // requested by the arguments of this method call) to the temporary
3981  // region, and don't use Region::CopyAssign() here for this task, since
3982  // it would also alter fast lookup helper variables here and there
3983  dimension_def_t newDef = {};
3984  for (int i = 0; i < Dimensions; ++i) {
3985  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3986  // is this the dimension requested by the method arguments? ...
3987  if (def.dimension == type) { // ... if yes, increment zone amount by one
3988  def.zones = newZoneSize;
3989  if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3990  newDef = def;
3991  }
3992  tempRgn->AddDimension(&def);
3993  }
3994  // silence clang sanitizer warning
3995  if (newDef.dimension == dimension_none)
3996  throw gig::Exception("Unexpected internal failure resolving dimension in SplitDimensionZone() [this is a bug].");
3997 
3998  // find the dimension index in the tempRegion which is the dimension
3999  // type passed to this method (paranoidly expecting different order)
4000  int tempIncreasedDimensionIndex = -1;
4001  for (int d = 0; d < tempRgn->Dimensions; ++d) {
4002  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
4003  tempIncreasedDimensionIndex = d;
4004  break;
4005  }
4006  }
4007 
4008  // copy dimension regions from this region to the temporary region
4009  for (int iSrc = 0; iSrc < 256; ++iSrc) {
4010  DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
4011  if (!srcDimRgn) continue;
4012  std::map<dimension_t,int> dimCase;
4013  bool isValidZone = true;
4014  for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
4015  const int srcBits = pDimensionDefinitions[d].bits;
4016  dimCase[pDimensionDefinitions[d].dimension] =
4017  (iSrc >> baseBits) & ((1 << srcBits) - 1);
4018  // there are also DimensionRegion objects for unused zones, skip them
4019  if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
4020  isValidZone = false;
4021  break;
4022  }
4023  baseBits += srcBits;
4024  }
4025  if (!isValidZone) continue;
4026  // a bit paranoid: cope with the chance that the dimensions would
4027  // have different order in source and destination regions
4028  if (dimCase[type] > zone) dimCase[type]++;
4029  DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
4030  dstDimRgn->CopyAssign(srcDimRgn);
4031  // if this is the requested zone to be splitted, then also copy
4032  // the source DimensionRegion to the newly created target zone
4033  // and set the old zones upper limit lower
4034  if (dimCase[type] == zone) {
4035  // lower old zones upper limit
4036  if (newDef.split_type == split_type_normal) {
4037  const int high =
4038  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
4039  int low = 0;
4040  if (zone > 0) {
4041  std::map<dimension_t,int> lowerCase = dimCase;
4042  lowerCase[type]--;
4043  DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
4044  low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
4045  }
4046  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
4047  }
4048  // fill the newly created zone of the divided zone as well
4049  dimCase[type]++;
4050  dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
4051  dstDimRgn->CopyAssign(srcDimRgn);
4052  }
4053  }
4054 
4055  // now tempRegion's dimensions and DimensionRegions basically reflect
4056  // what we wanted to get for this actual Region here, so we now just
4057  // delete and recreate the dimension in question with the new amount
4058  // zones and then copy back from tempRegion. we're actually deleting and
4059  // recreating all dimensions here, to avoid altering the precise order
4060  // of the dimensions (which would not be an error per se, but it would
4061  // cause usability issues with instrument editors)
4062  {
4063  std::vector<dimension_def_t> oldDefs;
4064  for (int i = 0; i < Dimensions; ++i)
4065  oldDefs.push_back(pDimensionDefinitions[i]); // copy, don't reference
4066  for (int i = Dimensions - 1; i >= 0; --i)
4067  DeleteDimension(&pDimensionDefinitions[i]);
4068  for (int i = 0; i < oldDefs.size(); ++i) {
4069  dimension_def_t& def = oldDefs[i];
4070  AddDimension(
4071  (def.dimension == newDef.dimension) ? &newDef : &def
4072  );
4073  }
4074  }
4075  for (int iSrc = 0; iSrc < 256; ++iSrc) {
4076  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
4077  if (!srcDimRgn) continue;
4078  std::map<dimension_t,int> dimCase;
4079  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
4080  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
4081  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
4082  (iSrc >> baseBits) & ((1 << srcBits) - 1);
4083  baseBits += srcBits;
4084  }
4085  // a bit paranoid: cope with the chance that the dimensions would
4086  // have different order in source and destination regions
4087  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
4088  if (!dstDimRgn) continue;
4089  dstDimRgn->CopyAssign(srcDimRgn);
4090  }
4091 
4092  // delete temporary region
4093  tempRgn->DeleteChunks();
4094  delete tempRgn;
4095 
4096  UpdateVelocityTable();
4097  }
4098 
4114  if (oldType == newType) return;
4115  dimension_def_t* def = GetDimensionDefinition(oldType);
4116  if (!def)
4117  throw gig::Exception("No dimension with provided old dimension type exists on this region");
4118  if (newType == dimension_samplechannel && def->zones != 2)
4119  throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
4120  if (GetDimensionDefinition(newType))
4121  throw gig::Exception("There is already a dimension with requested new dimension type on this region");
4122  def->dimension = newType;
4123  def->split_type = __resolveSplitType(newType);
4124  }
4125 
4126  DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
4127  uint8_t bits[8] = {};
4128  for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
4129  it != DimCase.end(); ++it)
4130  {
4131  for (int d = 0; d < Dimensions; ++d) {
4132  if (pDimensionDefinitions[d].dimension == it->first) {
4133  bits[d] = it->second;
4134  goto nextDimCaseSlice;
4135  }
4136  }
4137  assert(false); // do crash ... too harsh maybe ? ignore it instead ?
4138  nextDimCaseSlice:
4139  ; // noop
4140  }
4141  return GetDimensionRegionByBit(bits);
4142  }
4143 
4154  for (int i = 0; i < Dimensions; ++i)
4155  if (pDimensionDefinitions[i].dimension == type)
4156  return &pDimensionDefinitions[i];
4157  return NULL;
4158  }
4159 
4161  for (int i = 0; i < 256; i++) {
4162  if (pDimensionRegions[i]) delete pDimensionRegions[i];
4163  }
4164  }
4165 
4185  uint8_t bits;
4186  int veldim = -1;
4187  int velbitpos = 0;
4188  int bitpos = 0;
4189  int dimregidx = 0;
4190  for (uint i = 0; i < Dimensions; i++) {
4191  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4192  // the velocity dimension must be handled after the other dimensions
4193  veldim = i;
4194  velbitpos = bitpos;
4195  } else {
4196  switch (pDimensionDefinitions[i].split_type) {
4197  case split_type_normal:
4198  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4199  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4200  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4201  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4202  }
4203  } else {
4204  // gig2: evenly sized zones
4205  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4206  }
4207  break;
4208  case split_type_bit: // the value is already the sought dimension bit number
4209  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4210  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4211  break;
4212  }
4213  dimregidx |= bits << bitpos;
4214  }
4215  bitpos += pDimensionDefinitions[i].bits;
4216  }
4217  DimensionRegion* dimreg = pDimensionRegions[dimregidx & 255];
4218  if (!dimreg) return NULL;
4219  if (veldim != -1) {
4220  // (dimreg is now the dimension region for the lowest velocity)
4221  if (dimreg->VelocityTable) // custom defined zone ranges
4222  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4223  else // normal split type
4224  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4225 
4226  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4227  dimregidx |= (bits & limiter_mask) << velbitpos;
4228  dimreg = pDimensionRegions[dimregidx & 255];
4229  }
4230  return dimreg;
4231  }
4232 
4233  int Region::GetDimensionRegionIndexByValue(const uint DimValues[8]) {
4234  uint8_t bits;
4235  int veldim = -1;
4236  int velbitpos = 0;
4237  int bitpos = 0;
4238  int dimregidx = 0;
4239  for (uint i = 0; i < Dimensions; i++) {
4240  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4241  // the velocity dimension must be handled after the other dimensions
4242  veldim = i;
4243  velbitpos = bitpos;
4244  } else {
4245  switch (pDimensionDefinitions[i].split_type) {
4246  case split_type_normal:
4247  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4248  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4249  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4250  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4251  }
4252  } else {
4253  // gig2: evenly sized zones
4254  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4255  }
4256  break;
4257  case split_type_bit: // the value is already the sought dimension bit number
4258  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4259  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4260  break;
4261  }
4262  dimregidx |= bits << bitpos;
4263  }
4264  bitpos += pDimensionDefinitions[i].bits;
4265  }
4266  dimregidx &= 255;
4267  DimensionRegion* dimreg = pDimensionRegions[dimregidx];
4268  if (!dimreg) return -1;
4269  if (veldim != -1) {
4270  // (dimreg is now the dimension region for the lowest velocity)
4271  if (dimreg->VelocityTable) // custom defined zone ranges
4272  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4273  else // normal split type
4274  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4275 
4276  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4277  dimregidx |= (bits & limiter_mask) << velbitpos;
4278  dimregidx &= 255;
4279  }
4280  return dimregidx;
4281  }
4282 
4294  return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4295  << pDimensionDefinitions[5].bits | DimBits[5])
4296  << pDimensionDefinitions[4].bits | DimBits[4])
4297  << pDimensionDefinitions[3].bits | DimBits[3])
4298  << pDimensionDefinitions[2].bits | DimBits[2])
4299  << pDimensionDefinitions[1].bits | DimBits[1])
4300  << pDimensionDefinitions[0].bits | DimBits[0]];
4301  }
4302 
4313  if (pSample) return static_cast<gig::Sample*>(pSample);
4314  else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4315  }
4316 
4317  Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
4318  if ((int32_t)WavePoolTableIndex == -1) return NULL;
4319  File* file = (File*) GetParent()->GetParent();
4320  if (!file->pWavePoolTable) return NULL;
4321  if (WavePoolTableIndex + 1 > file->WavePoolCount) return NULL;
4322  // for new files or files >= 2 GB use 64 bit wave pool offsets
4323  if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
4324  // use 64 bit wave pool offsets (treating this as large file)
4325  uint64_t soughtoffset =
4326  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4327  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4328  size_t i = 0;
4329  for (Sample* sample = file->GetSample(i, pProgress); sample;
4330  sample = file->GetSample(++i))
4331  {
4332  if (sample->ullWavePoolOffset == soughtoffset)
4333  return sample;
4334  }
4335  } else {
4336  // use extension files and 32 bit wave pool offsets
4337  file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4338  file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4339  size_t i = 0;
4340  for (Sample* sample = file->GetSample(i, pProgress); sample;
4341  sample = file->GetSample(++i))
4342  {
4343  if (sample->ullWavePoolOffset == soughtoffset &&
4344  sample->FileNo == soughtfileno) return sample;
4345  }
4346  }
4347  return NULL;
4348  }
4349 
4359  void Region::CopyAssign(const Region* orig) {
4360  CopyAssign(orig, NULL);
4361  }
4362 
4370  void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
4371  // handle base classes
4373 
4374  if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
4375  pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
4376  }
4377 
4378  // handle own member variables
4379  for (int i = Dimensions - 1; i >= 0; --i) {
4380  DeleteDimension(&pDimensionDefinitions[i]);
4381  }
4382  Layers = 0; // just to be sure
4383  for (int i = 0; i < orig->Dimensions; i++) {
4384  // we need to copy the dim definition here, to avoid the compiler
4385  // complaining about const-ness issue
4386  dimension_def_t def = orig->pDimensionDefinitions[i];
4387  AddDimension(&def);
4388  }
4389  for (int i = 0; i < 256; i++) {
4390  if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
4391  pDimensionRegions[i]->CopyAssign(
4392  orig->pDimensionRegions[i],
4393  mSamples
4394  );
4395  }
4396  }
4397  Layers = orig->Layers;
4398  }
4399 
4413  bool Region::UsesAnyGigFormatExtension() const {
4414  for (int i = 0; i < 256; i++) {
4415  if (pDimensionRegions[i]) {
4416  if (pDimensionRegions[i]->UsesAnyGigFormatExtension())
4417  return true;
4418  }
4419  }
4420  return false;
4421  }
4422 
4423 
4424 // *************** MidiRule ***************
4425 // *
4426 
4427  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
4428  _3ewg->SetPos(36);
4429  Triggers = _3ewg->ReadUint8();
4430  _3ewg->SetPos(40);
4431  ControllerNumber = _3ewg->ReadUint8();
4432  _3ewg->SetPos(46);
4433  for (int i = 0 ; i < Triggers ; i++) {
4434  pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
4435  pTriggers[i].Descending = _3ewg->ReadUint8();
4436  pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
4437  pTriggers[i].Key = _3ewg->ReadUint8();
4438  pTriggers[i].NoteOff = _3ewg->ReadUint8();
4439  pTriggers[i].Velocity = _3ewg->ReadUint8();
4440  pTriggers[i].OverridePedal = _3ewg->ReadUint8();
4441  _3ewg->ReadUint8();
4442  }
4443  }
4444 
4445  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4446  ControllerNumber(0),
4447  Triggers(0) {
4448  }
4449 
4450  void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
4451  pData[32] = 4;
4452  pData[33] = 16;
4453  pData[36] = Triggers;
4454  pData[40] = ControllerNumber;
4455  for (int i = 0 ; i < Triggers ; i++) {
4456  pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4457  pData[47 + i * 8] = pTriggers[i].Descending;
4458  pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4459  pData[49 + i * 8] = pTriggers[i].Key;
4460  pData[50 + i * 8] = pTriggers[i].NoteOff;
4461  pData[51 + i * 8] = pTriggers[i].Velocity;
4462  pData[52 + i * 8] = pTriggers[i].OverridePedal;
4463  }
4464  }
4465 
4466  MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
4467  _3ewg->SetPos(36);
4468  LegatoSamples = _3ewg->ReadUint8(); // always 12
4469  _3ewg->SetPos(40);
4470  BypassUseController = _3ewg->ReadUint8();
4471  BypassKey = _3ewg->ReadUint8();
4472  BypassController = _3ewg->ReadUint8();
4473  ThresholdTime = _3ewg->ReadUint16();
4474  _3ewg->ReadInt16();
4475  ReleaseTime = _3ewg->ReadUint16();
4476  _3ewg->ReadInt16();
4477  KeyRange.low = _3ewg->ReadUint8();
4478  KeyRange.high = _3ewg->ReadUint8();
4479  _3ewg->SetPos(64);
4480  ReleaseTriggerKey = _3ewg->ReadUint8();
4481  AltSustain1Key = _3ewg->ReadUint8();
4482  AltSustain2Key = _3ewg->ReadUint8();
4483  }
4484 
4485  MidiRuleLegato::MidiRuleLegato() :
4486  LegatoSamples(12),
4487  BypassUseController(false),
4488  BypassKey(0),
4489  BypassController(1),
4490  ThresholdTime(20),
4491  ReleaseTime(20),
4492  ReleaseTriggerKey(0),
4493  AltSustain1Key(0),
4494  AltSustain2Key(0)
4495  {
4496  KeyRange.low = KeyRange.high = 0;
4497  }
4498 
4499  void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
4500  pData[32] = 0;
4501  pData[33] = 16;
4502  pData[36] = LegatoSamples;
4503  pData[40] = BypassUseController;
4504  pData[41] = BypassKey;
4505  pData[42] = BypassController;
4506  store16(&pData[43], ThresholdTime);
4507  store16(&pData[47], ReleaseTime);
4508  pData[51] = KeyRange.low;
4509  pData[52] = KeyRange.high;
4510  pData[64] = ReleaseTriggerKey;
4511  pData[65] = AltSustain1Key;
4512  pData[66] = AltSustain2Key;
4513  }
4514 
4515  MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
4516  _3ewg->SetPos(36);
4517  Articulations = _3ewg->ReadUint8();
4518  int flags = _3ewg->ReadUint8();
4519  Polyphonic = flags & 8;
4520  Chained = flags & 4;
4521  Selector = (flags & 2) ? selector_controller :
4522  (flags & 1) ? selector_key_switch : selector_none;
4523  Patterns = _3ewg->ReadUint8();
4524  _3ewg->ReadUint8(); // chosen row
4525  _3ewg->ReadUint8(); // unknown
4526  _3ewg->ReadUint8(); // unknown
4527  _3ewg->ReadUint8(); // unknown
4528  KeySwitchRange.low = _3ewg->ReadUint8();
4529  KeySwitchRange.high = _3ewg->ReadUint8();
4530  Controller = _3ewg->ReadUint8();
4531  PlayRange.low = _3ewg->ReadUint8();
4532  PlayRange.high = _3ewg->ReadUint8();
4533 
4534  int n = std::min(int(Articulations), 32);
4535  for (int i = 0 ; i < n ; i++) {
4536  _3ewg->ReadString(pArticulations[i], 32);
4537  }
4538  _3ewg->SetPos(1072);
4539  n = std::min(int(Patterns), 32);
4540  for (int i = 0 ; i < n ; i++) {
4541  _3ewg->ReadString(pPatterns[i].Name, 16);
4542  pPatterns[i].Size = _3ewg->ReadUint8();
4543  _3ewg->Read(&pPatterns[i][0], 1, 32);
4544  }
4545  }
4546 
4547  MidiRuleAlternator::MidiRuleAlternator() :
4548  Articulations(0),
4549  Patterns(0),
4550  Selector(selector_none),
4551  Controller(0),
4552  Polyphonic(false),
4553  Chained(false)
4554  {
4555  PlayRange.low = PlayRange.high = 0;
4556  KeySwitchRange.low = KeySwitchRange.high = 0;
4557  }
4558 
4559  void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
4560  pData[32] = 3;
4561  pData[33] = 16;
4562  pData[36] = Articulations;
4563  pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4564  (Selector == selector_controller ? 2 :
4565  (Selector == selector_key_switch ? 1 : 0));
4566  pData[38] = Patterns;
4567 
4568  pData[43] = KeySwitchRange.low;
4569  pData[44] = KeySwitchRange.high;
4570  pData[45] = Controller;
4571  pData[46] = PlayRange.low;
4572  pData[47] = PlayRange.high;
4573 
4574  char* str = reinterpret_cast<char*>(pData);
4575  int pos = 48;
4576  int n = std::min(int(Articulations), 32);
4577  for (int i = 0 ; i < n ; i++, pos += 32) {
4578  strncpy(&str[pos], pArticulations[i].c_str(), 32);
4579  }
4580 
4581  pos = 1072;
4582  n = std::min(int(Patterns), 32);
4583  for (int i = 0 ; i < n ; i++, pos += 49) {
4584  strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4585  pData[pos + 16] = pPatterns[i].Size;
4586  memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4587  }
4588  }
4589 
4590 // *************** Script ***************
4591 // *
4592 
4593  Script::Script(ScriptGroup* group, RIFF::Chunk* ckScri) {
4594  pGroup = group;
4595  pChunk = ckScri;
4596  if (ckScri) { // object is loaded from file ...
4597  ckScri->SetPos(0);
4598 
4599  // read header
4600  uint32_t headerSize = ckScri->ReadUint32();
4601  Compression = (Compression_t) ckScri->ReadUint32();
4602  Encoding = (Encoding_t) ckScri->ReadUint32();
4603  Language = (Language_t) ckScri->ReadUint32();
4604  Bypass = ckScri->ReadUint32() & 1;
4605  crc = ckScri->ReadUint32();
4606  uint32_t nameSize = ckScri->ReadUint32();
4607  Name.resize(nameSize, ' ');
4608  for (int i = 0; i < nameSize; ++i)
4609  Name[i] = ckScri->ReadUint8();
4610  // check if an uuid was already stored along with this script
4611  if (headerSize >= 6*sizeof(int32_t) + nameSize + 16) { // yes ...
4612  for (uint i = 0; i < 16; ++i) {
4613  Uuid[i] = ckScri->ReadUint8();
4614  }
4615  } else { // no uuid yet, generate one now ...
4616  GenerateUuid();
4617  }
4618  // to handle potential future extensions of the header
4619  ckScri->SetPos(sizeof(int32_t) + headerSize);
4620  // read actual script data
4621  uint32_t scriptSize = uint32_t(ckScri->GetSize() - ckScri->GetPos());
4622  data.resize(scriptSize);
4623  for (int i = 0; i < scriptSize; ++i)
4624  data[i] = ckScri->ReadUint8();
4625  } else { // this is a new script object, so just initialize it as such ...
4626  Compression = COMPRESSION_NONE;
4627  Encoding = ENCODING_ASCII;
4628  Language = LANGUAGE_NKSP;
4629  Bypass = false;
4630  crc = 0;
4631  Name = "Unnamed Script";
4632  GenerateUuid();
4633  }
4634  }
4635 
4636  Script::~Script() {
4637  }
4638 
4643  String s;
4644  s.resize(data.size(), ' ');
4645  memcpy(&s[0], &data[0], data.size());
4646  return s;
4647  }
4648 
4655  void Script::SetScriptAsText(const String& text) {
4656  data.resize(text.size());
4657  memcpy(&data[0], &text[0], text.size());
4658  }
4659 
4670  }
4671 
4682  // recalculate CRC32 check sum
4683  __resetCRC(crc);
4684  __calculateCRC(&data[0], data.size(), crc);
4685  __finalizeCRC(crc);
4686  // make sure chunk exists and has the required size
4687  const file_offset_t chunkSize =
4688  (file_offset_t) 7*sizeof(int32_t) + Name.size() + 16 + data.size();
4689  if (!pChunk) pChunk = pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4690  else pChunk->Resize(chunkSize);
4691  // fill the chunk data to be written to disk
4692  uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4693  int pos = 0;
4694  store32(&pData[pos], uint32_t(6*sizeof(int32_t) + Name.size() + 16)); // total header size
4695  pos += sizeof(int32_t);
4696  store32(&pData[pos], Compression);
4697  pos += sizeof(int32_t);
4698  store32(&pData[pos], Encoding);
4699  pos += sizeof(int32_t);
4700  store32(&pData[pos], Language);
4701  pos += sizeof(int32_t);
4702  store32(&pData[pos], Bypass ? 1 : 0);
4703  pos += sizeof(int32_t);
4704  store32(&pData[pos], crc);
4705  pos += sizeof(int32_t);
4706  store32(&pData[pos], (uint32_t) Name.size());
4707  pos += sizeof(int32_t);
4708  for (int i = 0; i < Name.size(); ++i, ++pos)
4709  pData[pos] = Name[i];
4710  for (int i = 0; i < 16; ++i, ++pos)
4711  pData[pos] = Uuid[i];
4712  for (int i = 0; i < data.size(); ++i, ++pos)
4713  pData[pos] = data[i];
4714  }
4715 
4720  DLS::dlsid_t dlsid;
4722  Uuid[0] = dlsid.ulData1 & 0xff;
4723  Uuid[1] = dlsid.ulData1 >> 8 & 0xff;
4724  Uuid[2] = dlsid.ulData1 >> 16 & 0xff;
4725  Uuid[3] = dlsid.ulData1 >> 24 & 0xff;
4726  Uuid[4] = dlsid.usData2 & 0xff;
4727  Uuid[5] = dlsid.usData2 >> 8 & 0xff;
4728  Uuid[6] = dlsid.usData3 & 0xff;
4729  Uuid[7] = dlsid.usData3 >> 8 & 0xff;
4730  Uuid[8] = dlsid.abData[0];
4731  Uuid[9] = dlsid.abData[1];
4732  Uuid[10] = dlsid.abData[2];
4733  Uuid[11] = dlsid.abData[3];
4734  Uuid[12] = dlsid.abData[4];
4735  Uuid[13] = dlsid.abData[5];
4736  Uuid[14] = dlsid.abData[6];
4737  Uuid[15] = dlsid.abData[7];
4738  }
4739 
4747  if (this->pGroup == pGroup) return;
4748  if (pChunk)
4749  pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4750  this->pGroup = pGroup;
4751  }
4752 
4760  return pGroup;
4761  }
4762 
4770  void Script::CopyAssign(const Script* orig) {
4771  Name = orig->Name;
4772  Compression = orig->Compression;
4773  Encoding = orig->Encoding;
4774  Language = orig->Language;
4775  Bypass = orig->Bypass;
4776  data = orig->data;
4777  }
4778 
4779  void Script::RemoveAllScriptReferences() {
4780  File* pFile = pGroup->pFile;
4781  for (int i = 0; pFile->GetInstrument(i); ++i) {
4782  Instrument* instr = pFile->GetInstrument(i);
4783  instr->RemoveScript(this);
4784  }
4785  }
4786 
4787 // *************** ScriptGroup ***************
4788 // *
4789 
4790  ScriptGroup::ScriptGroup(File* file, RIFF::List* lstRTIS) {
4791  pFile = file;
4792  pList = lstRTIS;
4793  pScripts = NULL;
4794  if (lstRTIS) {
4795  RIFF::Chunk* ckName = lstRTIS->GetSubChunk(CHUNK_ID_LSNM);
4796  ::LoadString(ckName, Name);
4797  } else {
4798  Name = "Default Group";
4799  }
4800  }
4801 
4802  ScriptGroup::~ScriptGroup() {
4803  if (pScripts) {
4804  std::vector<Script*>::iterator iter = pScripts->begin();
4805  std::vector<Script*>::iterator end = pScripts->end();
4806  while (iter != end) {
4807  delete *iter;
4808  ++iter;
4809  }
4810  delete pScripts;
4811  }
4812  }
4813 
4824  }
4825 
4836  if (pScripts) {
4837  if (!pList)
4838  pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4839 
4840  // now store the name of this group as <LSNM> chunk as subchunk of the <RTIS> list chunk
4841  ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String("Unnamed Group"), true, 64);
4842 
4843  for (std::vector<Script*>::iterator it = pScripts->begin();
4844  it != pScripts->end(); ++it)
4845  {
4846  (*it)->UpdateChunks(pProgress);
4847  }
4848  }
4849  }
4850 
4859  if (!pScripts) LoadScripts();
4860  if (index >= pScripts->size()) return NULL;
4861  return (*pScripts)[index];
4862  }
4863 
4876  if (!pScripts) LoadScripts();
4877  Script* pScript = new Script(this, NULL);
4878  pScripts->push_back(pScript);
4879  return pScript;
4880  }
4881 
4893  if (!pScripts) LoadScripts();
4894  std::vector<Script*>::iterator iter =
4895  find(pScripts->begin(), pScripts->end(), pScript);
4896  if (iter == pScripts->end())
4897  throw gig::Exception("Could not delete script, could not find given script");
4898  pScripts->erase(iter);
4899  pScript->RemoveAllScriptReferences();
4900  if (pScript->pChunk)
4901  pScript->pChunk->GetParent()->DeleteSubChunk(pScript->pChunk);
4902  delete pScript;
4903  }
4904 
4905  void ScriptGroup::LoadScripts() {
4906  if (pScripts) return;
4907  pScripts = new std::vector<Script*>;
4908  if (!pList) return;
4909 
4910  size_t i = 0;
4911  for (RIFF::Chunk* ck = pList->GetSubChunkAt(i); ck;
4912  ck = pList->GetSubChunkAt(++i))
4913  {
4914  if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4915  pScripts->push_back(new Script(this, ck));
4916  }
4917  }
4918  }
4919 
4920 // *************** Instrument ***************
4921 // *
4922 
4923  Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
4924  static const DLS::Info::string_length_t fixedStringLengths[] = {
4925  { CHUNK_ID_INAM, 64 },
4926  { CHUNK_ID_ISFT, 12 },
4927  { 0, 0 }
4928  };
4929  pInfo->SetFixedStringLengths(fixedStringLengths);
4930 
4931  // Initialization
4932  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4933  EffectSend = 0;
4934  Attenuation = 0;
4935  FineTune = 0;
4936  PitchbendRange = 2;
4937  PianoReleaseMode = false;
4938  DimensionKeyRange.low = 0;
4939  DimensionKeyRange.high = 0;
4940  pMidiRules = new MidiRule*[3];
4941  pMidiRules[0] = NULL;
4942  pScriptRefs = NULL;
4943 
4944  // Loading
4945  RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
4946  if (lart) {
4947  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4948  if (_3ewg) {
4949  _3ewg->SetPos(0);
4950 
4951  EffectSend = _3ewg->ReadUint16();
4952  Attenuation = _3ewg->ReadInt32();
4953  FineTune = _3ewg->ReadInt16();
4954  PitchbendRange = _3ewg->ReadInt16();
4955  uint8_t dimkeystart = _3ewg->ReadUint8();
4956  PianoReleaseMode = dimkeystart & 0x01;
4957  DimensionKeyRange.low = dimkeystart >> 1;
4958  DimensionKeyRange.high = _3ewg->ReadUint8();
4959 
4960  if (_3ewg->GetSize() > 32) {
4961  // read MIDI rules
4962  int i = 0;
4963  _3ewg->SetPos(32);
4964  uint8_t id1 = _3ewg->ReadUint8();
4965  uint8_t id2 = _3ewg->ReadUint8();
4966 
4967  if (id2 == 16) {
4968  if (id1 == 4) {
4969  pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4970  } else if (id1 == 0) {
4971  pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4972  } else if (id1 == 3) {
4973  pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4974  } else {
4975  pMidiRules[i++] = new MidiRuleUnknown;
4976  }
4977  }
4978  else if (id1 != 0 || id2 != 0) {
4979  pMidiRules[i++] = new MidiRuleUnknown;
4980  }
4981  //TODO: all the other types of rules
4982 
4983  pMidiRules[i] = NULL;
4984  }
4985  }
4986  }
4987 
4988  if (pFile->GetAutoLoad()) {
4989  if (!pRegions) pRegions = new RegionList;
4990  RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
4991  if (lrgn) {
4992  size_t i = 0;
4993  for (RIFF::List* rgn = lrgn->GetSubListAt(i); rgn;
4994  rgn = lrgn->GetSubListAt(++i))
4995  {
4996  if (rgn->GetListType() == LIST_TYPE_RGN) {
4997  if (pProgress)
4998  __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
4999  pRegions->push_back(new Region(this, rgn));
5000  }
5001  }
5002  // Creating Region Key Table for fast lookup
5003  UpdateRegionKeyTable();
5004  }
5005  }
5006 
5007  // own gig format extensions
5008  RIFF::List* lst3LS = insList->GetSubList(LIST_TYPE_3LS);
5009  if (lst3LS) {
5010  // script slots (that is references to instrument scripts)
5011  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
5012  if (ckSCSL) {
5013  ckSCSL->SetPos(0);
5014 
5015  int headerSize = ckSCSL->ReadUint32();
5016  int slotCount = ckSCSL->ReadUint32();
5017  if (slotCount) {
5018  int slotSize = ckSCSL->ReadUint32();
5019  ckSCSL->SetPos(headerSize); // in case of future header extensions
5020  int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions
5021  for (int i = 0; i < slotCount; ++i) {
5022  _ScriptPooolEntry e;
5023  e.fileOffset = ckSCSL->ReadUint32();
5024  e.bypass = ckSCSL->ReadUint32() & 1;
5025  if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions
5026  scriptPoolFileOffsets.push_back(e);
5027  }
5028  }
5029  }
5030 
5031  // overridden script 'patch' variables
5032  RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5033  if (ckSCPV) {
5034  ckSCPV->SetPos(0);
5035 
5036  int nScripts = ckSCPV->ReadUint32();
5037  for (int iScript = 0; iScript < nScripts; ++iScript) {
5038  _UUID uuid;
5039  for (int i = 0; i < 16; ++i)
5040  uuid[i] = ckSCPV->ReadUint8();
5041  uint slot = ckSCPV->ReadUint32();
5042  ckSCPV->ReadUint32(); // unused, reserved 32 bit
5043  int nVars = ckSCPV->ReadUint32();
5044  for (int iVar = 0; iVar < nVars; ++iVar) {
5045  uint8_t type = ckSCPV->ReadUint8();
5046  ckSCPV->ReadUint8(); // unused, reserved byte
5047  int blobSize = ckSCPV->ReadUint16();
5048  RIFF::file_offset_t pos = ckSCPV->GetPos();
5049  // assuming 1st bit is set in 'type', otherwise blob not
5050  // supported for decoding
5051  if (type & 1) {
5052  String name, value;
5053  int len = ckSCPV->ReadUint16();
5054  for (int i = 0; i < len; ++i)
5055  name += (char) ckSCPV->ReadUint8();
5056  len = ckSCPV->ReadUint16();
5057  for (int i = 0; i < len; ++i)
5058  value += (char) ckSCPV->ReadUint8();
5059  if (!name.empty()) // 'name' should never be empty, but just to be sure
5060  scriptVars[uuid][slot][name] = value;
5061  }
5062  // also for potential future extensions: seek forward
5063  // according to blob size
5064  ckSCPV->SetPos(pos + blobSize);
5065  }
5066  }
5067  }
5068  }
5069 
5070  if (pProgress)
5071  __notify_progress(pProgress, 1.0f); // notify done
5072  }
5073 
5074  void Instrument::UpdateRegionKeyTable() {
5075  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
5076  RegionList::iterator iter = pRegions->begin();
5077  RegionList::iterator end = pRegions->end();
5078  for (; iter != end; ++iter) {
5079  gig::Region* pRegion = static_cast<gig::Region*>(*iter);
5080  const int low = std::max(int(pRegion->KeyRange.low), 0);
5081  const int high = std::min(int(pRegion->KeyRange.high), 127);
5082  for (int iKey = low; iKey <= high; iKey++) {
5083  RegionKeyTable[iKey] = pRegion;
5084  }
5085  }
5086  }
5087 
5089  for (int i = 0 ; pMidiRules[i] ; i++) {
5090  delete pMidiRules[i];
5091  }
5092  delete[] pMidiRules;
5093  if (pScriptRefs) delete pScriptRefs;
5094  }
5095 
5107  // first update base classes' chunks
5108  DLS::Instrument::UpdateChunks(pProgress);
5109 
5110  // update Regions' chunks
5111  {
5112  RegionList::iterator iter = pRegions->begin();
5113  RegionList::iterator end = pRegions->end();
5114  for (; iter != end; ++iter)
5115  (*iter)->UpdateChunks(pProgress);
5116  }
5117 
5118  // make sure 'lart' RIFF list chunk exists
5119  RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
5120  if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
5121  // make sure '3ewg' RIFF chunk exists
5122  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
5123  if (!_3ewg) {
5124  File* pFile = (File*) GetParent();
5125 
5126  // 3ewg is bigger in gig3, as it includes the iMIDI rules
5127  int size = (pFile->pVersion && pFile->pVersion->major > 2) ? 16416 : 12;
5128  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
5129  memset(_3ewg->LoadChunkData(), 0, size);
5130  }
5131  // update '3ewg' RIFF chunk
5132  uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
5133  store16(&pData[0], EffectSend);
5134  store32(&pData[2], Attenuation);
5135  store16(&pData[6], FineTune);
5136  store16(&pData[8], PitchbendRange);
5137  const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
5138  DimensionKeyRange.low << 1;
5139  pData[10] = dimkeystart;
5140  pData[11] = DimensionKeyRange.high;
5141 
5142  if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
5143  pData[32] = 0;
5144  pData[33] = 0;
5145  } else {
5146  for (int i = 0 ; pMidiRules[i] ; i++) {
5147  pMidiRules[i]->UpdateChunks(pData);
5148  }
5149  }
5150 
5151  // own gig format extensions
5152  if (ScriptSlotCount()) {
5153  // make sure we have converted the original loaded script file
5154  // offsets into valid Script object pointers
5155  LoadScripts();
5156 
5157  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5158  if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS);
5159 
5160  // save script slots (that is references to instrument scripts)
5161  const int slotCount = (int) pScriptRefs->size();
5162  const int headerSize = 3 * sizeof(uint32_t);
5163  const int slotSize = 2 * sizeof(uint32_t);
5164  const int totalChunkSize = headerSize + slotCount * slotSize;
5165  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
5166  if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
5167  else ckSCSL->Resize(totalChunkSize);
5168  uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData();
5169  int pos = 0;
5170  store32(&pData[pos], headerSize);
5171  pos += sizeof(uint32_t);
5172  store32(&pData[pos], slotCount);
5173  pos += sizeof(uint32_t);
5174  store32(&pData[pos], slotSize);
5175  pos += sizeof(uint32_t);
5176  for (int i = 0; i < slotCount; ++i) {
5177  // arbitrary value, the actual file offset will be updated in
5178  // UpdateScriptFileOffsets() after the file has been resized
5179  int bogusFileOffset = 0;
5180  store32(&pData[pos], bogusFileOffset);
5181  pos += sizeof(uint32_t);
5182  store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
5183  pos += sizeof(uint32_t);
5184  }
5185 
5186  // save overridden script 'patch' variables ...
5187 
5188  // the actual 'scriptVars' member variable might contain variables of
5189  // scripts which are currently no longer assigned to any script slot
5190  // of this instrument, we need to get rid of these variables here to
5191  // prevent saving those persistently, however instead of touching the
5192  // member variable 'scriptVars' directly, rather strip a separate
5193  // copy such that the overridden values are not lost during an
5194  // instrument editor session (i.e. if script might be re-assigned)
5195  _VarsByScript vars = stripScriptVars();
5196  if (!vars.empty()) {
5197  // determine total size required for 'SCPV' RIFF chunk, and the
5198  // total amount of scripts being overridden (the latter is
5199  // required because a script might be used on several script
5200  // slots, hence vars.size() could then not be used here instead)
5201  size_t totalChunkSize = 4;
5202  size_t totalScriptsOverridden = 0;
5203  for (const auto& script : vars) {
5204  for (const auto& slot : script.second) {
5205  totalScriptsOverridden++;
5206  totalChunkSize += 16 + 4 + 4 + 4;
5207  for (const auto& var : slot.second) {
5208  totalChunkSize += 4 + 2 + var.first.length() +
5209  2 + var.second.length();
5210  }
5211  }
5212  }
5213 
5214  // ensure 'SCPV' RIFF chunk exists (with required size)
5215  RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5216  if (!ckSCPV) ckSCPV = lst3LS->AddSubChunk(CHUNK_ID_SCPV, totalChunkSize);
5217  else ckSCPV->Resize(totalChunkSize);
5218 
5219  // store the actual data to 'SCPV' RIFF chunk
5220  uint8_t* pData = (uint8_t*) ckSCPV->LoadChunkData();
5221  int pos = 0;
5222  store32(&pData[pos], (uint32_t) totalScriptsOverridden); // scripts count
5223  pos += 4;
5224  for (const auto& script : vars) {
5225  for (const auto& slot : script.second) {
5226  for (int i = 0; i < 16; ++i)
5227  pData[pos+i] = script.first[i]; // uuid
5228  pos += 16;
5229  store32(&pData[pos], (uint32_t) slot.first); // slot index
5230  pos += 4;
5231  store32(&pData[pos], (uint32_t) 0); // unused, reserved 32 bit
5232  pos += 4;
5233  store32(&pData[pos], (uint32_t) slot.second.size()); // variables count
5234  pos += 4;
5235  for (const auto& var : slot.second) {
5236  pData[pos++] = 1; // type
5237  pData[pos++] = 0; // reserved byte
5238  store16(&pData[pos], 2 + var.first.size() + 2 + var.second.size()); // blob size
5239  pos += 2;
5240  store16(&pData[pos], var.first.size()); // variable name length
5241  pos += 2;
5242  for (int i = 0; i < var.first.size(); ++i)
5243  pData[pos++] = var.first[i];
5244  store16(&pData[pos], var.second.size()); // variable value length
5245  pos += 2;
5246  for (int i = 0; i < var.second.size(); ++i)
5247  pData[pos++] = var.second[i];
5248  }
5249  }
5250  }
5251  } else {
5252  // no script variable overridden by this instrument, so get rid
5253  // of 'SCPV' RIFF chunk (if any)
5254  RIFF::Chunk* ckSCPV = lst3LS->GetSubChunk(CHUNK_ID_SCPV);
5255  if (ckSCPV) lst3LS->DeleteSubChunk(ckSCPV);
5256  }
5257  } else {
5258  // no script slots, so get rid of any LS custom RIFF chunks (if any)
5259  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5260  if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS);
5261  }
5262  }
5263 
5264  void Instrument::UpdateScriptFileOffsets() {
5265  // own gig format extensions
5266  if (pScriptRefs && pScriptRefs->size() > 0) {
5267  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
5268  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
5269  const int slotCount = (int) pScriptRefs->size();
5270  const int headerSize = 3 * sizeof(uint32_t);
5271  ckSCSL->SetPos(headerSize);
5272  for (int i = 0; i < slotCount; ++i) {
5273  uint32_t fileOffset = uint32_t(
5274  (*pScriptRefs)[i].script->pChunk->GetFilePos() -
5275  (*pScriptRefs)[i].script->pChunk->GetPos() -
5276  CHUNK_HEADER_SIZE(ckSCSL->GetFile()->GetFileOffsetSize())
5277  );
5278  ckSCSL->WriteUint32(&fileOffset);
5279  // jump over flags entry (containing the bypass flag)
5280  ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos);
5281  }
5282  }
5283  }
5284 
5292  Region* Instrument::GetRegion(unsigned int Key) {
5293  if (!pRegions || pRegions->empty() || Key > 127) return NULL;
5294  return RegionKeyTable[Key];
5295 
5296  /*for (int i = 0; i < Regions; i++) {
5297  if (Key <= pRegions[i]->KeyRange.high &&
5298  Key >= pRegions[i]->KeyRange.low) return pRegions[i];
5299  }
5300  return NULL;*/
5301  }
5302 
5314  if (!pRegions) return NULL;
5315  if (pos >= pRegions->size()) return NULL;
5316  return static_cast<gig::Region*>( (*pRegions)[pos] );
5317  }
5318 
5329  if (!pRegions) return NULL;
5330  RegionsIterator = pRegions->begin();
5331  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5332  }
5333 
5345  if (!pRegions) return NULL;
5346  RegionsIterator++;
5347  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5348  }
5349 
5350  Region* Instrument::AddRegion() {
5351  // create new Region object (and its RIFF chunks)
5352  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
5353  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
5354  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
5355  Region* pNewRegion = new Region(this, rgn);
5356  const size_t idxIt = RegionsIterator - pRegions->begin();
5357  pRegions->push_back(pNewRegion);
5358  RegionsIterator = pRegions->begin() + std::min(idxIt, pRegions->size()); // avoid iterator invalidation
5359  Regions = (uint32_t) pRegions->size();
5360  // update Region key table for fast lookup
5361  UpdateRegionKeyTable();
5362  // done
5363  return pNewRegion;
5364  }
5365 
5366  void Instrument::DeleteRegion(Region* pRegion) {
5367  if (!pRegions) return;
5368  DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
5369  // update Region key table for fast lookup
5370  UpdateRegionKeyTable();
5371  }
5372 
5402  if (dst && GetParent() != dst->GetParent())
5403  throw Exception(
5404  "gig::Instrument::MoveTo() can only be used for moving within "
5405  "the same gig file."
5406  );
5407 
5408  File* pFile = (File*) GetParent();
5409 
5410  // move this instrument within the instrument list
5411  {
5412  File::InstrumentList& list = *pFile->pInstruments;
5413 
5414  File::InstrumentList::iterator itFrom =
5415  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(this));
5416  if (itFrom == list.end())
5417  throw Exception(
5418  "gig::Instrument::MoveTo(): unexpected missing membership "
5419  "of this instrument."
5420  );
5421  list.erase(itFrom);
5422 
5423  File::InstrumentList::iterator itTo =
5424  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(dst));
5425 
5426  list.insert(itTo, this);
5427  }
5428 
5429  // move the instrument's actual list RIFF chunk appropriately
5430  RIFF::List* lstCkInstruments = pFile->pRIFF->GetSubList(LIST_TYPE_LINS);
5431  lstCkInstruments->MoveSubChunk(
5432  this->pCkInstrument,
5433  (RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5434  );
5435  }
5436 
5448  return pMidiRules[i];
5449  }
5450 
5457  delete pMidiRules[0];
5459  pMidiRules[0] = r;
5460  pMidiRules[1] = 0;
5461  return r;
5462  }
5463 
5470  delete pMidiRules[0];
5471  MidiRuleLegato* r = new MidiRuleLegato;
5472  pMidiRules[0] = r;
5473  pMidiRules[1] = 0;
5474  return r;
5475  }
5476 
5483  delete pMidiRules[0];
5485  pMidiRules[0] = r;
5486  pMidiRules[1] = 0;
5487  return r;
5488  }
5489 
5496  delete pMidiRules[i];
5497  pMidiRules[i] = 0;
5498  }
5499 
5500  void Instrument::LoadScripts() {
5501  if (pScriptRefs) return;
5502  pScriptRefs = new std::vector<_ScriptPooolRef>;
5503  if (scriptPoolFileOffsets.empty()) return;
5504  File* pFile = (File*) GetParent();
5505  for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5506  uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5507  for (size_t i = 0; pFile->GetScriptGroup(i); ++i) {
5508  ScriptGroup* group = pFile->GetScriptGroup(i);
5509  for (uint s = 0; group->GetScript(s); ++s) {
5510  Script* script = group->GetScript(s);
5511  if (script->pChunk) {
5512  uint32_t offset = uint32_t(
5513  script->pChunk->GetFilePos() -
5514  script->pChunk->GetPos() -
5515  CHUNK_HEADER_SIZE(script->pChunk->GetFile()->GetFileOffsetSize())
5516  );
5517  if (offset == soughtOffset)
5518  {
5519  _ScriptPooolRef ref;
5520  ref.script = script;
5521  ref.bypass = scriptPoolFileOffsets[k].bypass;
5522  pScriptRefs->push_back(ref);
5523  break;
5524  }
5525  }
5526  }
5527  }
5528  }
5529  // we don't need that anymore
5530  scriptPoolFileOffsets.clear();
5531  }
5532 
5546  LoadScripts();
5547  if (index >= pScriptRefs->size()) return NULL;
5548  return pScriptRefs->at(index).script;
5549  }
5550 
5586  void Instrument::AddScriptSlot(Script* pScript, bool bypass) {
5587  LoadScripts();
5588  _ScriptPooolRef ref = { pScript, bypass };
5589  pScriptRefs->push_back(ref);
5590  }
5591 
5606  void Instrument::SwapScriptSlots(size_t index1, size_t index2) {
5607  LoadScripts();
5608  if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5609  return;
5610  _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5611  (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5612  (*pScriptRefs)[index2] = tmp;
5613  }
5614 
5621  void Instrument::RemoveScriptSlot(size_t index) {
5622  LoadScripts();
5623  if (index >= pScriptRefs->size()) return;
5624  pScriptRefs->erase( pScriptRefs->begin() + index );
5625  }
5626 
5640  LoadScripts();
5641  for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5642  if ((*pScriptRefs)[i].script == pScript) {
5643  pScriptRefs->erase( pScriptRefs->begin() + i );
5644  }
5645  }
5646  }
5647 
5663  return pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size();
5664  }
5665 
5683  if (index >= ScriptSlotCount()) return false;
5684  return pScriptRefs ? pScriptRefs->at(index).bypass
5685  : scriptPoolFileOffsets.at(index).bypass;
5686 
5687  }
5688 
5702  void Instrument::SetScriptSlotBypassed(size_t index, bool bBypass) {
5703  if (index >= ScriptSlotCount()) return;
5704  if (pScriptRefs)
5705  pScriptRefs->at(index).bypass = bBypass;
5706  else
5707  scriptPoolFileOffsets.at(index).bypass = bBypass;
5708  }
5709 
5711  inline std::array<uint8_t,16> _UUIDFromCArray(const uint8_t* pData) {
5712  std::array<uint8_t,16> uuid;
5713  memcpy(&uuid[0], pData, 16);
5714  return uuid;
5715  }
5716 
5721  bool Instrument::ReferencesScriptWithUuid(const _UUID& uuid) {
5722  const size_t nSlots = ScriptSlotCount();
5723  for (size_t iSlot = 0; iSlot < nSlots; ++iSlot)
5724  if (_UUIDFromCArray(&GetScriptOfSlot(iSlot)->Uuid[0]) == uuid)
5725  return true;
5726  return false;
5727  }
5728 
5748  bool Instrument::IsScriptPatchVariableSet(size_t slot, String variable) {
5749  if (variable.empty()) return false;
5750  Script* script = GetScriptOfSlot(slot);
5751  if (!script) return false;
5752  const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5753  if (!scriptVars.count(uuid)) return false;
5754  const _VarsBySlot& slots = scriptVars.find(uuid)->second;
5755  if (slots.empty()) return false;
5756  if (slots.count(slot))
5757  return slots.find(slot)->second.count(variable);
5758  else
5759  return slots.begin()->second.count(variable);
5760  }
5761 
5782  std::map<String,String> Instrument::GetScriptPatchVariables(size_t slot) {
5783  Script* script = GetScriptOfSlot(slot);
5784  if (!script) return std::map<String,String>();
5785  const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5786  if (!scriptVars.count(uuid)) return std::map<String,String>();
5787  const _VarsBySlot& slots = scriptVars.find(uuid)->second;
5788  if (slots.empty()) return std::map<String,String>();
5789  const _PatchVars& vars =
5790  (slots.count(slot)) ?
5791  slots.find(slot)->second : slots.begin()->second;
5792  return vars;
5793  }
5794 
5814  String Instrument::GetScriptPatchVariable(size_t slot, String variable) {
5815  std::map<String,String> vars = GetScriptPatchVariables(slot);
5816  return (vars.count(variable)) ? vars.find(variable)->second : "";
5817  }
5818 
5841  void Instrument::SetScriptPatchVariable(size_t slot, String variable, String value) {
5842  if (variable.empty())
5843  throw Exception("Variable name must not be empty");
5844  Script* script = GetScriptOfSlot(slot);
5845  if (!script)
5846  throw Exception("No script slot with index " + ToString(slot));
5847  const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5848  scriptVars[uuid][slot][variable] = value;
5849  }
5850 
5882  void Instrument::UnsetScriptPatchVariable(ssize_t slot, String variable) {
5883  Script* script = GetScriptOfSlot(slot);
5884 
5885  // option 1: unset a particular variable of one particular script slot
5886  if (slot != -1 && !variable.empty()) {
5887  if (!script) return;
5888  const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5889  if (!scriptVars.count(uuid)) return;
5890  if (!scriptVars[uuid].count(slot)) return;
5891  if (scriptVars[uuid][slot].count(variable))
5892  scriptVars[uuid][slot].erase(
5893  scriptVars[uuid][slot].find(variable)
5894  );
5895  if (scriptVars[uuid][slot].empty())
5896  scriptVars[uuid].erase( scriptVars[uuid].find(slot) );
5897  if (scriptVars[uuid].empty())
5898  scriptVars.erase( scriptVars.find(uuid) );
5899  return;
5900  }
5901 
5902  // option 2: unset all variables of all script slots
5903  if (slot == -1 && variable.empty()) {
5904  scriptVars.clear();
5905  return;
5906  }
5907 
5908  // option 3: unset all variables of one particular script slot only
5909  if (slot != -1) {
5910  if (!script) return;
5911  const _UUID uuid = _UUIDFromCArray(&script->Uuid[0]);
5912  if (scriptVars.count(uuid))
5913  scriptVars.erase( scriptVars.find(uuid) );
5914  return;
5915  }
5916 
5917  // option 4: unset a particular variable of all script slots
5918  _VarsByScript::iterator itScript = scriptVars.begin();
5919  _VarsByScript::iterator endScript = scriptVars.end();
5920  while (itScript != endScript) {
5921  _VarsBySlot& slots = itScript->second;
5922  _VarsBySlot::iterator itSlot = slots.begin();
5923  _VarsBySlot::iterator endSlot = slots.end();
5924  while (itSlot != endSlot) {
5925  _PatchVars& vars = itSlot->second;
5926  if (vars.count(variable))
5927  vars.erase( vars.find(variable) );
5928  if (vars.empty())
5929  slots.erase(itSlot++); // postfix increment to avoid iterator invalidation
5930  else
5931  ++itSlot;
5932  }
5933  if (slots.empty())
5934  scriptVars.erase(itScript++); // postfix increment to avoid iterator invalidation
5935  else
5936  ++itScript;
5937  }
5938  }
5939 
5947  Instrument::_VarsByScript Instrument::stripScriptVars() {
5948  _VarsByScript vars;
5949  _VarsByScript::const_iterator itScript = scriptVars.begin();
5950  _VarsByScript::const_iterator endScript = scriptVars.end();
5951  for (; itScript != endScript; ++itScript) {
5952  const _UUID& uuid = itScript->first;
5953  if (!ReferencesScriptWithUuid(uuid))
5954  continue;
5955  const _VarsBySlot& slots = itScript->second;
5956  _VarsBySlot::const_iterator itSlot = slots.begin();
5957  _VarsBySlot::const_iterator endSlot = slots.end();
5958  for (; itSlot != endSlot; ++itSlot) {
5959  Script* script = GetScriptOfSlot(itSlot->first);
5960  if (!script) continue;
5961  if (_UUIDFromCArray(&script->Uuid[0]) != uuid) continue;
5962  if (itSlot->second.empty()) continue;
5963  vars[uuid][itSlot->first] = itSlot->second;
5964  }
5965  }
5966  return vars;
5967  }
5968 
5979  CopyAssign(orig, NULL);
5980  }
5981 
5990  void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
5991  // handle base class
5992  // (without copying DLS region stuff)
5993  DLS::Instrument::CopyAssignCore(orig);
5994 
5995  // handle own member variables
5996  Attenuation = orig->Attenuation;
5997  EffectSend = orig->EffectSend;
5998  FineTune = orig->FineTune;
5999  PitchbendRange = orig->PitchbendRange;
6000  PianoReleaseMode = orig->PianoReleaseMode;
6001  DimensionKeyRange = orig->DimensionKeyRange;
6002  scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
6003  // deep copy of pScriptRefs required (to avoid undefined behaviour)
6004  if (pScriptRefs) delete pScriptRefs;
6005  pScriptRefs = new std::vector<_ScriptPooolRef>;
6006  if (orig->pScriptRefs)
6007  *pScriptRefs = *orig->pScriptRefs;
6008  scriptVars = orig->scriptVars;
6009 
6010  // free old midi rules
6011  for (int i = 0 ; pMidiRules[i] ; i++) {
6012  delete pMidiRules[i];
6013  }
6014  //TODO: MIDI rule copying
6015  pMidiRules[0] = NULL;
6016 
6017  // delete all old regions
6018  while (Regions) DeleteRegion(GetRegionAt(0));
6019  // create new regions and copy them from original
6020  {
6021  RegionList::const_iterator it = orig->pRegions->begin();
6022  for (int i = 0; i < orig->Regions; ++i, ++it) {
6023  Region* dstRgn = AddRegion();
6024  //NOTE: Region does semi-deep copy !
6025  dstRgn->CopyAssign(
6026  static_cast<gig::Region*>(*it),
6027  mSamples
6028  );
6029  }
6030  }
6031 
6032  UpdateRegionKeyTable();
6033  }
6034 
6048  bool Instrument::UsesAnyGigFormatExtension() const {
6049  if (!pRegions) return false;
6050  if (!scriptVars.empty()) return true;
6051  RegionList::const_iterator iter = pRegions->begin();
6052  RegionList::const_iterator end = pRegions->end();
6053  for (; iter != end; ++iter) {
6054  gig::Region* rgn = static_cast<gig::Region*>(*iter);
6055  if (rgn->UsesAnyGigFormatExtension())
6056  return true;
6057  }
6058  return false;
6059  }
6060 
6061 
6062 // *************** Group ***************
6063 // *
6064 
6071  Group::Group(File* file, RIFF::Chunk* ck3gnm) {
6072  pFile = file;
6073  pNameChunk = ck3gnm;
6074  SamplesIterator = 0;
6075  ::LoadString(pNameChunk, Name);
6076  }
6077 
6083  }
6084 
6090  // handle own RIFF chunks
6091  if (pNameChunk) {
6092  pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
6093  pNameChunk = NULL;
6094  }
6095  }
6096 
6107  void Group::UpdateChunks(progress_t* pProgress) {
6108  // make sure <3gri> and <3gnl> list chunks exist
6109  RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
6110  if (!_3gri) {
6111  _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
6112  pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
6113  }
6114  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
6115  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
6116 
6117  if (!pNameChunk && pFile->pVersion && pFile->pVersion->major > 2) {
6118  // v3 has a fixed list of 128 strings, find a free one
6119  size_t i = 0;
6120  for (RIFF::Chunk* ck = _3gnl->GetSubChunkAt(i); ck; ck = _3gnl->GetSubChunkAt(++i)) {
6121  if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
6122  pNameChunk = ck;
6123  break;
6124  }
6125  }
6126  }
6127 
6128  // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
6129  ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
6130  }
6131 
6139  Sample* Group::GetSample(size_t index) {
6140  if (pFile->pSamples && index >= pFile->pSamples->size()) return NULL;
6141  size_t indexInFile = 0;
6142  size_t indexInGroup = 0;
6143  for (Sample* pSample = pFile->GetSample(indexInFile); pSample;
6144  pSample = pFile->GetSample(++indexInFile))
6145  {
6146  if (pSample->GetGroup() != this) continue;
6147  if (indexInGroup++ == index) return pSample;
6148  }
6149  return NULL;
6150  }
6151 
6166  size_t& i = this->SamplesIterator;
6167  i = 0;
6168  for (Sample* pSample = pFile->GetSample(i); pSample;
6169  pSample = pFile->GetSample(++i))
6170  {
6171  if (pSample->GetGroup() == this)
6172  return pSample;
6173  }
6174  return NULL;
6175  }
6176 
6190  size_t& i = this->SamplesIterator;
6191  for (Sample* pSample = pFile->GetSample(++i); pSample;
6192  pSample = pFile->GetSample(++i))
6193  {
6194  if (pSample->GetGroup() == this)
6195  return pSample;
6196  }
6197  return NULL;
6198  }
6199 
6203  void Group::AddSample(Sample* pSample) {
6204  pSample->pGroup = this;
6205  }
6206 
6214  // get "that" other group first
6215  size_t i = 0;
6216  Group* pOtherGroup = NULL;
6217  for (pOtherGroup = pFile->GetGroup(i); pOtherGroup;
6218  pOtherGroup = pFile->GetGroup(++i))
6219  {
6220  if (pOtherGroup != this) break;
6221  }
6222  if (!pOtherGroup) throw Exception(
6223  "Could not move samples to another group, since there is no "
6224  "other Group. This is a bug, report it!"
6225  );
6226  // now move all samples of this group to the other group
6227  Sample* pSample;
6228  while ((pSample = GetSample(0))) {
6229  pOtherGroup->AddSample(pSample);
6230  }
6231  }
6232 
6233 
6234 
6235 // *************** File ***************
6236 // *
6237 
6240  0, 2, 19980628 & 0xffff, 19980628 >> 16
6241  };
6242 
6245  0, 3, 20030331 & 0xffff, 20030331 >> 16
6246  };
6247 
6250  0, 4, 20071012 & 0xffff, 20071012 >> 16
6251  };
6252 
6253  static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
6254  { CHUNK_ID_IARL, 256 },
6255  { CHUNK_ID_IART, 128 },
6256  { CHUNK_ID_ICMS, 128 },
6257  { CHUNK_ID_ICMT, 1024 },
6258  { CHUNK_ID_ICOP, 128 },
6259  { CHUNK_ID_ICRD, 128 },
6260  { CHUNK_ID_IENG, 128 },
6261  { CHUNK_ID_IGNR, 128 },
6262  { CHUNK_ID_IKEY, 128 },
6263  { CHUNK_ID_IMED, 128 },
6264  { CHUNK_ID_INAM, 128 },
6265  { CHUNK_ID_IPRD, 128 },
6266  { CHUNK_ID_ISBJ, 128 },
6267  { CHUNK_ID_ISFT, 128 },
6268  { CHUNK_ID_ISRC, 128 },
6269  { CHUNK_ID_ISRF, 128 },
6270  { CHUNK_ID_ITCH, 128 },
6271  { 0, 0 }
6272  };
6273 
6274  File::File() : DLS::File() {
6275  bAutoLoad = true;
6276  *pVersion = VERSION_3;
6277  pGroups = NULL;
6278  pScriptGroups = NULL;
6279  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
6280  pInfo->ArchivalLocation = String(256, ' ');
6281 
6282  // add some mandatory chunks to get the file chunks in right
6283  // order (INFO chunk will be moved to first position later)
6284  pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
6285  pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
6286  pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
6287 
6288  GenerateDLSID();
6289  }
6290 
6291  File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
6292  bAutoLoad = true;
6293  pGroups = NULL;
6294  pScriptGroups = NULL;
6295  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
6296  }
6297 
6298  File::~File() {
6299  if (pGroups) {
6300  std::vector<Group*>::iterator iter = pGroups->begin();
6301  std::vector<Group*>::iterator end = pGroups->end();
6302  while (iter != end) {
6303  delete *iter;
6304  ++iter;
6305  }
6306  delete pGroups;
6307  }
6308  if (pScriptGroups) {
6309  std::vector<ScriptGroup*>::iterator iter = pScriptGroups->begin();
6310  std::vector<ScriptGroup*>::iterator end = pScriptGroups->end();
6311  while (iter != end) {
6312  delete *iter;
6313  ++iter;
6314  }
6315  delete pScriptGroups;
6316  }
6317  }
6318 
6328  if (!pSamples) LoadSamples(pProgress);
6329  if (!pSamples) return NULL;
6330  SamplesIterator = pSamples->begin();
6331  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
6332  }
6333 
6342  if (!pSamples) return NULL;
6343  SamplesIterator++;
6344  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
6345  }
6346 
6354  Sample* File::GetSample(size_t index, progress_t* pProgress) {
6355  if (!pSamples) LoadSamples(pProgress);
6356  if (!pSamples) return NULL;
6357  if (index >= pSamples->size()) return NULL;
6358  return static_cast<gig::Sample*>( (*pSamples)[index] );
6359  }
6360 
6370  if (!pSamples) LoadSamples();
6371  if (!pSamples) return 0;
6372  return pSamples->size();
6373  }
6374 
6383  if (!pSamples) LoadSamples();
6384  __ensureMandatoryChunksExist();
6385  RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
6386  // create new Sample object and its respective 'wave' list chunk
6387  RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
6388  Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
6389 
6390  // add mandatory chunks to get the chunks in right order
6391  wave->AddSubChunk(CHUNK_ID_FMT, 16);
6392  wave->AddSubList(LIST_TYPE_INFO);
6393 
6394  const size_t idxIt = SamplesIterator - pSamples->begin();
6395  pSamples->push_back(pSample);
6396  SamplesIterator = pSamples->begin() + std::min(idxIt, pSamples->size()); // avoid iterator invalidation
6397  return pSample;
6398  }
6399 
6409  void File::DeleteSample(Sample* pSample) {
6410  if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
6411  SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
6412  if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
6413  const size_t idxIt = SamplesIterator - pSamples->begin();
6414  pSamples->erase(iter);
6415  SamplesIterator = pSamples->begin() + std::min(idxIt, pSamples->size()); // avoid iterator invalidation
6416  pSample->DeleteChunks();
6417  delete pSample;
6418 
6419  // remove all references to the sample
6420  size_t iIns = 0;
6421  for (Instrument* instrument = GetInstrument(iIns); instrument;
6422  instrument = GetInstrument(++iIns))
6423  {
6424  size_t iRgn = 0;
6425  for (Region* region = instrument->GetRegionAt(iRgn); region;
6426  region = instrument->GetRegionAt(++iRgn))
6427  {
6428  if (region->GetSample() == pSample) region->SetSample(NULL);
6429 
6430  for (int i = 0 ; i < region->DimensionRegions ; i++) {
6431  gig::DimensionRegion *d = region->pDimensionRegions[i];
6432  if (d->pSample == pSample) d->pSample = NULL;
6433  }
6434  }
6435  }
6436  }
6437 
6438  void File::LoadSamples() {
6439  LoadSamples(NULL);
6440  }
6441 
6442  void File::LoadSamples(progress_t* pProgress) {
6443  // Groups must be loaded before samples, because samples will try
6444  // to resolve the group they belong to
6445  if (!pGroups) LoadGroups();
6446 
6447  if (!pSamples) pSamples = new SampleList;
6448 
6449  // just for progress calculation
6450  int iSampleIndex = 0;
6451  int iTotalSamples = WavePoolCount;
6452 
6453  // just for assembling path of optional extension files to be read
6454  const std::string folder = parentPath(pRIFF->GetFileName());
6455  const std::string baseName = pathWithoutExtension(pRIFF->GetFileName());
6456 
6457  // the main gig file and the extension files (.gx01, ... , .gx98) may
6458  // contain wave data (wave pool)
6459  std::vector<RIFF::File*> poolFiles;
6460  poolFiles.push_back(pRIFF);
6461 
6462  // get info about all extension files
6463  RIFF::Chunk* ckXfil = pRIFF->GetSubChunk(CHUNK_ID_XFIL);
6464  if (ckXfil) { // there are extension files (.gx01, ... , .gx98) ...
6465  const uint32_t n = ckXfil->ReadInt32();
6466  for (int i = 0; i < n; i++) {
6467  // read the filename and load the extension file
6468  std::string name;
6469  ckXfil->ReadString(name, 128);
6470  std::string path = concatPath(folder, name);
6471  RIFF::File* pExtFile = new RIFF::File(path);
6472  // check that the dlsids match
6473  RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
6474  if (ckDLSID) {
6475  ::DLS::dlsid_t idExpected;
6476  idExpected.ulData1 = ckXfil->ReadInt32();
6477  idExpected.usData2 = ckXfil->ReadInt16();
6478  idExpected.usData3 = ckXfil->ReadInt16();
6479  ckXfil->Read(idExpected.abData, 8, 1);
6480  ::DLS::dlsid_t idFound;
6481  ckDLSID->Read(&idFound.ulData1, 1, 4);
6482  ckDLSID->Read(&idFound.usData2, 1, 2);
6483  ckDLSID->Read(&idFound.usData3, 1, 2);
6484  ckDLSID->Read(idFound.abData, 8, 1);
6485  if (memcmp(&idExpected, &idFound, 16) != 0)
6486  throw gig::Exception("dlsid mismatch for extension file: %s", path.c_str());
6487  }
6488  poolFiles.push_back(pExtFile);
6489  ExtensionFiles.push_back(pExtFile);
6490  }
6491  }
6492 
6493  // check if a .gx99 (GigaPulse) file exists
6494  RIFF::Chunk* ckDoxf = pRIFF->GetSubChunk(CHUNK_ID_DOXF);
6495  if (ckDoxf) { // there is a .gx99 (GigaPulse) file ...
6496  std::string path = baseName + ".gx99";
6497  RIFF::File* pExtFile = new RIFF::File(path);
6498 
6499  // skip unused int and filename
6500  ckDoxf->SetPos(132, RIFF::stream_curpos);
6501 
6502  // check that the dlsids match
6503  RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
6504  if (ckDLSID) {
6505  ::DLS::dlsid_t idExpected;
6506  idExpected.ulData1 = ckDoxf->ReadInt32();
6507  idExpected.usData2 = ckDoxf->ReadInt16();
6508  idExpected.usData3 = ckDoxf->ReadInt16();
6509  ckDoxf->Read(idExpected.abData, 8, 1);
6510  ::DLS::dlsid_t idFound;
6511  ckDLSID->Read(&idFound.ulData1, 1, 4);
6512  ckDLSID->Read(&idFound.usData2, 1, 2);
6513  ckDLSID->Read(&idFound.usData3, 1, 2);
6514  ckDLSID->Read(idFound.abData, 8, 1);
6515  if (memcmp(&idExpected, &idFound, 16) != 0)
6516  throw gig::Exception("dlsid mismatch for GigaPulse file: %s", path.c_str());
6517  }
6518  poolFiles.push_back(pExtFile);
6519  ExtensionFiles.push_back(pExtFile);
6520  }
6521 
6522  // load all samples (both from this/main .gig file as well as from
6523  // extension files if required)
6524  for (int i = 0; i < poolFiles.size(); i++) {
6525  RIFF::File* file = poolFiles[i];
6526  RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
6527  if (wvpl) {
6528  file_offset_t wvplFileOffset = wvpl->GetFilePos() -
6529  wvpl->GetPos(); // should be zero, but just to be sure
6530  size_t iWaveCk = 0;
6531  for (RIFF::List* wave = wvpl->GetSubListAt(iWaveCk); wave;
6532  wave = wvpl->GetSubListAt(++iWaveCk))
6533  {
6534  if (wave->GetListType() == LIST_TYPE_WAVE) {
6535  // notify current progress
6536  if (pProgress) {
6537  const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
6538  __notify_progress(pProgress, subprogress);
6539  }
6540 
6541  file_offset_t waveFileOffset = wave->GetFilePos();
6542  pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, i, iSampleIndex));
6543 
6544  iSampleIndex++;
6545  }
6546  }
6547  }
6548  }
6549 
6550  if (pProgress)
6551  __notify_progress(pProgress, 1.0); // notify done
6552  }
6553 
6562  if (!pInstruments) LoadInstruments();
6563  if (!pInstruments) return NULL;
6564  InstrumentsIterator = pInstruments->begin();
6565  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
6566  }
6567 
6576  if (!pInstruments) return NULL;
6577  InstrumentsIterator++;
6578  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
6579  }
6580 
6590  if (!pInstruments) LoadInstruments();
6591  if (!pInstruments) return 0;
6592  return pInstruments->size();
6593  }
6594 
6602  Instrument* File::GetInstrument(size_t index, progress_t* pProgress) {
6603  if (!pInstruments) {
6604  // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
6605 
6606  if (pProgress) {
6607  // sample loading subtask
6608  progress_t subprogress;
6609  __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
6610  __notify_progress(&subprogress, 0.0f);
6611  if (GetAutoLoad())
6612  GetSample(0, &subprogress); // now force all samples to be loaded
6613  __notify_progress(&subprogress, 1.0f);
6614 
6615  // instrument loading subtask
6616  if (pProgress->callback) {
6617  subprogress.__range_min = subprogress.__range_max;
6618  subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
6619  }
6620  __notify_progress(&subprogress, 0.0f);
6621  LoadInstruments(&subprogress);
6622  __notify_progress(&subprogress, 1.0f);
6623  } else {
6624  // sample loading subtask
6625  if (GetAutoLoad())
6626  GetSample(0); // now force all samples to be loaded
6627 
6628  // instrument loading subtask
6629  LoadInstruments();
6630  }
6631  }
6632  if (!pInstruments) return NULL;
6633  if (index >= pInstruments->size()) return NULL;
6634  return static_cast<gig::Instrument*>( (*pInstruments)[index] );
6635  }
6636 
6645  if (!pInstruments) LoadInstruments();
6646  __ensureMandatoryChunksExist();
6647  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
6648  RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
6649 
6650  // add mandatory chunks to get the chunks in right order
6651  lstInstr->AddSubList(LIST_TYPE_INFO);
6652  lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
6653 
6654  Instrument* pInstrument = new Instrument(this, lstInstr);
6655  pInstrument->GenerateDLSID();
6656 
6657  lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
6658 
6659  // this string is needed for the gig to be loadable in GSt:
6660  pInstrument->pInfo->Software = "Endless Wave";
6661 
6662  const size_t idxIt = InstrumentsIterator - pInstruments->begin();
6663  pInstruments->push_back(pInstrument);
6664  InstrumentsIterator = pInstruments->begin() + std::min(idxIt, pInstruments->size()); // avoid iterator invalidation
6665  return pInstrument;
6666  }
6667 
6684  Instrument* instr = AddInstrument();
6685  instr->CopyAssign(orig);
6686  return instr;
6687  }
6688 
6700  void File::AddContentOf(File* pFile) {
6701  static int iCallCount = -1;
6702  iCallCount++;
6703  std::map<Group*,Group*> mGroups;
6704  std::map<Sample*,Sample*> mSamples;
6705 
6706  // clone sample groups
6707  for (int i = 0; pFile->GetGroup(i); ++i) {
6708  Group* g = AddGroup();
6709  g->Name =
6710  "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
6711  mGroups[pFile->GetGroup(i)] = g;
6712  }
6713 
6714  // clone samples (not waveform data here yet)
6715  for (int i = 0; pFile->GetSample(i); ++i) {
6716  Sample* s = AddSample();
6717  s->CopyAssignMeta(pFile->GetSample(i));
6718  mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
6719  mSamples[pFile->GetSample(i)] = s;
6720  }
6721 
6722  // clone script groups and their scripts
6723  for (size_t iGroup = 0; pFile->GetScriptGroup(iGroup); ++iGroup) {
6724  ScriptGroup* sg = pFile->GetScriptGroup(iGroup);
6725  ScriptGroup* dg = AddScriptGroup();
6726  dg->Name = "COPY" + ToString(iCallCount) + "_" + sg->Name;
6727  for (int iScript = 0; sg->GetScript(iScript); ++iScript) {
6728  Script* ss = sg->GetScript(iScript);
6729  Script* ds = dg->AddScript();
6730  ds->CopyAssign(ss);
6731  }
6732  }
6733 
6734  //BUG: For some reason this method only works with this additional
6735  // Save() call in between here.
6736  //
6737  // Important: The correct one of the 2 Save() methods has to be called
6738  // here, depending on whether the file is completely new or has been
6739  // saved to disk already, otherwise it will result in data corruption.
6740  if (pRIFF->IsNew())
6741  Save(GetFileName());
6742  else
6743  Save();
6744 
6745  // clone instruments
6746  // (passing the crosslink table here for the cloned samples)
6747  for (int i = 0; pFile->GetInstrument(i); ++i) {
6748  Instrument* instr = AddInstrument();
6749  instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
6750  }
6751 
6752  // Mandatory: file needs to be saved to disk at this point, so this
6753  // file has the correct size and data layout for writing the samples'
6754  // waveform data to disk.
6755  Save();
6756 
6757  // clone samples' waveform data
6758  // (using direct read & write disk streaming)
6759  for (int i = 0; pFile->GetSample(i); ++i) {
6760  mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
6761  }
6762  }
6763 
6772  void File::DeleteInstrument(Instrument* pInstrument) {
6773  if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
6774  InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
6775  if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
6776  const size_t idxIt = InstrumentsIterator - pInstruments->begin();
6777  pInstruments->erase(iter);
6778  InstrumentsIterator = pInstruments->begin() + std::min(idxIt, pInstruments->size()); // avoid iterator invalidation
6779  pInstrument->DeleteChunks();
6780  delete pInstrument;
6781  }
6782 
6783  void File::LoadInstruments() {
6784  LoadInstruments(NULL);
6785  }
6786 
6787  void File::LoadInstruments(progress_t* pProgress) {
6788  if (!pInstruments) pInstruments = new InstrumentList;
6789  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
6790  if (lstInstruments) {
6791  int iInstrumentIndex = 0;
6792  size_t i = 0;
6793  for (RIFF::List* lstInstr = lstInstruments->GetSubListAt(i);
6794  lstInstr; lstInstr = lstInstruments->GetSubListAt(++i))
6795  {
6796  if (lstInstr->GetListType() == LIST_TYPE_INS) {
6797  if (pProgress) {
6798  // notify current progress
6799  const float localProgress = (float) iInstrumentIndex / (float) Instruments;
6800  __notify_progress(pProgress, localProgress);
6801 
6802  // divide local progress into subprogress for loading current Instrument
6803  progress_t subprogress;
6804  __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
6805 
6806  pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
6807  } else {
6808  pInstruments->push_back(new Instrument(this, lstInstr));
6809  }
6810 
6811  iInstrumentIndex++;
6812  }
6813  }
6814  if (pProgress)
6815  __notify_progress(pProgress, 1.0); // notify done
6816  }
6817  }
6818 
6822  void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
6823  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6824  if (!_3crc) return;
6825 
6826  // get the index of the sample
6827  int iWaveIndex = GetWaveTableIndexOf(pSample);
6828  if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
6829 
6830  // write the CRC-32 checksum to disk
6831  _3crc->SetPos(iWaveIndex * 8);
6832  uint32_t one = 1;
6833  _3crc->WriteUint32(&one); // always 1
6834  _3crc->WriteUint32(&crc);
6835  }
6836 
6837  uint32_t File::GetSampleChecksum(Sample* pSample) {
6838  // get the index of the sample
6839  int iWaveIndex = GetWaveTableIndexOf(pSample);
6840  if (iWaveIndex < 0) throw gig::Exception("Could not retrieve reference crc of sample, could not resolve sample's wave table index");
6841 
6842  return GetSampleChecksumByIndex(iWaveIndex);
6843  }
6844 
6845  uint32_t File::GetSampleChecksumByIndex(int index) {
6846  if (index < 0) throw gig::Exception("Could not retrieve reference crc of sample, invalid wave pool index of sample");
6847 
6848  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6849  if (!_3crc) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6850  uint8_t* pData = (uint8_t*) _3crc->LoadChunkData();
6851  if (!pData) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6852 
6853  // read the CRC-32 checksum directly from disk
6854  size_t pos = index * 8;
6855  if (pos + 8 > _3crc->GetNewSize())
6856  throw gig::Exception("Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
6857 
6858  uint32_t one = load32(&pData[pos]); // always 1
6859  if (one != 1)
6860  throw gig::Exception("Could not retrieve reference crc of sample, because reference checksum table is damaged");
6861 
6862  return load32(&pData[pos+4]);
6863  }
6864 
6865  int File::GetWaveTableIndexOf(gig::Sample* pSample) {
6866  if (!pSamples) GetSample(0); // make sure sample chunks were scanned
6867  File::SampleList::iterator iter = pSamples->begin();
6868  File::SampleList::iterator end = pSamples->end();
6869  for (int index = 0; iter != end; ++iter, ++index)
6870  if (*iter == pSample)
6871  return index;
6872  return -1;
6873  }
6874 
6882  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6883  if (!_3crc) return false;
6884  if (_3crc->GetNewSize() <= 0) return false;
6885  if (_3crc->GetNewSize() % 8) return false;
6886  if (!pSamples) GetSample(0); // make sure sample chunks were scanned
6887  if (_3crc->GetNewSize() != pSamples->size() * 8) return false;
6888 
6889  const file_offset_t n = _3crc->GetNewSize() / 8;
6890 
6891  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6892  if (!pData) return false;
6893 
6894  for (file_offset_t i = 0; i < n; ++i) {
6895  uint32_t one = pData[i*2];
6896  if (one != 1) return false;
6897  }
6898 
6899  return true;
6900  }
6901 
6919  // make sure sample chunks were scanned
6920  if (!pSamples) GetSample(0);
6921 
6922  bool bRequiresSave = false;
6923 
6924  // make sure "3CRC" chunk exists with required size
6925  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6926  if (!_3crc) {
6927  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6928  // the order of einf and 3crc is not the same in v2 and v3
6929  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6930  if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
6931  bRequiresSave = true;
6932  } else if (_3crc->GetNewSize() != pSamples->size() * 8) {
6933  _3crc->Resize(pSamples->size() * 8);
6934  bRequiresSave = true;
6935  }
6936 
6937  if (bRequiresSave) { // refill CRC table for all samples in RAM ...
6938  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6939  {
6940  File::SampleList::iterator iter = pSamples->begin();
6941  File::SampleList::iterator end = pSamples->end();
6942  for (; iter != end; ++iter) {
6943  gig::Sample* pSample = (gig::Sample*) *iter;
6944  int index = GetWaveTableIndexOf(pSample);
6945  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6946  pData[index*2] = 1; // always 1
6947  pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6948  }
6949  }
6950  } else { // no file structure changes necessary, so directly write to disk and we are done ...
6951  // make sure file is in write mode
6952  pRIFF->SetMode(RIFF::stream_mode_read_write);
6953  {
6954  File::SampleList::iterator iter = pSamples->begin();
6955  File::SampleList::iterator end = pSamples->end();
6956  for (; iter != end; ++iter) {
6957  gig::Sample* pSample = (gig::Sample*) *iter;
6958  int index = GetWaveTableIndexOf(pSample);
6959  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6960  pSample->crc = pSample->CalculateWaveDataChecksum();
6961  SetSampleChecksum(pSample, pSample->crc);
6962  }
6963  }
6964  }
6965 
6966  return bRequiresSave;
6967  }
6968 
6976  if (!pGroups) LoadGroups();
6977  // there must always be at least one group
6978  GroupsIterator = pGroups->begin();
6979  return *GroupsIterator;
6980  }
6981 
6989  if (!pGroups) return NULL;
6990  ++GroupsIterator;
6991  return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6992  }
6993 
7000  Group* File::GetGroup(size_t index) {
7001  if (!pGroups) LoadGroups();
7002  if (index >= pGroups->size()) return NULL;
7003  return (*pGroups)[index];
7004  }
7005 
7016  Group* File::GetGroup(String name) {
7017  if (!pGroups) LoadGroups();
7018  size_t i = 0;
7019  for (Group* pGroup = GetGroup(i); pGroup; pGroup = GetGroup(++i))
7020  if (pGroup->Name == name) return pGroup;
7021  return NULL;
7022  }
7023 
7024  Group* File::AddGroup() {
7025  if (!pGroups) LoadGroups();
7026  // there must always be at least one group
7027  __ensureMandatoryChunksExist();
7028  Group* pGroup = new Group(this, NULL);
7029  pGroups->push_back(pGroup);
7030  return pGroup;
7031  }
7032 
7043  if (!pGroups) LoadGroups();
7044  std::vector<Group*>::iterator iter =
7045  find(pGroups->begin(), pGroups->end(), pGroup);
7046  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
7047  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
7048  // delete all members of this group
7049  Sample* pSample;
7050  while ((pSample = pGroup->GetSample(0))) {
7051  DeleteSample(pSample);
7052  }
7053  // now delete this group object
7054  pGroups->erase(iter);
7055  pGroup->DeleteChunks();
7056  delete pGroup;
7057  }
7058 
7070  if (!pGroups) LoadGroups();
7071  std::vector<Group*>::iterator iter =
7072  find(pGroups->begin(), pGroups->end(), pGroup);
7073  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
7074  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
7075  // move all members of this group to another group
7076  pGroup->MoveAll();
7077  pGroups->erase(iter);
7078  pGroup->DeleteChunks();
7079  delete pGroup;
7080  }
7081 
7082  void File::LoadGroups() {
7083  if (!pGroups) pGroups = new std::vector<Group*>;
7084  // try to read defined groups from file
7085  RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
7086  if (lst3gri) {
7087  RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
7088  if (lst3gnl) {
7089  size_t i = 0;
7090  for (RIFF::Chunk* ck = lst3gnl->GetSubChunkAt(i); ck;
7091  ck = lst3gnl->GetSubChunkAt(++i))
7092  {
7093  if (ck->GetChunkID() == CHUNK_ID_3GNM) {
7094  if (pVersion && pVersion->major > 2 &&
7095  strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
7096 
7097  pGroups->push_back(new Group(this, ck));
7098  }
7099  }
7100  }
7101  }
7102  // if there were no group(s), create at least the mandatory default group
7103  if (!pGroups->size()) {
7104  Group* pGroup = new Group(this, NULL);
7105  pGroup->Name = "Default Group";
7106  pGroups->push_back(pGroup);
7107  }
7108  }
7109 
7118  if (!pScriptGroups) LoadScriptGroups();
7119  if (index >= pScriptGroups->size()) return NULL;
7120  return (*pScriptGroups)[index];
7121  }
7122 
7131  ScriptGroup* File::GetScriptGroup(const String& name) {
7132  if (!pScriptGroups) LoadScriptGroups();
7133  for (size_t i = 0; i < pScriptGroups->size(); ++i) {
7134  ScriptGroup* pGroup = (*pScriptGroups)[i];
7135  if (pGroup->Name == name) return pGroup;
7136  }
7137  return NULL;
7138  }
7139 
7149  if (!pScriptGroups) LoadScriptGroups();
7150  ScriptGroup* pScriptGroup = new ScriptGroup(this, NULL);
7151  pScriptGroups->push_back(pScriptGroup);
7152  return pScriptGroup;
7153  }
7154 
7167  void File::DeleteScriptGroup(ScriptGroup* pScriptGroup) {
7168  if (!pScriptGroups) LoadScriptGroups();
7169  std::vector<ScriptGroup*>::iterator iter =
7170  find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
7171  if (iter == pScriptGroups->end())
7172  throw gig::Exception("Could not delete script group, could not find given script group");
7173  pScriptGroups->erase(iter);
7174  for (int i = 0; pScriptGroup->GetScript(i); ++i)
7175  pScriptGroup->DeleteScript(pScriptGroup->GetScript(i));
7176  if (pScriptGroup->pList)
7177  pScriptGroup->pList->GetParent()->DeleteSubChunk(pScriptGroup->pList);
7178  pScriptGroup->DeleteChunks();
7179  delete pScriptGroup;
7180  }
7181 
7182  void File::LoadScriptGroups() {
7183  if (pScriptGroups) return;
7184  pScriptGroups = new std::vector<ScriptGroup*>;
7185  RIFF::List* lstLS = pRIFF->GetSubList(LIST_TYPE_3LS);
7186  if (lstLS) {
7187  size_t i = 0;
7188  for (RIFF::List* lst = lstLS->GetSubListAt(i); lst;
7189  lst = lstLS->GetSubListAt(++i))
7190  {
7191  if (lst->GetListType() == LIST_TYPE_RTIS) {
7192  pScriptGroups->push_back(new ScriptGroup(this, lst));
7193  }
7194  }
7195  }
7196  }
7197 
7209  void File::UpdateChunks(progress_t* pProgress) {
7210  bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
7211 
7212  // update own gig format extension chunks
7213  // (not part of the GigaStudio 4 format)
7214  RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);
7215  if (!lst3LS) {
7216  lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
7217  }
7218  // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
7219  // location of <3LS > is irrelevant, however it should be located
7220  // before the actual wave data
7221  RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
7222  pRIFF->MoveSubChunk(lst3LS, ckPTBL);
7223 
7224  // This must be performed before writing the chunks for instruments,
7225  // because the instruments' script slots will write the file offsets
7226  // of the respective instrument script chunk as reference.
7227  if (pScriptGroups) {
7228  // Update instrument script (group) chunks.
7229  for (std::vector<ScriptGroup*>::iterator it = pScriptGroups->begin();
7230  it != pScriptGroups->end(); ++it)
7231  {
7232  (*it)->UpdateChunks(pProgress);
7233  }
7234  }
7235 
7236  // in case no libgig custom format data was added, then remove the
7237  // custom "3LS " chunk again
7238  if (!lst3LS->CountSubChunks()) {
7239  pRIFF->DeleteSubChunk(lst3LS);
7240  lst3LS = NULL;
7241  }
7242 
7243  // first update base class's chunks
7244  DLS::File::UpdateChunks(pProgress);
7245 
7246  if (newFile) {
7247  // INFO was added by Resource::UpdateChunks - make sure it
7248  // is placed first in file
7249  RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
7250  RIFF::Chunk* first = pRIFF->GetSubChunkAt(0);
7251  if (first != info) {
7252  pRIFF->MoveSubChunk(info, first);
7253  }
7254  }
7255 
7256  // update group's chunks
7257  if (pGroups) {
7258  // make sure '3gri' and '3gnl' list chunks exist
7259  // (before updating the Group chunks)
7260  RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
7261  if (!_3gri) {
7262  _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
7263  pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
7264  }
7265  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
7266  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
7267 
7268  // v3: make sure the file has 128 3gnm chunks
7269  // (before updating the Group chunks)
7270  if (pVersion && pVersion->major > 2) {
7271  size_t i = 0;
7272  for (RIFF::Chunk* _3gnm = _3gnl->GetSubChunkAt(i); i < 128;
7273  _3gnm = _3gnl->GetSubChunkAt(++i))
7274  {
7275  // create 128 empty placeholder strings which will either
7276  // be filled by Group::UpdateChunks below or left empty.
7277  ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
7278  }
7279  }
7280 
7281  std::vector<Group*>::iterator iter = pGroups->begin();
7282  std::vector<Group*>::iterator end = pGroups->end();
7283  for (; iter != end; ++iter) {
7284  (*iter)->UpdateChunks(pProgress);
7285  }
7286  }
7287 
7288  // update einf chunk
7289 
7290  // The einf chunk contains statistics about the gig file, such
7291  // as the number of regions and samples used by each
7292  // instrument. It is divided in equally sized parts, where the
7293  // first part contains information about the whole gig file,
7294  // and the rest of the parts map to each instrument in the
7295  // file.
7296  //
7297  // At the end of each part there is a bit map of each sample
7298  // in the file, where a set bit means that the sample is used
7299  // by the file/instrument.
7300  //
7301  // Note that there are several fields with unknown use. These
7302  // are set to zero.
7303 
7304  int sublen = int(pSamples->size() / 8 + 49);
7305  int einfSize = (Instruments + 1) * sublen;
7306 
7307  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
7308  if (einf) {
7309  if (einf->GetSize() != einfSize) {
7310  einf->Resize(einfSize);
7311  memset(einf->LoadChunkData(), 0, einfSize);
7312  }
7313  } else if (newFile) {
7314  einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
7315  }
7316  if (einf) {
7317  uint8_t* pData = (uint8_t*) einf->LoadChunkData();
7318 
7319  std::map<gig::Sample*,int> sampleMap;
7320  size_t sampleIdx = 0;
7321  for (Sample* pSample = GetSample(0); pSample;
7322  pSample = GetSample(++sampleIdx))
7323  {
7324  sampleMap[pSample] = sampleIdx;
7325  }
7326 
7327  int totnbusedsamples = 0;
7328  int totnbusedchannels = 0;
7329  int totnbregions = 0;
7330  int totnbdimregions = 0;
7331  int totnbloops = 0;
7332  int instrumentIdx = 0;
7333 
7334  memset(&pData[48], 0, sublen - 48);
7335 
7336  size_t iIns = 0;
7337  for (Instrument* instrument = GetInstrument(iIns); instrument;
7338  instrument = GetInstrument(++iIns))
7339  {
7340  int nbusedsamples = 0;
7341  int nbusedchannels = 0;
7342  int nbdimregions = 0;
7343  int nbloops = 0;
7344 
7345  memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
7346 
7347  size_t iRgn = 0;
7348  for (Region* region = instrument->GetRegionAt(iRgn); region;
7349  region = instrument->GetRegionAt(++iRgn))
7350  {
7351  for (int i = 0 ; i < region->DimensionRegions ; i++) {
7352  gig::DimensionRegion *d = region->pDimensionRegions[i];
7353  if (d->pSample) {
7354  int sampleIdx = sampleMap[d->pSample];
7355  int byte = 48 + sampleIdx / 8;
7356  int bit = 1 << (sampleIdx & 7);
7357  if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
7358  pData[(instrumentIdx + 1) * sublen + byte] |= bit;
7359  nbusedsamples++;
7360  nbusedchannels += d->pSample->Channels;
7361 
7362  if ((pData[byte] & bit) == 0) {
7363  pData[byte] |= bit;
7364  totnbusedsamples++;
7365  totnbusedchannels += d->pSample->Channels;
7366  }
7367  }
7368  }
7369  if (d->SampleLoops) nbloops++;
7370  }
7371  nbdimregions += region->DimensionRegions;
7372  }
7373  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
7374  // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
7375  store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
7376  store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
7377  store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
7378  store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
7379  store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
7380  store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
7381  // next 8 bytes unknown
7382  store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
7383  store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
7384  // next 4 bytes unknown
7385 
7386  totnbregions += instrument->Regions;
7387  totnbdimregions += nbdimregions;
7388  totnbloops += nbloops;
7389  instrumentIdx++;
7390  }
7391  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
7392  // store32(&pData[0], sublen);
7393  store32(&pData[4], totnbusedchannels);
7394  store32(&pData[8], totnbusedsamples);
7395  store32(&pData[12], Instruments);
7396  store32(&pData[16], totnbregions);
7397  store32(&pData[20], totnbdimregions);
7398  store32(&pData[24], totnbloops);
7399  // next 8 bytes unknown
7400  // next 4 bytes unknown, not always 0
7401  store32(&pData[40], (uint32_t) pSamples->size());
7402  // next 4 bytes unknown
7403  }
7404 
7405  // update 3crc chunk
7406 
7407  // The 3crc chunk contains CRC-32 checksums for the
7408  // samples. When saving a gig file to disk, we first update the 3CRC
7409  // chunk here (in RAM) with the old crc values which we read from the
7410  // 3CRC chunk when we opened the file (available with gig::Sample::crc
7411  // member variable). This step is required, because samples might have
7412  // been deleted by the user since the file was opened, which in turn
7413  // changes the order of the (i.e. old) checksums within the 3crc chunk.
7414  // If a sample was conciously modified by the user (that is if
7415  // Sample::Write() was called later on) then Sample::Write() will just
7416  // update the respective individual checksum(s) directly on disk and
7417  // leaves all other sample checksums untouched.
7418 
7419  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
7420  if (_3crc) {
7421  _3crc->Resize(pSamples->size() * 8);
7422  } else /*if (newFile)*/ {
7423  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
7424  // the order of einf and 3crc is not the same in v2 and v3
7425  if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
7426  }
7427  { // must be performed in RAM here ...
7428  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
7429  if (pData) {
7430  File::SampleList::iterator iter = pSamples->begin();
7431  File::SampleList::iterator end = pSamples->end();
7432  for (int index = 0; iter != end; ++iter, ++index) {
7433  gig::Sample* pSample = (gig::Sample*) *iter;
7434  pData[index*2] = 1; // always 1
7435  pData[index*2+1] = pSample->crc;
7436  }
7437  }
7438  }
7439  }
7440 
7443 
7444  size_t i = 0;
7445  for (Instrument* instrument = GetInstrument(i); instrument;
7446  instrument = GetInstrument(++i))
7447  {
7448  instrument->UpdateScriptFileOffsets();
7449  }
7450  }
7451 
7467  void File::SetAutoLoad(bool b) {
7468  bAutoLoad = b;
7469  }
7470 
7476  return bAutoLoad;
7477  }
7478 
7492  bool File::UsesAnyGigFormatExtension() const {
7493  if (!pInstruments) return false;
7494  InstrumentList::iterator iter = pInstruments->begin();
7495  InstrumentList::iterator end = pInstruments->end();
7496  for (; iter != end; ++iter) {
7497  Instrument* pInstrument = static_cast<gig::Instrument*>(*iter);
7498  if (pInstrument->UsesAnyGigFormatExtension())
7499  return true;
7500  }
7501  return false;
7502  }
7503 
7504 
7505 // *************** Exception ***************
7506 // *
7507 
7508  Exception::Exception() : DLS::Exception() {
7509  }
7510 
7511  Exception::Exception(String format, ...) : DLS::Exception() {
7512  va_list arg;
7513  va_start(arg, format);
7514  Message = assemble(format, arg);
7515  va_end(arg);
7516  }
7517 
7518  Exception::Exception(String format, va_list arg) : DLS::Exception() {
7519  Message = assemble(format, arg);
7520  }
7521 
7522  void Exception::PrintMessage() {
7523  std::cout << "gig::Exception: " << Message << std::endl;
7524  }
7525 
7526 
7527 // *************** functions ***************
7528 // *
7529 
7535  String libraryName() {
7536  return PACKAGE;
7537  }
7538 
7543  String libraryVersion() {
7544  return VERSION;
7545  }
7546 
7547 } // namespace gig
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:828
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
Definition: gig.cpp:4655
void AddContentOf(File *pFile)
Add content of another existing file.
Definition: gig.cpp:6700
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
Definition: gig.cpp:6213
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:2439
~Instrument()
Destructor.
Definition: gig.cpp:5088
file_offset_t position
Current position within the sample.
Definition: gig.h:423
Encapsulates articulation informations of a dimension region.
Definition: gig.h:535
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
Definition: gig.h:1284
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:433
Non-linear curve type.
Definition: gig.h:156
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
Definition: gig.cpp:4113
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Definition: gig.h:424
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:862
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Definition: DLS.h:531
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
Definition: gig.cpp:5292
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
Definition: gig.cpp:6203
lfo_wave_t
Defines the wave form type used by an LFO (gig format extension).
Definition: gig.h:173
String GetScriptAsText()
Returns the current script (i.e.
Definition: gig.cpp:4642
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
Definition: gig.h:864
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
Definition: gig.cpp:5482
Sample * AddSample()
Add a new sample.
Definition: gig.cpp:6382
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:892
Standard lowpass filter type (GigaStudio).
Definition: gig.h:396
Parses DLS Level 1 and 2 compliant files and provides abstract access to the data.
Definition: DLS.h:564
no SMPTE offset
Definition: gig.h:145
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
Definition: gig.cpp:3608
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:710
stream_whence_t
File stream position dependent to these relations.
Definition: RIFF.h:124
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Definition: gig.h:820
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
Definition: gig.h:867
lfo1_ctrl_t
Defines how LFO1 is controlled by.
Definition: gig.h:219
Group of Gigasampler samples.
Definition: gig.h:1365
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
Definition: DLS.h:237
String Name
Stores the name of this Group.
Definition: gig.h:1367
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index)...
Definition: gig.cpp:4293
Special dimension for triggering samples on releasing a key.
Definition: gig.h:343
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Definition: gig.h:1282
Defines behavior options for envelope generators (gig format extension).
Definition: gig.h:451
void SwapScriptSlots(size_t index1, size_t index2)
Flip two script slots with each other (gig format extension).
Definition: gig.cpp:5606
Script * AddScript()
Add new instrument script.
Definition: gig.cpp:4875
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:1228
Unknown curve type.
Definition: gig.h:156
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Definition: gig.h:828
Instrument * AddInstrument()
Add a new instrument definition.
Definition: gig.cpp:6644
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
Definition: RIFF.h:186
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:825
List * GetSubListAt(size_t pos)
Returns sublist chunk with list type ListType at supplied pos position among all subchunks of type Li...
Definition: RIFF.cpp:1264
Only internally controlled.
Definition: gig.h:207
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: DLS.cpp:1777
virtual void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Definition: gig.cpp:4835
Will be thrown whenever a DLS specific error occurs while trying to access a DLS File.
Definition: DLS.h:623
MIDI rule for triggering notes by control change events.
Definition: gig.h:1026
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:749
size_t CountInstruments()
Returns the total amount of instruments of this gig file.
Definition: gig.cpp:6589
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:1325
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
Definition: RIFF.h:164
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
Definition: gig.h:866
Instrument * GetInstrument(size_t index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
Definition: gig.cpp:6602
file_offset_t Size
Size of the actual data in the buffer in bytes.
Definition: gig.h:116
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
Definition: gig.cpp:5586
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Instrument object.
Definition: DLS.cpp:1575
static size_t Instances
Number of instances of class Sample.
Definition: gig.h:859
dimension values are already the sought bit number
Definition: gig.h:354
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Definition: gig.cpp:1407
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
Definition: gig.cpp:6561
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
Definition: RIFF.cpp:806
file_offset_t GetSize() const
Returns sample size.
Definition: DLS.cpp:986
Sample * GetSample(size_t index)
Returns Sample object at index of this sample group.
Definition: gig.cpp:6139
For MIDI tools like legato and repetition mode.
Definition: gig.h:343
Group * GetGroup(size_t index)
Returns the group with the given index.
Definition: gig.cpp:7000
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
Definition: gig.cpp:546
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:872
Defines a controller that has a certain contrained influence on a particular synthesis parameter (use...
Definition: gig.h:260
sust_rel_trg_t
Defines behaviour of release triggered sample(s) on sustain pedal up event.
Definition: gig.h:482
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:460
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3226
Defines Region information of a Gigasampler/GigaStudio instrument.
Definition: gig.h:927
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise)...
Definition: DLS.h:465
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
Definition: gig.h:830
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it&#39;s original sample rate...
Definition: gig.h:819
ScriptGroup * GetScriptGroup(size_t index)
Get instrument script group (by index).
Definition: gig.cpp:7117
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
Definition: RIFF.cpp:1287
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Definition: RIFF.cpp:1556
Defines Sample Loop Points.
Definition: DLS.h:235
Language_t Language
Programming language and dialect the script is written in.
Definition: gig.h:1194
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
Definition: gig.cpp:5495
unsigned int Dimensions
Number of defined dimensions, do not alter!
Definition: gig.h:929
Only controlled by external modulation wheel.
Definition: gig.h:195
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:425
bool VerifySampleChecksumTable()
Checks whether the file&#39;s "3CRC" chunk was damaged.
Definition: gig.cpp:6881
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
Definition: gig.cpp:5456
void RemoveScriptSlot(size_t index)
Remove script slot.
Definition: gig.cpp:5621
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:4184
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used...
Definition: gig.h:1192
Different samples triggered each time a note is played, any key advances the counter.
Definition: gig.h:343
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction...
Definition: gig.h:833
Region * GetFirstRegion()
Returns the first Region of the instrument.
Definition: gig.cpp:5328
String libraryVersion()
Returns version of this C++ library.
Definition: gig.cpp:7543
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set...
Definition: gig.h:537
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File...
Definition: gig.h:1512
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:755
static const DLS::version_t VERSION_4
Reflects Gigasampler file format version 4.0 (2007-10-12).
Definition: gig.h:1426
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
Definition: gig.cpp:4681
void GenerateDLSID()
Generates a new DLSID for the resource.
Definition: DLS.cpp:587
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:3199
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Definition: gig.h:1424
Sample * pSample
Points to the Sample which is assigned to the dimension region.
Definition: gig.h:538
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used...
Definition: DLS.h:466
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:706
List * GetParent() const
Returns pointer to the chunk&#39;s parent list chunk.
Definition: RIFF.h:185
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:826
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
Definition: gig.cpp:6988
Loop forward (normal)
Definition: gig.h:133
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3208
Every subject of an DLS file and the file itself can have an unique, computer generated ID...
Definition: DLS.h:123
virtual void CopyAssign(const Sample *orig)
Make a deep copy of the Sample object given by orig and assign it to this object. ...
Definition: DLS.cpp:917
void SetAutoLoad(bool b)
Enable / disable automatic loading.
Definition: gig.cpp:7467
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
Definition: gig.cpp:5447
Sine (sinus) wave form (this is the default wave form).
Definition: gig.h:173
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
Definition: gig.h:821
uint16_t low
Low value of range.
Definition: DLS.h:211
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
Definition: gig.h:456
lfo3_ctrl_t
Defines how LFO3 is controlled by.
Definition: gig.h:195
Special curve type.
Definition: gig.h:156
RIFF List Chunk.
Definition: RIFF.h:261
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:362
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
Definition: gig.cpp:5639
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:441
static buffer_t InternalDecompressionBuffer
Buffer used for decompression of samples, and only if no external decompression buffer was supplied...
Definition: gig.h:860
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Definition: gig.cpp:1390
Pointer address and size of a buffer.
Definition: gig.h:114
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:454
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
Definition: gig.h:358
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument...
Definition: gig.h:1195
virtual void DeleteChunks()
Remove all RIFF chunks associated with this ScriptGroup object.
Definition: gig.cpp:4823
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
Definition: gig.cpp:6975
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:341
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
Definition: gig.h:1191
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
Definition: gig.cpp:6683
Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
Definition: gig.h:343
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors...
Definition: gig.h:831
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
Definition: gig.cpp:829
uint32_t SampleLoops
Reflects the number of sample loops.
Definition: DLS.h:432
More poles than normal lowpass (GigaStudio).
Definition: gig.h:396
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
Definition: gig.cpp:3810
void Resize(file_offset_t NewSize)
Resize sample.
Definition: DLS.cpp:1019
The difference between none and none2 is unknown.
Definition: gig.h:238
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
Definition: gig.cpp:1373
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: gig.cpp:7441
size_t ScriptSlotCount() const
Instrument&#39;s amount of script slots.
Definition: gig.cpp:5662
void Resize(file_offset_t NewSize)
Resize sample.
Definition: gig.cpp:866
Script * GetScript(size_t index)
Get instrument script.
Definition: gig.cpp:4858
uint16_t high
High value of range.
Definition: DLS.h:212
Sample * GetSample(size_t index, progress_t *pProgress=NULL)
Returns Sample object of index.
Definition: gig.cpp:6354
uint64_t file_offset_t
Type used by libgig for handling file positioning during file I/O tasks.
Definition: RIFF.h:107
float __range_min
Only for internal usage, do not modify!
Definition: RIFF.h:167
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:933
void * pStart
Points to the beginning of the buffer.
Definition: gig.h:115
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:788
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Definition: gig.h:861
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
Definition: RIFF.cpp:1246
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Definition: gig.cpp:926
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
Definition: gig.cpp:5469
bool IsScriptPatchVariableSet(size_t slot, String variable)
Checks whether a certain script &#39;patch&#39; variable value is set.
Definition: gig.cpp:5748
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Definition: gig.cpp:3720
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
Definition: gig.cpp:6575
void DeleteGroupOnly(Group *pGroup)
Delete a group.
Definition: gig.cpp:7069
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
Definition: DLS.h:464
std::array< uint8_t, 16 > _UUIDFromCArray(const uint8_t *pData)
type cast (by copy) uint8_t[16] -> std::array<uint8_t,16>
Definition: gig.cpp:5711
Ordinary RIFF Chunk.
Definition: RIFF.h:179
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:824
void DeleteSample(Sample *pSample)
Delete a sample.
Definition: gig.cpp:6409
int16_t FineTune
in cents
Definition: gig.h:1281
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:2555
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
Definition: gig.h:1425
uint32_t LoopLength
Length of the looping area (in sample points).
Definition: DLS.h:239
uint8_t Uuid[16]
Persistent Universally Unique Identifier of this script, which remains identical after any changes to...
Definition: gig.h:1196
ScriptGroup * AddScriptGroup()
Add new instrument script group.
Definition: gig.cpp:7148
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
Definition: gig.h:932
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field...
Definition: gig.h:817
split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:354
Alternating loop (forward/backward, also known as Ping Pong)
Definition: gig.h:133
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
Definition: RIFF.cpp:376
~Sample()
Destructor.
Definition: gig.cpp:1477
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file&#39;s checksum table with those n...
Definition: gig.cpp:6918
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Definition: gig.cpp:6822
Sample * GetNextSample()
Returns the next Sample of the Group.
Definition: gig.cpp:6189
Used for indicating the progress of a certain task.
Definition: RIFF.h:163
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:965
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:517
Region * GetRegionAt(size_t pos)
Returns Region at supplied pos position within the region list of this instrument.
Definition: gig.cpp:5313
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
Definition: gig.h:823
uint32_t GetListType() const
Returns unsigned integer representation of the list&#39;s ID.
Definition: RIFF.h:265
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
Definition: gig.h:822
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:593
size_t CountSamples()
Returns the total amount of samples of this gig file.
Definition: gig.cpp:6369
Chunk * GetSubChunkAt(size_t pos)
Returns subchunk at supplied pos position within this chunk list.
Definition: RIFF.cpp:1229
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:1423
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:869
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Definition: gig.cpp:3954
Ordinary MIDI control change controller, see field &#39;controller_number&#39;.
Definition: gig.h:270
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: DLS.cpp:1519
vcf_type_t
Audio filter types.
Definition: gig.h:396
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:566
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
Definition: gig.cpp:6772
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
Definition: DLS.h:238
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
Definition: gig.cpp:6107
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:453
String Name
Name of this script group. For example to be displayed in an instrument editor.
Definition: gig.h:1232
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame...
Definition: gig.h:863
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
Definition: gig.cpp:1329
Loop backward (reverse)
Definition: gig.h:133
bool GetAutoLoad()
Returns whether automatic loading is enabled.
Definition: gig.cpp:7475
For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers).
Definition: gig.h:343
void * LoadChunkData()
Load chunk body into RAM.
Definition: RIFF.cpp:960
Different samples triggered each time a note is played, random order.
Definition: gig.h:343
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:117
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:4359
~Region()
Destructor.
Definition: gig.cpp:4160
Abstract base class for all MIDI rules.
Definition: gig.h:1005
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
Definition: gig.cpp:4759
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3169
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:7209
dimension_t
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
Definition: gig.h:343
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
Definition: gig.h:865
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:827
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:452
Different samples triggered each time a note is played, dimension regions selected in sequence...
Definition: gig.h:343
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:930
uint8_t zones
Number of zones the dimension has.
Definition: gig.h:360
String GetScriptPatchVariable(size_t slot, String variable)
Get overridden initial value for &#39;patch&#39; variable.
Definition: gig.cpp:5814
Effect 5 Depth (MIDI Controller 95)
Definition: gig.h:183
No release triggered sample(s) are played on sustain pedal up (default).
Definition: gig.h:482
void GenerateUuid()
Generate a new Universally Unique Identifier (UUID) for this script.
Definition: gig.cpp:4719
buffer_t GetCache()
Returns current cached sample points.
Definition: gig.cpp:814
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3217
vcf_cutoff_ctrl_t
Defines how the filter cutoff frequency is controlled by.
Definition: gig.h:238
void Resize(file_offset_t NewSize)
Resize chunk.
Definition: RIFF.cpp:1034
No controller defined.
Definition: gig.h:270
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
Definition: gig.h:814
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value...
Definition: gig.cpp:2000
Sample * GetSample(size_t index)
Returns Sample object of index.
Definition: DLS.cpp:1763
RIFF File.
Definition: RIFF.h:313
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Definition: RIFF.cpp:1537
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
Definition: gig.cpp:6071
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:1140
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
Definition: DLS.cpp:693
dimension value between 0-127
Definition: gig.h:354
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
Definition: gig.cpp:2014
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
Definition: DLS.h:376
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
Definition: gig.cpp:6341
String ArchivalLocation
<IARL-ck>. Indicates where the subject of the file is stored.
Definition: DLS.h:366
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:187
int32_t Attenuation
in dB
Definition: gig.h:1279
Encapsulates sample waves used for playback.
Definition: DLS.h:457
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: gig.cpp:5106
type_t type
Controller type.
Definition: gig.h:272
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
Definition: gig.h:273
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
Definition: gig.h:663
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
Definition: RIFF.cpp:1480
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
Definition: DLS.h:461
File * GetFile() const
Returns pointer to the chunk&#39;s File object.
Definition: RIFF.h:184
A MIDI rule not yet implemented by libgig.
Definition: gig.h:1152
std::map< String, String > GetScriptPatchVariables(size_t slot)
Get all overridden script &#39;patch&#39; variables.
Definition: gig.cpp:5782
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Definition: RIFF.cpp:1396
Real-time instrument script (gig format extension).
Definition: gig.h:1179
bool SetMode(stream_mode_t NewMode)
Change file access mode.
Definition: RIFF.cpp:2055
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3157
Gigasampler/GigaStudio specific classes and definitions.
Definition: gig.h:101
float __range_max
Only for internal usage, do not modify!
Definition: RIFF.h:168
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
Definition: gig.h:628
Script * GetScriptOfSlot(size_t index)
Get instrument script (gig format extension).
Definition: gig.cpp:5545
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:1842
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks. ...
Definition: gig.cpp:3399
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:829
bool IsScriptSlotBypassed(size_t index)
Whether script execution shall be skipped.
Definition: gig.cpp:5682
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0, 4 or 6)
Definition: gig.h:832
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:897
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Group object.
Definition: gig.cpp:6089
void SetScriptSlotBypassed(size_t index, bool bBypass)
Defines whether execution shall be skipped.
Definition: gig.cpp:5702
Group of instrument scripts (gig format extension).
Definition: gig.h:1230
file_offset_t GetFilePos() const
Current, actual offset in file of current chunk data body read/write position.
Definition: RIFF.cpp:324
Only internally controlled.
Definition: gig.h:219
Provides convenient access to Gigasampler/GigaStudio .gig files.
Definition: gig.h:1422
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
Definition: gig.cpp:4746
lfo2_ctrl_t
Defines how LFO2 is controlled by.
Definition: gig.h:207
Dimension for keyswitching.
Definition: gig.h:343
MIDI rule for instruments with legato samples.
Definition: gig.h:1067
virtual ~Group()
Destructor.
Definition: gig.cpp:6082
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3190
range_t KeyRange
Definition: DLS.h:495
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: DLS.cpp:1098
Sample * GetFirstSample()
Returns the first Sample of this Group.
Definition: gig.cpp:6165
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:4153
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample&#39;s raw audio wave data.
Definition: gig.cpp:1452
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:2461
Provides all neccessary information for the synthesis of a DLS Instrument.
Definition: DLS.h:524
Provides access to a Gigasampler/GigaStudio instrument.
Definition: gig.h:1266
void SetScriptPatchVariable(size_t slot, String variable, String value)
Override initial value for &#39;patch&#39; variable.
Definition: gig.cpp:5841
void UnsetScriptPatchVariable(ssize_t slot=-1, String variable="")
Drop overridden initial value(s) for &#39;patch&#39; variable(s).
Definition: gig.cpp:5882
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Definition: gig.cpp:7042
Encoding_t Encoding
Format the script&#39;s source code text is encoded with.
Definition: gig.h:1193
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
Definition: gig.h:868
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:5978
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sample object.
Definition: DLS.cpp:874
String libraryName()
Returns the name of this C++ library.
Definition: gig.cpp:7535
Quadtuple version number ("major.minor.release.build").
Definition: DLS.h:115
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:455
void MoveTo(Instrument *dst)
Move this instrument at the position before.
Definition: gig.cpp:5401
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Definition: gig.h:818
Dimension not in use.
Definition: gig.h:343
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:4770
curve_type_t
Defines the shape of a function graph.
Definition: gig.h:156
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
Definition: gig.h:359
file_offset_t GetPos() const
Current read/write position within the chunk data body (starting with 0).
Definition: RIFF.cpp:311
No MIDI controller assigned for filter resonance.
Definition: gig.h:250
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:3514
DLS specific classes and definitions.
Definition: DLS.h:108
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
Definition: DLS.h:406
uint32_t Manufacturer
Specifies the MIDI Manufacturer&#39;s Association (MMA) Manufacturer code for the sampler intended to rec...
Definition: gig.h:816
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Region object.
Definition: DLS.cpp:1184
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:671
MIDI rule to automatically cycle through specified sequences of different articulations.
Definition: gig.h:1099
Reflects the current playback state for a sample.
Definition: gig.h:422
void DeleteChunks()
Remove all RIFF chunks associated with this Script object.
Definition: gig.cpp:4669
General dimension definition.
Definition: gig.h:357
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:510
Linear curve type.
Definition: gig.h:156
No MIDI controller assigned for filter cutoff frequency.
Definition: gig.h:238
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:361
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
Definition: DLS.cpp:1263
void DeleteScript(Script *pScript)
Delete an instrument script.
Definition: gig.cpp:4892
No controller bypass.
Definition: gig.h:183
If used sample has more than one channel (thus is not mono).
Definition: gig.h:343
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: gig.cpp:574
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3181
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:632
Defines Region information of an Instrument.
Definition: DLS.h:493
Effect 4 Depth (MIDI Controller 94)
Definition: gig.h:183
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Definition: gig.cpp:3129
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
Definition: gig.cpp:4312
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:3145
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Definition: RIFF.cpp:1458
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Definition: gig.cpp:7167
Region * GetNextRegion()
Returns the next Region of the instrument.
Definition: gig.cpp:5344
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:2021
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: DLS.cpp:2385