libgig  4.2.0
gig.cpp
1 /***************************************************************************
2  * *
3  * libgig - C++ cross-platform Gigasampler format file access library *
4  * *
5  * Copyright (C) 2003-2019 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 and for truncating 24 bit samples to 16 bit
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::list<Group*>::iterator iter = pFile->pGroups->begin();
613  std::list<Group*>::iterator end = pFile->pGroups->end();
614  for (int i = 0; iter != end; i++, iter++) {
615  if (*iter == pGroup) {
616  iSampleGroup = i;
617  break; // found
618  }
619  }
620  }
621  // update '3gix' chunk
622  pData = (uint8_t*) pCk3gix->LoadChunkData();
623  store16(&pData[0], iSampleGroup);
624 
625  // if the library user toggled the "Compressed" attribute from true to
626  // false, then the EWAV chunk associated with compressed samples needs
627  // to be deleted
628  RIFF::Chunk* ewav = pWaveList->GetSubChunk(CHUNK_ID_EWAV);
629  if (ewav && !Compressed) {
630  pWaveList->DeleteSubChunk(ewav);
631  }
632  }
633 
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() == pCkData->GetSize()) {
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  // chunk for own format extensions, these will *NOT* work with Gigasampler/GigaStudio !
1744  RIFF::Chunk* lsde = _3ewl->GetSubChunk(CHUNK_ID_LSDE);
1745  if (lsde) { // format extension for EG behavior options
1746  lsde->SetPos(0);
1747 
1748  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1749  for (int i = 0; i < 2; ++i) { // NOTE: we reserved a 3rd byte for a potential future EG3 option
1750  unsigned char byte = lsde->ReadUint8();
1751  pEGOpts[i]->AttackCancel = byte & 1;
1752  pEGOpts[i]->AttackHoldCancel = byte & (1 << 1);
1753  pEGOpts[i]->Decay1Cancel = byte & (1 << 2);
1754  pEGOpts[i]->Decay2Cancel = byte & (1 << 3);
1755  pEGOpts[i]->ReleaseCancel = byte & (1 << 4);
1756  }
1757  }
1758  // format extension for sustain pedal up effect on release trigger samples
1759  if (lsde && lsde->GetSize() > 3) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
1760  lsde->SetPos(3);
1761  uint8_t byte = lsde->ReadUint8();
1762  SustainReleaseTrigger = static_cast<sust_rel_trg_t>(byte & 0x03);
1763  NoNoteOffReleaseTrigger = byte >> 7;
1764  } else {
1765  SustainReleaseTrigger = sust_rel_trg_none;
1766  NoNoteOffReleaseTrigger = false;
1767  }
1768 
1769  pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1770  VelocityResponseDepth,
1771  VelocityResponseCurveScaling);
1772 
1773  pVelocityReleaseTable = GetReleaseVelocityTable(
1774  ReleaseVelocityResponseCurve,
1775  ReleaseVelocityResponseDepth
1776  );
1777 
1778  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1779  VCFVelocityDynamicRange,
1780  VCFVelocityScale,
1781  VCFCutoffController);
1782 
1783  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1784  VelocityTable = 0;
1785  }
1786 
1787  /*
1788  * Constructs a DimensionRegion by copying all parameters from
1789  * another DimensionRegion
1790  */
1791  DimensionRegion::DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src) : DLS::Sampler(_3ewl) {
1792  Instances++;
1793  //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1794  *this = src; // default memberwise shallow copy of all parameters
1795  pParentList = _3ewl; // restore the chunk pointer
1796 
1797  // deep copy of owned structures
1798  if (src.VelocityTable) {
1799  VelocityTable = new uint8_t[128];
1800  for (int k = 0 ; k < 128 ; k++)
1801  VelocityTable[k] = src.VelocityTable[k];
1802  }
1803  if (src.pSampleLoops) {
1804  pSampleLoops = new DLS::sample_loop_t[src.SampleLoops];
1805  for (int k = 0 ; k < src.SampleLoops ; k++)
1806  pSampleLoops[k] = src.pSampleLoops[k];
1807  }
1808  }
1809 
1820  CopyAssign(orig, NULL);
1821  }
1822 
1831  void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1832  // delete all allocated data first
1833  if (VelocityTable) delete [] VelocityTable;
1834  if (pSampleLoops) delete [] pSampleLoops;
1835 
1836  // backup parent list pointer
1837  RIFF::List* p = pParentList;
1838 
1839  gig::Sample* pOriginalSample = pSample;
1840  gig::Region* pOriginalRegion = pRegion;
1841 
1842  //NOTE: copy code copied from assignment constructor above, see comment there as well
1843 
1844  *this = *orig; // default memberwise shallow copy of all parameters
1845 
1846  // restore members that shall not be altered
1847  pParentList = p; // restore the chunk pointer
1848  pRegion = pOriginalRegion;
1849 
1850  // only take the raw sample reference reference if the
1851  // two DimensionRegion objects are part of the same file
1852  if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1853  pSample = pOriginalSample;
1854  }
1855 
1856  if (mSamples && mSamples->count(orig->pSample)) {
1857  pSample = mSamples->find(orig->pSample)->second;
1858  }
1859 
1860  // deep copy of owned structures
1861  if (orig->VelocityTable) {
1862  VelocityTable = new uint8_t[128];
1863  for (int k = 0 ; k < 128 ; k++)
1864  VelocityTable[k] = orig->VelocityTable[k];
1865  }
1866  if (orig->pSampleLoops) {
1868  for (int k = 0 ; k < orig->SampleLoops ; k++)
1869  pSampleLoops[k] = orig->pSampleLoops[k];
1870  }
1871  }
1872 
1873  void DimensionRegion::serialize(Serialization::Archive* archive) {
1874  // in case this class will become backward incompatible one day,
1875  // then set a version and minimum version for this class like:
1876  //archive->setVersion(*this, 2);
1877  //archive->setMinVersion(*this, 1);
1878 
1879  SRLZ(VelocityUpperLimit);
1880  SRLZ(EG1PreAttack);
1881  SRLZ(EG1Attack);
1882  SRLZ(EG1Decay1);
1883  SRLZ(EG1Decay2);
1884  SRLZ(EG1InfiniteSustain);
1885  SRLZ(EG1Sustain);
1886  SRLZ(EG1Release);
1887  SRLZ(EG1Hold);
1888  SRLZ(EG1Controller);
1889  SRLZ(EG1ControllerInvert);
1893  SRLZ(LFO1Frequency);
1894  SRLZ(LFO1InternalDepth);
1895  SRLZ(LFO1ControlDepth);
1896  SRLZ(LFO1Controller);
1897  SRLZ(LFO1FlipPhase);
1898  SRLZ(LFO1Sync);
1899  SRLZ(EG2PreAttack);
1900  SRLZ(EG2Attack);
1901  SRLZ(EG2Decay1);
1902  SRLZ(EG2Decay2);
1903  SRLZ(EG2InfiniteSustain);
1904  SRLZ(EG2Sustain);
1905  SRLZ(EG2Release);
1906  SRLZ(EG2Controller);
1907  SRLZ(EG2ControllerInvert);
1911  SRLZ(LFO2Frequency);
1912  SRLZ(LFO2InternalDepth);
1913  SRLZ(LFO2ControlDepth);
1914  SRLZ(LFO2Controller);
1915  SRLZ(LFO2FlipPhase);
1916  SRLZ(LFO2Sync);
1917  SRLZ(EG3Attack);
1918  SRLZ(EG3Depth);
1919  SRLZ(LFO3Frequency);
1920  SRLZ(LFO3InternalDepth);
1921  SRLZ(LFO3ControlDepth);
1922  SRLZ(LFO3Controller);
1923  SRLZ(LFO3Sync);
1924  SRLZ(VCFEnabled);
1925  SRLZ(VCFType);
1926  SRLZ(VCFCutoffController);
1928  SRLZ(VCFCutoff);
1929  SRLZ(VCFVelocityCurve);
1930  SRLZ(VCFVelocityScale);
1932  SRLZ(VCFResonance);
1933  SRLZ(VCFResonanceDynamic);
1934  SRLZ(VCFResonanceController);
1935  SRLZ(VCFKeyboardTracking);
1937  SRLZ(VelocityResponseCurve);
1938  SRLZ(VelocityResponseDepth);
1942  SRLZ(ReleaseTriggerDecay);
1943  SRLZ(Crossfade);
1944  SRLZ(PitchTrack);
1945  SRLZ(DimensionBypass);
1946  SRLZ(Pan);
1947  SRLZ(SelfMask);
1948  SRLZ(AttenuationController);
1951  SRLZ(ChannelOffset);
1952  SRLZ(SustainDefeat);
1953  SRLZ(MSDecode);
1954  //SRLZ(SampleStartOffset);
1955  SRLZ(SampleAttenuation);
1956  SRLZ(EG1Options);
1957  SRLZ(EG2Options);
1958  SRLZ(SustainReleaseTrigger);
1960 
1961  // derived attributes from DLS::Sampler
1962  SRLZ(FineTune);
1963  SRLZ(Gain);
1964  }
1965 
1970  void DimensionRegion::SetGain(int32_t gain) {
1971  DLS::Sampler::SetGain(gain);
1972  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1973  }
1974 
1985  // first update base class's chunk
1986  DLS::Sampler::UpdateChunks(pProgress);
1987 
1988  RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1989  uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1990  pData[12] = Crossfade.in_start;
1991  pData[13] = Crossfade.in_end;
1992  pData[14] = Crossfade.out_start;
1993  pData[15] = Crossfade.out_end;
1994 
1995  // make sure '3ewa' chunk exists
1996  RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1997  if (!_3ewa) {
1998  File* pFile = (File*) GetParent()->GetParent()->GetParent();
1999  bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
2000  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, versiongt2 ? 148 : 140);
2001  }
2002  pData = (uint8_t*) _3ewa->LoadChunkData();
2003 
2004  // update '3ewa' chunk with DimensionRegion's current settings
2005 
2006  const uint32_t chunksize = (uint32_t) _3ewa->GetNewSize();
2007  store32(&pData[0], chunksize); // unknown, always chunk size?
2008 
2009  const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
2010  store32(&pData[4], lfo3freq);
2011 
2012  const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
2013  store32(&pData[8], eg3attack);
2014 
2015  // next 2 bytes unknown
2016 
2017  store16(&pData[14], LFO1InternalDepth);
2018 
2019  // next 2 bytes unknown
2020 
2021  store16(&pData[18], LFO3InternalDepth);
2022 
2023  // next 2 bytes unknown
2024 
2025  store16(&pData[22], LFO1ControlDepth);
2026 
2027  // next 2 bytes unknown
2028 
2029  store16(&pData[26], LFO3ControlDepth);
2030 
2031  const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
2032  store32(&pData[28], eg1attack);
2033 
2034  const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
2035  store32(&pData[32], eg1decay1);
2036 
2037  // next 2 bytes unknown
2038 
2039  store16(&pData[38], EG1Sustain);
2040 
2041  const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
2042  store32(&pData[40], eg1release);
2043 
2044  const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
2045  pData[44] = eg1ctl;
2046 
2047  const uint8_t eg1ctrloptions =
2048  (EG1ControllerInvert ? 0x01 : 0x00) |
2049  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2050  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2051  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2052  pData[45] = eg1ctrloptions;
2053 
2054  const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2055  pData[46] = eg2ctl;
2056 
2057  const uint8_t eg2ctrloptions =
2058  (EG2ControllerInvert ? 0x01 : 0x00) |
2059  GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2060  GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2061  GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
2062  pData[47] = eg2ctrloptions;
2063 
2064  const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
2065  store32(&pData[48], lfo1freq);
2066 
2067  const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
2068  store32(&pData[52], eg2attack);
2069 
2070  const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
2071  store32(&pData[56], eg2decay1);
2072 
2073  // next 2 bytes unknown
2074 
2075  store16(&pData[62], EG2Sustain);
2076 
2077  const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2078  store32(&pData[64], eg2release);
2079 
2080  // next 2 bytes unknown
2081 
2082  store16(&pData[70], LFO2ControlDepth);
2083 
2084  const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2085  store32(&pData[72], lfo2freq);
2086 
2087  // next 2 bytes unknown
2088 
2089  store16(&pData[78], LFO2InternalDepth);
2090 
2091  const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2092  store32(&pData[80], eg1decay2);
2093 
2094  // next 2 bytes unknown
2095 
2096  store16(&pData[86], EG1PreAttack);
2097 
2098  const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2099  store32(&pData[88], eg2decay2);
2100 
2101  // next 2 bytes unknown
2102 
2103  store16(&pData[94], EG2PreAttack);
2104 
2105  {
2106  if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
2107  uint8_t velocityresponse = VelocityResponseDepth;
2108  switch (VelocityResponseCurve) {
2109  case curve_type_nonlinear:
2110  break;
2111  case curve_type_linear:
2112  velocityresponse += 5;
2113  break;
2114  case curve_type_special:
2115  velocityresponse += 10;
2116  break;
2117  case curve_type_unknown:
2118  default:
2119  throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2120  }
2121  pData[96] = velocityresponse;
2122  }
2123 
2124  {
2125  if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
2126  uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2127  switch (ReleaseVelocityResponseCurve) {
2128  case curve_type_nonlinear:
2129  break;
2130  case curve_type_linear:
2131  releasevelocityresponse += 5;
2132  break;
2133  case curve_type_special:
2134  releasevelocityresponse += 10;
2135  break;
2136  case curve_type_unknown:
2137  default:
2138  throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2139  }
2140  pData[97] = releasevelocityresponse;
2141  }
2142 
2143  pData[98] = VelocityResponseCurveScaling;
2144 
2145  pData[99] = AttenuationControllerThreshold;
2146 
2147  // next 4 bytes unknown
2148 
2149  store16(&pData[104], SampleStartOffset);
2150 
2151  // next 2 bytes unknown
2152 
2153  {
2154  uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2155  switch (DimensionBypass) {
2156  case dim_bypass_ctrl_94:
2157  pitchTrackDimensionBypass |= 0x10;
2158  break;
2159  case dim_bypass_ctrl_95:
2160  pitchTrackDimensionBypass |= 0x20;
2161  break;
2162  case dim_bypass_ctrl_none:
2163  //FIXME: should we set anything here?
2164  break;
2165  default:
2166  throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2167  }
2168  pData[108] = pitchTrackDimensionBypass;
2169  }
2170 
2171  const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
2172  pData[109] = pan;
2173 
2174  const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
2175  pData[110] = selfmask;
2176 
2177  // next byte unknown
2178 
2179  {
2180  uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
2181  if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
2182  if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
2183  if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
2184  pData[112] = lfo3ctrl;
2185  }
2186 
2187  const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2188  pData[113] = attenctl;
2189 
2190  {
2191  uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
2192  if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
2193  if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
2194  if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
2195  pData[114] = lfo2ctrl;
2196  }
2197 
2198  {
2199  uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
2200  if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
2201  if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
2203  lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2204  pData[115] = lfo1ctrl;
2205  }
2206 
2207  const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2208  : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
2209  store16(&pData[116], eg3depth);
2210 
2211  // next 2 bytes unknown
2212 
2213  const uint8_t channeloffset = ChannelOffset * 4;
2214  pData[120] = channeloffset;
2215 
2216  {
2217  uint8_t regoptions = 0;
2218  if (MSDecode) regoptions |= 0x01; // bit 0
2219  if (SustainDefeat) regoptions |= 0x02; // bit 1
2220  pData[121] = regoptions;
2221  }
2222 
2223  // next 2 bytes unknown
2224 
2225  pData[124] = VelocityUpperLimit;
2226 
2227  // next 3 bytes unknown
2228 
2229  pData[128] = ReleaseTriggerDecay;
2230 
2231  // next 2 bytes unknown
2232 
2233  const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
2234  pData[131] = eg1hold;
2235 
2236  const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
2237  (VCFCutoff & 0x7f); /* lower 7 bits */
2238  pData[132] = vcfcutoff;
2239 
2240  pData[133] = VCFCutoffController;
2241 
2242  const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
2243  (VCFVelocityScale & 0x7f); /* lower 7 bits */
2244  pData[134] = vcfvelscale;
2245 
2246  // next byte unknown
2247 
2248  const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
2249  (VCFResonance & 0x7f); /* lower 7 bits */
2250  pData[136] = vcfresonance;
2251 
2252  const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2253  (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2254  pData[137] = vcfbreakpoint;
2255 
2256  const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2257  VCFVelocityCurve * 5;
2258  pData[138] = vcfvelocity;
2259 
2260  const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2261  pData[139] = vcftype;
2262 
2263  if (chunksize >= 148) {
2264  memcpy(&pData[140], DimensionUpperLimits, 8);
2265  }
2266 
2267  // chunk for own format extensions, these will *NOT* work with
2268  // Gigasampler/GigaStudio !
2269  RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2270  const int lsdeSize = 4; // NOTE: we reserved the 3rd byte for a potential future EG3 option
2271  if (!lsde) {
2272  // only add this "LSDE" chunk if either EG options or release
2273  // trigger options deviate from their default behaviour
2274  eg_opt_t defaultOpt;
2275  if (memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||
2276  memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)) ||
2278  {
2279  lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2280  // move LSDE chunk to the end of parent list
2281  pParentList->MoveSubChunk(lsde, (RIFF::Chunk*)NULL);
2282  }
2283  }
2284  if (lsde) {
2285  if (lsde->GetNewSize() < lsdeSize)
2286  lsde->Resize(lsdeSize);
2287  // format extension for EG behavior options
2288  unsigned char* pData = (unsigned char*) lsde->LoadChunkData();
2289  eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
2290  for (int i = 0; i < 2; ++i) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
2291  pData[i] =
2292  (pEGOpts[i]->AttackCancel ? 1 : 0) |
2293  (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2294  (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2295  (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2296  (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2297  }
2298  // format extension for release trigger options
2299  pData[3] = static_cast<uint8_t>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 0);
2300  }
2301  }
2302 
2303  double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2304  curve_type_t curveType = releaseVelocityResponseCurve;
2305  uint8_t depth = releaseVelocityResponseDepth;
2306  // this models a strange behaviour or bug in GSt: two of the
2307  // velocity response curves for release time are not used even
2308  // if specified, instead another curve is chosen.
2309  if ((curveType == curve_type_nonlinear && depth == 0) ||
2310  (curveType == curve_type_special && depth == 4)) {
2311  curveType = curve_type_nonlinear;
2312  depth = 3;
2313  }
2314  return GetVelocityTable(curveType, depth, 0);
2315  }
2316 
2317  double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2318  uint8_t vcfVelocityDynamicRange,
2319  uint8_t vcfVelocityScale,
2320  vcf_cutoff_ctrl_t vcfCutoffController)
2321  {
2322  curve_type_t curveType = vcfVelocityCurve;
2323  uint8_t depth = vcfVelocityDynamicRange;
2324  // even stranger GSt: two of the velocity response curves for
2325  // filter cutoff are not used, instead another special curve
2326  // is chosen. This curve is not used anywhere else.
2327  if ((curveType == curve_type_nonlinear && depth == 0) ||
2328  (curveType == curve_type_special && depth == 4)) {
2329  curveType = curve_type_special;
2330  depth = 5;
2331  }
2332  return GetVelocityTable(curveType, depth,
2333  (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2334  ? vcfVelocityScale : 0);
2335  }
2336 
2337  // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
2338  double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2339  {
2340  // sanity check input parameters
2341  // (fallback to some default parameters on ill input)
2342  switch (curveType) {
2343  case curve_type_nonlinear:
2344  case curve_type_linear:
2345  if (depth > 4) {
2346  printf("Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2347  depth = 0;
2348  scaling = 0;
2349  }
2350  break;
2351  case curve_type_special:
2352  if (depth > 5) {
2353  printf("Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2354  depth = 0;
2355  scaling = 0;
2356  }
2357  break;
2358  case curve_type_unknown:
2359  default:
2360  printf("Warning: Unknown velocity curve type (0x%x).\n", curveType);
2361  curveType = curve_type_linear;
2362  depth = 0;
2363  scaling = 0;
2364  break;
2365  }
2366 
2367  double* table;
2368  uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2369  if (pVelocityTables->count(tableKey)) { // if key exists
2370  table = (*pVelocityTables)[tableKey];
2371  }
2372  else {
2373  table = CreateVelocityTable(curveType, depth, scaling);
2374  (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
2375  }
2376  return table;
2377  }
2378 
2379  Region* DimensionRegion::GetParent() const {
2380  return pRegion;
2381  }
2382 
2383 // show error if some _lev_ctrl_* enum entry is not listed in the following function
2384 // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2385 // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2386 //#pragma GCC diagnostic push
2387 //#pragma GCC diagnostic error "-Wswitch"
2388 
2389  leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2390  leverage_ctrl_t decodedcontroller;
2391  switch (EncodedController) {
2392  // special controller
2393  case _lev_ctrl_none:
2394  decodedcontroller.type = leverage_ctrl_t::type_none;
2395  decodedcontroller.controller_number = 0;
2396  break;
2397  case _lev_ctrl_velocity:
2398  decodedcontroller.type = leverage_ctrl_t::type_velocity;
2399  decodedcontroller.controller_number = 0;
2400  break;
2401  case _lev_ctrl_channelaftertouch:
2402  decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
2403  decodedcontroller.controller_number = 0;
2404  break;
2405 
2406  // ordinary MIDI control change controller
2407  case _lev_ctrl_modwheel:
2408  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2409  decodedcontroller.controller_number = 1;
2410  break;
2411  case _lev_ctrl_breath:
2412  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2413  decodedcontroller.controller_number = 2;
2414  break;
2415  case _lev_ctrl_foot:
2416  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2417  decodedcontroller.controller_number = 4;
2418  break;
2419  case _lev_ctrl_effect1:
2420  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2421  decodedcontroller.controller_number = 12;
2422  break;
2423  case _lev_ctrl_effect2:
2424  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2425  decodedcontroller.controller_number = 13;
2426  break;
2427  case _lev_ctrl_genpurpose1:
2428  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2429  decodedcontroller.controller_number = 16;
2430  break;
2431  case _lev_ctrl_genpurpose2:
2432  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2433  decodedcontroller.controller_number = 17;
2434  break;
2435  case _lev_ctrl_genpurpose3:
2436  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2437  decodedcontroller.controller_number = 18;
2438  break;
2439  case _lev_ctrl_genpurpose4:
2440  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2441  decodedcontroller.controller_number = 19;
2442  break;
2443  case _lev_ctrl_portamentotime:
2444  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2445  decodedcontroller.controller_number = 5;
2446  break;
2447  case _lev_ctrl_sustainpedal:
2448  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2449  decodedcontroller.controller_number = 64;
2450  break;
2451  case _lev_ctrl_portamento:
2452  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2453  decodedcontroller.controller_number = 65;
2454  break;
2455  case _lev_ctrl_sostenutopedal:
2456  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2457  decodedcontroller.controller_number = 66;
2458  break;
2459  case _lev_ctrl_softpedal:
2460  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2461  decodedcontroller.controller_number = 67;
2462  break;
2463  case _lev_ctrl_genpurpose5:
2464  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2465  decodedcontroller.controller_number = 80;
2466  break;
2467  case _lev_ctrl_genpurpose6:
2468  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2469  decodedcontroller.controller_number = 81;
2470  break;
2471  case _lev_ctrl_genpurpose7:
2472  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2473  decodedcontroller.controller_number = 82;
2474  break;
2475  case _lev_ctrl_genpurpose8:
2476  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2477  decodedcontroller.controller_number = 83;
2478  break;
2479  case _lev_ctrl_effect1depth:
2480  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2481  decodedcontroller.controller_number = 91;
2482  break;
2483  case _lev_ctrl_effect2depth:
2484  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2485  decodedcontroller.controller_number = 92;
2486  break;
2487  case _lev_ctrl_effect3depth:
2488  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2489  decodedcontroller.controller_number = 93;
2490  break;
2491  case _lev_ctrl_effect4depth:
2492  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2493  decodedcontroller.controller_number = 94;
2494  break;
2495  case _lev_ctrl_effect5depth:
2496  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2497  decodedcontroller.controller_number = 95;
2498  break;
2499 
2500  // format extension (these controllers are so far only supported by
2501  // LinuxSampler & gigedit) they will *NOT* work with
2502  // Gigasampler/GigaStudio !
2503  case _lev_ctrl_CC3_EXT:
2504  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2505  decodedcontroller.controller_number = 3;
2506  break;
2507  case _lev_ctrl_CC6_EXT:
2508  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2509  decodedcontroller.controller_number = 6;
2510  break;
2511  case _lev_ctrl_CC7_EXT:
2512  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2513  decodedcontroller.controller_number = 7;
2514  break;
2515  case _lev_ctrl_CC8_EXT:
2516  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2517  decodedcontroller.controller_number = 8;
2518  break;
2519  case _lev_ctrl_CC9_EXT:
2520  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2521  decodedcontroller.controller_number = 9;
2522  break;
2523  case _lev_ctrl_CC10_EXT:
2524  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2525  decodedcontroller.controller_number = 10;
2526  break;
2527  case _lev_ctrl_CC11_EXT:
2528  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2529  decodedcontroller.controller_number = 11;
2530  break;
2531  case _lev_ctrl_CC14_EXT:
2532  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2533  decodedcontroller.controller_number = 14;
2534  break;
2535  case _lev_ctrl_CC15_EXT:
2536  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2537  decodedcontroller.controller_number = 15;
2538  break;
2539  case _lev_ctrl_CC20_EXT:
2540  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2541  decodedcontroller.controller_number = 20;
2542  break;
2543  case _lev_ctrl_CC21_EXT:
2544  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2545  decodedcontroller.controller_number = 21;
2546  break;
2547  case _lev_ctrl_CC22_EXT:
2548  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2549  decodedcontroller.controller_number = 22;
2550  break;
2551  case _lev_ctrl_CC23_EXT:
2552  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2553  decodedcontroller.controller_number = 23;
2554  break;
2555  case _lev_ctrl_CC24_EXT:
2556  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2557  decodedcontroller.controller_number = 24;
2558  break;
2559  case _lev_ctrl_CC25_EXT:
2560  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2561  decodedcontroller.controller_number = 25;
2562  break;
2563  case _lev_ctrl_CC26_EXT:
2564  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2565  decodedcontroller.controller_number = 26;
2566  break;
2567  case _lev_ctrl_CC27_EXT:
2568  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2569  decodedcontroller.controller_number = 27;
2570  break;
2571  case _lev_ctrl_CC28_EXT:
2572  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2573  decodedcontroller.controller_number = 28;
2574  break;
2575  case _lev_ctrl_CC29_EXT:
2576  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2577  decodedcontroller.controller_number = 29;
2578  break;
2579  case _lev_ctrl_CC30_EXT:
2580  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2581  decodedcontroller.controller_number = 30;
2582  break;
2583  case _lev_ctrl_CC31_EXT:
2584  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2585  decodedcontroller.controller_number = 31;
2586  break;
2587  case _lev_ctrl_CC68_EXT:
2588  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2589  decodedcontroller.controller_number = 68;
2590  break;
2591  case _lev_ctrl_CC69_EXT:
2592  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2593  decodedcontroller.controller_number = 69;
2594  break;
2595  case _lev_ctrl_CC70_EXT:
2596  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2597  decodedcontroller.controller_number = 70;
2598  break;
2599  case _lev_ctrl_CC71_EXT:
2600  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2601  decodedcontroller.controller_number = 71;
2602  break;
2603  case _lev_ctrl_CC72_EXT:
2604  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2605  decodedcontroller.controller_number = 72;
2606  break;
2607  case _lev_ctrl_CC73_EXT:
2608  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2609  decodedcontroller.controller_number = 73;
2610  break;
2611  case _lev_ctrl_CC74_EXT:
2612  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2613  decodedcontroller.controller_number = 74;
2614  break;
2615  case _lev_ctrl_CC75_EXT:
2616  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2617  decodedcontroller.controller_number = 75;
2618  break;
2619  case _lev_ctrl_CC76_EXT:
2620  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2621  decodedcontroller.controller_number = 76;
2622  break;
2623  case _lev_ctrl_CC77_EXT:
2624  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2625  decodedcontroller.controller_number = 77;
2626  break;
2627  case _lev_ctrl_CC78_EXT:
2628  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2629  decodedcontroller.controller_number = 78;
2630  break;
2631  case _lev_ctrl_CC79_EXT:
2632  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2633  decodedcontroller.controller_number = 79;
2634  break;
2635  case _lev_ctrl_CC84_EXT:
2636  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2637  decodedcontroller.controller_number = 84;
2638  break;
2639  case _lev_ctrl_CC85_EXT:
2640  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2641  decodedcontroller.controller_number = 85;
2642  break;
2643  case _lev_ctrl_CC86_EXT:
2644  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2645  decodedcontroller.controller_number = 86;
2646  break;
2647  case _lev_ctrl_CC87_EXT:
2648  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2649  decodedcontroller.controller_number = 87;
2650  break;
2651  case _lev_ctrl_CC89_EXT:
2652  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2653  decodedcontroller.controller_number = 89;
2654  break;
2655  case _lev_ctrl_CC90_EXT:
2656  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2657  decodedcontroller.controller_number = 90;
2658  break;
2659  case _lev_ctrl_CC96_EXT:
2660  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2661  decodedcontroller.controller_number = 96;
2662  break;
2663  case _lev_ctrl_CC97_EXT:
2664  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2665  decodedcontroller.controller_number = 97;
2666  break;
2667  case _lev_ctrl_CC102_EXT:
2668  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2669  decodedcontroller.controller_number = 102;
2670  break;
2671  case _lev_ctrl_CC103_EXT:
2672  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2673  decodedcontroller.controller_number = 103;
2674  break;
2675  case _lev_ctrl_CC104_EXT:
2676  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2677  decodedcontroller.controller_number = 104;
2678  break;
2679  case _lev_ctrl_CC105_EXT:
2680  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2681  decodedcontroller.controller_number = 105;
2682  break;
2683  case _lev_ctrl_CC106_EXT:
2684  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2685  decodedcontroller.controller_number = 106;
2686  break;
2687  case _lev_ctrl_CC107_EXT:
2688  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2689  decodedcontroller.controller_number = 107;
2690  break;
2691  case _lev_ctrl_CC108_EXT:
2692  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2693  decodedcontroller.controller_number = 108;
2694  break;
2695  case _lev_ctrl_CC109_EXT:
2696  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2697  decodedcontroller.controller_number = 109;
2698  break;
2699  case _lev_ctrl_CC110_EXT:
2700  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2701  decodedcontroller.controller_number = 110;
2702  break;
2703  case _lev_ctrl_CC111_EXT:
2704  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2705  decodedcontroller.controller_number = 111;
2706  break;
2707  case _lev_ctrl_CC112_EXT:
2708  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2709  decodedcontroller.controller_number = 112;
2710  break;
2711  case _lev_ctrl_CC113_EXT:
2712  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2713  decodedcontroller.controller_number = 113;
2714  break;
2715  case _lev_ctrl_CC114_EXT:
2716  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2717  decodedcontroller.controller_number = 114;
2718  break;
2719  case _lev_ctrl_CC115_EXT:
2720  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2721  decodedcontroller.controller_number = 115;
2722  break;
2723  case _lev_ctrl_CC116_EXT:
2724  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2725  decodedcontroller.controller_number = 116;
2726  break;
2727  case _lev_ctrl_CC117_EXT:
2728  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2729  decodedcontroller.controller_number = 117;
2730  break;
2731  case _lev_ctrl_CC118_EXT:
2732  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2733  decodedcontroller.controller_number = 118;
2734  break;
2735  case _lev_ctrl_CC119_EXT:
2736  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2737  decodedcontroller.controller_number = 119;
2738  break;
2739 
2740  // unknown controller type
2741  default:
2742  decodedcontroller.type = leverage_ctrl_t::type_none;
2743  decodedcontroller.controller_number = 0;
2744  printf("Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2745  break;
2746  }
2747  return decodedcontroller;
2748  }
2749 
2750 // see above (diagnostic push not supported prior GCC 4.6)
2751 //#pragma GCC diagnostic pop
2752 
2753  DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2754  _lev_ctrl_t encodedcontroller;
2755  switch (DecodedController.type) {
2756  // special controller
2758  encodedcontroller = _lev_ctrl_none;
2759  break;
2761  encodedcontroller = _lev_ctrl_velocity;
2762  break;
2764  encodedcontroller = _lev_ctrl_channelaftertouch;
2765  break;
2766 
2767  // ordinary MIDI control change controller
2769  switch (DecodedController.controller_number) {
2770  case 1:
2771  encodedcontroller = _lev_ctrl_modwheel;
2772  break;
2773  case 2:
2774  encodedcontroller = _lev_ctrl_breath;
2775  break;
2776  case 4:
2777  encodedcontroller = _lev_ctrl_foot;
2778  break;
2779  case 12:
2780  encodedcontroller = _lev_ctrl_effect1;
2781  break;
2782  case 13:
2783  encodedcontroller = _lev_ctrl_effect2;
2784  break;
2785  case 16:
2786  encodedcontroller = _lev_ctrl_genpurpose1;
2787  break;
2788  case 17:
2789  encodedcontroller = _lev_ctrl_genpurpose2;
2790  break;
2791  case 18:
2792  encodedcontroller = _lev_ctrl_genpurpose3;
2793  break;
2794  case 19:
2795  encodedcontroller = _lev_ctrl_genpurpose4;
2796  break;
2797  case 5:
2798  encodedcontroller = _lev_ctrl_portamentotime;
2799  break;
2800  case 64:
2801  encodedcontroller = _lev_ctrl_sustainpedal;
2802  break;
2803  case 65:
2804  encodedcontroller = _lev_ctrl_portamento;
2805  break;
2806  case 66:
2807  encodedcontroller = _lev_ctrl_sostenutopedal;
2808  break;
2809  case 67:
2810  encodedcontroller = _lev_ctrl_softpedal;
2811  break;
2812  case 80:
2813  encodedcontroller = _lev_ctrl_genpurpose5;
2814  break;
2815  case 81:
2816  encodedcontroller = _lev_ctrl_genpurpose6;
2817  break;
2818  case 82:
2819  encodedcontroller = _lev_ctrl_genpurpose7;
2820  break;
2821  case 83:
2822  encodedcontroller = _lev_ctrl_genpurpose8;
2823  break;
2824  case 91:
2825  encodedcontroller = _lev_ctrl_effect1depth;
2826  break;
2827  case 92:
2828  encodedcontroller = _lev_ctrl_effect2depth;
2829  break;
2830  case 93:
2831  encodedcontroller = _lev_ctrl_effect3depth;
2832  break;
2833  case 94:
2834  encodedcontroller = _lev_ctrl_effect4depth;
2835  break;
2836  case 95:
2837  encodedcontroller = _lev_ctrl_effect5depth;
2838  break;
2839 
2840  // format extension (these controllers are so far only
2841  // supported by LinuxSampler & gigedit) they will *NOT*
2842  // work with Gigasampler/GigaStudio !
2843  case 3:
2844  encodedcontroller = _lev_ctrl_CC3_EXT;
2845  break;
2846  case 6:
2847  encodedcontroller = _lev_ctrl_CC6_EXT;
2848  break;
2849  case 7:
2850  encodedcontroller = _lev_ctrl_CC7_EXT;
2851  break;
2852  case 8:
2853  encodedcontroller = _lev_ctrl_CC8_EXT;
2854  break;
2855  case 9:
2856  encodedcontroller = _lev_ctrl_CC9_EXT;
2857  break;
2858  case 10:
2859  encodedcontroller = _lev_ctrl_CC10_EXT;
2860  break;
2861  case 11:
2862  encodedcontroller = _lev_ctrl_CC11_EXT;
2863  break;
2864  case 14:
2865  encodedcontroller = _lev_ctrl_CC14_EXT;
2866  break;
2867  case 15:
2868  encodedcontroller = _lev_ctrl_CC15_EXT;
2869  break;
2870  case 20:
2871  encodedcontroller = _lev_ctrl_CC20_EXT;
2872  break;
2873  case 21:
2874  encodedcontroller = _lev_ctrl_CC21_EXT;
2875  break;
2876  case 22:
2877  encodedcontroller = _lev_ctrl_CC22_EXT;
2878  break;
2879  case 23:
2880  encodedcontroller = _lev_ctrl_CC23_EXT;
2881  break;
2882  case 24:
2883  encodedcontroller = _lev_ctrl_CC24_EXT;
2884  break;
2885  case 25:
2886  encodedcontroller = _lev_ctrl_CC25_EXT;
2887  break;
2888  case 26:
2889  encodedcontroller = _lev_ctrl_CC26_EXT;
2890  break;
2891  case 27:
2892  encodedcontroller = _lev_ctrl_CC27_EXT;
2893  break;
2894  case 28:
2895  encodedcontroller = _lev_ctrl_CC28_EXT;
2896  break;
2897  case 29:
2898  encodedcontroller = _lev_ctrl_CC29_EXT;
2899  break;
2900  case 30:
2901  encodedcontroller = _lev_ctrl_CC30_EXT;
2902  break;
2903  case 31:
2904  encodedcontroller = _lev_ctrl_CC31_EXT;
2905  break;
2906  case 68:
2907  encodedcontroller = _lev_ctrl_CC68_EXT;
2908  break;
2909  case 69:
2910  encodedcontroller = _lev_ctrl_CC69_EXT;
2911  break;
2912  case 70:
2913  encodedcontroller = _lev_ctrl_CC70_EXT;
2914  break;
2915  case 71:
2916  encodedcontroller = _lev_ctrl_CC71_EXT;
2917  break;
2918  case 72:
2919  encodedcontroller = _lev_ctrl_CC72_EXT;
2920  break;
2921  case 73:
2922  encodedcontroller = _lev_ctrl_CC73_EXT;
2923  break;
2924  case 74:
2925  encodedcontroller = _lev_ctrl_CC74_EXT;
2926  break;
2927  case 75:
2928  encodedcontroller = _lev_ctrl_CC75_EXT;
2929  break;
2930  case 76:
2931  encodedcontroller = _lev_ctrl_CC76_EXT;
2932  break;
2933  case 77:
2934  encodedcontroller = _lev_ctrl_CC77_EXT;
2935  break;
2936  case 78:
2937  encodedcontroller = _lev_ctrl_CC78_EXT;
2938  break;
2939  case 79:
2940  encodedcontroller = _lev_ctrl_CC79_EXT;
2941  break;
2942  case 84:
2943  encodedcontroller = _lev_ctrl_CC84_EXT;
2944  break;
2945  case 85:
2946  encodedcontroller = _lev_ctrl_CC85_EXT;
2947  break;
2948  case 86:
2949  encodedcontroller = _lev_ctrl_CC86_EXT;
2950  break;
2951  case 87:
2952  encodedcontroller = _lev_ctrl_CC87_EXT;
2953  break;
2954  case 89:
2955  encodedcontroller = _lev_ctrl_CC89_EXT;
2956  break;
2957  case 90:
2958  encodedcontroller = _lev_ctrl_CC90_EXT;
2959  break;
2960  case 96:
2961  encodedcontroller = _lev_ctrl_CC96_EXT;
2962  break;
2963  case 97:
2964  encodedcontroller = _lev_ctrl_CC97_EXT;
2965  break;
2966  case 102:
2967  encodedcontroller = _lev_ctrl_CC102_EXT;
2968  break;
2969  case 103:
2970  encodedcontroller = _lev_ctrl_CC103_EXT;
2971  break;
2972  case 104:
2973  encodedcontroller = _lev_ctrl_CC104_EXT;
2974  break;
2975  case 105:
2976  encodedcontroller = _lev_ctrl_CC105_EXT;
2977  break;
2978  case 106:
2979  encodedcontroller = _lev_ctrl_CC106_EXT;
2980  break;
2981  case 107:
2982  encodedcontroller = _lev_ctrl_CC107_EXT;
2983  break;
2984  case 108:
2985  encodedcontroller = _lev_ctrl_CC108_EXT;
2986  break;
2987  case 109:
2988  encodedcontroller = _lev_ctrl_CC109_EXT;
2989  break;
2990  case 110:
2991  encodedcontroller = _lev_ctrl_CC110_EXT;
2992  break;
2993  case 111:
2994  encodedcontroller = _lev_ctrl_CC111_EXT;
2995  break;
2996  case 112:
2997  encodedcontroller = _lev_ctrl_CC112_EXT;
2998  break;
2999  case 113:
3000  encodedcontroller = _lev_ctrl_CC113_EXT;
3001  break;
3002  case 114:
3003  encodedcontroller = _lev_ctrl_CC114_EXT;
3004  break;
3005  case 115:
3006  encodedcontroller = _lev_ctrl_CC115_EXT;
3007  break;
3008  case 116:
3009  encodedcontroller = _lev_ctrl_CC116_EXT;
3010  break;
3011  case 117:
3012  encodedcontroller = _lev_ctrl_CC117_EXT;
3013  break;
3014  case 118:
3015  encodedcontroller = _lev_ctrl_CC118_EXT;
3016  break;
3017  case 119:
3018  encodedcontroller = _lev_ctrl_CC119_EXT;
3019  break;
3020 
3021  default:
3022  throw gig::Exception("leverage controller number is not supported by the gig format");
3023  }
3024  break;
3025  default:
3026  throw gig::Exception("Unknown leverage controller type.");
3027  }
3028  return encodedcontroller;
3029  }
3030 
3031  DimensionRegion::~DimensionRegion() {
3032  Instances--;
3033  if (!Instances) {
3034  // delete the velocity->volume tables
3035  VelocityTableMap::iterator iter;
3036  for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3037  double* pTable = iter->second;
3038  if (pTable) delete[] pTable;
3039  }
3040  pVelocityTables->clear();
3041  delete pVelocityTables;
3042  pVelocityTables = NULL;
3043  }
3044  if (VelocityTable) delete[] VelocityTable;
3045  }
3046 
3058  double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
3059  return pVelocityAttenuationTable[MIDIKeyVelocity];
3060  }
3061 
3062  double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3063  return pVelocityReleaseTable[MIDIKeyVelocity];
3064  }
3065 
3066  double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3067  return pVelocityCutoffTable[MIDIKeyVelocity];
3068  }
3069 
3075  pVelocityAttenuationTable =
3076  GetVelocityTable(
3078  );
3079  VelocityResponseCurve = curve;
3080  }
3081 
3087  pVelocityAttenuationTable =
3088  GetVelocityTable(
3090  );
3091  VelocityResponseDepth = depth;
3092  }
3093 
3099  pVelocityAttenuationTable =
3100  GetVelocityTable(
3102  );
3103  VelocityResponseCurveScaling = scaling;
3104  }
3105 
3111  pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3113  }
3114 
3120  pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3122  }
3123 
3129  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3130  VCFCutoffController = controller;
3131  }
3132 
3138  pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3139  VCFVelocityCurve = curve;
3140  }
3141 
3147  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3148  VCFVelocityDynamicRange = range;
3149  }
3150 
3156  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3157  VCFVelocityScale = scaling;
3158  }
3159 
3160  double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3161 
3162  // line-segment approximations of the 15 velocity curves
3163 
3164  // linear
3165  const int lin0[] = { 1, 1, 127, 127 };
3166  const int lin1[] = { 1, 21, 127, 127 };
3167  const int lin2[] = { 1, 45, 127, 127 };
3168  const int lin3[] = { 1, 74, 127, 127 };
3169  const int lin4[] = { 1, 127, 127, 127 };
3170 
3171  // non-linear
3172  const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3173  const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3174  127, 127 };
3175  const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3176  127, 127 };
3177  const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3178  127, 127 };
3179  const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3180 
3181  // special
3182  const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3183  113, 127, 127, 127 };
3184  const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3185  118, 127, 127, 127 };
3186  const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3187  85, 90, 91, 127, 127, 127 };
3188  const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3189  117, 127, 127, 127 };
3190  const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3191  127, 127 };
3192 
3193  // this is only used by the VCF velocity curve
3194  const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3195  91, 127, 127, 127 };
3196 
3197  const int* const curves[] = { non0, non1, non2, non3, non4,
3198  lin0, lin1, lin2, lin3, lin4,
3199  spe0, spe1, spe2, spe3, spe4, spe5 };
3200 
3201  double* const table = new double[128];
3202 
3203  const int* curve = curves[curveType * 5 + depth];
3204  const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
3205 
3206  table[0] = 0;
3207  for (int x = 1 ; x < 128 ; x++) {
3208 
3209  if (x > curve[2]) curve += 2;
3210  double y = curve[1] + (x - curve[0]) *
3211  (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3212  y = y / 127;
3213 
3214  // Scale up for s > 20, down for s < 20. When
3215  // down-scaling, the curve still ends at 1.0.
3216  if (s < 20 && y >= 0.5)
3217  y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3218  else
3219  y = y * (s / 20.0);
3220  if (y > 1) y = 1;
3221 
3222  table[x] = y;
3223  }
3224  return table;
3225  }
3226 
3227 
3228 // *************** Region ***************
3229 // *
3230 
3231  Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
3232  // Initialization
3233  Dimensions = 0;
3234  for (int i = 0; i < 256; i++) {
3235  pDimensionRegions[i] = NULL;
3236  }
3237  Layers = 1;
3238  File* file = (File*) GetParent()->GetParent();
3239  int dimensionBits = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3240 
3241  // Actual Loading
3242 
3243  if (!file->GetAutoLoad()) return;
3244 
3245  LoadDimensionRegions(rgnList);
3246 
3247  RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
3248  if (_3lnk) {
3249  _3lnk->SetPos(0);
3250 
3251  DimensionRegions = _3lnk->ReadUint32();
3252  for (int i = 0; i < dimensionBits; i++) {
3253  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
3254  uint8_t bits = _3lnk->ReadUint8();
3255  _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
3256  _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
3257  uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
3258  if (dimension == dimension_none) { // inactive dimension
3259  pDimensionDefinitions[i].dimension = dimension_none;
3260  pDimensionDefinitions[i].bits = 0;
3261  pDimensionDefinitions[i].zones = 0;
3262  pDimensionDefinitions[i].split_type = split_type_bit;
3263  pDimensionDefinitions[i].zone_size = 0;
3264  }
3265  else { // active dimension
3266  pDimensionDefinitions[i].dimension = dimension;
3267  pDimensionDefinitions[i].bits = bits;
3268  pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
3269  pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3270  pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3271  Dimensions++;
3272 
3273  // if this is a layer dimension, remember the amount of layers
3274  if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
3275  }
3276  _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
3277  }
3278  for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3279 
3280  // if there's a velocity dimension and custom velocity zone splits are used,
3281  // update the VelocityTables in the dimension regions
3282  UpdateVelocityTable();
3283 
3284  // jump to start of the wave pool indices (if not already there)
3285  if (file->pVersion && file->pVersion->major > 2)
3286  _3lnk->SetPos(68); // version 3 has a different 3lnk structure
3287  else
3288  _3lnk->SetPos(44);
3289 
3290  // load sample references (if auto loading is enabled)
3291  if (file->GetAutoLoad()) {
3292  for (uint i = 0; i < DimensionRegions; i++) {
3293  uint32_t wavepoolindex = _3lnk->ReadUint32();
3294  if (file->pWavePoolTable && pDimensionRegions[i])
3295  pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3296  }
3297  GetSample(); // load global region sample reference
3298  }
3299  } else {
3300  DimensionRegions = 0;
3301  for (int i = 0 ; i < 8 ; i++) {
3302  pDimensionDefinitions[i].dimension = dimension_none;
3303  pDimensionDefinitions[i].bits = 0;
3304  pDimensionDefinitions[i].zones = 0;
3305  }
3306  }
3307 
3308  // make sure there is at least one dimension region
3309  if (!DimensionRegions) {
3310  RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
3311  if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
3312  RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
3313  pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
3314  DimensionRegions = 1;
3315  }
3316  }
3317 
3329  // in the gig format we don't care about the Region's sample reference
3330  // but we still have to provide some existing one to not corrupt the
3331  // file, so to avoid the latter we simply always assign the sample of
3332  // the first dimension region of this region
3333  pSample = pDimensionRegions[0]->pSample;
3334 
3335  // first update base class's chunks
3336  DLS::Region::UpdateChunks(pProgress);
3337 
3338  // update dimension region's chunks
3339  for (int i = 0; i < DimensionRegions; i++) {
3340  pDimensionRegions[i]->UpdateChunks(pProgress);
3341  }
3342 
3343  File* pFile = (File*) GetParent()->GetParent();
3344  bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2;
3345  const int iMaxDimensions = versiongt2 ? 8 : 5;
3346  const int iMaxDimensionRegions = versiongt2 ? 256 : 32;
3347 
3348  // make sure '3lnk' chunk exists
3349  RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3350  if (!_3lnk) {
3351  const int _3lnkChunkSize = versiongt2 ? 1092 : 172;
3352  _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3353  memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3354 
3355  // move 3prg to last position
3356  pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (RIFF::Chunk*)NULL);
3357  }
3358 
3359  // update dimension definitions in '3lnk' chunk
3360  uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3361  store32(&pData[0], DimensionRegions);
3362  int shift = 0;
3363  for (int i = 0; i < iMaxDimensions; i++) {
3364  pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3365  pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3366  pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3367  pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3368  pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3369  // next 3 bytes unknown, always zero?
3370 
3371  shift += pDimensionDefinitions[i].bits;
3372  }
3373 
3374  // update wave pool table in '3lnk' chunk
3375  const int iWavePoolOffset = versiongt2 ? 68 : 44;
3376  for (uint i = 0; i < iMaxDimensionRegions; i++) {
3377  int iWaveIndex = -1;
3378  if (i < DimensionRegions) {
3379  if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
3380  File::SampleList::iterator iter = pFile->pSamples->begin();
3381  File::SampleList::iterator end = pFile->pSamples->end();
3382  for (int index = 0; iter != end; ++iter, ++index) {
3383  if (*iter == pDimensionRegions[i]->pSample) {
3384  iWaveIndex = index;
3385  break;
3386  }
3387  }
3388  }
3389  store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3390  }
3391  }
3392 
3393  void Region::LoadDimensionRegions(RIFF::List* rgn) {
3394  RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
3395  if (_3prg) {
3396  int dimensionRegionNr = 0;
3397  RIFF::List* _3ewl = _3prg->GetFirstSubList();
3398  while (_3ewl) {
3399  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3400  pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3401  dimensionRegionNr++;
3402  }
3403  _3ewl = _3prg->GetNextSubList();
3404  }
3405  if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
3406  }
3407  }
3408 
3409  void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3410  // update KeyRange struct and make sure regions are in correct order
3411  DLS::Region::SetKeyRange(Low, High);
3412  // update Region key table for fast lookup
3413  ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3414  }
3415 
3416  void Region::UpdateVelocityTable() {
3417  // get velocity dimension's index
3418  int veldim = -1;
3419  for (int i = 0 ; i < Dimensions ; i++) {
3420  if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3421  veldim = i;
3422  break;
3423  }
3424  }
3425  if (veldim == -1) return;
3426 
3427  int step = 1;
3428  for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3429  int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3430 
3431  // loop through all dimension regions for all dimensions except the velocity dimension
3432  int dim[8] = { 0 };
3433  for (int i = 0 ; i < DimensionRegions ; i++) {
3434  const int end = i + step * pDimensionDefinitions[veldim].zones;
3435 
3436  // create a velocity table for all cases where the velocity zone is zero
3437  if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3438  pDimensionRegions[i]->VelocityUpperLimit) {
3439  // create the velocity table
3440  uint8_t* table = pDimensionRegions[i]->VelocityTable;
3441  if (!table) {
3442  table = new uint8_t[128];
3443  pDimensionRegions[i]->VelocityTable = table;
3444  }
3445  int tableidx = 0;
3446  int velocityZone = 0;
3447  if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
3448  for (int k = i ; k < end ; k += step) {
3449  DimensionRegion *d = pDimensionRegions[k];
3450  for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3451  velocityZone++;
3452  }
3453  } else { // gig2
3454  for (int k = i ; k < end ; k += step) {
3455  DimensionRegion *d = pDimensionRegions[k];
3456  for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3457  velocityZone++;
3458  }
3459  }
3460  } else {
3461  if (pDimensionRegions[i]->VelocityTable) {
3462  delete[] pDimensionRegions[i]->VelocityTable;
3464  }
3465  }
3466 
3467  // jump to the next case where the velocity zone is zero
3468  int j;
3469  int shift = 0;
3470  for (j = 0 ; j < Dimensions ; j++) {
3471  if (j == veldim) i += skipveldim; // skip velocity dimension
3472  else {
3473  dim[j]++;
3474  if (dim[j] < pDimensionDefinitions[j].zones) break;
3475  else {
3476  // skip unused dimension regions
3477  dim[j] = 0;
3478  i += ((1 << pDimensionDefinitions[j].bits) -
3479  pDimensionDefinitions[j].zones) << shift;
3480  }
3481  }
3482  shift += pDimensionDefinitions[j].bits;
3483  }
3484  if (j == Dimensions) break;
3485  }
3486  }
3487 
3504  // some initial sanity checks of the given dimension definition
3505  if (pDimDef->zones < 2)
3506  throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3507  if (pDimDef->bits < 1)
3508  throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3509  if (pDimDef->dimension == dimension_samplechannel) {
3510  if (pDimDef->zones != 2)
3511  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3512  if (pDimDef->bits != 1)
3513  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3514  }
3515 
3516  // check if max. amount of dimensions reached
3517  File* file = (File*) GetParent()->GetParent();
3518  const int iMaxDimensions = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3519  if (Dimensions >= iMaxDimensions)
3520  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
3521  // check if max. amount of dimension bits reached
3522  int iCurrentBits = 0;
3523  for (int i = 0; i < Dimensions; i++)
3524  iCurrentBits += pDimensionDefinitions[i].bits;
3525  if (iCurrentBits >= iMaxDimensions)
3526  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
3527  const int iNewBits = iCurrentBits + pDimDef->bits;
3528  if (iNewBits > iMaxDimensions)
3529  throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
3530  // check if there's already a dimensions of the same type
3531  for (int i = 0; i < Dimensions; i++)
3532  if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3533  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3534 
3535  // pos is where the new dimension should be placed, normally
3536  // last in list, except for the samplechannel dimension which
3537  // has to be first in list
3538  int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3539  int bitpos = 0;
3540  for (int i = 0 ; i < pos ; i++)
3541  bitpos += pDimensionDefinitions[i].bits;
3542 
3543  // make room for the new dimension
3544  for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3545  for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3546  for (int j = Dimensions ; j > pos ; j--) {
3549  }
3550  }
3551 
3552  // assign definition of new dimension
3553  pDimensionDefinitions[pos] = *pDimDef;
3554 
3555  // auto correct certain dimension definition fields (where possible)
3557  __resolveSplitType(pDimensionDefinitions[pos].dimension);
3559  __resolveZoneSize(pDimensionDefinitions[pos]);
3560 
3561  // create new dimension region(s) for this new dimension, and make
3562  // sure that the dimension regions are placed correctly in both the
3563  // RIFF list and the pDimensionRegions array
3564  RIFF::Chunk* moveTo = NULL;
3565  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3566  for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3567  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3568  pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3569  }
3570  for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3571  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3572  RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3573  if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3574  // create a new dimension region and copy all parameter values from
3575  // an existing dimension region
3576  pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3577  new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3578 
3579  DimensionRegions++;
3580  }
3581  }
3582  moveTo = pDimensionRegions[i]->pParentList;
3583  }
3584 
3585  // initialize the upper limits for this dimension
3586  int mask = (1 << bitpos) - 1;
3587  for (int z = 0 ; z < pDimDef->zones ; z++) {
3588  uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3589  for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3590  pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3591  (z << bitpos) |
3592  (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3593  }
3594  }
3595 
3596  Dimensions++;
3597 
3598  // if this is a layer dimension, update 'Layers' attribute
3599  if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
3600 
3601  UpdateVelocityTable();
3602  }
3603 
3616  // get dimension's index
3617  int iDimensionNr = -1;
3618  for (int i = 0; i < Dimensions; i++) {
3619  if (&pDimensionDefinitions[i] == pDimDef) {
3620  iDimensionNr = i;
3621  break;
3622  }
3623  }
3624  if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
3625 
3626  // get amount of bits below the dimension to delete
3627  int iLowerBits = 0;
3628  for (int i = 0; i < iDimensionNr; i++)
3629  iLowerBits += pDimensionDefinitions[i].bits;
3630 
3631  // get amount ot bits above the dimension to delete
3632  int iUpperBits = 0;
3633  for (int i = iDimensionNr + 1; i < Dimensions; i++)
3634  iUpperBits += pDimensionDefinitions[i].bits;
3635 
3636  RIFF::List* _3prg = pCkRegion->GetSubList(LIST_TYPE_3PRG);
3637 
3638  // delete dimension regions which belong to the given dimension
3639  // (that is where the dimension's bit > 0)
3640  for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3641  for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3642  for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3643  int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3644  iObsoleteBit << iLowerBits |
3645  iLowerBit;
3646 
3647  _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3648  delete pDimensionRegions[iToDelete];
3649  pDimensionRegions[iToDelete] = NULL;
3650  DimensionRegions--;
3651  }
3652  }
3653  }
3654 
3655  // defrag pDimensionRegions array
3656  // (that is remove the NULL spaces within the pDimensionRegions array)
3657  for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3658  if (!pDimensionRegions[iTo]) {
3659  if (iFrom <= iTo) iFrom = iTo + 1;
3660  while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3661  if (iFrom < 256 && pDimensionRegions[iFrom]) {
3662  pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3663  pDimensionRegions[iFrom] = NULL;
3664  }
3665  }
3666  }
3667 
3668  // remove the this dimension from the upper limits arrays
3669  for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3671  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3672  d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3673  }
3674  d->DimensionUpperLimits[Dimensions - 1] = 127;
3675  }
3676 
3677  // 'remove' dimension definition
3678  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3680  }
3684 
3685  Dimensions--;
3686 
3687  // if this was a layer dimension, update 'Layers' attribute
3688  if (pDimDef->dimension == dimension_layer) Layers = 1;
3689  }
3690 
3706  dimension_def_t* oldDef = GetDimensionDefinition(type);
3707  if (!oldDef)
3708  throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3709  if (oldDef->zones <= 2)
3710  throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3711  if (zone < 0 || zone >= oldDef->zones)
3712  throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3713 
3714  const int newZoneSize = oldDef->zones - 1;
3715 
3716  // create a temporary Region which just acts as a temporary copy
3717  // container and will be deleted at the end of this function and will
3718  // also not be visible through the API during this process
3719  gig::Region* tempRgn = NULL;
3720  {
3721  // adding these temporary chunks is probably not even necessary
3722  Instrument* instr = static_cast<Instrument*>(GetParent());
3723  RIFF::List* pCkInstrument = instr->pCkInstrument;
3724  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3725  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3726  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3727  tempRgn = new Region(instr, rgn);
3728  }
3729 
3730  // copy this region's dimensions (with already the dimension split size
3731  // requested by the arguments of this method call) to the temporary
3732  // region, and don't use Region::CopyAssign() here for this task, since
3733  // it would also alter fast lookup helper variables here and there
3734  dimension_def_t newDef;
3735  for (int i = 0; i < Dimensions; ++i) {
3736  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3737  // is this the dimension requested by the method arguments? ...
3738  if (def.dimension == type) { // ... if yes, decrement zone amount by one
3739  def.zones = newZoneSize;
3740  if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3741  newDef = def;
3742  }
3743  tempRgn->AddDimension(&def);
3744  }
3745 
3746  // find the dimension index in the tempRegion which is the dimension
3747  // type passed to this method (paranoidly expecting different order)
3748  int tempReducedDimensionIndex = -1;
3749  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3750  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3751  tempReducedDimensionIndex = d;
3752  break;
3753  }
3754  }
3755 
3756  // copy dimension regions from this region to the temporary region
3757  for (int iDst = 0; iDst < 256; ++iDst) {
3758  DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3759  if (!dstDimRgn) continue;
3760  std::map<dimension_t,int> dimCase;
3761  bool isValidZone = true;
3762  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3763  const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3764  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3765  (iDst >> baseBits) & ((1 << dstBits) - 1);
3766  baseBits += dstBits;
3767  // there are also DimensionRegion objects of unused zones, skip them
3768  if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3769  isValidZone = false;
3770  break;
3771  }
3772  }
3773  if (!isValidZone) continue;
3774  // a bit paranoid: cope with the chance that the dimensions would
3775  // have different order in source and destination regions
3776  const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3777  if (dimCase[type] >= zone) dimCase[type]++;
3778  DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3779  dstDimRgn->CopyAssign(srcDimRgn);
3780  // if this is the upper most zone of the dimension passed to this
3781  // method, then correct (raise) its upper limit to 127
3782  if (newDef.split_type == split_type_normal && isLastZone)
3783  dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3784  }
3785 
3786  // now tempRegion's dimensions and DimensionRegions basically reflect
3787  // what we wanted to get for this actual Region here, so we now just
3788  // delete and recreate the dimension in question with the new amount
3789  // zones and then copy back from tempRegion
3790  DeleteDimension(oldDef);
3791  AddDimension(&newDef);
3792  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3793  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3794  if (!srcDimRgn) continue;
3795  std::map<dimension_t,int> dimCase;
3796  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3797  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3798  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3799  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3800  baseBits += srcBits;
3801  }
3802  // a bit paranoid: cope with the chance that the dimensions would
3803  // have different order in source and destination regions
3804  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3805  if (!dstDimRgn) continue;
3806  dstDimRgn->CopyAssign(srcDimRgn);
3807  }
3808 
3809  // delete temporary region
3810  tempRgn->DeleteChunks();
3811  delete tempRgn;
3812 
3813  UpdateVelocityTable();
3814  }
3815 
3831  dimension_def_t* oldDef = GetDimensionDefinition(type);
3832  if (!oldDef)
3833  throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3834  if (zone < 0 || zone >= oldDef->zones)
3835  throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3836 
3837  const int newZoneSize = oldDef->zones + 1;
3838 
3839  // create a temporary Region which just acts as a temporary copy
3840  // container and will be deleted at the end of this function and will
3841  // also not be visible through the API during this process
3842  gig::Region* tempRgn = NULL;
3843  {
3844  // adding these temporary chunks is probably not even necessary
3845  Instrument* instr = static_cast<Instrument*>(GetParent());
3846  RIFF::List* pCkInstrument = instr->pCkInstrument;
3847  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3848  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3849  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3850  tempRgn = new Region(instr, rgn);
3851  }
3852 
3853  // copy this region's dimensions (with already the dimension split size
3854  // requested by the arguments of this method call) to the temporary
3855  // region, and don't use Region::CopyAssign() here for this task, since
3856  // it would also alter fast lookup helper variables here and there
3857  dimension_def_t newDef;
3858  for (int i = 0; i < Dimensions; ++i) {
3859  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3860  // is this the dimension requested by the method arguments? ...
3861  if (def.dimension == type) { // ... if yes, increment zone amount by one
3862  def.zones = newZoneSize;
3863  if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3864  newDef = def;
3865  }
3866  tempRgn->AddDimension(&def);
3867  }
3868 
3869  // find the dimension index in the tempRegion which is the dimension
3870  // type passed to this method (paranoidly expecting different order)
3871  int tempIncreasedDimensionIndex = -1;
3872  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3873  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3874  tempIncreasedDimensionIndex = d;
3875  break;
3876  }
3877  }
3878 
3879  // copy dimension regions from this region to the temporary region
3880  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3881  DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
3882  if (!srcDimRgn) continue;
3883  std::map<dimension_t,int> dimCase;
3884  bool isValidZone = true;
3885  for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
3886  const int srcBits = pDimensionDefinitions[d].bits;
3887  dimCase[pDimensionDefinitions[d].dimension] =
3888  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3889  // there are also DimensionRegion objects for unused zones, skip them
3890  if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
3891  isValidZone = false;
3892  break;
3893  }
3894  baseBits += srcBits;
3895  }
3896  if (!isValidZone) continue;
3897  // a bit paranoid: cope with the chance that the dimensions would
3898  // have different order in source and destination regions
3899  if (dimCase[type] > zone) dimCase[type]++;
3900  DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3901  dstDimRgn->CopyAssign(srcDimRgn);
3902  // if this is the requested zone to be splitted, then also copy
3903  // the source DimensionRegion to the newly created target zone
3904  // and set the old zones upper limit lower
3905  if (dimCase[type] == zone) {
3906  // lower old zones upper limit
3907  if (newDef.split_type == split_type_normal) {
3908  const int high =
3909  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
3910  int low = 0;
3911  if (zone > 0) {
3912  std::map<dimension_t,int> lowerCase = dimCase;
3913  lowerCase[type]--;
3914  DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
3915  low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
3916  }
3917  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
3918  }
3919  // fill the newly created zone of the divided zone as well
3920  dimCase[type]++;
3921  dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3922  dstDimRgn->CopyAssign(srcDimRgn);
3923  }
3924  }
3925 
3926  // now tempRegion's dimensions and DimensionRegions basically reflect
3927  // what we wanted to get for this actual Region here, so we now just
3928  // delete and recreate the dimension in question with the new amount
3929  // zones and then copy back from tempRegion
3930  DeleteDimension(oldDef);
3931  AddDimension(&newDef);
3932  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3933  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3934  if (!srcDimRgn) continue;
3935  std::map<dimension_t,int> dimCase;
3936  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3937  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3938  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3939  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3940  baseBits += srcBits;
3941  }
3942  // a bit paranoid: cope with the chance that the dimensions would
3943  // have different order in source and destination regions
3944  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3945  if (!dstDimRgn) continue;
3946  dstDimRgn->CopyAssign(srcDimRgn);
3947  }
3948 
3949  // delete temporary region
3950  tempRgn->DeleteChunks();
3951  delete tempRgn;
3952 
3953  UpdateVelocityTable();
3954  }
3955 
3971  if (oldType == newType) return;
3972  dimension_def_t* def = GetDimensionDefinition(oldType);
3973  if (!def)
3974  throw gig::Exception("No dimension with provided old dimension type exists on this region");
3975  if (newType == dimension_samplechannel && def->zones != 2)
3976  throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
3977  if (GetDimensionDefinition(newType))
3978  throw gig::Exception("There is already a dimension with requested new dimension type on this region");
3979  def->dimension = newType;
3980  def->split_type = __resolveSplitType(newType);
3981  }
3982 
3983  DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
3984  uint8_t bits[8] = {};
3985  for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3986  it != DimCase.end(); ++it)
3987  {
3988  for (int d = 0; d < Dimensions; ++d) {
3989  if (pDimensionDefinitions[d].dimension == it->first) {
3990  bits[d] = it->second;
3991  goto nextDimCaseSlice;
3992  }
3993  }
3994  assert(false); // do crash ... too harsh maybe ? ignore it instead ?
3995  nextDimCaseSlice:
3996  ; // noop
3997  }
3998  return GetDimensionRegionByBit(bits);
3999  }
4000 
4011  for (int i = 0; i < Dimensions; ++i)
4012  if (pDimensionDefinitions[i].dimension == type)
4013  return &pDimensionDefinitions[i];
4014  return NULL;
4015  }
4016 
4018  for (int i = 0; i < 256; i++) {
4019  if (pDimensionRegions[i]) delete pDimensionRegions[i];
4020  }
4021  }
4022 
4042  uint8_t bits;
4043  int veldim = -1;
4044  int velbitpos = 0;
4045  int bitpos = 0;
4046  int dimregidx = 0;
4047  for (uint i = 0; i < Dimensions; i++) {
4048  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4049  // the velocity dimension must be handled after the other dimensions
4050  veldim = i;
4051  velbitpos = bitpos;
4052  } else {
4053  switch (pDimensionDefinitions[i].split_type) {
4054  case split_type_normal:
4055  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4056  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4057  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4058  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4059  }
4060  } else {
4061  // gig2: evenly sized zones
4062  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4063  }
4064  break;
4065  case split_type_bit: // the value is already the sought dimension bit number
4066  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4067  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4068  break;
4069  }
4070  dimregidx |= bits << bitpos;
4071  }
4072  bitpos += pDimensionDefinitions[i].bits;
4073  }
4074  DimensionRegion* dimreg = pDimensionRegions[dimregidx & 255];
4075  if (!dimreg) return NULL;
4076  if (veldim != -1) {
4077  // (dimreg is now the dimension region for the lowest velocity)
4078  if (dimreg->VelocityTable) // custom defined zone ranges
4079  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4080  else // normal split type
4081  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4082 
4083  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4084  dimregidx |= (bits & limiter_mask) << velbitpos;
4085  dimreg = pDimensionRegions[dimregidx & 255];
4086  }
4087  return dimreg;
4088  }
4089 
4090  int Region::GetDimensionRegionIndexByValue(const uint DimValues[8]) {
4091  uint8_t bits;
4092  int veldim = -1;
4093  int velbitpos = 0;
4094  int bitpos = 0;
4095  int dimregidx = 0;
4096  for (uint i = 0; i < Dimensions; i++) {
4097  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4098  // the velocity dimension must be handled after the other dimensions
4099  veldim = i;
4100  velbitpos = bitpos;
4101  } else {
4102  switch (pDimensionDefinitions[i].split_type) {
4103  case split_type_normal:
4104  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4105  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
4106  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4107  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
4108  }
4109  } else {
4110  // gig2: evenly sized zones
4111  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4112  }
4113  break;
4114  case split_type_bit: // the value is already the sought dimension bit number
4115  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4116  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
4117  break;
4118  }
4119  dimregidx |= bits << bitpos;
4120  }
4121  bitpos += pDimensionDefinitions[i].bits;
4122  }
4123  dimregidx &= 255;
4124  DimensionRegion* dimreg = pDimensionRegions[dimregidx];
4125  if (!dimreg) return -1;
4126  if (veldim != -1) {
4127  // (dimreg is now the dimension region for the lowest velocity)
4128  if (dimreg->VelocityTable) // custom defined zone ranges
4129  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
4130  else // normal split type
4131  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4132 
4133  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4134  dimregidx |= (bits & limiter_mask) << velbitpos;
4135  dimregidx &= 255;
4136  }
4137  return dimregidx;
4138  }
4139 
4151  return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4152  << pDimensionDefinitions[5].bits | DimBits[5])
4153  << pDimensionDefinitions[4].bits | DimBits[4])
4154  << pDimensionDefinitions[3].bits | DimBits[3])
4155  << pDimensionDefinitions[2].bits | DimBits[2])
4156  << pDimensionDefinitions[1].bits | DimBits[1])
4157  << pDimensionDefinitions[0].bits | DimBits[0]];
4158  }
4159 
4170  if (pSample) return static_cast<gig::Sample*>(pSample);
4171  else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4172  }
4173 
4174  Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
4175  if ((int32_t)WavePoolTableIndex == -1) return NULL;
4176  File* file = (File*) GetParent()->GetParent();
4177  if (!file->pWavePoolTable) return NULL;
4178  if (WavePoolTableIndex + 1 > file->WavePoolCount) return NULL;
4179  // for new files or files >= 2 GB use 64 bit wave pool offsets
4180  if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
4181  // use 64 bit wave pool offsets (treating this as large file)
4182  uint64_t soughtoffset =
4183  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4184  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4185  Sample* sample = file->GetFirstSample(pProgress);
4186  while (sample) {
4187  if (sample->ullWavePoolOffset == soughtoffset)
4188  return static_cast<gig::Sample*>(sample);
4189  sample = file->GetNextSample();
4190  }
4191  } else {
4192  // use extension files and 32 bit wave pool offsets
4193  file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4194  file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4195  Sample* sample = file->GetFirstSample(pProgress);
4196  while (sample) {
4197  if (sample->ullWavePoolOffset == soughtoffset &&
4198  sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
4199  sample = file->GetNextSample();
4200  }
4201  }
4202  return NULL;
4203  }
4204 
4214  void Region::CopyAssign(const Region* orig) {
4215  CopyAssign(orig, NULL);
4216  }
4217 
4225  void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
4226  // handle base classes
4228 
4229  if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
4230  pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
4231  }
4232 
4233  // handle own member variables
4234  for (int i = Dimensions - 1; i >= 0; --i) {
4236  }
4237  Layers = 0; // just to be sure
4238  for (int i = 0; i < orig->Dimensions; i++) {
4239  // we need to copy the dim definition here, to avoid the compiler
4240  // complaining about const-ness issue
4241  dimension_def_t def = orig->pDimensionDefinitions[i];
4242  AddDimension(&def);
4243  }
4244  for (int i = 0; i < 256; i++) {
4245  if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
4247  orig->pDimensionRegions[i],
4248  mSamples
4249  );
4250  }
4251  }
4252  Layers = orig->Layers;
4253  }
4254 
4255 
4256 // *************** MidiRule ***************
4257 // *
4258 
4259  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) {
4260  _3ewg->SetPos(36);
4261  Triggers = _3ewg->ReadUint8();
4262  _3ewg->SetPos(40);
4263  ControllerNumber = _3ewg->ReadUint8();
4264  _3ewg->SetPos(46);
4265  for (int i = 0 ; i < Triggers ; i++) {
4266  pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
4267  pTriggers[i].Descending = _3ewg->ReadUint8();
4268  pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
4269  pTriggers[i].Key = _3ewg->ReadUint8();
4270  pTriggers[i].NoteOff = _3ewg->ReadUint8();
4271  pTriggers[i].Velocity = _3ewg->ReadUint8();
4272  pTriggers[i].OverridePedal = _3ewg->ReadUint8();
4273  _3ewg->ReadUint8();
4274  }
4275  }
4276 
4277  MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4278  ControllerNumber(0),
4279  Triggers(0) {
4280  }
4281 
4282  void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
4283  pData[32] = 4;
4284  pData[33] = 16;
4285  pData[36] = Triggers;
4286  pData[40] = ControllerNumber;
4287  for (int i = 0 ; i < Triggers ; i++) {
4288  pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4289  pData[47 + i * 8] = pTriggers[i].Descending;
4290  pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4291  pData[49 + i * 8] = pTriggers[i].Key;
4292  pData[50 + i * 8] = pTriggers[i].NoteOff;
4293  pData[51 + i * 8] = pTriggers[i].Velocity;
4294  pData[52 + i * 8] = pTriggers[i].OverridePedal;
4295  }
4296  }
4297 
4298  MidiRuleLegato::MidiRuleLegato(RIFF::Chunk* _3ewg) {
4299  _3ewg->SetPos(36);
4300  LegatoSamples = _3ewg->ReadUint8(); // always 12
4301  _3ewg->SetPos(40);
4302  BypassUseController = _3ewg->ReadUint8();
4303  BypassKey = _3ewg->ReadUint8();
4304  BypassController = _3ewg->ReadUint8();
4305  ThresholdTime = _3ewg->ReadUint16();
4306  _3ewg->ReadInt16();
4307  ReleaseTime = _3ewg->ReadUint16();
4308  _3ewg->ReadInt16();
4309  KeyRange.low = _3ewg->ReadUint8();
4310  KeyRange.high = _3ewg->ReadUint8();
4311  _3ewg->SetPos(64);
4312  ReleaseTriggerKey = _3ewg->ReadUint8();
4313  AltSustain1Key = _3ewg->ReadUint8();
4314  AltSustain2Key = _3ewg->ReadUint8();
4315  }
4316 
4317  MidiRuleLegato::MidiRuleLegato() :
4318  LegatoSamples(12),
4319  BypassUseController(false),
4320  BypassKey(0),
4321  BypassController(1),
4322  ThresholdTime(20),
4323  ReleaseTime(20),
4324  ReleaseTriggerKey(0),
4325  AltSustain1Key(0),
4326  AltSustain2Key(0)
4327  {
4328  KeyRange.low = KeyRange.high = 0;
4329  }
4330 
4331  void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
4332  pData[32] = 0;
4333  pData[33] = 16;
4334  pData[36] = LegatoSamples;
4335  pData[40] = BypassUseController;
4336  pData[41] = BypassKey;
4337  pData[42] = BypassController;
4338  store16(&pData[43], ThresholdTime);
4339  store16(&pData[47], ReleaseTime);
4340  pData[51] = KeyRange.low;
4341  pData[52] = KeyRange.high;
4342  pData[64] = ReleaseTriggerKey;
4343  pData[65] = AltSustain1Key;
4344  pData[66] = AltSustain2Key;
4345  }
4346 
4347  MidiRuleAlternator::MidiRuleAlternator(RIFF::Chunk* _3ewg) {
4348  _3ewg->SetPos(36);
4349  Articulations = _3ewg->ReadUint8();
4350  int flags = _3ewg->ReadUint8();
4351  Polyphonic = flags & 8;
4352  Chained = flags & 4;
4353  Selector = (flags & 2) ? selector_controller :
4354  (flags & 1) ? selector_key_switch : selector_none;
4355  Patterns = _3ewg->ReadUint8();
4356  _3ewg->ReadUint8(); // chosen row
4357  _3ewg->ReadUint8(); // unknown
4358  _3ewg->ReadUint8(); // unknown
4359  _3ewg->ReadUint8(); // unknown
4360  KeySwitchRange.low = _3ewg->ReadUint8();
4361  KeySwitchRange.high = _3ewg->ReadUint8();
4362  Controller = _3ewg->ReadUint8();
4363  PlayRange.low = _3ewg->ReadUint8();
4364  PlayRange.high = _3ewg->ReadUint8();
4365 
4366  int n = std::min(int(Articulations), 32);
4367  for (int i = 0 ; i < n ; i++) {
4368  _3ewg->ReadString(pArticulations[i], 32);
4369  }
4370  _3ewg->SetPos(1072);
4371  n = std::min(int(Patterns), 32);
4372  for (int i = 0 ; i < n ; i++) {
4373  _3ewg->ReadString(pPatterns[i].Name, 16);
4374  pPatterns[i].Size = _3ewg->ReadUint8();
4375  _3ewg->Read(&pPatterns[i][0], 1, 32);
4376  }
4377  }
4378 
4379  MidiRuleAlternator::MidiRuleAlternator() :
4380  Articulations(0),
4381  Patterns(0),
4382  Selector(selector_none),
4383  Controller(0),
4384  Polyphonic(false),
4385  Chained(false)
4386  {
4387  PlayRange.low = PlayRange.high = 0;
4388  KeySwitchRange.low = KeySwitchRange.high = 0;
4389  }
4390 
4391  void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
4392  pData[32] = 3;
4393  pData[33] = 16;
4394  pData[36] = Articulations;
4395  pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4396  (Selector == selector_controller ? 2 :
4397  (Selector == selector_key_switch ? 1 : 0));
4398  pData[38] = Patterns;
4399 
4400  pData[43] = KeySwitchRange.low;
4401  pData[44] = KeySwitchRange.high;
4402  pData[45] = Controller;
4403  pData[46] = PlayRange.low;
4404  pData[47] = PlayRange.high;
4405 
4406  char* str = reinterpret_cast<char*>(pData);
4407  int pos = 48;
4408  int n = std::min(int(Articulations), 32);
4409  for (int i = 0 ; i < n ; i++, pos += 32) {
4410  strncpy(&str[pos], pArticulations[i].c_str(), 32);
4411  }
4412 
4413  pos = 1072;
4414  n = std::min(int(Patterns), 32);
4415  for (int i = 0 ; i < n ; i++, pos += 49) {
4416  strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4417  pData[pos + 16] = pPatterns[i].Size;
4418  memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4419  }
4420  }
4421 
4422 // *************** Script ***************
4423 // *
4424 
4425  Script::Script(ScriptGroup* group, RIFF::Chunk* ckScri) {
4426  pGroup = group;
4427  pChunk = ckScri;
4428  if (ckScri) { // object is loaded from file ...
4429  ckScri->SetPos(0);
4430 
4431  // read header
4432  uint32_t headerSize = ckScri->ReadUint32();
4433  Compression = (Compression_t) ckScri->ReadUint32();
4434  Encoding = (Encoding_t) ckScri->ReadUint32();
4435  Language = (Language_t) ckScri->ReadUint32();
4436  Bypass = (Language_t) ckScri->ReadUint32() & 1;
4437  crc = ckScri->ReadUint32();
4438  uint32_t nameSize = ckScri->ReadUint32();
4439  Name.resize(nameSize, ' ');
4440  for (int i = 0; i < nameSize; ++i)
4441  Name[i] = ckScri->ReadUint8();
4442  // to handle potential future extensions of the header
4443  ckScri->SetPos(sizeof(int32_t) + headerSize);
4444  // read actual script data
4445  uint32_t scriptSize = uint32_t(ckScri->GetSize() - ckScri->GetPos());
4446  data.resize(scriptSize);
4447  for (int i = 0; i < scriptSize; ++i)
4448  data[i] = ckScri->ReadUint8();
4449  } else { // this is a new script object, so just initialize it as such ...
4453  Bypass = false;
4454  crc = 0;
4455  Name = "Unnamed Script";
4456  }
4457  }
4458 
4459  Script::~Script() {
4460  }
4461 
4466  String s;
4467  s.resize(data.size(), ' ');
4468  memcpy(&s[0], &data[0], data.size());
4469  return s;
4470  }
4471 
4478  void Script::SetScriptAsText(const String& text) {
4479  data.resize(text.size());
4480  memcpy(&data[0], &text[0], text.size());
4481  }
4482 
4493  }
4494 
4505  // recalculate CRC32 check sum
4506  __resetCRC(crc);
4507  __calculateCRC(&data[0], data.size(), crc);
4508  __finalizeCRC(crc);
4509  // make sure chunk exists and has the required size
4510  const file_offset_t chunkSize = (file_offset_t) 7*sizeof(int32_t) + Name.size() + data.size();
4511  if (!pChunk) pChunk = pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4512  else pChunk->Resize(chunkSize);
4513  // fill the chunk data to be written to disk
4514  uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4515  int pos = 0;
4516  store32(&pData[pos], uint32_t(6*sizeof(int32_t) + Name.size())); // total header size
4517  pos += sizeof(int32_t);
4518  store32(&pData[pos], Compression);
4519  pos += sizeof(int32_t);
4520  store32(&pData[pos], Encoding);
4521  pos += sizeof(int32_t);
4522  store32(&pData[pos], Language);
4523  pos += sizeof(int32_t);
4524  store32(&pData[pos], Bypass ? 1 : 0);
4525  pos += sizeof(int32_t);
4526  store32(&pData[pos], crc);
4527  pos += sizeof(int32_t);
4528  store32(&pData[pos], (uint32_t) Name.size());
4529  pos += sizeof(int32_t);
4530  for (int i = 0; i < Name.size(); ++i, ++pos)
4531  pData[pos] = Name[i];
4532  for (int i = 0; i < data.size(); ++i, ++pos)
4533  pData[pos] = data[i];
4534  }
4535 
4543  if (this->pGroup == pGroup) return;
4544  if (pChunk)
4545  pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4546  this->pGroup = pGroup;
4547  }
4548 
4556  return pGroup;
4557  }
4558 
4566  void Script::CopyAssign(const Script* orig) {
4567  Name = orig->Name;
4568  Compression = orig->Compression;
4569  Encoding = orig->Encoding;
4570  Language = orig->Language;
4571  Bypass = orig->Bypass;
4572  data = orig->data;
4573  }
4574 
4575  void Script::RemoveAllScriptReferences() {
4576  File* pFile = pGroup->pFile;
4577  for (int i = 0; pFile->GetInstrument(i); ++i) {
4578  Instrument* instr = pFile->GetInstrument(i);
4579  instr->RemoveScript(this);
4580  }
4581  }
4582 
4583 // *************** ScriptGroup ***************
4584 // *
4585 
4586  ScriptGroup::ScriptGroup(File* file, RIFF::List* lstRTIS) {
4587  pFile = file;
4588  pList = lstRTIS;
4589  pScripts = NULL;
4590  if (lstRTIS) {
4591  RIFF::Chunk* ckName = lstRTIS->GetSubChunk(CHUNK_ID_LSNM);
4592  ::LoadString(ckName, Name);
4593  } else {
4594  Name = "Default Group";
4595  }
4596  }
4597 
4598  ScriptGroup::~ScriptGroup() {
4599  if (pScripts) {
4600  std::list<Script*>::iterator iter = pScripts->begin();
4601  std::list<Script*>::iterator end = pScripts->end();
4602  while (iter != end) {
4603  delete *iter;
4604  ++iter;
4605  }
4606  delete pScripts;
4607  }
4608  }
4609 
4620  }
4621 
4632  if (pScripts) {
4633  if (!pList)
4634  pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4635 
4636  // now store the name of this group as <LSNM> chunk as subchunk of the <RTIS> list chunk
4637  ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String("Unnamed Group"), true, 64);
4638 
4639  for (std::list<Script*>::iterator it = pScripts->begin();
4640  it != pScripts->end(); ++it)
4641  {
4642  (*it)->UpdateChunks(pProgress);
4643  }
4644  }
4645  }
4646 
4655  if (!pScripts) LoadScripts();
4656  std::list<Script*>::iterator it = pScripts->begin();
4657  for (uint i = 0; it != pScripts->end(); ++i, ++it)
4658  if (i == index) return *it;
4659  return NULL;
4660  }
4661 
4674  if (!pScripts) LoadScripts();
4675  Script* pScript = new Script(this, NULL);
4676  pScripts->push_back(pScript);
4677  return pScript;
4678  }
4679 
4691  if (!pScripts) LoadScripts();
4692  std::list<Script*>::iterator iter =
4693  find(pScripts->begin(), pScripts->end(), pScript);
4694  if (iter == pScripts->end())
4695  throw gig::Exception("Could not delete script, could not find given script");
4696  pScripts->erase(iter);
4697  pScript->RemoveAllScriptReferences();
4698  if (pScript->pChunk)
4699  pScript->pChunk->GetParent()->DeleteSubChunk(pScript->pChunk);
4700  delete pScript;
4701  }
4702 
4703  void ScriptGroup::LoadScripts() {
4704  if (pScripts) return;
4705  pScripts = new std::list<Script*>;
4706  if (!pList) return;
4707 
4708  for (RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4709  ck = pList->GetNextSubChunk())
4710  {
4711  if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4712  pScripts->push_back(new Script(this, ck));
4713  }
4714  }
4715  }
4716 
4717 // *************** Instrument ***************
4718 // *
4719 
4720  Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
4721  static const DLS::Info::string_length_t fixedStringLengths[] = {
4722  { CHUNK_ID_INAM, 64 },
4723  { CHUNK_ID_ISFT, 12 },
4724  { 0, 0 }
4725  };
4726  pInfo->SetFixedStringLengths(fixedStringLengths);
4727 
4728  // Initialization
4729  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4730  EffectSend = 0;
4731  Attenuation = 0;
4732  FineTune = 0;
4733  PitchbendRange = 2;
4734  PianoReleaseMode = false;
4735  DimensionKeyRange.low = 0;
4736  DimensionKeyRange.high = 0;
4737  pMidiRules = new MidiRule*[3];
4738  pMidiRules[0] = NULL;
4739  pScriptRefs = NULL;
4740 
4741  // Loading
4742  RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
4743  if (lart) {
4744  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4745  if (_3ewg) {
4746  _3ewg->SetPos(0);
4747 
4748  EffectSend = _3ewg->ReadUint16();
4749  Attenuation = _3ewg->ReadInt32();
4750  FineTune = _3ewg->ReadInt16();
4751  PitchbendRange = _3ewg->ReadInt16();
4752  uint8_t dimkeystart = _3ewg->ReadUint8();
4753  PianoReleaseMode = dimkeystart & 0x01;
4754  DimensionKeyRange.low = dimkeystart >> 1;
4755  DimensionKeyRange.high = _3ewg->ReadUint8();
4756 
4757  if (_3ewg->GetSize() > 32) {
4758  // read MIDI rules
4759  int i = 0;
4760  _3ewg->SetPos(32);
4761  uint8_t id1 = _3ewg->ReadUint8();
4762  uint8_t id2 = _3ewg->ReadUint8();
4763 
4764  if (id2 == 16) {
4765  if (id1 == 4) {
4766  pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4767  } else if (id1 == 0) {
4768  pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4769  } else if (id1 == 3) {
4770  pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4771  } else {
4772  pMidiRules[i++] = new MidiRuleUnknown;
4773  }
4774  }
4775  else if (id1 != 0 || id2 != 0) {
4776  pMidiRules[i++] = new MidiRuleUnknown;
4777  }
4778  //TODO: all the other types of rules
4779 
4780  pMidiRules[i] = NULL;
4781  }
4782  }
4783  }
4784 
4785  if (pFile->GetAutoLoad()) {
4786  if (!pRegions) pRegions = new RegionList;
4787  RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
4788  if (lrgn) {
4789  RIFF::List* rgn = lrgn->GetFirstSubList();
4790  while (rgn) {
4791  if (rgn->GetListType() == LIST_TYPE_RGN) {
4792  if (pProgress)
4793  __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
4794  pRegions->push_back(new Region(this, rgn));
4795  }
4796  rgn = lrgn->GetNextSubList();
4797  }
4798  // Creating Region Key Table for fast lookup
4799  UpdateRegionKeyTable();
4800  }
4801  }
4802 
4803  // own gig format extensions
4804  RIFF::List* lst3LS = insList->GetSubList(LIST_TYPE_3LS);
4805  if (lst3LS) {
4806  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4807  if (ckSCSL) {
4808  ckSCSL->SetPos(0);
4809 
4810  int headerSize = ckSCSL->ReadUint32();
4811  int slotCount = ckSCSL->ReadUint32();
4812  if (slotCount) {
4813  int slotSize = ckSCSL->ReadUint32();
4814  ckSCSL->SetPos(headerSize); // in case of future header extensions
4815  int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions
4816  for (int i = 0; i < slotCount; ++i) {
4817  _ScriptPooolEntry e;
4818  e.fileOffset = ckSCSL->ReadUint32();
4819  e.bypass = ckSCSL->ReadUint32() & 1;
4820  if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions
4821  scriptPoolFileOffsets.push_back(e);
4822  }
4823  }
4824  }
4825  }
4826 
4827  if (pProgress)
4828  __notify_progress(pProgress, 1.0f); // notify done
4829  }
4830 
4831  void Instrument::UpdateRegionKeyTable() {
4832  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4833  RegionList::iterator iter = pRegions->begin();
4834  RegionList::iterator end = pRegions->end();
4835  for (; iter != end; ++iter) {
4836  gig::Region* pRegion = static_cast<gig::Region*>(*iter);
4837  const int low = std::max(int(pRegion->KeyRange.low), 0);
4838  const int high = std::min(int(pRegion->KeyRange.high), 127);
4839  for (int iKey = low; iKey <= high; iKey++) {
4840  RegionKeyTable[iKey] = pRegion;
4841  }
4842  }
4843  }
4844 
4846  for (int i = 0 ; pMidiRules[i] ; i++) {
4847  delete pMidiRules[i];
4848  }
4849  delete[] pMidiRules;
4850  if (pScriptRefs) delete pScriptRefs;
4851  }
4852 
4864  // first update base classes' chunks
4865  DLS::Instrument::UpdateChunks(pProgress);
4866 
4867  // update Regions' chunks
4868  {
4869  RegionList::iterator iter = pRegions->begin();
4870  RegionList::iterator end = pRegions->end();
4871  for (; iter != end; ++iter)
4872  (*iter)->UpdateChunks(pProgress);
4873  }
4874 
4875  // make sure 'lart' RIFF list chunk exists
4876  RIFF::List* lart = pCkInstrument->GetSubList(LIST_TYPE_LART);
4877  if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
4878  // make sure '3ewg' RIFF chunk exists
4879  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4880  if (!_3ewg) {
4881  File* pFile = (File*) GetParent();
4882 
4883  // 3ewg is bigger in gig3, as it includes the iMIDI rules
4884  int size = (pFile->pVersion && pFile->pVersion->major > 2) ? 16416 : 12;
4885  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
4886  memset(_3ewg->LoadChunkData(), 0, size);
4887  }
4888  // update '3ewg' RIFF chunk
4889  uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
4890  store16(&pData[0], EffectSend);
4891  store32(&pData[2], Attenuation);
4892  store16(&pData[6], FineTune);
4893  store16(&pData[8], PitchbendRange);
4894  const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4895  DimensionKeyRange.low << 1;
4896  pData[10] = dimkeystart;
4897  pData[11] = DimensionKeyRange.high;
4898 
4899  if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
4900  pData[32] = 0;
4901  pData[33] = 0;
4902  } else {
4903  for (int i = 0 ; pMidiRules[i] ; i++) {
4904  pMidiRules[i]->UpdateChunks(pData);
4905  }
4906  }
4907 
4908  // own gig format extensions
4909  if (ScriptSlotCount()) {
4910  // make sure we have converted the original loaded script file
4911  // offsets into valid Script object pointers
4912  LoadScripts();
4913 
4914  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4915  if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS);
4916  const int slotCount = (int) pScriptRefs->size();
4917  const int headerSize = 3 * sizeof(uint32_t);
4918  const int slotSize = 2 * sizeof(uint32_t);
4919  const int totalChunkSize = headerSize + slotCount * slotSize;
4920  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4921  if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
4922  else ckSCSL->Resize(totalChunkSize);
4923  uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData();
4924  int pos = 0;
4925  store32(&pData[pos], headerSize);
4926  pos += sizeof(uint32_t);
4927  store32(&pData[pos], slotCount);
4928  pos += sizeof(uint32_t);
4929  store32(&pData[pos], slotSize);
4930  pos += sizeof(uint32_t);
4931  for (int i = 0; i < slotCount; ++i) {
4932  // arbitrary value, the actual file offset will be updated in
4933  // UpdateScriptFileOffsets() after the file has been resized
4934  int bogusFileOffset = 0;
4935  store32(&pData[pos], bogusFileOffset);
4936  pos += sizeof(uint32_t);
4937  store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
4938  pos += sizeof(uint32_t);
4939  }
4940  } else {
4941  // no script slots, so get rid of any LS custom RIFF chunks (if any)
4942  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4943  if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS);
4944  }
4945  }
4946 
4947  void Instrument::UpdateScriptFileOffsets() {
4948  // own gig format extensions
4949  if (pScriptRefs && pScriptRefs->size() > 0) {
4950  RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS);
4951  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4952  const int slotCount = (int) pScriptRefs->size();
4953  const int headerSize = 3 * sizeof(uint32_t);
4954  ckSCSL->SetPos(headerSize);
4955  for (int i = 0; i < slotCount; ++i) {
4956  uint32_t fileOffset = uint32_t(
4957  (*pScriptRefs)[i].script->pChunk->GetFilePos() -
4958  (*pScriptRefs)[i].script->pChunk->GetPos() -
4959  CHUNK_HEADER_SIZE(ckSCSL->GetFile()->GetFileOffsetSize())
4960  );
4961  ckSCSL->WriteUint32(&fileOffset);
4962  // jump over flags entry (containing the bypass flag)
4963  ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos);
4964  }
4965  }
4966  }
4967 
4975  Region* Instrument::GetRegion(unsigned int Key) {
4976  if (!pRegions || pRegions->empty() || Key > 127) return NULL;
4977  return RegionKeyTable[Key];
4978 
4979  /*for (int i = 0; i < Regions; i++) {
4980  if (Key <= pRegions[i]->KeyRange.high &&
4981  Key >= pRegions[i]->KeyRange.low) return pRegions[i];
4982  }
4983  return NULL;*/
4984  }
4985 
4994  if (!pRegions) return NULL;
4995  RegionsIterator = pRegions->begin();
4996  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4997  }
4998 
5008  if (!pRegions) return NULL;
5009  RegionsIterator++;
5010  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5011  }
5012 
5013  Region* Instrument::AddRegion() {
5014  // create new Region object (and its RIFF chunks)
5015  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
5016  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
5017  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
5018  Region* pNewRegion = new Region(this, rgn);
5019  pRegions->push_back(pNewRegion);
5020  Regions = (uint32_t) pRegions->size();
5021  // update Region key table for fast lookup
5022  UpdateRegionKeyTable();
5023  // done
5024  return pNewRegion;
5025  }
5026 
5027  void Instrument::DeleteRegion(Region* pRegion) {
5028  if (!pRegions) return;
5029  DLS::Instrument::DeleteRegion((DLS::Region*) pRegion);
5030  // update Region key table for fast lookup
5031  UpdateRegionKeyTable();
5032  }
5033 
5062  if (dst && GetParent() != dst->GetParent())
5063  throw Exception(
5064  "gig::Instrument::MoveTo() can only be used for moving within "
5065  "the same gig file."
5066  );
5067 
5068  File* pFile = (File*) GetParent();
5069 
5070  // move this instrument within the instrument list
5071  {
5072  File::InstrumentList& list = *pFile->pInstruments;
5073 
5074  File::InstrumentList::iterator itFrom =
5075  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(this));
5076 
5077  File::InstrumentList::iterator itTo =
5078  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(dst));
5079 
5080  list.splice(itTo, list, itFrom);
5081  }
5082 
5083  // move the instrument's actual list RIFF chunk appropriately
5084  RIFF::List* lstCkInstruments = pFile->pRIFF->GetSubList(LIST_TYPE_LINS);
5085  lstCkInstruments->MoveSubChunk(
5086  this->pCkInstrument,
5087  (RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5088  );
5089  }
5090 
5102  return pMidiRules[i];
5103  }
5104 
5111  delete pMidiRules[0];
5113  pMidiRules[0] = r;
5114  pMidiRules[1] = 0;
5115  return r;
5116  }
5117 
5124  delete pMidiRules[0];
5125  MidiRuleLegato* r = new MidiRuleLegato;
5126  pMidiRules[0] = r;
5127  pMidiRules[1] = 0;
5128  return r;
5129  }
5130 
5137  delete pMidiRules[0];
5139  pMidiRules[0] = r;
5140  pMidiRules[1] = 0;
5141  return r;
5142  }
5143 
5150  delete pMidiRules[i];
5151  pMidiRules[i] = 0;
5152  }
5153 
5154  void Instrument::LoadScripts() {
5155  if (pScriptRefs) return;
5156  pScriptRefs = new std::vector<_ScriptPooolRef>;
5157  if (scriptPoolFileOffsets.empty()) return;
5158  File* pFile = (File*) GetParent();
5159  for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5160  uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5161  for (uint i = 0; pFile->GetScriptGroup(i); ++i) {
5162  ScriptGroup* group = pFile->GetScriptGroup(i);
5163  for (uint s = 0; group->GetScript(s); ++s) {
5164  Script* script = group->GetScript(s);
5165  if (script->pChunk) {
5166  uint32_t offset = uint32_t(
5167  script->pChunk->GetFilePos() -
5168  script->pChunk->GetPos() -
5169  CHUNK_HEADER_SIZE(script->pChunk->GetFile()->GetFileOffsetSize())
5170  );
5171  if (offset == soughtOffset)
5172  {
5173  _ScriptPooolRef ref;
5174  ref.script = script;
5175  ref.bypass = scriptPoolFileOffsets[k].bypass;
5176  pScriptRefs->push_back(ref);
5177  break;
5178  }
5179  }
5180  }
5181  }
5182  }
5183  // we don't need that anymore
5184  scriptPoolFileOffsets.clear();
5185  }
5186 
5200  LoadScripts();
5201  if (index >= pScriptRefs->size()) return NULL;
5202  return pScriptRefs->at(index).script;
5203  }
5204 
5240  void Instrument::AddScriptSlot(Script* pScript, bool bypass) {
5241  LoadScripts();
5242  _ScriptPooolRef ref = { pScript, bypass };
5243  pScriptRefs->push_back(ref);
5244  }
5245 
5260  void Instrument::SwapScriptSlots(uint index1, uint index2) {
5261  LoadScripts();
5262  if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5263  return;
5264  _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5265  (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5266  (*pScriptRefs)[index2] = tmp;
5267  }
5268 
5275  void Instrument::RemoveScriptSlot(uint index) {
5276  LoadScripts();
5277  if (index >= pScriptRefs->size()) return;
5278  pScriptRefs->erase( pScriptRefs->begin() + index );
5279  }
5280 
5294  LoadScripts();
5295  for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5296  if ((*pScriptRefs)[i].script == pScript) {
5297  pScriptRefs->erase( pScriptRefs->begin() + i );
5298  }
5299  }
5300  }
5301 
5317  return uint(pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size());
5318  }
5319 
5337  if (index >= ScriptSlotCount()) return false;
5338  return pScriptRefs ? pScriptRefs->at(index).bypass
5339  : scriptPoolFileOffsets.at(index).bypass;
5340 
5341  }
5342 
5356  void Instrument::SetScriptSlotBypassed(uint index, bool bBypass) {
5357  if (index >= ScriptSlotCount()) return;
5358  if (pScriptRefs)
5359  pScriptRefs->at(index).bypass = bBypass;
5360  else
5361  scriptPoolFileOffsets.at(index).bypass = bBypass;
5362  }
5363 
5374  CopyAssign(orig, NULL);
5375  }
5376 
5385  void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
5386  // handle base class
5387  // (without copying DLS region stuff)
5388  DLS::Instrument::CopyAssignCore(orig);
5389 
5390  // handle own member variables
5391  Attenuation = orig->Attenuation;
5392  EffectSend = orig->EffectSend;
5393  FineTune = orig->FineTune;
5395  PianoReleaseMode = orig->PianoReleaseMode;
5397  scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5398  pScriptRefs = orig->pScriptRefs;
5399 
5400  // free old midi rules
5401  for (int i = 0 ; pMidiRules[i] ; i++) {
5402  delete pMidiRules[i];
5403  }
5404  //TODO: MIDI rule copying
5405  pMidiRules[0] = NULL;
5406 
5407  // delete all old regions
5408  while (Regions) DeleteRegion(GetFirstRegion());
5409  // create new regions and copy them from original
5410  {
5411  RegionList::const_iterator it = orig->pRegions->begin();
5412  for (int i = 0; i < orig->Regions; ++i, ++it) {
5413  Region* dstRgn = AddRegion();
5414  //NOTE: Region does semi-deep copy !
5415  dstRgn->CopyAssign(
5416  static_cast<gig::Region*>(*it),
5417  mSamples
5418  );
5419  }
5420  }
5421 
5422  UpdateRegionKeyTable();
5423  }
5424 
5425 
5426 // *************** Group ***************
5427 // *
5428 
5435  Group::Group(File* file, RIFF::Chunk* ck3gnm) {
5436  pFile = file;
5437  pNameChunk = ck3gnm;
5438  ::LoadString(pNameChunk, Name);
5439  }
5440 
5446  }
5447 
5453  // handle own RIFF chunks
5454  if (pNameChunk) {
5455  pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
5456  pNameChunk = NULL;
5457  }
5458  }
5459 
5470  void Group::UpdateChunks(progress_t* pProgress) {
5471  // make sure <3gri> and <3gnl> list chunks exist
5472  RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
5473  if (!_3gri) {
5474  _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
5475  pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
5476  }
5477  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
5478  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
5479 
5480  if (!pNameChunk && pFile->pVersion && pFile->pVersion->major > 2) {
5481  // v3 has a fixed list of 128 strings, find a free one
5482  for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
5483  if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
5484  pNameChunk = ck;
5485  break;
5486  }
5487  }
5488  }
5489 
5490  // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
5491  ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
5492  }
5493 
5506  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5507  for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
5508  if (pSample->GetGroup() == this) return pSample;
5509  }
5510  return NULL;
5511  }
5512 
5524  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5525  for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
5526  if (pSample->GetGroup() == this) return pSample;
5527  }
5528  return NULL;
5529  }
5530 
5534  void Group::AddSample(Sample* pSample) {
5535  pSample->pGroup = this;
5536  }
5537 
5545  // get "that" other group first
5546  Group* pOtherGroup = NULL;
5547  for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
5548  if (pOtherGroup != this) break;
5549  }
5550  if (!pOtherGroup) throw Exception(
5551  "Could not move samples to another group, since there is no "
5552  "other Group. This is a bug, report it!"
5553  );
5554  // now move all samples of this group to the other group
5555  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
5556  pOtherGroup->AddSample(pSample);
5557  }
5558  }
5559 
5560 
5561 
5562 // *************** File ***************
5563 // *
5564 
5567  0, 2, 19980628 & 0xffff, 19980628 >> 16
5568  };
5569 
5572  0, 3, 20030331 & 0xffff, 20030331 >> 16
5573  };
5574 
5577  0, 4, 20071012 & 0xffff, 20071012 >> 16
5578  };
5579 
5580  static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
5581  { CHUNK_ID_IARL, 256 },
5582  { CHUNK_ID_IART, 128 },
5583  { CHUNK_ID_ICMS, 128 },
5584  { CHUNK_ID_ICMT, 1024 },
5585  { CHUNK_ID_ICOP, 128 },
5586  { CHUNK_ID_ICRD, 128 },
5587  { CHUNK_ID_IENG, 128 },
5588  { CHUNK_ID_IGNR, 128 },
5589  { CHUNK_ID_IKEY, 128 },
5590  { CHUNK_ID_IMED, 128 },
5591  { CHUNK_ID_INAM, 128 },
5592  { CHUNK_ID_IPRD, 128 },
5593  { CHUNK_ID_ISBJ, 128 },
5594  { CHUNK_ID_ISFT, 128 },
5595  { CHUNK_ID_ISRC, 128 },
5596  { CHUNK_ID_ISRF, 128 },
5597  { CHUNK_ID_ITCH, 128 },
5598  { 0, 0 }
5599  };
5600 
5601  File::File() : DLS::File() {
5602  bAutoLoad = true;
5603  *pVersion = VERSION_3;
5604  pGroups = NULL;
5605  pScriptGroups = NULL;
5606  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5607  pInfo->ArchivalLocation = String(256, ' ');
5608 
5609  // add some mandatory chunks to get the file chunks in right
5610  // order (INFO chunk will be moved to first position later)
5611  pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
5612  pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
5613  pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
5614 
5615  GenerateDLSID();
5616  }
5617 
5618  File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
5619  bAutoLoad = true;
5620  pGroups = NULL;
5621  pScriptGroups = NULL;
5622  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5623  }
5624 
5625  File::~File() {
5626  if (pGroups) {
5627  std::list<Group*>::iterator iter = pGroups->begin();
5628  std::list<Group*>::iterator end = pGroups->end();
5629  while (iter != end) {
5630  delete *iter;
5631  ++iter;
5632  }
5633  delete pGroups;
5634  }
5635  if (pScriptGroups) {
5636  std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
5637  std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
5638  while (iter != end) {
5639  delete *iter;
5640  ++iter;
5641  }
5642  delete pScriptGroups;
5643  }
5644  }
5645 
5647  if (!pSamples) LoadSamples(pProgress);
5648  if (!pSamples) return NULL;
5649  SamplesIterator = pSamples->begin();
5650  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5651  }
5652 
5654  if (!pSamples) return NULL;
5655  SamplesIterator++;
5656  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5657  }
5658 
5664  Sample* File::GetSample(uint index) {
5665  if (!pSamples) LoadSamples();
5666  if (!pSamples) return NULL;
5667  DLS::File::SampleList::iterator it = pSamples->begin();
5668  for (int i = 0; i < index; ++i) {
5669  ++it;
5670  if (it == pSamples->end()) return NULL;
5671  }
5672  if (it == pSamples->end()) return NULL;
5673  return static_cast<gig::Sample*>( *it );
5674  }
5675 
5685  if (!pSamples) LoadSamples();
5686  if (!pSamples) return 0;
5687  return pSamples->size();
5688  }
5689 
5698  if (!pSamples) LoadSamples();
5700  RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
5701  // create new Sample object and its respective 'wave' list chunk
5702  RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
5703  Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
5704 
5705  // add mandatory chunks to get the chunks in right order
5706  wave->AddSubChunk(CHUNK_ID_FMT, 16);
5707  wave->AddSubList(LIST_TYPE_INFO);
5708 
5709  pSamples->push_back(pSample);
5710  return pSample;
5711  }
5712 
5722  void File::DeleteSample(Sample* pSample) {
5723  if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
5724  SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
5725  if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
5726  if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
5727  pSamples->erase(iter);
5728  pSample->DeleteChunks();
5729  delete pSample;
5730 
5731  SampleList::iterator tmp = SamplesIterator;
5732  // remove all references to the sample
5733  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
5734  instrument = GetNextInstrument()) {
5735  for (Region* region = instrument->GetFirstRegion() ; region ;
5736  region = instrument->GetNextRegion()) {
5737 
5738  if (region->GetSample() == pSample) region->SetSample(NULL);
5739 
5740  for (int i = 0 ; i < region->DimensionRegions ; i++) {
5741  gig::DimensionRegion *d = region->pDimensionRegions[i];
5742  if (d->pSample == pSample) d->pSample = NULL;
5743  }
5744  }
5745  }
5746  SamplesIterator = tmp; // restore iterator
5747  }
5748 
5749  void File::LoadSamples() {
5750  LoadSamples(NULL);
5751  }
5752 
5753  void File::LoadSamples(progress_t* pProgress) {
5754  // Groups must be loaded before samples, because samples will try
5755  // to resolve the group they belong to
5756  if (!pGroups) LoadGroups();
5757 
5758  if (!pSamples) pSamples = new SampleList;
5759 
5760  RIFF::File* file = pRIFF;
5761 
5762  // just for progress calculation
5763  int iSampleIndex = 0;
5764  int iTotalSamples = WavePoolCount;
5765 
5766  // just for assembling path of optional extension files to be read
5767  const std::string folder = parentPath(pRIFF->GetFileName());
5768  const std::string baseName = pathWithoutExtension(pRIFF->GetFileName());
5769 
5770  // the main gig file and the extension files (.gx01, ... , .gx98) may
5771  // contain wave data (wave pool)
5772  std::vector<RIFF::File*> poolFiles;
5773  poolFiles.push_back(pRIFF);
5774 
5775  // get info about all extension files
5776  RIFF::Chunk* ckXfil = pRIFF->GetSubChunk(CHUNK_ID_XFIL);
5777  if (ckXfil) { // there are extension files (.gx01, ... , .gx98) ...
5778  const uint32_t n = ckXfil->ReadInt32();
5779  for (int i = 0; i < n; i++) {
5780  // read the filename and load the extension file
5781  std::string name;
5782  ckXfil->ReadString(name, 128);
5783  std::string path = concatPath(folder, name);
5784  RIFF::File* pExtFile = new RIFF::File(path);
5785  // check that the dlsids match
5786  RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
5787  if (ckDLSID) {
5788  ::DLS::dlsid_t idExpected;
5789  idExpected.ulData1 = ckXfil->ReadInt32();
5790  idExpected.usData2 = ckXfil->ReadInt16();
5791  idExpected.usData3 = ckXfil->ReadInt16();
5792  ckXfil->Read(idExpected.abData, 8, 1);
5793  ::DLS::dlsid_t idFound;
5794  ckDLSID->Read(&idFound.ulData1, 1, 4);
5795  ckDLSID->Read(&idFound.usData2, 1, 2);
5796  ckDLSID->Read(&idFound.usData3, 1, 2);
5797  ckDLSID->Read(idFound.abData, 8, 1);
5798  if (memcmp(&idExpected, &idFound, 16) != 0)
5799  throw gig::Exception("dlsid mismatch for extension file: %s", path.c_str());
5800  }
5801  poolFiles.push_back(pExtFile);
5802  ExtensionFiles.push_back(pExtFile);
5803  }
5804  }
5805 
5806  // check if a .gx99 (GigaPulse) file exists
5807  RIFF::Chunk* ckDoxf = pRIFF->GetSubChunk(CHUNK_ID_DOXF);
5808  if (ckDoxf) { // there is a .gx99 (GigaPulse) file ...
5809  std::string path = baseName + ".gx99";
5810  RIFF::File* pExtFile = new RIFF::File(path);
5811 
5812  // skip unused int and filename
5813  ckDoxf->SetPos(132, RIFF::stream_curpos);
5814 
5815  // check that the dlsids match
5816  RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
5817  if (ckDLSID) {
5818  ::DLS::dlsid_t idExpected;
5819  idExpected.ulData1 = ckDoxf->ReadInt32();
5820  idExpected.usData2 = ckDoxf->ReadInt16();
5821  idExpected.usData3 = ckDoxf->ReadInt16();
5822  ckDoxf->Read(idExpected.abData, 8, 1);
5823  ::DLS::dlsid_t idFound;
5824  ckDLSID->Read(&idFound.ulData1, 1, 4);
5825  ckDLSID->Read(&idFound.usData2, 1, 2);
5826  ckDLSID->Read(&idFound.usData3, 1, 2);
5827  ckDLSID->Read(idFound.abData, 8, 1);
5828  if (memcmp(&idExpected, &idFound, 16) != 0)
5829  throw gig::Exception("dlsid mismatch for GigaPulse file: %s", path.c_str());
5830  }
5831  poolFiles.push_back(pExtFile);
5832  ExtensionFiles.push_back(pExtFile);
5833  }
5834 
5835  // load samples from extension files (if required)
5836  for (int i = 0; i < poolFiles.size(); i++) {
5837  RIFF::File* file = poolFiles[i];
5838  RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
5839  if (wvpl) {
5840  file_offset_t wvplFileOffset = wvpl->GetFilePos() -
5841  wvpl->GetPos(); // should be zero, but just to be sure
5842  RIFF::List* wave = wvpl->GetFirstSubList();
5843  while (wave) {
5844  if (wave->GetListType() == LIST_TYPE_WAVE) {
5845  // notify current progress
5846  if (pProgress) {
5847  const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
5848  __notify_progress(pProgress, subprogress);
5849  }
5850 
5851  file_offset_t waveFileOffset = wave->GetFilePos();
5852  pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, i, iSampleIndex));
5853 
5854  iSampleIndex++;
5855  }
5856  wave = wvpl->GetNextSubList();
5857  }
5858  }
5859  }
5860 
5861  if (pProgress)
5862  __notify_progress(pProgress, 1.0); // notify done
5863  }
5864 
5866  if (!pInstruments) LoadInstruments();
5867  if (!pInstruments) return NULL;
5868  InstrumentsIterator = pInstruments->begin();
5869  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5870  }
5871 
5873  if (!pInstruments) return NULL;
5874  InstrumentsIterator++;
5875  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5876  }
5877 
5887  if (!pInstruments) LoadInstruments();
5888  if (!pInstruments) return 0;
5889  return pInstruments->size();
5890  }
5891 
5899  Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
5900  if (!pInstruments) {
5901  // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
5902 
5903  if (pProgress) {
5904  // sample loading subtask
5905  progress_t subprogress;
5906  __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
5907  __notify_progress(&subprogress, 0.0f);
5908  if (GetAutoLoad())
5909  GetFirstSample(&subprogress); // now force all samples to be loaded
5910  __notify_progress(&subprogress, 1.0f);
5911 
5912  // instrument loading subtask
5913  if (pProgress->callback) {
5914  subprogress.__range_min = subprogress.__range_max;
5915  subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
5916  }
5917  __notify_progress(&subprogress, 0.0f);
5918  LoadInstruments(&subprogress);
5919  __notify_progress(&subprogress, 1.0f);
5920  } else {
5921  // sample loading subtask
5922  if (GetAutoLoad())
5923  GetFirstSample(); // now force all samples to be loaded
5924 
5925  // instrument loading subtask
5926  LoadInstruments();
5927  }
5928  }
5929  if (!pInstruments) return NULL;
5930  InstrumentsIterator = pInstruments->begin();
5931  for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
5932  if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
5933  InstrumentsIterator++;
5934  }
5935  return NULL;
5936  }
5937 
5946  if (!pInstruments) LoadInstruments();
5948  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
5949  RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
5950 
5951  // add mandatory chunks to get the chunks in right order
5952  lstInstr->AddSubList(LIST_TYPE_INFO);
5953  lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
5954 
5955  Instrument* pInstrument = new Instrument(this, lstInstr);
5956  pInstrument->GenerateDLSID();
5957 
5958  lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
5959 
5960  // this string is needed for the gig to be loadable in GSt:
5961  pInstrument->pInfo->Software = "Endless Wave";
5962 
5963  pInstruments->push_back(pInstrument);
5964  return pInstrument;
5965  }
5966 
5983  Instrument* instr = AddInstrument();
5984  instr->CopyAssign(orig);
5985  return instr;
5986  }
5987 
5999  void File::AddContentOf(File* pFile) {
6000  static int iCallCount = -1;
6001  iCallCount++;
6002  std::map<Group*,Group*> mGroups;
6003  std::map<Sample*,Sample*> mSamples;
6004 
6005  // clone sample groups
6006  for (int i = 0; pFile->GetGroup(i); ++i) {
6007  Group* g = AddGroup();
6008  g->Name =
6009  "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
6010  mGroups[pFile->GetGroup(i)] = g;
6011  }
6012 
6013  // clone samples (not waveform data here yet)
6014  for (int i = 0; pFile->GetSample(i); ++i) {
6015  Sample* s = AddSample();
6016  s->CopyAssignMeta(pFile->GetSample(i));
6017  mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
6018  mSamples[pFile->GetSample(i)] = s;
6019  }
6020 
6021  // clone script groups and their scripts
6022  for (int iGroup = 0; pFile->GetScriptGroup(iGroup); ++iGroup) {
6023  ScriptGroup* sg = pFile->GetScriptGroup(iGroup);
6024  ScriptGroup* dg = AddScriptGroup();
6025  dg->Name = "COPY" + ToString(iCallCount) + "_" + sg->Name;
6026  for (int iScript = 0; sg->GetScript(iScript); ++iScript) {
6027  Script* ss = sg->GetScript(iScript);
6028  Script* ds = dg->AddScript();
6029  ds->CopyAssign(ss);
6030  }
6031  }
6032 
6033  //BUG: For some reason this method only works with this additional
6034  // Save() call in between here.
6035  //
6036  // Important: The correct one of the 2 Save() methods has to be called
6037  // here, depending on whether the file is completely new or has been
6038  // saved to disk already, otherwise it will result in data corruption.
6039  if (pRIFF->IsNew())
6040  Save(GetFileName());
6041  else
6042  Save();
6043 
6044  // clone instruments
6045  // (passing the crosslink table here for the cloned samples)
6046  for (int i = 0; pFile->GetInstrument(i); ++i) {
6047  Instrument* instr = AddInstrument();
6048  instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
6049  }
6050 
6051  // Mandatory: file needs to be saved to disk at this point, so this
6052  // file has the correct size and data layout for writing the samples'
6053  // waveform data to disk.
6054  Save();
6055 
6056  // clone samples' waveform data
6057  // (using direct read & write disk streaming)
6058  for (int i = 0; pFile->GetSample(i); ++i) {
6059  mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
6060  }
6061  }
6062 
6071  void File::DeleteInstrument(Instrument* pInstrument) {
6072  if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
6073  InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
6074  if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
6075  pInstruments->erase(iter);
6076  pInstrument->DeleteChunks();
6077  delete pInstrument;
6078  }
6079 
6080  void File::LoadInstruments() {
6081  LoadInstruments(NULL);
6082  }
6083 
6084  void File::LoadInstruments(progress_t* pProgress) {
6085  if (!pInstruments) pInstruments = new InstrumentList;
6086  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
6087  if (lstInstruments) {
6088  int iInstrumentIndex = 0;
6089  RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
6090  while (lstInstr) {
6091  if (lstInstr->GetListType() == LIST_TYPE_INS) {
6092  if (pProgress) {
6093  // notify current progress
6094  const float localProgress = (float) iInstrumentIndex / (float) Instruments;
6095  __notify_progress(pProgress, localProgress);
6096 
6097  // divide local progress into subprogress for loading current Instrument
6098  progress_t subprogress;
6099  __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
6100 
6101  pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
6102  } else {
6103  pInstruments->push_back(new Instrument(this, lstInstr));
6104  }
6105 
6106  iInstrumentIndex++;
6107  }
6108  lstInstr = lstInstruments->GetNextSubList();
6109  }
6110  if (pProgress)
6111  __notify_progress(pProgress, 1.0); // notify done
6112  }
6113  }
6114 
6118  void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
6119  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6120  if (!_3crc) return;
6121 
6122  // get the index of the sample
6123  int iWaveIndex = GetWaveTableIndexOf(pSample);
6124  if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
6125 
6126  // write the CRC-32 checksum to disk
6127  _3crc->SetPos(iWaveIndex * 8);
6128  uint32_t one = 1;
6129  _3crc->WriteUint32(&one); // always 1
6130  _3crc->WriteUint32(&crc);
6131  }
6132 
6133  uint32_t File::GetSampleChecksum(Sample* pSample) {
6134  // get the index of the sample
6135  int iWaveIndex = GetWaveTableIndexOf(pSample);
6136  if (iWaveIndex < 0) throw gig::Exception("Could not retrieve reference crc of sample, could not resolve sample's wave table index");
6137 
6138  return GetSampleChecksumByIndex(iWaveIndex);
6139  }
6140 
6141  uint32_t File::GetSampleChecksumByIndex(int index) {
6142  if (index < 0) throw gig::Exception("Could not retrieve reference crc of sample, invalid wave pool index of sample");
6143 
6144  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6145  if (!_3crc) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6146  uint8_t* pData = (uint8_t*) _3crc->LoadChunkData();
6147  if (!pData) throw gig::Exception("Could not retrieve reference crc of sample, no checksums stored for this file yet");
6148 
6149  // read the CRC-32 checksum directly from disk
6150  size_t pos = index * 8;
6151  if (pos + 8 > _3crc->GetNewSize())
6152  throw gig::Exception("Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
6153 
6154  uint32_t one = load32(&pData[pos]); // always 1
6155  if (one != 1)
6156  throw gig::Exception("Could not retrieve reference crc of sample, because reference checksum table is damaged");
6157 
6158  return load32(&pData[pos+4]);
6159  }
6160 
6161  int File::GetWaveTableIndexOf(gig::Sample* pSample) {
6162  if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
6163  File::SampleList::iterator iter = pSamples->begin();
6164  File::SampleList::iterator end = pSamples->end();
6165  for (int index = 0; iter != end; ++iter, ++index)
6166  if (*iter == pSample)
6167  return index;
6168  return -1;
6169  }
6170 
6178  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6179  if (!_3crc) return false;
6180  if (_3crc->GetNewSize() <= 0) return false;
6181  if (_3crc->GetNewSize() % 8) return false;
6182  if (!pSamples) GetFirstSample(); // make sure sample chunks were scanned
6183  if (_3crc->GetNewSize() != pSamples->size() * 8) return false;
6184 
6185  const file_offset_t n = _3crc->GetNewSize() / 8;
6186 
6187  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6188  if (!pData) return false;
6189 
6190  for (file_offset_t i = 0; i < n; ++i) {
6191  uint32_t one = pData[i*2];
6192  if (one != 1) return false;
6193  }
6194 
6195  return true;
6196  }
6197 
6215  // make sure sample chunks were scanned
6216  if (!pSamples) GetFirstSample();
6217 
6218  bool bRequiresSave = false;
6219 
6220  // make sure "3CRC" chunk exists with required size
6221  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6222  if (!_3crc) {
6223  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6224  // the order of einf and 3crc is not the same in v2 and v3
6225  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6226  if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
6227  bRequiresSave = true;
6228  } else if (_3crc->GetNewSize() != pSamples->size() * 8) {
6229  _3crc->Resize(pSamples->size() * 8);
6230  bRequiresSave = true;
6231  }
6232 
6233  if (bRequiresSave) { // refill CRC table for all samples in RAM ...
6234  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6235  {
6236  File::SampleList::iterator iter = pSamples->begin();
6237  File::SampleList::iterator end = pSamples->end();
6238  for (; iter != end; ++iter) {
6239  gig::Sample* pSample = (gig::Sample*) *iter;
6240  int index = GetWaveTableIndexOf(pSample);
6241  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6242  pData[index*2] = 1; // always 1
6243  pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6244  }
6245  }
6246  } else { // no file structure changes necessary, so directly write to disk and we are done ...
6247  // make sure file is in write mode
6248  pRIFF->SetMode(RIFF::stream_mode_read_write);
6249  {
6250  File::SampleList::iterator iter = pSamples->begin();
6251  File::SampleList::iterator end = pSamples->end();
6252  for (; iter != end; ++iter) {
6253  gig::Sample* pSample = (gig::Sample*) *iter;
6254  int index = GetWaveTableIndexOf(pSample);
6255  if (index < 0) throw gig::Exception("Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6256  pSample->crc = pSample->CalculateWaveDataChecksum();
6257  SetSampleChecksum(pSample, pSample->crc);
6258  }
6259  }
6260  }
6261 
6262  return bRequiresSave;
6263  }
6264 
6266  if (!pGroups) LoadGroups();
6267  // there must always be at least one group
6268  GroupsIterator = pGroups->begin();
6269  return *GroupsIterator;
6270  }
6271 
6273  if (!pGroups) return NULL;
6274  ++GroupsIterator;
6275  return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6276  }
6277 
6284  Group* File::GetGroup(uint index) {
6285  if (!pGroups) LoadGroups();
6286  GroupsIterator = pGroups->begin();
6287  for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
6288  if (i == index) return *GroupsIterator;
6289  ++GroupsIterator;
6290  }
6291  return NULL;
6292  }
6293 
6304  Group* File::GetGroup(String name) {
6305  if (!pGroups) LoadGroups();
6306  GroupsIterator = pGroups->begin();
6307  for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
6308  if ((*GroupsIterator)->Name == name) return *GroupsIterator;
6309  return NULL;
6310  }
6311 
6312  Group* File::AddGroup() {
6313  if (!pGroups) LoadGroups();
6314  // there must always be at least one group
6316  Group* pGroup = new Group(this, NULL);
6317  pGroups->push_back(pGroup);
6318  return pGroup;
6319  }
6320 
6330  void File::DeleteGroup(Group* pGroup) {
6331  if (!pGroups) LoadGroups();
6332  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6333  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6334  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6335  // delete all members of this group
6336  for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
6337  DeleteSample(pSample);
6338  }
6339  // now delete this group object
6340  pGroups->erase(iter);
6341  pGroup->DeleteChunks();
6342  delete pGroup;
6343  }
6344 
6356  if (!pGroups) LoadGroups();
6357  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6358  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
6359  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
6360  // move all members of this group to another group
6361  pGroup->MoveAll();
6362  pGroups->erase(iter);
6363  pGroup->DeleteChunks();
6364  delete pGroup;
6365  }
6366 
6367  void File::LoadGroups() {
6368  if (!pGroups) pGroups = new std::list<Group*>;
6369  // try to read defined groups from file
6370  RIFF::List* lst3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
6371  if (lst3gri) {
6372  RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
6373  if (lst3gnl) {
6374  RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
6375  while (ck) {
6376  if (ck->GetChunkID() == CHUNK_ID_3GNM) {
6377  if (pVersion && pVersion->major > 2 &&
6378  strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
6379 
6380  pGroups->push_back(new Group(this, ck));
6381  }
6382  ck = lst3gnl->GetNextSubChunk();
6383  }
6384  }
6385  }
6386  // if there were no group(s), create at least the mandatory default group
6387  if (!pGroups->size()) {
6388  Group* pGroup = new Group(this, NULL);
6389  pGroup->Name = "Default Group";
6390  pGroups->push_back(pGroup);
6391  }
6392  }
6393 
6402  if (!pScriptGroups) LoadScriptGroups();
6403  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6404  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6405  if (i == index) return *it;
6406  return NULL;
6407  }
6408 
6417  ScriptGroup* File::GetScriptGroup(const String& name) {
6418  if (!pScriptGroups) LoadScriptGroups();
6419  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6420  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6421  if ((*it)->Name == name) return *it;
6422  return NULL;
6423  }
6424 
6434  if (!pScriptGroups) LoadScriptGroups();
6435  ScriptGroup* pScriptGroup = new ScriptGroup(this, NULL);
6436  pScriptGroups->push_back(pScriptGroup);
6437  return pScriptGroup;
6438  }
6439 
6452  void File::DeleteScriptGroup(ScriptGroup* pScriptGroup) {
6453  if (!pScriptGroups) LoadScriptGroups();
6454  std::list<ScriptGroup*>::iterator iter =
6455  find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
6456  if (iter == pScriptGroups->end())
6457  throw gig::Exception("Could not delete script group, could not find given script group");
6458  pScriptGroups->erase(iter);
6459  for (int i = 0; pScriptGroup->GetScript(i); ++i)
6460  pScriptGroup->DeleteScript(pScriptGroup->GetScript(i));
6461  if (pScriptGroup->pList)
6462  pScriptGroup->pList->GetParent()->DeleteSubChunk(pScriptGroup->pList);
6463  pScriptGroup->DeleteChunks();
6464  delete pScriptGroup;
6465  }
6466 
6467  void File::LoadScriptGroups() {
6468  if (pScriptGroups) return;
6469  pScriptGroups = new std::list<ScriptGroup*>;
6470  RIFF::List* lstLS = pRIFF->GetSubList(LIST_TYPE_3LS);
6471  if (lstLS) {
6472  for (RIFF::List* lst = lstLS->GetFirstSubList(); lst;
6473  lst = lstLS->GetNextSubList())
6474  {
6475  if (lst->GetListType() == LIST_TYPE_RTIS) {
6476  pScriptGroups->push_back(new ScriptGroup(this, lst));
6477  }
6478  }
6479  }
6480  }
6481 
6493  void File::UpdateChunks(progress_t* pProgress) {
6494  bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
6495 
6496  // update own gig format extension chunks
6497  // (not part of the GigaStudio 4 format)
6498  RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);
6499  if (!lst3LS) {
6500  lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
6501  }
6502  // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
6503  // location of <3LS > is irrelevant, however it should be located
6504  // before the actual wave data
6505  RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
6506  pRIFF->MoveSubChunk(lst3LS, ckPTBL);
6507 
6508  // This must be performed before writing the chunks for instruments,
6509  // because the instruments' script slots will write the file offsets
6510  // of the respective instrument script chunk as reference.
6511  if (pScriptGroups) {
6512  // Update instrument script (group) chunks.
6513  for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6514  it != pScriptGroups->end(); ++it)
6515  {
6516  (*it)->UpdateChunks(pProgress);
6517  }
6518  }
6519 
6520  // in case no libgig custom format data was added, then remove the
6521  // custom "3LS " chunk again
6522  if (!lst3LS->CountSubChunks()) {
6523  pRIFF->DeleteSubChunk(lst3LS);
6524  lst3LS = NULL;
6525  }
6526 
6527  // first update base class's chunks
6528  DLS::File::UpdateChunks(pProgress);
6529 
6530  if (newFile) {
6531  // INFO was added by Resource::UpdateChunks - make sure it
6532  // is placed first in file
6533  RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO);
6534  RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
6535  if (first != info) {
6536  pRIFF->MoveSubChunk(info, first);
6537  }
6538  }
6539 
6540  // update group's chunks
6541  if (pGroups) {
6542  // make sure '3gri' and '3gnl' list chunks exist
6543  // (before updating the Group chunks)
6544  RIFF::List* _3gri = pRIFF->GetSubList(LIST_TYPE_3GRI);
6545  if (!_3gri) {
6546  _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
6547  pRIFF->MoveSubChunk(_3gri, pRIFF->GetSubChunk(CHUNK_ID_PTBL));
6548  }
6549  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
6550  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
6551 
6552  // v3: make sure the file has 128 3gnm chunks
6553  // (before updating the Group chunks)
6554  if (pVersion && pVersion->major > 2) {
6555  RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
6556  for (int i = 0 ; i < 128 ; i++) {
6557  if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
6558  if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
6559  }
6560  }
6561 
6562  std::list<Group*>::iterator iter = pGroups->begin();
6563  std::list<Group*>::iterator end = pGroups->end();
6564  for (; iter != end; ++iter) {
6565  (*iter)->UpdateChunks(pProgress);
6566  }
6567  }
6568 
6569  // update einf chunk
6570 
6571  // The einf chunk contains statistics about the gig file, such
6572  // as the number of regions and samples used by each
6573  // instrument. It is divided in equally sized parts, where the
6574  // first part contains information about the whole gig file,
6575  // and the rest of the parts map to each instrument in the
6576  // file.
6577  //
6578  // At the end of each part there is a bit map of each sample
6579  // in the file, where a set bit means that the sample is used
6580  // by the file/instrument.
6581  //
6582  // Note that there are several fields with unknown use. These
6583  // are set to zero.
6584 
6585  int sublen = int(pSamples->size() / 8 + 49);
6586  int einfSize = (Instruments + 1) * sublen;
6587 
6588  RIFF::Chunk* einf = pRIFF->GetSubChunk(CHUNK_ID_EINF);
6589  if (einf) {
6590  if (einf->GetSize() != einfSize) {
6591  einf->Resize(einfSize);
6592  memset(einf->LoadChunkData(), 0, einfSize);
6593  }
6594  } else if (newFile) {
6595  einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
6596  }
6597  if (einf) {
6598  uint8_t* pData = (uint8_t*) einf->LoadChunkData();
6599 
6600  std::map<gig::Sample*,int> sampleMap;
6601  int sampleIdx = 0;
6602  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
6603  sampleMap[pSample] = sampleIdx++;
6604  }
6605 
6606  int totnbusedsamples = 0;
6607  int totnbusedchannels = 0;
6608  int totnbregions = 0;
6609  int totnbdimregions = 0;
6610  int totnbloops = 0;
6611  int instrumentIdx = 0;
6612 
6613  memset(&pData[48], 0, sublen - 48);
6614 
6615  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
6616  instrument = GetNextInstrument()) {
6617  int nbusedsamples = 0;
6618  int nbusedchannels = 0;
6619  int nbdimregions = 0;
6620  int nbloops = 0;
6621 
6622  memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
6623 
6624  for (Region* region = instrument->GetFirstRegion() ; region ;
6625  region = instrument->GetNextRegion()) {
6626  for (int i = 0 ; i < region->DimensionRegions ; i++) {
6627  gig::DimensionRegion *d = region->pDimensionRegions[i];
6628  if (d->pSample) {
6629  int sampleIdx = sampleMap[d->pSample];
6630  int byte = 48 + sampleIdx / 8;
6631  int bit = 1 << (sampleIdx & 7);
6632  if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
6633  pData[(instrumentIdx + 1) * sublen + byte] |= bit;
6634  nbusedsamples++;
6635  nbusedchannels += d->pSample->Channels;
6636 
6637  if ((pData[byte] & bit) == 0) {
6638  pData[byte] |= bit;
6639  totnbusedsamples++;
6640  totnbusedchannels += d->pSample->Channels;
6641  }
6642  }
6643  }
6644  if (d->SampleLoops) nbloops++;
6645  }
6646  nbdimregions += region->DimensionRegions;
6647  }
6648  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6649  // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
6650  store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
6651  store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
6652  store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
6653  store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
6654  store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
6655  store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
6656  // next 8 bytes unknown
6657  store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
6658  store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
6659  // next 4 bytes unknown
6660 
6661  totnbregions += instrument->Regions;
6662  totnbdimregions += nbdimregions;
6663  totnbloops += nbloops;
6664  instrumentIdx++;
6665  }
6666  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6667  // store32(&pData[0], sublen);
6668  store32(&pData[4], totnbusedchannels);
6669  store32(&pData[8], totnbusedsamples);
6670  store32(&pData[12], Instruments);
6671  store32(&pData[16], totnbregions);
6672  store32(&pData[20], totnbdimregions);
6673  store32(&pData[24], totnbloops);
6674  // next 8 bytes unknown
6675  // next 4 bytes unknown, not always 0
6676  store32(&pData[40], (uint32_t) pSamples->size());
6677  // next 4 bytes unknown
6678  }
6679 
6680  // update 3crc chunk
6681 
6682  // The 3crc chunk contains CRC-32 checksums for the
6683  // samples. When saving a gig file to disk, we first update the 3CRC
6684  // chunk here (in RAM) with the old crc values which we read from the
6685  // 3CRC chunk when we opened the file (available with gig::Sample::crc
6686  // member variable). This step is required, because samples might have
6687  // been deleted by the user since the file was opened, which in turn
6688  // changes the order of the (i.e. old) checksums within the 3crc chunk.
6689  // If a sample was conciously modified by the user (that is if
6690  // Sample::Write() was called later on) then Sample::Write() will just
6691  // update the respective individual checksum(s) directly on disk and
6692  // leaves all other sample checksums untouched.
6693 
6694  RIFF::Chunk* _3crc = pRIFF->GetSubChunk(CHUNK_ID_3CRC);
6695  if (_3crc) {
6696  _3crc->Resize(pSamples->size() * 8);
6697  } else /*if (newFile)*/ {
6698  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6699  // the order of einf and 3crc is not the same in v2 and v3
6700  if (einf && pVersion && pVersion->major > 2) pRIFF->MoveSubChunk(_3crc, einf);
6701  }
6702  { // must be performed in RAM here ...
6703  uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6704  if (pData) {
6705  File::SampleList::iterator iter = pSamples->begin();
6706  File::SampleList::iterator end = pSamples->end();
6707  for (int index = 0; iter != end; ++iter, ++index) {
6708  gig::Sample* pSample = (gig::Sample*) *iter;
6709  pData[index*2] = 1; // always 1
6710  pData[index*2+1] = pSample->crc;
6711  }
6712  }
6713  }
6714  }
6715 
6718 
6719  for (Instrument* instrument = GetFirstInstrument(); instrument;
6720  instrument = GetNextInstrument())
6721  {
6722  instrument->UpdateScriptFileOffsets();
6723  }
6724  }
6725 
6741  void File::SetAutoLoad(bool b) {
6742  bAutoLoad = b;
6743  }
6744 
6750  return bAutoLoad;
6751  }
6752 
6753 
6754 
6755 // *************** Exception ***************
6756 // *
6757 
6758  Exception::Exception() : DLS::Exception() {
6759  }
6760 
6761  Exception::Exception(String format, ...) : DLS::Exception() {
6762  va_list arg;
6763  va_start(arg, format);
6764  Message = assemble(format, arg);
6765  va_end(arg);
6766  }
6767 
6768  Exception::Exception(String format, va_list arg) : DLS::Exception() {
6769  Message = assemble(format, arg);
6770  }
6771 
6772  void Exception::PrintMessage() {
6773  std::cout << "gig::Exception: " << Message << std::endl;
6774  }
6775 
6776 
6777 // *************** functions ***************
6778 // *
6779 
6785  String libraryName() {
6786  return PACKAGE;
6787  }
6788 
6793  String libraryVersion() {
6794  return VERSION;
6795  }
6796 
6797 } // namespace gig
gig::Sample::~Sample
~Sample()
Destructor.
Definition: gig.cpp:1477
gig::DimensionRegion::InvertAttenuationController
bool InvertAttenuationController
Inverts the values coming from the defined Attenuation Controller.
Definition: gig.h:569
gig::Region::SetDimensionType
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
Definition: gig.cpp:3970
gig::Sample::Write
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
Definition: gig.cpp:1329
gig::DimensionRegion::EG2Decay1
double EG2Decay1
Decay time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:517
gig::Instrument
Provides access to a Gigasampler/GigaStudio instrument.
Definition: gig.h:1209
RIFF::List::GetNextSubChunk
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk).
Definition: RIFF.cpp:1211
gig::crossfade_t::in_start
uint8_t in_start
Start position of fade in.
Definition: gig.h:367
RIFF::List::CountSubChunks
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Definition: RIFF.cpp:1269
gig::Script::Encoding_t
Encoding_t
Definition: gig.h:1126
gig::Instrument::AddScriptSlot
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
Definition: gig.cpp:5240
gig::MidiRuleAlternator::Articulations
uint8_t Articulations
Number of articulations in the instrument.
Definition: gig.h:1046
gig::Sample::SamplesInLastFrame
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
Definition: gig.h:812
gig::Sample::CopyAssignWave
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
Definition: gig.cpp:546
gig::Sample::GetWaveDataCRC32Checksum
uint32_t GetWaveDataCRC32Checksum()
Returns the CRC-32 checksum of the sample's raw wave form data at the time when this sample's wave fo...
Definition: gig.cpp:1423
gig::lfo2_ctrl_internal
@ lfo2_ctrl_internal
Only internally controlled.
Definition: gig.h:183
gig::Script::Encoding
Encoding_t Encoding
Format the script's source code text is encoded with.
Definition: gig.h:1138
gig::DimensionRegion::LFO2ControlDepth
uint16_t LFO2ControlDepth
Controller depth influencing filter cutoff LFO pitch (0 - 1200).
Definition: gig.h:529
gig::Instrument::GetNextRegion
Region * GetNextRegion()
Returns the next Region of the instrument.
Definition: gig.cpp:5007
gig::DimensionRegion::EG3Depth
int16_t EG3Depth
Depth of the sample pitch EG (-1200 - +1200).
Definition: gig.h:535
gig::File::DeleteScriptGroup
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Definition: gig.cpp:6452
DLS::Sample::DeleteChunks
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sample object.
Definition: DLS.cpp:838
gig::MidiRuleCtrlTrigger::Triggers
uint8_t Triggers
Number of triggers.
Definition: gig.h:974
RIFF::File::GetCurrentFileSize
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:2213
gig::Script::GetGroup
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
Definition: gig.cpp:4555
gig::Instrument::SetScriptSlotBypassed
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
Definition: gig.cpp:5356
gig::Group::DeleteChunks
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Group object.
Definition: gig.cpp:5452
gig::DimensionRegion::EG2ControllerReleaseInfluence
uint8_t EG2ControllerReleaseInfluence
Amount EG2 Controller has influence on the EG2 Release time (0 - 3, where 0 means off).
Definition: gig.h:526
DLS::Instrument::DeleteChunks
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Instrument object.
Definition: DLS.cpp:1481
gig::Instrument::~Instrument
~Instrument()
Destructor.
Definition: gig.cpp:4845
DLS::File::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file's current instruments, samples and settings to the respective RIFF chunks.
Definition: DLS.cpp:1861
gig::Sample::Loops
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
Definition: gig.h:770
gig::Region::pDimensionDefinitions
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension's controller and number of...
Definition: gig.h:877
gig::Sample::LoopEnd
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:774
gig::dimension_releasetrigger
@ dimension_releasetrigger
Special dimension for triggering samples on releasing a key.
Definition: gig.h:319
gig::Script::DeleteChunks
void DeleteChunks()
Remove all RIFF chunks associated with this Script object.
Definition: gig.cpp:4492
gig::Region::DeleteDimensionZone
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
Definition: gig.cpp:3705
gig::DimensionRegion::SetVelocityResponseCurveScaling
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3098
DLS::version_t
Quadtuple version number ("major.minor.release.build").
Definition: DLS.h:115
gig::DimensionRegion::SelfMask
bool SelfMask
If true: high velocity notes will stop low velocity notes at the same note, with that you can save vo...
Definition: gig.h:567
gig::smpte_format_no_offset
@ smpte_format_no_offset
no SMPTE offset
Definition: gig.h:138
DLS::Sample::Channels
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:459
gig::DimensionRegion::EG2ControllerAttackInfluence
uint8_t EG2ControllerAttackInfluence
Amount EG2 Controller has influence on the EG2 Attack time (0 - 3, where 0 means off).
Definition: gig.h:524
gig::Region::GetSample
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
Definition: gig.cpp:4169
DLS::Sampler::Gain
int32_t Gain
Definition: DLS.h:428
gig
Gigasampler/GigaStudio specific classes and definitions.
Definition: gig.h:94
gig::ScriptGroup
Group of instrument scripts (gig format extension).
Definition: gig.h:1173
DLS::Sample
Encapsulates sample waves used for playback.
Definition: DLS.h:456
gig::Sample::MIDIUnityNote
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it's original sample rate.
Definition: gig.h:766
gig::Sample::FineTune
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Definition: gig.h:767
gig::playback_state_t
Reflects the current playback state for a sample.
Definition: gig.h:377
gig::vcf_type_lowpass
@ vcf_type_lowpass
Standard lowpass filter type.
Definition: gig.h:351
gig::leverage_ctrl_t::type_velocity
@ type_velocity
Key Velocity.
Definition: gig.h:246
gig::DimensionRegion::AttenuationControllerThreshold
uint8_t AttenuationControllerThreshold
0-127
Definition: gig.h:570
gig::loop_type_normal
@ loop_type_normal
Loop forward (normal)
Definition: gig.h:126
gig::DimensionRegion::EG1InfiniteSustain
bool EG1InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released.
Definition: gig.h:499
gig::buffer_t::Size
file_offset_t Size
Size of the actual data in the buffer in bytes.
Definition: gig.h:109
gig::DimensionRegion::LFO3InternalDepth
int16_t LFO3InternalDepth
Firm depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:537
gig::Script::Bypass
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument.
Definition: gig.h:1140
gig::MidiRuleAlternator::PlayRange
range_t PlayRange
Key range of the playable keys in the instrument.
Definition: gig.h:1049
gig::DimensionRegion::EG2Controller
eg2_ctrl_t EG2Controller
MIDI Controller which has influence on filter cutoff EG parameters (attack, decay,...
Definition: gig.h:522
gig::curve_type_t
curve_type_t
Defines the shape of a function graph.
Definition: gig.h:149
gig::DimensionRegion::LFO3Frequency
double LFO3Frequency
Frequency of the sample pitch LFO (0.10 - 10.00 Hz).
Definition: gig.h:536
gig::DimensionRegion::LFO3Sync
bool LFO3Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:540
gig::DimensionRegion::PitchTrack
bool PitchTrack
If true: sample will be pitched according to the key position (this will be disabled for drums for ex...
Definition: gig.h:564
gig::DimensionRegion::LFO1InternalDepth
uint16_t LFO1InternalDepth
Firm pitch of the sample amplitude LFO (0 - 1200 cents).
Definition: gig.h:509
gig::DimensionRegion::EG2Release
double EG2Release
Release time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:521
DLS::Region::CopyAssign
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:1288
gig::Instrument::PitchbendRange
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Definition: gig.h:1225
RIFF::List
RIFF List Chunk.
Definition: RIFF.h:308
gig::DimensionRegion::VCFKeyboardTrackingBreakpoint
uint8_t VCFKeyboardTrackingBreakpoint
See VCFKeyboardTracking (0 - 127).
Definition: gig.h:554
gig::lfo3_ctrl_modwheel
@ lfo3_ctrl_modwheel
Only controlled by external modulation wheel.
Definition: gig.h:171
gig::split_type_bit
@ split_type_bit
dimension values are already the sought bit number
Definition: gig.h:330
RIFF::Chunk::Write
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:465
gig::DimensionRegion::EG1Sustain
uint16_t EG1Sustain
Sustain value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:500
gig::File
Provides convenient access to Gigasampler/GigaStudio .gig files.
Definition: gig.h:1347
RIFF::List::GetFirstSubList
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
Definition: RIFF.cpp:1229
gig::Sample::FrameTable
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame.
Definition: gig.h:810
gig::Instrument::RegionKeyTable
Region * RegionKeyTable[128]
fast lookup for the corresponding Region of a MIDI key
Definition: gig.h:1257
RIFF::File::IsNew
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:2191
gig::Script::Language_t
Language_t
Definition: gig.h:1132
RIFF::Chunk::ReadInt32
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:686
gig::DimensionRegion::EG2PreAttack
uint16_t EG2PreAttack
Preattack value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:515
DLS::Sample::CopyAssignCore
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:861
RIFF::List::GetNextSubList
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Definition: RIFF.cpp:1251
gig::dimension_def_t::bits
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...
Definition: gig.h:335
gig::DimensionRegion::EG2InfiniteSustain
bool EG2InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released.
Definition: gig.h:519
gig::lfo3_ctrl_t
lfo3_ctrl_t
Defines how LFO3 is controlled by.
Definition: gig.h:171
gig::File::AddInstrument
Instrument * AddInstrument()
Add a new instrument definition.
Definition: gig.cpp:5945
gig::Exception
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File.
Definition: gig.h:1435
gig::Script::GetScriptAsText
String GetScriptAsText()
Returns the current script (i.e.
Definition: gig.cpp:4465
gig::Sample::SetPos
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
DLS::File::__ensureMandatoryChunksExist
void __ensureMandatoryChunksExist()
Checks if all (for DLS) mandatory chunks exist, if not they will be created.
Definition: DLS.cpp:2234
RIFF::List::AddSubChunk
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Definition: RIFF.cpp:1331
RIFF::progress_t
Used for indicating the progress of a certain task.
Definition: RIFF.h:216
RIFF::Chunk::Read
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:395
gig::Group::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
Definition: gig.cpp:5470
gig::vcf_res_ctrl_none
@ vcf_res_ctrl_none
No MIDI controller assigned for filter resonance.
Definition: gig.h:226
gig::DimensionRegion::EG1ControllerInvert
bool EG1ControllerInvert
Invert values coming from defined EG1 controller.
Definition: gig.h:504
gig::Instrument::GetRegion
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
Definition: gig.cpp:4975
gig::dimension_roundrobinkeyboard
@ dimension_roundrobinkeyboard
Different samples triggered each time a note is played, any key advances the counter.
Definition: gig.h:319
gig::MidiRuleLegato::AltSustain2Key
uint8_t AltSustain2Key
Key triggering a second set of alternate sustain samples.
Definition: gig.h:1023
gig::DimensionRegion::EG2Attack
double EG2Attack
Attack time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:516
gig::DimensionRegion::LFO1Frequency
double LFO1Frequency
Frequency of the sample amplitude LFO (0.10 - 10.00 Hz).
Definition: gig.h:508
gig::dimension_def_t
General dimension definition.
Definition: gig.h:333
gig::dimension_def_t::split_type
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:337
gig::File::CountInstruments
size_t CountInstruments()
Returns the total amount of instruments of this gig file.
Definition: gig.cpp:5886
gig::leverage_ctrl_t::type
type_t type
Controller type.
Definition: gig.h:248
DLS::sample_loop_t
Defines Sample Loop Points.
Definition: DLS.h:235
gig::DimensionRegion::SustainReleaseTrigger
sust_rel_trg_t SustainReleaseTrigger
[gig extension]: Whether a sustain pedal up event shall play release trigger sample.
Definition: gig.h:579
DLS::File::GetFirstSample
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: DLS.cpp:1663
gig::Instrument::AddMidiRuleAlternator
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
Definition: gig.cpp:5136
DLS::Instrument
Provides all neccessary information for the synthesis of a DLS Instrument.
Definition: DLS.h:523
gig::ScriptGroup::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Definition: gig.cpp:4631
RIFF::List::MoveSubChunk
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
Definition: RIFF.cpp:1353
gig::Instrument::DeleteMidiRule
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
Definition: gig.cpp:5149
gig::DimensionRegion::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
Definition: gig.cpp:1984
gig::lfo1_ctrl_t
lfo1_ctrl_t
Defines how LFO1 is controlled by.
Definition: gig.h:195
RIFF::List::GetFirstSubChunk
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk).
Definition: RIFF.cpp:1194
RIFF::List::AddSubList
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Definition: RIFF.cpp:1401
gig::DimensionRegion::SustainDefeat
bool SustainDefeat
If true: Sustain pedal will not hold a note.
Definition: gig.h:572
gig::playback_state_t::loop_cycles_left
file_offset_t loop_cycles_left
How many times the loop has still to be passed, this value will be decremented with each loop cycle.
Definition: gig.h:380
gig::Sample::LoopType
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:772
gig::MidiRuleLegato::KeyRange
range_t KeyRange
Key range for legato notes.
Definition: gig.h:1020
gig::File::VerifySampleChecksumTable
bool VerifySampleChecksumTable()
Checks whether the file's "3CRC" chunk was damaged.
Definition: gig.cpp:6177
gig::Script::Compression_t
Compression_t
Definition: gig.h:1129
gig::Region::SetKeyRange
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:3409
gig::DimensionRegion::EG2ControllerDecayInfluence
uint8_t EG2ControllerDecayInfluence
Amount EG2 Controller has influence on the EG2 Decay time (0 - 3, where 0 means off).
Definition: gig.h:525
DLS::sample_loop_t::LoopType
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
Definition: DLS.h:237
gig::Sample
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
Definition: gig.h:761
gig::Sample::LoopPlayCount
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
Definition: gig.h:777
gig::DimensionRegion::LFO2Sync
bool LFO2Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:532
RIFF::Chunk::RemainingBytes
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
Definition: RIFF.cpp:333
gig::DimensionRegion::VCFCutoff
uint8_t VCFCutoff
Max. cutoff frequency.
Definition: gig.h:546
gig::MidiRuleLegato::BypassController
uint8_t BypassController
Controller to be used to bypass the sustain note.
Definition: gig.h:1017
gig::DimensionRegion::SetVelocityResponseDepth
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3086
DLS::Sample::SamplesTotal
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise),...
Definition: DLS.h:464
gig::Sample::WorstCaseFrameSize
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
Definition: gig.h:813
gig::curve_type_nonlinear
@ curve_type_nonlinear
Non-linear curve type.
Definition: gig.h:149
DLS::Info::SetFixedStringLengths
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:326
gig::File::GetFirstGroup
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
Definition: gig.cpp:6265
gig::Region::Layers
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:880
gig::Sample::Resize
void Resize(file_offset_t NewSize)
Resize sample.
Definition: gig.cpp:866
DLS::Region::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
Definition: DLS.cpp:1226
gig::DimensionRegion::Pan
int8_t Pan
Panorama / Balance (-64..0..63 <-> left..middle..right)
Definition: gig.h:566
gig::File::VERSION_2
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Definition: gig.h:1349
gig::Group::~Group
virtual ~Group()
Destructor.
Definition: gig.cpp:5445
gig::Group::Name
String Name
Stores the name of this Group.
Definition: gig.h:1294
gig::crossfade_t::out_end
uint8_t out_end
End postition of fade out.
Definition: gig.h:370
gig::MidiRuleCtrlTrigger
MIDI rule for triggering notes by control change events.
Definition: gig.h:971
gig::DimensionRegion::SetGain
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value.
Definition: gig.cpp:1970
gig::Sample::ReadAndLoop
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
gig::Script::SetScriptAsText
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
Definition: gig.cpp:4478
gig::DimensionRegion::VCFVelocityCurve
curve_type_t VCFVelocityCurve
Defines a transformation curve for the incoming velocity values, affecting the VCF.
Definition: gig.h:547
DLS::dlsid_t
Every subject of an DLS file and the file itself can have an unique, computer generated ID.
Definition: DLS.h:123
DLS::Sample::BitDepth
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
Definition: DLS.h:463
gig::DimensionRegion::VelocityTable
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
Definition: gig.h:611
gig::Region::SplitDimensionZone
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Definition: gig.cpp:3830
gig::dimension_velocity
@ dimension_velocity
Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
Definition: gig.h:319
gig::MidiRuleAlternator::Controller
uint8_t Controller
CC number for controller selector.
Definition: gig.h:1072
gig::File::UpdateFileOffsets
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: gig.cpp:6716
gig::DimensionRegion::EG1ControllerReleaseInfluence
uint8_t EG1ControllerReleaseInfluence
Amount EG1 Controller has influence on the EG1 Release time (0 - 3, where 0 means off).
Definition: gig.h:507
gig::DimensionRegion::VCFCutoffControllerInvert
bool VCFCutoffControllerInvert
Inverts values coming from the defined cutoff controller.
Definition: gig.h:545
gig::eg_opt_t::ReleaseCancel
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
Definition: gig.h:411
gig::File::GetFirstInstrument
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5865
gig::DimensionRegion::EG2Sustain
uint16_t EG2Sustain
Sustain value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:520
RIFF::Chunk::SetPos
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:301
gig::ScriptGroup::Name
String Name
Name of this script group. For example to be displayed in an instrument editor.
Definition: gig.h:1175
gig::Script::SetGroup
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
Definition: gig.cpp:4542
gig::Region::CopyAssign
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:4214
gig::dim_bypass_ctrl_95
@ dim_bypass_ctrl_95
Effect 5 Depth (MIDI Controller 95)
Definition: gig.h:159
DLS::Sample::SamplesPerSecond
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
Definition: DLS.h:460
gig::MidiRuleLegato::AltSustain1Key
uint8_t AltSustain1Key
Key triggering alternate sustain samples.
Definition: gig.h:1022
gig::Instrument::GetFirstRegion
Region * GetFirstRegion()
Returns the first Region of the instrument.
Definition: gig.cpp:4993
gig::DimensionRegion::SetVCFVelocityDynamicRange
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3146
gig::DimensionRegion::ReleaseVelocityResponseCurve
curve_type_t ReleaseVelocityResponseCurve
Defines a transformation curve to the incoming release veloctiy values affecting envelope times.
Definition: gig.h:559
gig::DimensionRegion::CopyAssign
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:1819
gig::DimensionRegion::VelocityResponseDepth
uint8_t VelocityResponseDepth
Dynamic range of velocity affecting amplitude (0 - 4) (usually you don't have to interpret this param...
Definition: gig.h:557
DLS::File::Save
virtual void Save(const String &Path, progress_t *pProgress=NULL)
Save changes to another file.
Definition: DLS.cpp:2103
gig::Group::GetFirstSample
Sample * GetFirstSample()
Returns the first Sample of this Group.
Definition: gig.cpp:5505
gig::Region::AddDimension
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
Definition: gig.cpp:3503
gig::split_type_t
split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:330
RIFF::Chunk::ReadUint32
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:723
gig::Sample::VerifyWaveData
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample's raw audio wave data.
Definition: gig.cpp:1452
gig::DimensionRegion::VCFResonanceController
vcf_res_ctrl_t VCFResonanceController
Specifies which external controller has influence on the filter resonance Q.
Definition: gig.h:552
gig::Script::COMPRESSION_NONE
@ COMPRESSION_NONE
Is not compressed at all (default).
Definition: gig.h:1130
gig::DimensionRegion::EG1Controller
eg1_ctrl_t EG1Controller
MIDI Controller which has influence on sample amplitude EG parameters (attack, decay,...
Definition: gig.h:503
gig::Sample::FileNo
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it's in the gig)
Definition: gig.h:816
gig::DimensionRegion::NoNoteOffReleaseTrigger
bool NoNoteOffReleaseTrigger
[gig extension]: If true then don't play a release trigger sample on MIDI note-off events.
Definition: gig.h:580
gig::DimensionRegion::SetReleaseVelocityResponseCurve
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3110
gig::range_t::low
uint8_t low
Low value of range.
Definition: gig.h:102
gig::MidiRuleLegato::LegatoSamples
uint8_t LegatoSamples
Number of legato samples per key in each direction (always 12)
Definition: gig.h:1014
DLS::Sampler::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
Definition: DLS.cpp:657
gig::DimensionRegion::SetReleaseVelocityResponseDepth
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3119
gig::Instrument::FineTune
int16_t FineTune
in cents
Definition: gig.h:1224
gig::Sample::SamplePeriod
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Definition: gig.h:765
gig::ScriptGroup::DeleteScript
void DeleteScript(Script *pScript)
Delete an instrument script.
Definition: gig.cpp:4690
gig::Sample::GetGroup
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Definition: gig.cpp:1407
gig::MidiRuleLegato::BypassUseController
bool BypassUseController
If a controller should be used to bypass the sustain note.
Definition: gig.h:1015
gig::Script::CopyAssign
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:4566
gig::DimensionRegion::VCFEnabled
bool VCFEnabled
If filter should be used.
Definition: gig.h:542
gig::DimensionRegion::EG2Decay2
double EG2Decay2
Only if EG2InfiniteSustain == false: 2nd stage decay time of the filter cutoff EG (0....
Definition: gig.h:518
DLS::Region::KeyRange
range_t KeyRange
Definition: DLS.h:494
gig::eg_opt_t::Decay2Cancel
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:410
gig::File::SetAutoLoad
void SetAutoLoad(bool b)
Enable / disable automatic loading.
Definition: gig.cpp:6741
gig::DimensionRegion::SetVelocityResponseCurve
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3074
RIFF::progress_t::callback
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
Definition: RIFF.h:217
gig::MidiRuleCtrlTrigger::ControllerNumber
uint8_t ControllerNumber
MIDI controller number.
Definition: gig.h:973
gig::Instrument::IsScriptSlotBypassed
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
Definition: gig.cpp:5336
gig::Sample::SMPTEFormat
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
Definition: gig.h:768
RIFF::Chunk
Ordinary RIFF Chunk.
Definition: RIFF.h:232
gig::DimensionRegion::EG1Release
double EG1Release
Release time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:501
gig::leverage_ctrl_t::type_channelaftertouch
@ type_channelaftertouch
Channel Key Pressure.
Definition: gig.h:246
gig::DimensionRegion::VelocityResponseCurve
curve_type_t VelocityResponseCurve
Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don't...
Definition: gig.h:556
gig::DimensionRegion::LFO2Frequency
double LFO2Frequency
Frequency of the filter cutoff LFO (0.10 - 10.00 Hz).
Definition: gig.h:527
Serialization::Archive
Destination container for serialization, and source container for deserialization.
Definition: Serialization.h:709
gig::Instrument::AddMidiRuleCtrlTrigger
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
Definition: gig.cpp:5110
gig::Region::GetDimensionDefinition
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:4010
gig::File::GetScriptGroup
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
Definition: gig.cpp:6401
gig::Script::UpdateChunks
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
Definition: gig.cpp:4504
gig::DimensionRegion::VCFType
vcf_type_t VCFType
Defines the general filter characteristic (lowpass, highpass, bandpass, etc.).
Definition: gig.h:543
gig::DimensionRegion::VCFVelocityScale
uint8_t VCFVelocityScale
(0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defi...
Definition: gig.h:548
gig::DimensionRegion::DimensionUpperLimits
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
Definition: gig.h:576
gig::DimensionRegion::EG1Options
eg_opt_t EG1Options
[gig extension]: Behavior options which should be used for envelope generator 1 (volume amplitude EG)...
Definition: gig.h:577
DLS::Resource::pInfo
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
Definition: DLS.h:405
RIFF::Chunk::ReadString
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
Definition: RIFF.cpp:740
gig::File::GetFirstSample
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: gig.cpp:5646
gig::Group::MoveAll
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
Definition: gig.cpp:5544
gig::Sample::LoadSampleDataWithNullSamplesExtension
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:755
gig::Instrument::RemoveScriptSlot
void RemoveScriptSlot(uint index)
Remove script slot.
Definition: gig.cpp:5275
gig::File::VERSION_4
static const DLS::version_t VERSION_4
Reflects Gigasampler file format version 4.0 (2007-10-12).
Definition: gig.h:1351
gig::File::GetGroup
Group * GetGroup(uint index)
Returns the group with the given index.
Definition: gig.cpp:6284
gig::Script
Real-time instrument script (gig format extension).
Definition: gig.h:1124
gig::vcf_type_lowpassturbo
@ vcf_type_lowpassturbo
More poles than normal lowpass.
Definition: gig.h:351
gig::DimensionRegion::EG1ControllerDecayInfluence
uint8_t EG1ControllerDecayInfluence
Amount EG1 Controller has influence on the EG1 Decay time (0 - 3, where 0 means off).
Definition: gig.h:506
gig::File::GetNextInstrument
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5872
RIFF::Chunk::Resize
void Resize(file_offset_t NewSize)
Resize chunk.
Definition: RIFF.cpp:957
gig::Region::GetDimensionRegionByBit
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index).
Definition: gig.cpp:4150
RIFF::stream_whence_t
stream_whence_t
File stream position dependent to these relations.
Definition: RIFF.h:177
gig::Sample::CreateDecompressionBuffer
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
Definition: gig.cpp:1373
gig::Sample::LoopID
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:771
DLS::sample_loop_t::LoopStart
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
gig::DimensionRegion::GetVelocityAttenuation
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Definition: gig.cpp:3058
gig::vcf_type_t
vcf_type_t
Defines which frequencies are filtered by the VCF.
Definition: gig.h:351
gig::Script::LANGUAGE_NKSP
@ LANGUAGE_NKSP
NKSP stands for "Is Not KSP" (default). Refer to the NKSP Reference Manual for details about this scr...
Definition: gig.h:1133
gig::File::GetNextGroup
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
Definition: gig.cpp:6272
gig::File::DeleteSample
void DeleteSample(Sample *pSample)
Delete a sample.
Definition: gig.cpp:5722
RIFF::Chunk::WriteUint32
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:761
DLS::sample_loop_t::LoopLength
uint32_t LoopLength
Length of the looping area (in sample points).
Definition: DLS.h:239
gig::Instrument::GetMidiRule
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
Definition: gig.cpp:5101
gig::crossfade_t::in_end
uint8_t in_end
End position of fade in.
Definition: gig.h:368
gig::crossfade_t::out_start
uint8_t out_start
Start position of fade out.
Definition: gig.h:369
gig::DimensionRegion::EG1PreAttack
uint16_t EG1PreAttack
Preattack value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:495
gig::MidiRuleLegato::ThresholdTime
uint16_t ThresholdTime
Maximum time (ms) between two notes that should be played legato.
Definition: gig.h:1018
gig::buffer_t::pStart
void * pStart
Points to the beginning of the buffer.
Definition: gig.h:108
gig::Region::pDimensionRegions
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
Definition: gig.h:879
DLS::Region::SetKeyRange
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:1191
gig::dimension_smartmidi
@ dimension_smartmidi
For MIDI tools like legato and repetition mode.
Definition: gig.h:319
gig::DimensionRegion::VCFKeyboardTracking
bool VCFKeyboardTracking
If true: VCF cutoff frequence will be dependend to the note key position relative to the defined brea...
Definition: gig.h:553
gig::Instrument::RemoveScript
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
Definition: gig.cpp:5293
gig::MidiRuleAlternator::pPatterns
struct gig::MidiRuleAlternator::pattern_t pPatterns[32]
A pattern is a sequence of articulation numbers.
gig::playback_state_t::position
file_offset_t position
Current position within the sample.
Definition: gig.h:378
gig::leverage_ctrl_t::type_none
@ type_none
No controller defined.
Definition: gig.h:246
gig::DimensionRegion::LFO1Controller
lfo1_ctrl_t LFO1Controller
MIDI Controller which controls sample amplitude LFO.
Definition: gig.h:511
gig::Sample::SamplesPerFrame
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
Definition: gig.h:814
gig::dimension_def_t::zones
uint8_t zones
Number of zones the dimension has.
Definition: gig.h:336
gig::ScriptGroup::GetScript
Script * GetScript(uint index)
Get instrument script.
Definition: gig.cpp:4654
gig::Sample::TruncatedBits
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0,...
Definition: gig.h:779
gig::File::DeleteGroupOnly
void DeleteGroupOnly(Group *pGroup)
Delete a group.
Definition: gig.cpp:6355
gig::File::AddDuplicateInstrument
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
Definition: gig.cpp:5982
gig::File::DeleteInstrument
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
Definition: gig.cpp:6071
gig::Instrument::ScriptSlotCount
uint ScriptSlotCount() const
Instrument's amount of script slots.
Definition: gig.cpp:5316
gig::vcf_cutoff_ctrl_none2
@ vcf_cutoff_ctrl_none2
The difference between none and none2 is unknown.
Definition: gig.h:214
gig::Sample::GetCache
buffer_t GetCache()
Returns current cached sample points.
Definition: gig.cpp:814
gig::sust_rel_trg_none
@ sust_rel_trg_none
No release triggered sample(s) are played on sustain pedal up (default).
Definition: gig.h:437
gig::Instrument::Attenuation
int32_t Attenuation
in dB
Definition: gig.h:1222
RIFF::progress_t::__range_max
float __range_max
Only for internal usage, do not modify!
Definition: RIFF.h:221
gig::DimensionRegion::EG1Attack
double EG1Attack
Attack time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:496
gig::Sample::crc
uint32_t crc
Reflects CRC-32 checksum of the raw sample data at the last time when the sample's raw wave form data...
Definition: gig.h:819
gig::Script::Compression
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used.
Definition: gig.h:1137
gig::DimensionRegion::VelocityResponseCurveScaling
uint8_t VelocityResponseCurveScaling
0 - 127 (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead).
Definition: gig.h:558
gig::DimensionRegion::VCFVelocityDynamicRange
uint8_t VCFVelocityDynamicRange
0x04 = lowest, 0x00 = highest .
Definition: gig.h:549
RIFF::File
RIFF File.
Definition: RIFF.h:358
gig::buffer_t
Pointer address and size of a buffer.
Definition: gig.h:107
gig::DimensionRegion::VCFResonance
uint8_t VCFResonance
Firm internal filter resonance weight.
Definition: gig.h:550
DLS::range_t::low
uint16_t low
Low value of range.
Definition: DLS.h:211
gig::DimensionRegion::LFO2FlipPhase
bool LFO2FlipPhase
Inverts phase of the filter cutoff LFO wave.
Definition: gig.h:531
gig::loop_type_bidirectional
@ loop_type_bidirectional
Alternating loop (forward/backward, also known as Ping Pong)
Definition: gig.h:126
gig::Sample::Product
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field....
Definition: gig.h:764
gig::Sample::RAMCache
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
Definition: gig.h:815
gig::DimensionRegion::DimensionBypass
dim_bypass_ctrl_t DimensionBypass
If defined, the MIDI controller can switch on/off the dimension in realtime.
Definition: gig.h:565
gig::File::GetSample
Sample * GetSample(uint index)
Returns Sample object of index.
Definition: gig.cpp:5664
gig::Sample::InternalDecompressionBuffer
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
Definition: gig.h:807
gig::DimensionRegion::EG1Decay1
double EG1Decay1
Decay time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:497
gig::dimension_random
@ dimension_random
Different samples triggered each time a note is played, random order.
Definition: gig.h:319
gig::range_t::high
uint8_t high
High value of range.
Definition: gig.h:103
gig::Sample::DestroyDecompressionBuffer
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Definition: gig.cpp:1390
RIFF::Chunk::ReadUint8
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:575
DLS
DLS specific classes and definitions.
Definition: DLS.h:108
gig::Region::~Region
~Region()
Destructor.
Definition: gig.cpp:4017
DLS::Region::DeleteChunks
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Region object.
Definition: DLS.cpp:1148
gig::curve_type_linear
@ curve_type_linear
Linear curve type.
Definition: gig.h:149
gig::DimensionRegion::SampleStartOffset
uint16_t SampleStartOffset
Number of samples the sample start should be moved (0 - 2000).
Definition: gig.h:574
gig::DimensionRegion::SetVCFVelocityScale
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3155
gig::File::GetInstrument
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
Definition: gig.cpp:5899
gig::DimensionRegion::ReleaseVelocityResponseDepth
uint8_t ReleaseVelocityResponseDepth
Dynamic range of release velocity affecting envelope time (0 - 4).
Definition: gig.h:560
gig::Instrument::AddMidiRuleLegato
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
Definition: gig.cpp:5123
gig::MidiRuleLegato::ReleaseTime
uint16_t ReleaseTime
Release time.
Definition: gig.h:1019
gig::File::CountSamples
size_t CountSamples()
Returns the total amount of samples of this gig file.
Definition: gig.cpp:5684
gig::MidiRuleAlternator::Chained
bool Chained
If all patterns should be chained together.
Definition: gig.h:1075
gig::DimensionRegion::VelocityUpperLimit
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set,...
Definition: gig.h:492
gig::ScriptGroup::AddScript
Script * AddScript()
Add new instrument script.
Definition: gig.cpp:4673
gig::vcf_cutoff_ctrl_t
vcf_cutoff_ctrl_t
Defines how the filter cutoff frequency is controlled by.
Definition: gig.h:214
gig::DimensionRegion::ReleaseTriggerDecay
uint8_t ReleaseTriggerDecay
0 - 8
Definition: gig.h:561
gig::ScriptGroup::DeleteChunks
virtual void DeleteChunks()
Remove all RIFF chunks associated with this ScriptGroup object.
Definition: gig.cpp:4619
gig::Sample::Compressed
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors,...
Definition: gig.h:778
gig::dimension_roundrobin
@ dimension_roundrobin
Different samples triggered each time a note is played, dimension regions selected in sequence.
Definition: gig.h:319
DLS::Sampler::SampleLoops
uint32_t SampleLoops
Reflects the number of sample loops.
Definition: DLS.h:431
gig::DimensionRegion::LFO1ControlDepth
uint16_t LFO1ControlDepth
Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents).
Definition: gig.h:510
gig::loop_type_backward
@ loop_type_backward
Loop backward (reverse)
Definition: gig.h:126
DLS::Resource::GenerateDLSID
void GenerateDLSID()
Generates a new DLSID for the resource.
Definition: DLS.cpp:551
gig::eg_opt_t::AttackCancel
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:407
gig::MidiRuleLegato
MIDI rule for instruments with legato samples.
Definition: gig.h:1012
DLS::Instrument::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: DLS.cpp:1425
gig::Region
Defines Region information of a Gigasampler/GigaStudio instrument.
Definition: gig.h:874
gig::DimensionRegion::EG1Hold
bool EG1Hold
If true, Decay1 stage should be postponed until the sample reached the sample loop start.
Definition: gig.h:502
gig::dimension_keyboard
@ dimension_keyboard
Dimension for keyswitching.
Definition: gig.h:319
gig::Instrument::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: gig.cpp:4863
gig::Region::GetDimensionRegionByValue
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it's articulation d...
Definition: gig.cpp:4041
RIFF::progress_t::__range_min
float __range_min
Only for internal usage, do not modify!
Definition: RIFF.h:220
gig::File::GetAutoLoad
bool GetAutoLoad()
Returns whether automatic loading is enabled.
Definition: gig.cpp:6749
gig::DimensionRegion::VCFResonanceDynamic
bool VCFResonanceDynamic
If true: Increases the resonance Q according to changes of controllers that actually control the VCF ...
Definition: gig.h:551
gig::lfo1_ctrl_internal
@ lfo1_ctrl_internal
Only internally controlled.
Definition: gig.h:195
gig::buffer_t::NullExtensionSize
file_offset_t NullExtensionSize
The buffer might be bigger than the actual data, if that's the case that unused space at the end of t...
Definition: gig.h:110
gig::DimensionRegion::SampleAttenuation
double SampleAttenuation
Sample volume (calculated from DLS::Sampler::Gain)
Definition: gig.h:575
DLS::Sample::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: DLS.cpp:1062
gig::dimension_def_t::zone_size
float zone_size
Intended for internal usage: reflects the size of each zone (128/zones) for normal split types only,...
Definition: gig.h:338
gig::File::VERSION_3
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
Definition: gig.h:1350
gig::Instrument::CopyAssign
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:5373
gig::sust_rel_trg_t
sust_rel_trg_t
Defines behaviour of release triggered sample(s) on sustain pedal up event.
Definition: gig.h:437
gig::File::AddScriptGroup
ScriptGroup * AddScriptGroup()
Add new instrument script group.
Definition: gig.cpp:6433
RIFF::List::GetSubList
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
Definition: RIFF.cpp:1168
gig::leverage_ctrl_t::controller_number
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
Definition: gig.h:249
gig::Sample::SMPTEOffset
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
Definition: gig.h:769
gig::split_type_normal
@ split_type_normal
dimension value between 0-127
Definition: gig.h:330
gig::curve_type_special
@ curve_type_special
Special curve type.
Definition: gig.h:149
gig::Sample::pGroup
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Definition: gig.h:808
gig::File::RebuildSampleChecksumTable
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file's checksum table with those n...
Definition: gig.cpp:6214
gig::File::SetSampleChecksum
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Definition: gig.cpp:6118
gig::DimensionRegion::LFO2Controller
lfo2_ctrl_t LFO2Controller
MIDI Controlle which controls the filter cutoff LFO.
Definition: gig.h:530
gig::Region::DimensionRegions
uint32_t DimensionRegions
Total number of DimensionRegions this Region contains, do not alter!
Definition: gig.h:878
gig::Sample::Instances
static size_t Instances
Number of instances of class Sample.
Definition: gig.h:806
gig::playback_state_t::reverse
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
Definition: gig.h:379
DLS::Region
Defines Region information of an Instrument.
Definition: DLS.h:492
RIFF::List::DeleteSubChunk
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Definition: RIFF.cpp:1420
gig::Script::Language
Language_t Language
Programming language and dialect the script is written in.
Definition: gig.h:1139
DLS::Sampler::pSampleLoops
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:432
gig::DimensionRegion::LFO3Controller
lfo3_ctrl_t LFO3Controller
MIDI Controller which controls the sample pitch LFO.
Definition: gig.h:539
gig::DimensionRegion::SetVCFCutoffController
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:3128
gig::dimension_none
@ dimension_none
Dimension not in use.
Definition: gig.h:319
gig::MidiRuleAlternator
MIDI rule to automatically cycle through specified sequences of different articulations.
Definition: gig.h:1044
gig::DimensionRegion::ChannelOffset
uint8_t ChannelOffset
Audio output where the audio signal of the dimension region should be routed to (0 - 9).
Definition: gig.h:571
DLS::File::Instruments
uint32_t Instruments
Reflects the number of available Instrument objects.
Definition: DLS.h:564
gig::DimensionRegion::SetVCFVelocityCurve
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
Definition: gig.cpp:3137
gig::leverage_ctrl_t::type_controlchange
@ type_controlchange
Ordinary MIDI control change controller, see field 'controller_number'.
Definition: gig.h:246
DLS::File::pVersion
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL.
Definition: DLS.h:563
gig::DimensionRegion::EG1ControllerAttackInfluence
uint8_t EG1ControllerAttackInfluence
Amount EG1 Controller has influence on the EG1 Attack time (0 - 3, where 0 means off).
Definition: gig.h:505
gig::Group::GetNextSample
Sample * GetNextSample()
Returns the next Sample of the Group.
Definition: gig.cpp:5523
gig::dimension_samplechannel
@ dimension_samplechannel
If used sample has more than one channel (thus is not mono).
Definition: gig.h:319
gig::dimension_layer
@ dimension_layer
For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers).
Definition: gig.h:319
gig::eg_opt_t::AttackHoldCancel
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:408
gig::DimensionRegion::MSDecode
bool MSDecode
Gigastudio flag: defines if Mid Side Recordings should be decoded.
Definition: gig.h:573
gig::Sample::Read
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
gig::File::GetNextSample
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
Definition: gig.cpp:5653
gig::dim_bypass_ctrl_none
@ dim_bypass_ctrl_none
No controller bypass.
Definition: gig.h:159
gig::MidiRuleLegato::ReleaseTriggerKey
uint8_t ReleaseTriggerKey
Key triggering release samples.
Definition: gig.h:1021
gig::Group
Group of Gigasampler samples.
Definition: gig.h:1292
gig::MidiRuleAlternator::KeySwitchRange
range_t KeySwitchRange
Key range for key switch selector.
Definition: gig.h:1071
gig::libraryName
String libraryName()
Returns the name of this C++ library.
Definition: gig.cpp:6785
gig::Sample::FrameOffset
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
Definition: gig.h:809
gig::Sample::SamplePos
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
Definition: gig.h:811
gig::DimensionRegion::VCFCutoffController
vcf_cutoff_ctrl_t VCFCutoffController
Specifies which external controller has influence on the filter cutoff frequency.
Definition: gig.h:544
gig::File::DeleteGroup
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Definition: gig.cpp:6330
gig::dimension_t
dimension_t
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
Definition: gig.h:319
gig::MidiRule
Abstract base class for all MIDI rules.
Definition: gig.h:950
gig::DimensionRegion::AttenuationController
attenuation_ctrl_t AttenuationController
MIDI Controller which has influence on the volume level of the sample (or entire sample group).
Definition: gig.h:568
gig::Instrument::SwapScriptSlots
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
Definition: gig.cpp:5260
RIFF::Chunk::ReadInt16
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:612
gig::vcf_res_ctrl_t
vcf_res_ctrl_t
Defines how the filter resonance is controlled by.
Definition: gig.h:226
gig::Instrument::MoveTo
void MoveTo(Instrument *dst)
Move this instrument at the position before.
Definition: gig.cpp:5061
gig::DimensionRegion
Encapsulates articulation informations of a dimension region.
Definition: gig.h:490
gig::Sample::LoopFraction
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:776
gig::Region::DeleteDimension
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Definition: gig.cpp:3615
DLS::File::UpdateFileOffsets
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: DLS.cpp:2225
DLS::File::GetFileName
String GetFileName()
File name of this DLS file.
Definition: DLS.cpp:1841
gig::File::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file's current instruments, samples, groups and settings to the respective RIFF chu...
Definition: gig.cpp:6493
gig::Instrument::DimensionKeyRange
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
Definition: gig.h:1227
gig::curve_type_unknown
@ curve_type_unknown
Unknown curve type.
Definition: gig.h:149
DLS::Info::Software
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
Definition: DLS.h:375
gig::MidiRuleAlternator::Selector
selector_t Selector
Method by which pattern is chosen.
Definition: gig.h:1070
DLS::range_t::high
uint16_t high
High value of range.
Definition: DLS.h:212
gig::eg_opt_t
Defines behavior options for envelope generators (gig format extension).
Definition: gig.h:406
gig::Region::Dimensions
unsigned int Dimensions
Number of defined dimensions, do not alter!
Definition: gig.h:876
gig::DimensionRegion::EG2ControllerInvert
bool EG2ControllerInvert
Invert values coming from defined EG2 controller.
Definition: gig.h:523
gig::Region::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks.
Definition: gig.cpp:3328
RIFF::Chunk::ReadInt8
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:538
gig::DimensionRegion::LFO3ControlDepth
int16_t LFO3ControlDepth
Controller depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:538
gig::MidiRuleLegato::BypassKey
uint8_t BypassKey
Key to be used to bypass the sustain note.
Definition: gig.h:1016
gig::DimensionRegion::EG2Options
eg_opt_t EG2Options
[gig extension]: Behavior options which should be used for envelope generator 2 (filter cutoff EG).
Definition: gig.h:578
gig::MidiRuleAlternator::Polyphonic
bool Polyphonic
If alternator should step forward only when all notes are off.
Definition: gig.h:1074
gig::Group::AddSample
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
Definition: gig.cpp:5534
DLS::Sample::GetSize
file_offset_t GetSize() const
Returns sample size.
Definition: DLS.cpp:950
gig::MidiRuleAlternator::Patterns
uint8_t Patterns
Number of alternator patterns.
Definition: gig.h:1051
gig::DimensionRegion::EG3Attack
double EG3Attack
Attack time of the sample pitch EG (0.000 - 10.000s).
Definition: gig.h:534
RIFF::file_offset_t
uint64_t file_offset_t
Type used by libgig for handling file positioning during file I/O tasks.
Definition: RIFF.h:160
gig::Sample::Sample
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0, int index=-1)
Constructor.
Definition: gig.cpp:390
gig::Sample::LoopSize
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Definition: gig.h:775
gig::dimension_def_t::dimension
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
Definition: gig.h:334
gig::File::AddSample
Sample * AddSample()
Add a new sample.
Definition: gig.cpp:5697
gig::Group::Group
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
Definition: gig.cpp:5435
RIFF::Chunk::ReadUint16
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:649
gig::DimensionRegion::LFO1FlipPhase
bool LFO1FlipPhase
Inverts phase of the sample amplitude LFO wave.
Definition: gig.h:512
RIFF::Chunk::LoadChunkData
void * LoadChunkData()
Load chunk body into RAM.
Definition: RIFF.cpp:886
gig::Script::ENCODING_ASCII
@ ENCODING_ASCII
Standard 8 bit US ASCII character encoding (default).
Definition: gig.h:1127
gig::vcf_cutoff_ctrl_none
@ vcf_cutoff_ctrl_none
No MIDI controller assigned for filter cutoff frequency.
Definition: gig.h:214
gig::Sample::GetPos
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Definition: gig.cpp:926
gig::libraryVersion
String libraryVersion()
Returns version of this C++ library.
Definition: gig.cpp:6793
gig::Sample::UpdateChunks
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: gig.cpp:574
gig::Sample::LoopStart
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:773
gig::dim_bypass_ctrl_94
@ dim_bypass_ctrl_94
Effect 4 Depth (MIDI Controller 94)
Definition: gig.h:159
gig::eg_opt_t::Decay1Cancel
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
Definition: gig.h:409
DLS::Sample::FrameSize
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used,...
Definition: DLS.h:465
gig::DimensionRegion::LFO2InternalDepth
uint16_t LFO2InternalDepth
Firm pitch of the filter cutoff LFO (0 - 1200 cents).
Definition: gig.h:528
gig::DimensionRegion::EG1Decay2
double EG1Decay2
Only if EG1InfiniteSustain == false: 2nd decay stage time of the sample amplitude EG (0....
Definition: gig.h:498
gig::Sample::Dithered
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction.
Definition: gig.h:780
gig::Script::Name
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
Definition: gig.h:1136
gig::File::AddContentOf
void AddContentOf(File *pFile)
Add content of another existing file.
Definition: gig.cpp:5999
DLS::Instrument::Regions
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Definition: DLS.h:530
RIFF::List::GetSubChunk
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
Definition: RIFF.cpp:1149
gig::MidiRuleAlternator::pArticulations
String pArticulations[32]
Names of the articulations.
Definition: gig.h:1047
gig::Sample::LoadSampleData
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:706
gig::Sample::Manufacturer
uint32_t Manufacturer
Specifies the MIDI Manufacturer's Association (MMA) Manufacturer code for the sampler intended to rec...
Definition: gig.h:763
gig::DimensionRegion::LFO1Sync
bool LFO1Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:513
gig::Sample::CopyAssignMeta
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
RIFF::File::SetMode
bool SetMode(stream_mode_t NewMode)
Change file access mode.
Definition: RIFF.cpp:1824
gig::Instrument::GetScriptOfSlot
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
Definition: gig.cpp:5199
DLS::Sample::Resize
void Resize(file_offset_t NewSize)
Resize sample.
Definition: DLS.cpp:983
gig::Sample::ReleaseSampleData
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
Definition: gig.cpp:829
gig::DimensionRegion::pSample
Sample * pSample
Points to the Sample which is assigned to the dimension region.
Definition: gig.h:493
gig::lfo2_ctrl_t
lfo2_ctrl_t
Defines how LFO2 is controlled by.
Definition: gig.h:183