libgig  4.0.0.6svn2980
gig.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * libgig - C++ cross-platform Gigasampler format file access library *
4  * *
5  * Copyright (C) 2003-2016 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 
28 #include <algorithm>
29 #include <math.h>
30 #include <iostream>
31 #include <assert.h>
32 
35 #define GIG_FILE_EXT_VERSION 2
36 
42 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
43 
45 #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x))
46 #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822))
47 #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01))
48 #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01)
49 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03)
50 #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4)
51 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03)
52 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03)
53 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
54 #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1)
55 #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3)
56 #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5)
57 
58 namespace gig {
59 
60 // *************** Internal functions for sample decompression ***************
61 // *
62 
63 namespace {
64 
65  inline int get12lo(const unsigned char* pSrc)
66  {
67  const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
68  return x & 0x800 ? x - 0x1000 : x;
69  }
70 
71  inline int get12hi(const unsigned char* pSrc)
72  {
73  const int x = pSrc[1] >> 4 | pSrc[2] << 4;
74  return x & 0x800 ? x - 0x1000 : x;
75  }
76 
77  inline int16_t get16(const unsigned char* pSrc)
78  {
79  return int16_t(pSrc[0] | pSrc[1] << 8);
80  }
81 
82  inline int get24(const unsigned char* pSrc)
83  {
84  const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
85  return x & 0x800000 ? x - 0x1000000 : x;
86  }
87 
88  inline void store24(unsigned char* pDst, int x)
89  {
90  pDst[0] = x;
91  pDst[1] = x >> 8;
92  pDst[2] = x >> 16;
93  }
94 
95  void Decompress16(int compressionmode, const unsigned char* params,
96  int srcStep, int dstStep,
97  const unsigned char* pSrc, int16_t* pDst,
98  file_offset_t currentframeoffset,
99  file_offset_t copysamples)
100  {
101  switch (compressionmode) {
102  case 0: // 16 bit uncompressed
103  pSrc += currentframeoffset * srcStep;
104  while (copysamples) {
105  *pDst = get16(pSrc);
106  pDst += dstStep;
107  pSrc += srcStep;
108  copysamples--;
109  }
110  break;
111 
112  case 1: // 16 bit compressed to 8 bit
113  int y = get16(params);
114  int dy = get16(params + 2);
115  while (currentframeoffset) {
116  dy -= int8_t(*pSrc);
117  y -= dy;
118  pSrc += srcStep;
119  currentframeoffset--;
120  }
121  while (copysamples) {
122  dy -= int8_t(*pSrc);
123  y -= dy;
124  *pDst = y;
125  pDst += dstStep;
126  pSrc += srcStep;
127  copysamples--;
128  }
129  break;
130  }
131  }
132 
133  void Decompress24(int compressionmode, const unsigned char* params,
134  int dstStep, const unsigned char* pSrc, uint8_t* pDst,
135  file_offset_t currentframeoffset,
136  file_offset_t copysamples, int truncatedBits)
137  {
138  int y, dy, ddy, dddy;
139 
140 #define GET_PARAMS(params) \
141  y = get24(params); \
142  dy = y - get24((params) + 3); \
143  ddy = get24((params) + 6); \
144  dddy = get24((params) + 9)
145 
146 #define SKIP_ONE(x) \
147  dddy -= (x); \
148  ddy -= dddy; \
149  dy = -dy - ddy; \
150  y += dy
151 
152 #define COPY_ONE(x) \
153  SKIP_ONE(x); \
154  store24(pDst, y << truncatedBits); \
155  pDst += dstStep
156 
157  switch (compressionmode) {
158  case 2: // 24 bit uncompressed
159  pSrc += currentframeoffset * 3;
160  while (copysamples) {
161  store24(pDst, get24(pSrc) << truncatedBits);
162  pDst += dstStep;
163  pSrc += 3;
164  copysamples--;
165  }
166  break;
167 
168  case 3: // 24 bit compressed to 16 bit
169  GET_PARAMS(params);
170  while (currentframeoffset) {
171  SKIP_ONE(get16(pSrc));
172  pSrc += 2;
173  currentframeoffset--;
174  }
175  while (copysamples) {
176  COPY_ONE(get16(pSrc));
177  pSrc += 2;
178  copysamples--;
179  }
180  break;
181 
182  case 4: // 24 bit compressed to 12 bit
183  GET_PARAMS(params);
184  while (currentframeoffset > 1) {
185  SKIP_ONE(get12lo(pSrc));
186  SKIP_ONE(get12hi(pSrc));
187  pSrc += 3;
188  currentframeoffset -= 2;
189  }
190  if (currentframeoffset) {
191  SKIP_ONE(get12lo(pSrc));
192  currentframeoffset--;
193  if (copysamples) {
194  COPY_ONE(get12hi(pSrc));
195  pSrc += 3;
196  copysamples--;
197  }
198  }
199  while (copysamples > 1) {
200  COPY_ONE(get12lo(pSrc));
201  COPY_ONE(get12hi(pSrc));
202  pSrc += 3;
203  copysamples -= 2;
204  }
205  if (copysamples) {
206  COPY_ONE(get12lo(pSrc));
207  }
208  break;
209 
210  case 5: // 24 bit compressed to 8 bit
211  GET_PARAMS(params);
212  while (currentframeoffset) {
213  SKIP_ONE(int8_t(*pSrc++));
214  currentframeoffset--;
215  }
216  while (copysamples) {
217  COPY_ONE(int8_t(*pSrc++));
218  copysamples--;
219  }
220  break;
221  }
222  }
223 
224  const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
225  const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
226  const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
227  const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
228 }
229 
230 
231 
232 // *************** Internal CRC-32 (Cyclic Redundancy Check) functions ***************
233 // *
234 
235  static uint32_t* __initCRCTable() {
236  static uint32_t res[256];
237 
238  for (int i = 0 ; i < 256 ; i++) {
239  uint32_t c = i;
240  for (int j = 0 ; j < 8 ; j++) {
241  c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
242  }
243  res[i] = c;
244  }
245  return res;
246  }
247 
248  static const uint32_t* __CRCTable = __initCRCTable();
249 
255  inline static void __resetCRC(uint32_t& crc) {
256  crc = 0xffffffff;
257  }
258 
278  static void __calculateCRC(unsigned char* buf, int bufSize, uint32_t& crc) {
279  for (int i = 0 ; i < bufSize ; i++) {
280  crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
281  }
282  }
283 
289  inline static uint32_t __encodeCRC(const uint32_t& crc) {
290  return crc ^ 0xffffffff;
291  }
292 
293 
294 
295 // *************** Other Internal functions ***************
296 // *
297 
298  static split_type_t __resolveSplitType(dimension_t dimension) {
299  return (
300  dimension == dimension_layer ||
301  dimension == dimension_samplechannel ||
302  dimension == dimension_releasetrigger ||
303  dimension == dimension_keyboard ||
304  dimension == dimension_roundrobin ||
305  dimension == dimension_random ||
306  dimension == dimension_smartmidi ||
307  dimension == dimension_roundrobinkeyboard
309  }
310 
311  static int __resolveZoneSize(dimension_def_t& dimension_definition) {
312  return (dimension_definition.split_type == split_type_normal)
313  ? int(128.0 / dimension_definition.zones) : 0;
314  }
315 
316 
317 
318 // *************** Sample ***************
319 // *
320 
321  size_t Sample::Instances = 0;
323 
342  Sample::Sample(File* pFile, RIFF::List* waveList, file_offset_t WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
343  static const DLS::Info::string_length_t fixedStringLengths[] = {
344  { CHUNK_ID_INAM, 64 },
345  { 0, 0 }
346  };
347  pInfo->SetFixedStringLengths(fixedStringLengths);
348  Instances++;
349  FileNo = fileNo;
350 
351  __resetCRC(crc);
352 
353  pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
354  if (pCk3gix) {
355  uint16_t iSampleGroup = pCk3gix->ReadInt16();
356  pGroup = pFile->GetGroup(iSampleGroup);
357  } else { // '3gix' chunk missing
358  // by default assigned to that mandatory "Default Group"
359  pGroup = pFile->GetGroup(0);
360  }
361 
362  pCkSmpl = waveList->GetSubChunk(CHUNK_ID_SMPL);
363  if (pCkSmpl) {
369  pCkSmpl->Read(&SMPTEFormat, 1, 4);
371  Loops = pCkSmpl->ReadInt32();
372  pCkSmpl->ReadInt32(); // manufByt
373  LoopID = pCkSmpl->ReadInt32();
374  pCkSmpl->Read(&LoopType, 1, 4);
379  } else { // 'smpl' chunk missing
380  // use default values
381  Manufacturer = 0;
382  Product = 0;
383  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
384  MIDIUnityNote = 60;
385  FineTune = 0;
387  SMPTEOffset = 0;
388  Loops = 0;
389  LoopID = 0;
391  LoopStart = 0;
392  LoopEnd = 0;
393  LoopFraction = 0;
394  LoopPlayCount = 0;
395  }
396 
397  FrameTable = NULL;
398  SamplePos = 0;
399  RAMCache.Size = 0;
400  RAMCache.pStart = NULL;
402 
403  if (BitDepth > 24) throw gig::Exception("Only samples up to 24 bit supported");
404 
405  RIFF::Chunk* ewav = waveList->GetSubChunk(CHUNK_ID_EWAV);
406  Compressed = ewav;
407  Dithered = false;
408  TruncatedBits = 0;
409  if (Compressed) {
410  uint32_t version = ewav->ReadInt32();
411  if (version == 3 && BitDepth == 24) {
412  Dithered = ewav->ReadInt32();
413  ewav->SetPos(Channels == 2 ? 84 : 64);
414  TruncatedBits = ewav->ReadInt32();
415  }
416  ScanCompressedSample();
417  }
418 
419  // we use a buffer for decompression and for truncating 24 bit samples to 16 bit
423  }
424  FrameOffset = 0; // just for streaming compressed samples
425 
426  LoopSize = LoopEnd - LoopStart + 1;
427  }
428 
444  void Sample::CopyAssignMeta(const Sample* orig) {
445  // handle base classes
447 
448  // handle actual own attributes of this class
449  Manufacturer = orig->Manufacturer;
450  Product = orig->Product;
451  SamplePeriod = orig->SamplePeriod;
453  FineTune = orig->FineTune;
454  SMPTEFormat = orig->SMPTEFormat;
455  SMPTEOffset = orig->SMPTEOffset;
456  Loops = orig->Loops;
457  LoopID = orig->LoopID;
458  LoopType = orig->LoopType;
459  LoopStart = orig->LoopStart;
460  LoopEnd = orig->LoopEnd;
461  LoopSize = orig->LoopSize;
462  LoopFraction = orig->LoopFraction;
464 
465  // schedule resizing this sample to the given sample's size
466  Resize(orig->GetSize());
467  }
468 
480  void Sample::CopyAssignWave(const Sample* orig) {
481  const int iReadAtOnce = 32*1024;
482  char* buf = new char[iReadAtOnce * orig->FrameSize];
483  Sample* pOrig = (Sample*) orig; //HACK: remove constness for now
484  file_offset_t restorePos = pOrig->GetPos();
485  pOrig->SetPos(0);
486  SetPos(0);
487  for (file_offset_t n = pOrig->Read(buf, iReadAtOnce); n;
488  n = pOrig->Read(buf, iReadAtOnce))
489  {
490  Write(buf, n);
491  }
492  pOrig->SetPos(restorePos);
493  delete [] buf;
494  }
495 
508  void Sample::UpdateChunks(progress_t* pProgress) {
509  // first update base class's chunks
510  DLS::Sample::UpdateChunks(pProgress);
511 
512  // make sure 'smpl' chunk exists
514  if (!pCkSmpl) {
516  memset(pCkSmpl->LoadChunkData(), 0, 60);
517  }
518  // update 'smpl' chunk
519  uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
520  SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
521  store32(&pData[0], Manufacturer);
522  store32(&pData[4], Product);
523  store32(&pData[8], SamplePeriod);
524  store32(&pData[12], MIDIUnityNote);
525  store32(&pData[16], FineTune);
526  store32(&pData[20], SMPTEFormat);
527  store32(&pData[24], SMPTEOffset);
528  store32(&pData[28], Loops);
529 
530  // we skip 'manufByt' for now (4 bytes)
531 
532  store32(&pData[36], LoopID);
533  store32(&pData[40], LoopType);
534  store32(&pData[44], LoopStart);
535  store32(&pData[48], LoopEnd);
536  store32(&pData[52], LoopFraction);
537  store32(&pData[56], LoopPlayCount);
538 
539  // make sure '3gix' chunk exists
542  // determine appropriate sample group index (to be stored in chunk)
543  uint16_t iSampleGroup = 0; // 0 refers to default sample group
544  File* pFile = static_cast<File*>(pParent);
545  if (pFile->pGroups) {
546  std::list<Group*>::iterator iter = pFile->pGroups->begin();
547  std::list<Group*>::iterator end = pFile->pGroups->end();
548  for (int i = 0; iter != end; i++, iter++) {
549  if (*iter == pGroup) {
550  iSampleGroup = i;
551  break; // found
552  }
553  }
554  }
555  // update '3gix' chunk
556  pData = (uint8_t*) pCk3gix->LoadChunkData();
557  store16(&pData[0], iSampleGroup);
558 
559  // if the library user toggled the "Compressed" attribute from true to
560  // false, then the EWAV chunk associated with compressed samples needs
561  // to be deleted
563  if (ewav && !Compressed) {
564  pWaveList->DeleteSubChunk(ewav);
565  }
566  }
567 
569  void Sample::ScanCompressedSample() {
570  //TODO: we have to add some more scans here (e.g. determine compression rate)
571  this->SamplesTotal = 0;
572  std::list<file_offset_t> frameOffsets;
573 
574  SamplesPerFrame = BitDepth == 24 ? 256 : 2048;
575  WorstCaseFrameSize = SamplesPerFrame * FrameSize + Channels; // +Channels for compression flag
576 
577  // Scanning
578  pCkData->SetPos(0);
579  if (Channels == 2) { // Stereo
580  for (int i = 0 ; ; i++) {
581  // for 24 bit samples every 8:th frame offset is
582  // stored, to save some memory
583  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
584 
585  const int mode_l = pCkData->ReadUint8();
586  const int mode_r = pCkData->ReadUint8();
587  if (mode_l > 5 || mode_r > 5) throw gig::Exception("Unknown compression mode");
588  const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
589 
590  if (pCkData->RemainingBytes() <= frameSize) {
592  ((pCkData->RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
593  (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
595  break;
596  }
598  pCkData->SetPos(frameSize, RIFF::stream_curpos);
599  }
600  }
601  else { // Mono
602  for (int i = 0 ; ; i++) {
603  if (BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->GetPos());
604 
605  const int mode = pCkData->ReadUint8();
606  if (mode > 5) throw gig::Exception("Unknown compression mode");
607  const file_offset_t frameSize = bytesPerFrame[mode];
608 
609  if (pCkData->RemainingBytes() <= frameSize) {
611  ((pCkData->RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
613  break;
614  }
616  pCkData->SetPos(frameSize, RIFF::stream_curpos);
617  }
618  }
619  pCkData->SetPos(0);
620 
621  // Build the frames table (which is used for fast resolving of a frame's chunk offset)
622  if (FrameTable) delete[] FrameTable;
623  FrameTable = new file_offset_t[frameOffsets.size()];
624  std::list<file_offset_t>::iterator end = frameOffsets.end();
625  std::list<file_offset_t>::iterator iter = frameOffsets.begin();
626  for (int i = 0; iter != end; i++, iter++) {
627  FrameTable[i] = *iter;
628  }
629  }
630 
641  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, 0); // 0 amount of NullSamples
642  }
643 
667  return LoadSampleDataWithNullSamplesExtension(SampleCount, 0); // 0 amount of NullSamples
668  }
669 
690  return LoadSampleDataWithNullSamplesExtension(this->SamplesTotal, NullSamplesCount);
691  }
692 
726  if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal;
727  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
728  file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize;
729  SetPos(0); // reset read position to begin of sample
730  RAMCache.pStart = new int8_t[allocationsize];
731  RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize;
732  RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
733  // fill the remaining buffer space with silence samples
734  memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
735  return GetCache();
736  }
737 
749  // return a copy of the buffer_t structure
750  buffer_t result;
751  result.Size = this->RAMCache.Size;
752  result.pStart = this->RAMCache.pStart;
754  return result;
755  }
756 
764  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
765  RAMCache.pStart = NULL;
766  RAMCache.Size = 0;
768  }
769 
801  if (Compressed) throw gig::Exception("There is no support for modifying compressed samples (yet)");
802  DLS::Sample::Resize(NewSize);
803  }
804 
827  if (Compressed) {
828  switch (Whence) {
829  case RIFF::stream_curpos:
830  this->SamplePos += SampleCount;
831  break;
832  case RIFF::stream_end:
833  this->SamplePos = this->SamplesTotal - 1 - SampleCount;
834  break;
836  this->SamplePos -= SampleCount;
837  break;
838  case RIFF::stream_start: default:
839  this->SamplePos = SampleCount;
840  break;
841  }
842  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
843 
844  file_offset_t frame = this->SamplePos / 2048; // to which frame to jump
845  this->FrameOffset = this->SamplePos % 2048; // offset (in sample points) within that frame
846  pCkData->SetPos(FrameTable[frame]); // set chunk pointer to the start of sought frame
847  return this->SamplePos;
848  }
849  else { // not compressed
850  file_offset_t orderedBytes = SampleCount * this->FrameSize;
851  file_offset_t result = pCkData->SetPos(orderedBytes, Whence);
852  return (result == orderedBytes) ? SampleCount
853  : result / this->FrameSize;
854  }
855  }
856 
861  if (Compressed) return SamplePos;
862  else return pCkData->GetPos() / FrameSize;
863  }
864 
899  file_offset_t Sample::ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState,
900  DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer) {
901  file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
902  uint8_t* pDst = (uint8_t*) pBuffer;
903 
904  SetPos(pPlaybackState->position); // recover position from the last time
905 
906  if (pDimRgn->SampleLoops) { // honor looping if there are loop points defined
907 
908  const DLS::sample_loop_t& loop = pDimRgn->pSampleLoops[0];
909  const uint32_t loopEnd = loop.LoopStart + loop.LoopLength;
910 
911  if (GetPos() <= loopEnd) {
912  switch (loop.LoopType) {
913 
914  case loop_type_bidirectional: { //TODO: not tested yet!
915  do {
916  // if not endless loop check if max. number of loop cycles have been passed
917  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
918 
919  if (!pPlaybackState->reverse) { // forward playback
920  do {
921  samplestoloopend = loopEnd - GetPos();
922  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
923  samplestoread -= readsamples;
924  totalreadsamples += readsamples;
925  if (readsamples == samplestoloopend) {
926  pPlaybackState->reverse = true;
927  break;
928  }
929  } while (samplestoread && readsamples);
930  }
931  else { // backward playback
932 
933  // as we can only read forward from disk, we have to
934  // determine the end position within the loop first,
935  // read forward from that 'end' and finally after
936  // reading, swap all sample frames so it reflects
937  // backward playback
938 
939  file_offset_t swapareastart = totalreadsamples;
940  file_offset_t loopoffset = GetPos() - loop.LoopStart;
941  file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
942  file_offset_t reverseplaybackend = GetPos() - samplestoreadinloop;
943 
944  SetPos(reverseplaybackend);
945 
946  // read samples for backward playback
947  do {
948  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
949  samplestoreadinloop -= readsamples;
950  samplestoread -= readsamples;
951  totalreadsamples += readsamples;
952  } while (samplestoreadinloop && readsamples);
953 
954  SetPos(reverseplaybackend); // pretend we really read backwards
955 
956  if (reverseplaybackend == loop.LoopStart) {
957  pPlaybackState->loop_cycles_left--;
958  pPlaybackState->reverse = false;
959  }
960 
961  // reverse the sample frames for backward playback
962  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!
963  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
964  }
965  } while (samplestoread && readsamples);
966  break;
967  }
968 
969  case loop_type_backward: { // TODO: not tested yet!
970  // forward playback (not entered the loop yet)
971  if (!pPlaybackState->reverse) do {
972  samplestoloopend = loopEnd - GetPos();
973  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
974  samplestoread -= readsamples;
975  totalreadsamples += readsamples;
976  if (readsamples == samplestoloopend) {
977  pPlaybackState->reverse = true;
978  break;
979  }
980  } while (samplestoread && readsamples);
981 
982  if (!samplestoread) break;
983 
984  // as we can only read forward from disk, we have to
985  // determine the end position within the loop first,
986  // read forward from that 'end' and finally after
987  // reading, swap all sample frames so it reflects
988  // backward playback
989 
990  file_offset_t swapareastart = totalreadsamples;
991  file_offset_t loopoffset = GetPos() - loop.LoopStart;
992  file_offset_t samplestoreadinloop = (this->LoopPlayCount) ? Min(samplestoread, pPlaybackState->loop_cycles_left * loop.LoopLength - loopoffset)
993  : samplestoread;
994  file_offset_t reverseplaybackend = loop.LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.LoopLength);
995 
996  SetPos(reverseplaybackend);
997 
998  // read samples for backward playback
999  do {
1000  // if not endless loop check if max. number of loop cycles have been passed
1001  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1002  samplestoloopend = loopEnd - GetPos();
1003  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1004  samplestoreadinloop -= readsamples;
1005  samplestoread -= readsamples;
1006  totalreadsamples += readsamples;
1007  if (readsamples == samplestoloopend) {
1008  pPlaybackState->loop_cycles_left--;
1009  SetPos(loop.LoopStart);
1010  }
1011  } while (samplestoreadinloop && readsamples);
1012 
1013  SetPos(reverseplaybackend); // pretend we really read backwards
1014 
1015  // reverse the sample frames for backward playback
1016  SwapMemoryArea(&pDst[swapareastart * this->FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1017  break;
1018  }
1019 
1020  default: case loop_type_normal: {
1021  do {
1022  // if not endless loop check if max. number of loop cycles have been passed
1023  if (this->LoopPlayCount && !pPlaybackState->loop_cycles_left) break;
1024  samplestoloopend = loopEnd - GetPos();
1025  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1026  samplestoread -= readsamples;
1027  totalreadsamples += readsamples;
1028  if (readsamples == samplestoloopend) {
1029  pPlaybackState->loop_cycles_left--;
1030  SetPos(loop.LoopStart);
1031  }
1032  } while (samplestoread && readsamples);
1033  break;
1034  }
1035  }
1036  }
1037  }
1038 
1039  // read on without looping
1040  if (samplestoread) do {
1041  readsamples = Read(&pDst[totalreadsamples * this->FrameSize], samplestoread, pExternalDecompressionBuffer);
1042  samplestoread -= readsamples;
1043  totalreadsamples += readsamples;
1044  } while (readsamples && samplestoread);
1045 
1046  // store current position
1047  pPlaybackState->position = GetPos();
1048 
1049  return totalreadsamples;
1050  }
1051 
1074  file_offset_t Sample::Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer) {
1075  if (SampleCount == 0) return 0;
1076  if (!Compressed) {
1077  if (BitDepth == 24) {
1078  return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1079  }
1080  else { // 16 bit
1081  // (pCkData->Read does endian correction)
1082  return Channels == 2 ? pCkData->Read(pBuffer, SampleCount << 1, 2) >> 1
1083  : pCkData->Read(pBuffer, SampleCount, 2);
1084  }
1085  }
1086  else {
1087  if (this->SamplePos >= this->SamplesTotal) return 0;
1088  //TODO: efficiency: maybe we should test for an average compression rate
1089  file_offset_t assumedsize = GuessSize(SampleCount),
1090  remainingbytes = 0, // remaining bytes in the local buffer
1091  remainingsamples = SampleCount,
1092  copysamples, skipsamples,
1093  currentframeoffset = this->FrameOffset; // offset in current sample frame since last Read()
1094  this->FrameOffset = 0;
1095 
1096  buffer_t* pDecompressionBuffer = (pExternalDecompressionBuffer) ? pExternalDecompressionBuffer : &InternalDecompressionBuffer;
1097 
1098  // if decompression buffer too small, then reduce amount of samples to read
1099  if (pDecompressionBuffer->Size < assumedsize) {
1100  std::cerr << "gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1101  SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1102  remainingsamples = SampleCount;
1103  assumedsize = GuessSize(SampleCount);
1104  }
1105 
1106  unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1107  int16_t* pDst = static_cast<int16_t*>(pBuffer);
1108  uint8_t* pDst24 = static_cast<uint8_t*>(pBuffer);
1109  remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
1110 
1111  while (remainingsamples && remainingbytes) {
1112  file_offset_t framesamples = SamplesPerFrame;
1113  file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1114 
1115  int mode_l = *pSrc++, mode_r = 0;
1116 
1117  if (Channels == 2) {
1118  mode_r = *pSrc++;
1119  framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1120  rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1121  nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1122  if (remainingbytes < framebytes) { // last frame in sample
1123  framesamples = SamplesInLastFrame;
1124  if (mode_l == 4 && (framesamples & 1)) {
1125  rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1126  }
1127  else {
1128  rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1129  }
1130  }
1131  }
1132  else {
1133  framebytes = bytesPerFrame[mode_l] + 1;
1134  nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1135  if (remainingbytes < framebytes) {
1136  framesamples = SamplesInLastFrame;
1137  }
1138  }
1139 
1140  // determine how many samples in this frame to skip and read
1141  if (currentframeoffset + remainingsamples >= framesamples) {
1142  if (currentframeoffset <= framesamples) {
1143  copysamples = framesamples - currentframeoffset;
1144  skipsamples = currentframeoffset;
1145  }
1146  else {
1147  copysamples = 0;
1148  skipsamples = framesamples;
1149  }
1150  }
1151  else {
1152  // This frame has enough data for pBuffer, but not
1153  // all of the frame is needed. Set file position
1154  // to start of this frame for next call to Read.
1155  copysamples = remainingsamples;
1156  skipsamples = currentframeoffset;
1157  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1158  this->FrameOffset = currentframeoffset + copysamples;
1159  }
1160  remainingsamples -= copysamples;
1161 
1162  if (remainingbytes > framebytes) {
1163  remainingbytes -= framebytes;
1164  if (remainingsamples == 0 &&
1165  currentframeoffset + copysamples == framesamples) {
1166  // This frame has enough data for pBuffer, and
1167  // all of the frame is needed. Set file
1168  // position to start of next frame for next
1169  // call to Read. FrameOffset is 0.
1170  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1171  }
1172  }
1173  else remainingbytes = 0;
1174 
1175  currentframeoffset -= skipsamples;
1176 
1177  if (copysamples == 0) {
1178  // skip this frame
1179  pSrc += framebytes - Channels;
1180  }
1181  else {
1182  const unsigned char* const param_l = pSrc;
1183  if (BitDepth == 24) {
1184  if (mode_l != 2) pSrc += 12;
1185 
1186  if (Channels == 2) { // Stereo
1187  const unsigned char* const param_r = pSrc;
1188  if (mode_r != 2) pSrc += 12;
1189 
1190  Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1191  skipsamples, copysamples, TruncatedBits);
1192  Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1193  skipsamples, copysamples, TruncatedBits);
1194  pDst24 += copysamples * 6;
1195  }
1196  else { // Mono
1197  Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1198  skipsamples, copysamples, TruncatedBits);
1199  pDst24 += copysamples * 3;
1200  }
1201  }
1202  else { // 16 bit
1203  if (mode_l) pSrc += 4;
1204 
1205  int step;
1206  if (Channels == 2) { // Stereo
1207  const unsigned char* const param_r = pSrc;
1208  if (mode_r) pSrc += 4;
1209 
1210  step = (2 - mode_l) + (2 - mode_r);
1211  Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1212  Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1213  skipsamples, copysamples);
1214  pDst += copysamples << 1;
1215  }
1216  else { // Mono
1217  step = 2 - mode_l;
1218  Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1219  pDst += copysamples;
1220  }
1221  }
1222  pSrc += nextFrameOffset;
1223  }
1224 
1225  // reload from disk to local buffer if needed
1226  if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1227  assumedsize = GuessSize(remainingsamples);
1228  pCkData->SetPos(remainingbytes, RIFF::stream_backward);
1229  if (pCkData->RemainingBytes() < assumedsize) assumedsize = pCkData->RemainingBytes();
1230  remainingbytes = pCkData->Read(pDecompressionBuffer->pStart, assumedsize, 1);
1231  pSrc = (unsigned char*) pDecompressionBuffer->pStart;
1232  }
1233  } // while
1234 
1235  this->SamplePos += (SampleCount - remainingsamples);
1236  if (this->SamplePos > this->SamplesTotal) this->SamplePos = this->SamplesTotal;
1237  return (SampleCount - remainingsamples);
1238  }
1239  }
1240 
1263  file_offset_t Sample::Write(void* pBuffer, file_offset_t SampleCount) {
1264  if (Compressed) throw gig::Exception("There is no support for writing compressed gig samples (yet)");
1265 
1266  // if this is the first write in this sample, reset the
1267  // checksum calculator
1268  if (pCkData->GetPos() == 0) {
1269  __resetCRC(crc);
1270  }
1271  if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1272  file_offset_t res;
1273  if (BitDepth == 24) {
1274  res = pCkData->Write(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
1275  } else { // 16 bit
1276  res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1277  : pCkData->Write(pBuffer, SampleCount, 2);
1278  }
1279  __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1280 
1281  // if this is the last write, update the checksum chunk in the
1282  // file
1283  if (pCkData->GetPos() == pCkData->GetSize()) {
1284  File* pFile = static_cast<File*>(GetParent());
1285  pFile->SetSampleChecksum(this, __encodeCRC(crc));
1286  }
1287  return res;
1288  }
1289 
1307  buffer_t result;
1308  const double worstCaseHeaderOverhead =
1309  (256.0 /*frame size*/ + 12.0 /*header*/ + 2.0 /*compression type flag (stereo)*/) / 256.0;
1310  result.Size = (file_offset_t) (double(MaxReadSize) * 3.0 /*(24 Bit)*/ * 2.0 /*stereo*/ * worstCaseHeaderOverhead);
1311  result.pStart = new int8_t[result.Size];
1312  result.NullExtensionSize = 0;
1313  return result;
1314  }
1315 
1323  void Sample::DestroyDecompressionBuffer(buffer_t& DecompressionBuffer) {
1324  if (DecompressionBuffer.Size && DecompressionBuffer.pStart) {
1325  delete[] (int8_t*) DecompressionBuffer.pStart;
1326  DecompressionBuffer.pStart = NULL;
1327  DecompressionBuffer.Size = 0;
1328  DecompressionBuffer.NullExtensionSize = 0;
1329  }
1330  }
1331 
1341  return pGroup;
1342  }
1343 
1345  Instances--;
1347  delete[] (unsigned char*) InternalDecompressionBuffer.pStart;
1350  }
1351  if (FrameTable) delete[] FrameTable;
1352  if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
1353  }
1354 
1355 
1356 
1357 // *************** DimensionRegion ***************
1358 // *
1359 
1360  size_t DimensionRegion::Instances = 0;
1361  DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1362 
1364  Instances++;
1365 
1366  pSample = NULL;
1367  pRegion = pParent;
1368 
1369  if (_3ewl->GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1370  else memset(&Crossfade, 0, 4);
1371 
1372  if (!pVelocityTables) pVelocityTables = new VelocityTableMap;
1373 
1374  RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
1375  if (_3ewa) { // if '3ewa' chunk exists
1376  _3ewa->ReadInt32(); // unknown, always == chunk size ?
1377  LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1378  EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1379  _3ewa->ReadInt16(); // unknown
1380  LFO1InternalDepth = _3ewa->ReadUint16();
1381  _3ewa->ReadInt16(); // unknown
1382  LFO3InternalDepth = _3ewa->ReadInt16();
1383  _3ewa->ReadInt16(); // unknown
1384  LFO1ControlDepth = _3ewa->ReadUint16();
1385  _3ewa->ReadInt16(); // unknown
1386  LFO3ControlDepth = _3ewa->ReadInt16();
1387  EG1Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1388  EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1389  _3ewa->ReadInt16(); // unknown
1390  EG1Sustain = _3ewa->ReadUint16();
1391  EG1Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1392  EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1393  uint8_t eg1ctrloptions = _3ewa->ReadUint8();
1394  EG1ControllerInvert = eg1ctrloptions & 0x01;
1398  EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1399  uint8_t eg2ctrloptions = _3ewa->ReadUint8();
1400  EG2ControllerInvert = eg2ctrloptions & 0x01;
1404  LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1405  EG2Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1406  EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1407  _3ewa->ReadInt16(); // unknown
1408  EG2Sustain = _3ewa->ReadUint16();
1409  EG2Release = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1410  _3ewa->ReadInt16(); // unknown
1411  LFO2ControlDepth = _3ewa->ReadUint16();
1412  LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
1413  _3ewa->ReadInt16(); // unknown
1414  LFO2InternalDepth = _3ewa->ReadUint16();
1415  int32_t eg1decay2 = _3ewa->ReadInt32();
1416  EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1417  EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1418  _3ewa->ReadInt16(); // unknown
1419  EG1PreAttack = _3ewa->ReadUint16();
1420  int32_t eg2decay2 = _3ewa->ReadInt32();
1421  EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1422  EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1423  _3ewa->ReadInt16(); // unknown
1424  EG2PreAttack = _3ewa->ReadUint16();
1425  uint8_t velocityresponse = _3ewa->ReadUint8();
1426  if (velocityresponse < 5) {
1428  VelocityResponseDepth = velocityresponse;
1429  } else if (velocityresponse < 10) {
1431  VelocityResponseDepth = velocityresponse - 5;
1432  } else if (velocityresponse < 15) {
1434  VelocityResponseDepth = velocityresponse - 10;
1435  } else {
1438  }
1439  uint8_t releasevelocityresponse = _3ewa->ReadUint8();
1440  if (releasevelocityresponse < 5) {
1442  ReleaseVelocityResponseDepth = releasevelocityresponse;
1443  } else if (releasevelocityresponse < 10) {
1445  ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1446  } else if (releasevelocityresponse < 15) {
1448  ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1449  } else {
1452  }
1455  _3ewa->ReadInt32(); // unknown
1456  SampleStartOffset = (uint16_t) _3ewa->ReadInt16();
1457  _3ewa->ReadInt16(); // unknown
1458  uint8_t pitchTrackDimensionBypass = _3ewa->ReadInt8();
1459  PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1460  if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1461  else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1463  uint8_t pan = _3ewa->ReadUint8();
1464  Pan = (pan < 64) ? pan : -((int)pan - 63); // signed 7 bit -> signed 8 bit
1465  SelfMask = _3ewa->ReadInt8() & 0x01;
1466  _3ewa->ReadInt8(); // unknown
1467  uint8_t lfo3ctrl = _3ewa->ReadUint8();
1468  LFO3Controller = static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07); // lower 3 bits
1469  LFO3Sync = lfo3ctrl & 0x20; // bit 5
1470  InvertAttenuationController = lfo3ctrl & 0x80; // bit 7
1471  AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->ReadUint8()));
1472  uint8_t lfo2ctrl = _3ewa->ReadUint8();
1473  LFO2Controller = static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07); // lower 3 bits
1474  LFO2FlipPhase = lfo2ctrl & 0x80; // bit 7
1475  LFO2Sync = lfo2ctrl & 0x20; // bit 5
1476  bool extResonanceCtrl = lfo2ctrl & 0x40; // bit 6
1477  uint8_t lfo1ctrl = _3ewa->ReadUint8();
1478  LFO1Controller = static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07); // lower 3 bits
1479  LFO1FlipPhase = lfo1ctrl & 0x80; // bit 7
1480  LFO1Sync = lfo1ctrl & 0x40; // bit 6
1481  VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1483  uint16_t eg3depth = _3ewa->ReadUint16();
1484  EG3Depth = (eg3depth <= 1200) ? eg3depth /* positives */
1485  : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1); /* binary complementary for negatives */
1486  _3ewa->ReadInt16(); // unknown
1487  ChannelOffset = _3ewa->ReadUint8() / 4;
1488  uint8_t regoptions = _3ewa->ReadUint8();
1489  MSDecode = regoptions & 0x01; // bit 0
1490  SustainDefeat = regoptions & 0x02; // bit 1
1491  _3ewa->ReadInt16(); // unknown
1492  VelocityUpperLimit = _3ewa->ReadInt8();
1493  _3ewa->ReadInt8(); // unknown
1494  _3ewa->ReadInt16(); // unknown
1495  ReleaseTriggerDecay = _3ewa->ReadUint8(); // release trigger decay
1496  _3ewa->ReadInt8(); // unknown
1497  _3ewa->ReadInt8(); // unknown
1498  EG1Hold = _3ewa->ReadUint8() & 0x80; // bit 7
1499  uint8_t vcfcutoff = _3ewa->ReadUint8();
1500  VCFEnabled = vcfcutoff & 0x80; // bit 7
1501  VCFCutoff = vcfcutoff & 0x7f; // lower 7 bits
1502  VCFCutoffController = static_cast<vcf_cutoff_ctrl_t>(_3ewa->ReadUint8());
1503  uint8_t vcfvelscale = _3ewa->ReadUint8();
1504  VCFCutoffControllerInvert = vcfvelscale & 0x80; // bit 7
1505  VCFVelocityScale = vcfvelscale & 0x7f; // lower 7 bits
1506  _3ewa->ReadInt8(); // unknown
1507  uint8_t vcfresonance = _3ewa->ReadUint8();
1508  VCFResonance = vcfresonance & 0x7f; // lower 7 bits
1509  VCFResonanceDynamic = !(vcfresonance & 0x80); // bit 7
1510  uint8_t vcfbreakpoint = _3ewa->ReadUint8();
1511  VCFKeyboardTracking = vcfbreakpoint & 0x80; // bit 7
1512  VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f; // lower 7 bits
1513  uint8_t vcfvelocity = _3ewa->ReadUint8();
1514  VCFVelocityDynamicRange = vcfvelocity % 5;
1515  VCFVelocityCurve = static_cast<curve_type_t>(vcfvelocity / 5);
1516  VCFType = static_cast<vcf_type_t>(_3ewa->ReadUint8());
1517  if (VCFType == vcf_type_lowpass) {
1518  if (lfo3ctrl & 0x40) // bit 6
1520  }
1521  if (_3ewa->RemainingBytes() >= 8) {
1522  _3ewa->Read(DimensionUpperLimits, 1, 8);
1523  } else {
1524  memset(DimensionUpperLimits, 0, 8);
1525  }
1526  } else { // '3ewa' chunk does not exist yet
1527  // use default values
1528  LFO3Frequency = 1.0;
1529  EG3Attack = 0.0;
1530  LFO1InternalDepth = 0;
1531  LFO3InternalDepth = 0;
1532  LFO1ControlDepth = 0;
1533  LFO3ControlDepth = 0;
1534  EG1Attack = 0.0;
1535  EG1Decay1 = 0.005;
1536  EG1Sustain = 1000;
1537  EG1Release = 0.3;
1540  EG1ControllerInvert = false;
1546  EG2ControllerInvert = false;
1550  LFO1Frequency = 1.0;
1551  EG2Attack = 0.0;
1552  EG2Decay1 = 0.005;
1553  EG2Sustain = 1000;
1554  EG2Release = 0.3;
1555  LFO2ControlDepth = 0;
1556  LFO2Frequency = 1.0;
1557  LFO2InternalDepth = 0;
1558  EG1Decay2 = 0.0;
1559  EG1InfiniteSustain = true;
1560  EG1PreAttack = 0;
1561  EG2Decay2 = 0.0;
1562  EG2InfiniteSustain = true;
1563  EG2PreAttack = 0;
1570  SampleStartOffset = 0;
1571  PitchTrack = true;
1573  Pan = 0;
1574  SelfMask = true;
1576  LFO3Sync = false;
1581  LFO2FlipPhase = false;
1582  LFO2Sync = false;
1584  LFO1FlipPhase = false;
1585  LFO1Sync = false;
1587  EG3Depth = 0;
1588  ChannelOffset = 0;
1589  MSDecode = false;
1590  SustainDefeat = false;
1591  VelocityUpperLimit = 0;
1592  ReleaseTriggerDecay = 0;
1593  EG1Hold = false;
1594  VCFEnabled = false;
1595  VCFCutoff = 0;
1597  VCFCutoffControllerInvert = false;
1598  VCFVelocityScale = 0;
1599  VCFResonance = 0;
1600  VCFResonanceDynamic = false;
1601  VCFKeyboardTracking = false;
1603  VCFVelocityDynamicRange = 0x04;
1606  memset(DimensionUpperLimits, 127, 8);
1607  }
1608 
1609  pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1612 
1613  pVelocityReleaseTable = GetReleaseVelocityTable(
1616  );
1617 
1618  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1622 
1623  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1624  VelocityTable = 0;
1625  }
1626 
1627  /*
1628  * Constructs a DimensionRegion by copying all parameters from
1629  * another DimensionRegion
1630  */
1632  Instances++;
1633  //NOTE: I think we cannot call CopyAssign() here (in a constructor) as long as its a virtual method
1634  *this = src; // default memberwise shallow copy of all parameters
1635  pParentList = _3ewl; // restore the chunk pointer
1636 
1637  // deep copy of owned structures
1638  if (src.VelocityTable) {
1639  VelocityTable = new uint8_t[128];
1640  for (int k = 0 ; k < 128 ; k++)
1641  VelocityTable[k] = src.VelocityTable[k];
1642  }
1643  if (src.pSampleLoops) {
1645  for (int k = 0 ; k < src.SampleLoops ; k++)
1646  pSampleLoops[k] = src.pSampleLoops[k];
1647  }
1648  }
1649 
1660  CopyAssign(orig, NULL);
1661  }
1662 
1671  void DimensionRegion::CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples) {
1672  // delete all allocated data first
1673  if (VelocityTable) delete [] VelocityTable;
1674  if (pSampleLoops) delete [] pSampleLoops;
1675 
1676  // backup parent list pointer
1677  RIFF::List* p = pParentList;
1678 
1679  gig::Sample* pOriginalSample = pSample;
1680  gig::Region* pOriginalRegion = pRegion;
1681 
1682  //NOTE: copy code copied from assignment constructor above, see comment there as well
1683 
1684  *this = *orig; // default memberwise shallow copy of all parameters
1685 
1686  // restore members that shall not be altered
1687  pParentList = p; // restore the chunk pointer
1688  pRegion = pOriginalRegion;
1689 
1690  // only take the raw sample reference reference if the
1691  // two DimensionRegion objects are part of the same file
1692  if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1693  pSample = pOriginalSample;
1694  }
1695 
1696  if (mSamples && mSamples->count(orig->pSample)) {
1697  pSample = mSamples->find(orig->pSample)->second;
1698  }
1699 
1700  // deep copy of owned structures
1701  if (orig->VelocityTable) {
1702  VelocityTable = new uint8_t[128];
1703  for (int k = 0 ; k < 128 ; k++)
1704  VelocityTable[k] = orig->VelocityTable[k];
1705  }
1706  if (orig->pSampleLoops) {
1708  for (int k = 0 ; k < orig->SampleLoops ; k++)
1709  pSampleLoops[k] = orig->pSampleLoops[k];
1710  }
1711  }
1712 
1717  void DimensionRegion::SetGain(int32_t gain) {
1718  DLS::Sampler::SetGain(gain);
1719  SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1720  }
1721 
1732  // first update base class's chunk
1733  DLS::Sampler::UpdateChunks(pProgress);
1734 
1736  uint8_t* pData = (uint8_t*) wsmp->LoadChunkData();
1737  pData[12] = Crossfade.in_start;
1738  pData[13] = Crossfade.in_end;
1739  pData[14] = Crossfade.out_start;
1740  pData[15] = Crossfade.out_end;
1741 
1742  // make sure '3ewa' chunk exists
1744  if (!_3ewa) {
1745  File* pFile = (File*) GetParent()->GetParent()->GetParent();
1746  bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
1747  _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1748  }
1749  pData = (uint8_t*) _3ewa->LoadChunkData();
1750 
1751  // update '3ewa' chunk with DimensionRegion's current settings
1752 
1753  const uint32_t chunksize = _3ewa->GetNewSize();
1754  store32(&pData[0], chunksize); // unknown, always chunk size?
1755 
1756  const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1757  store32(&pData[4], lfo3freq);
1758 
1759  const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1760  store32(&pData[8], eg3attack);
1761 
1762  // next 2 bytes unknown
1763 
1764  store16(&pData[14], LFO1InternalDepth);
1765 
1766  // next 2 bytes unknown
1767 
1768  store16(&pData[18], LFO3InternalDepth);
1769 
1770  // next 2 bytes unknown
1771 
1772  store16(&pData[22], LFO1ControlDepth);
1773 
1774  // next 2 bytes unknown
1775 
1776  store16(&pData[26], LFO3ControlDepth);
1777 
1778  const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
1779  store32(&pData[28], eg1attack);
1780 
1781  const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
1782  store32(&pData[32], eg1decay1);
1783 
1784  // next 2 bytes unknown
1785 
1786  store16(&pData[38], EG1Sustain);
1787 
1788  const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
1789  store32(&pData[40], eg1release);
1790 
1791  const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
1792  pData[44] = eg1ctl;
1793 
1794  const uint8_t eg1ctrloptions =
1795  (EG1ControllerInvert ? 0x01 : 0x00) |
1799  pData[45] = eg1ctrloptions;
1800 
1801  const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
1802  pData[46] = eg2ctl;
1803 
1804  const uint8_t eg2ctrloptions =
1805  (EG2ControllerInvert ? 0x01 : 0x00) |
1809  pData[47] = eg2ctrloptions;
1810 
1811  const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
1812  store32(&pData[48], lfo1freq);
1813 
1814  const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
1815  store32(&pData[52], eg2attack);
1816 
1817  const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
1818  store32(&pData[56], eg2decay1);
1819 
1820  // next 2 bytes unknown
1821 
1822  store16(&pData[62], EG2Sustain);
1823 
1824  const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
1825  store32(&pData[64], eg2release);
1826 
1827  // next 2 bytes unknown
1828 
1829  store16(&pData[70], LFO2ControlDepth);
1830 
1831  const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
1832  store32(&pData[72], lfo2freq);
1833 
1834  // next 2 bytes unknown
1835 
1836  store16(&pData[78], LFO2InternalDepth);
1837 
1838  const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
1839  store32(&pData[80], eg1decay2);
1840 
1841  // next 2 bytes unknown
1842 
1843  store16(&pData[86], EG1PreAttack);
1844 
1845  const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
1846  store32(&pData[88], eg2decay2);
1847 
1848  // next 2 bytes unknown
1849 
1850  store16(&pData[94], EG2PreAttack);
1851 
1852  {
1853  if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
1854  uint8_t velocityresponse = VelocityResponseDepth;
1855  switch (VelocityResponseCurve) {
1856  case curve_type_nonlinear:
1857  break;
1858  case curve_type_linear:
1859  velocityresponse += 5;
1860  break;
1861  case curve_type_special:
1862  velocityresponse += 10;
1863  break;
1864  case curve_type_unknown:
1865  default:
1866  throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
1867  }
1868  pData[96] = velocityresponse;
1869  }
1870 
1871  {
1872  if (ReleaseVelocityResponseDepth > 4) throw Exception("ReleaseVelocityResponseDepth must be between 0 and 4");
1873  uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
1874  switch (ReleaseVelocityResponseCurve) {
1875  case curve_type_nonlinear:
1876  break;
1877  case curve_type_linear:
1878  releasevelocityresponse += 5;
1879  break;
1880  case curve_type_special:
1881  releasevelocityresponse += 10;
1882  break;
1883  case curve_type_unknown:
1884  default:
1885  throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
1886  }
1887  pData[97] = releasevelocityresponse;
1888  }
1889 
1890  pData[98] = VelocityResponseCurveScaling;
1891 
1892  pData[99] = AttenuationControllerThreshold;
1893 
1894  // next 4 bytes unknown
1895 
1896  store16(&pData[104], SampleStartOffset);
1897 
1898  // next 2 bytes unknown
1899 
1900  {
1901  uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
1902  switch (DimensionBypass) {
1903  case dim_bypass_ctrl_94:
1904  pitchTrackDimensionBypass |= 0x10;
1905  break;
1906  case dim_bypass_ctrl_95:
1907  pitchTrackDimensionBypass |= 0x20;
1908  break;
1909  case dim_bypass_ctrl_none:
1910  //FIXME: should we set anything here?
1911  break;
1912  default:
1913  throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
1914  }
1915  pData[108] = pitchTrackDimensionBypass;
1916  }
1917 
1918  const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
1919  pData[109] = pan;
1920 
1921  const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
1922  pData[110] = selfmask;
1923 
1924  // next byte unknown
1925 
1926  {
1927  uint8_t lfo3ctrl = LFO3Controller & 0x07; // lower 3 bits
1928  if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
1929  if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
1930  if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
1931  pData[112] = lfo3ctrl;
1932  }
1933 
1934  const uint8_t attenctl = EncodeLeverageController(AttenuationController);
1935  pData[113] = attenctl;
1936 
1937  {
1938  uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
1939  if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
1940  if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
1941  if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
1942  pData[114] = lfo2ctrl;
1943  }
1944 
1945  {
1946  uint8_t lfo1ctrl = LFO1Controller & 0x07; // lower 3 bits
1947  if (LFO1FlipPhase) lfo1ctrl |= 0x80; // bit 7
1948  if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
1951  pData[115] = lfo1ctrl;
1952  }
1953 
1954  const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
1955  : uint16_t(((-EG3Depth) - 1) ^ 0xfff); /* binary complementary for negatives */
1956  store16(&pData[116], eg3depth);
1957 
1958  // next 2 bytes unknown
1959 
1960  const uint8_t channeloffset = ChannelOffset * 4;
1961  pData[120] = channeloffset;
1962 
1963  {
1964  uint8_t regoptions = 0;
1965  if (MSDecode) regoptions |= 0x01; // bit 0
1966  if (SustainDefeat) regoptions |= 0x02; // bit 1
1967  pData[121] = regoptions;
1968  }
1969 
1970  // next 2 bytes unknown
1971 
1972  pData[124] = VelocityUpperLimit;
1973 
1974  // next 3 bytes unknown
1975 
1976  pData[128] = ReleaseTriggerDecay;
1977 
1978  // next 2 bytes unknown
1979 
1980  const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
1981  pData[131] = eg1hold;
1982 
1983  const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) | /* bit 7 */
1984  (VCFCutoff & 0x7f); /* lower 7 bits */
1985  pData[132] = vcfcutoff;
1986 
1987  pData[133] = VCFCutoffController;
1988 
1989  const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) | /* bit 7 */
1990  (VCFVelocityScale & 0x7f); /* lower 7 bits */
1991  pData[134] = vcfvelscale;
1992 
1993  // next byte unknown
1994 
1995  const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) | /* bit 7 */
1996  (VCFResonance & 0x7f); /* lower 7 bits */
1997  pData[136] = vcfresonance;
1998 
1999  const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) | /* bit 7 */
2000  (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
2001  pData[137] = vcfbreakpoint;
2002 
2003  const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2004  VCFVelocityCurve * 5;
2005  pData[138] = vcfvelocity;
2006 
2007  const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
2008  pData[139] = vcftype;
2009 
2010  if (chunksize >= 148) {
2011  memcpy(&pData[140], DimensionUpperLimits, 8);
2012  }
2013  }
2014 
2015  double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2016  curve_type_t curveType = releaseVelocityResponseCurve;
2017  uint8_t depth = releaseVelocityResponseDepth;
2018  // this models a strange behaviour or bug in GSt: two of the
2019  // velocity response curves for release time are not used even
2020  // if specified, instead another curve is chosen.
2021  if ((curveType == curve_type_nonlinear && depth == 0) ||
2022  (curveType == curve_type_special && depth == 4)) {
2023  curveType = curve_type_nonlinear;
2024  depth = 3;
2025  }
2026  return GetVelocityTable(curveType, depth, 0);
2027  }
2028 
2029  double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2030  uint8_t vcfVelocityDynamicRange,
2031  uint8_t vcfVelocityScale,
2032  vcf_cutoff_ctrl_t vcfCutoffController)
2033  {
2034  curve_type_t curveType = vcfVelocityCurve;
2035  uint8_t depth = vcfVelocityDynamicRange;
2036  // even stranger GSt: two of the velocity response curves for
2037  // filter cutoff are not used, instead another special curve
2038  // is chosen. This curve is not used anywhere else.
2039  if ((curveType == curve_type_nonlinear && depth == 0) ||
2040  (curveType == curve_type_special && depth == 4)) {
2041  curveType = curve_type_special;
2042  depth = 5;
2043  }
2044  return GetVelocityTable(curveType, depth,
2045  (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2046  ? vcfVelocityScale : 0);
2047  }
2048 
2049  // get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
2050  double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2051  {
2052  double* table;
2053  uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2054  if (pVelocityTables->count(tableKey)) { // if key exists
2055  table = (*pVelocityTables)[tableKey];
2056  }
2057  else {
2058  table = CreateVelocityTable(curveType, depth, scaling);
2059  (*pVelocityTables)[tableKey] = table; // put the new table into the tables map
2060  }
2061  return table;
2062  }
2063 
2065  return pRegion;
2066  }
2067 
2068 // show error if some _lev_ctrl_* enum entry is not listed in the following function
2069 // (commented out for now, because "diagnostic push" not supported prior GCC 4.6)
2070 // TODO: uncomment and add a GCC version check (see also commented "#pragma GCC diagnostic pop" below)
2071 //#pragma GCC diagnostic push
2072 //#pragma GCC diagnostic error "-Wswitch"
2073 
2074  leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2075  leverage_ctrl_t decodedcontroller;
2076  switch (EncodedController) {
2077  // special controller
2078  case _lev_ctrl_none:
2079  decodedcontroller.type = leverage_ctrl_t::type_none;
2080  decodedcontroller.controller_number = 0;
2081  break;
2082  case _lev_ctrl_velocity:
2083  decodedcontroller.type = leverage_ctrl_t::type_velocity;
2084  decodedcontroller.controller_number = 0;
2085  break;
2086  case _lev_ctrl_channelaftertouch:
2087  decodedcontroller.type = leverage_ctrl_t::type_channelaftertouch;
2088  decodedcontroller.controller_number = 0;
2089  break;
2090 
2091  // ordinary MIDI control change controller
2092  case _lev_ctrl_modwheel:
2093  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2094  decodedcontroller.controller_number = 1;
2095  break;
2096  case _lev_ctrl_breath:
2097  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2098  decodedcontroller.controller_number = 2;
2099  break;
2100  case _lev_ctrl_foot:
2101  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2102  decodedcontroller.controller_number = 4;
2103  break;
2104  case _lev_ctrl_effect1:
2105  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2106  decodedcontroller.controller_number = 12;
2107  break;
2108  case _lev_ctrl_effect2:
2109  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2110  decodedcontroller.controller_number = 13;
2111  break;
2112  case _lev_ctrl_genpurpose1:
2113  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2114  decodedcontroller.controller_number = 16;
2115  break;
2116  case _lev_ctrl_genpurpose2:
2117  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2118  decodedcontroller.controller_number = 17;
2119  break;
2120  case _lev_ctrl_genpurpose3:
2121  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2122  decodedcontroller.controller_number = 18;
2123  break;
2124  case _lev_ctrl_genpurpose4:
2125  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2126  decodedcontroller.controller_number = 19;
2127  break;
2128  case _lev_ctrl_portamentotime:
2129  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2130  decodedcontroller.controller_number = 5;
2131  break;
2132  case _lev_ctrl_sustainpedal:
2133  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2134  decodedcontroller.controller_number = 64;
2135  break;
2136  case _lev_ctrl_portamento:
2137  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2138  decodedcontroller.controller_number = 65;
2139  break;
2140  case _lev_ctrl_sostenutopedal:
2141  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2142  decodedcontroller.controller_number = 66;
2143  break;
2144  case _lev_ctrl_softpedal:
2145  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2146  decodedcontroller.controller_number = 67;
2147  break;
2148  case _lev_ctrl_genpurpose5:
2149  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2150  decodedcontroller.controller_number = 80;
2151  break;
2152  case _lev_ctrl_genpurpose6:
2153  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2154  decodedcontroller.controller_number = 81;
2155  break;
2156  case _lev_ctrl_genpurpose7:
2157  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2158  decodedcontroller.controller_number = 82;
2159  break;
2160  case _lev_ctrl_genpurpose8:
2161  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2162  decodedcontroller.controller_number = 83;
2163  break;
2164  case _lev_ctrl_effect1depth:
2165  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2166  decodedcontroller.controller_number = 91;
2167  break;
2168  case _lev_ctrl_effect2depth:
2169  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2170  decodedcontroller.controller_number = 92;
2171  break;
2172  case _lev_ctrl_effect3depth:
2173  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2174  decodedcontroller.controller_number = 93;
2175  break;
2176  case _lev_ctrl_effect4depth:
2177  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2178  decodedcontroller.controller_number = 94;
2179  break;
2180  case _lev_ctrl_effect5depth:
2181  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2182  decodedcontroller.controller_number = 95;
2183  break;
2184 
2185  // format extension (these controllers are so far only supported by
2186  // LinuxSampler & gigedit) they will *NOT* work with
2187  // Gigasampler/GigaStudio !
2188  case _lev_ctrl_CC3_EXT:
2189  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2190  decodedcontroller.controller_number = 3;
2191  break;
2192  case _lev_ctrl_CC6_EXT:
2193  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2194  decodedcontroller.controller_number = 6;
2195  break;
2196  case _lev_ctrl_CC7_EXT:
2197  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2198  decodedcontroller.controller_number = 7;
2199  break;
2200  case _lev_ctrl_CC8_EXT:
2201  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2202  decodedcontroller.controller_number = 8;
2203  break;
2204  case _lev_ctrl_CC9_EXT:
2205  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2206  decodedcontroller.controller_number = 9;
2207  break;
2208  case _lev_ctrl_CC10_EXT:
2209  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2210  decodedcontroller.controller_number = 10;
2211  break;
2212  case _lev_ctrl_CC11_EXT:
2213  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2214  decodedcontroller.controller_number = 11;
2215  break;
2216  case _lev_ctrl_CC14_EXT:
2217  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2218  decodedcontroller.controller_number = 14;
2219  break;
2220  case _lev_ctrl_CC15_EXT:
2221  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2222  decodedcontroller.controller_number = 15;
2223  break;
2224  case _lev_ctrl_CC20_EXT:
2225  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2226  decodedcontroller.controller_number = 20;
2227  break;
2228  case _lev_ctrl_CC21_EXT:
2229  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2230  decodedcontroller.controller_number = 21;
2231  break;
2232  case _lev_ctrl_CC22_EXT:
2233  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2234  decodedcontroller.controller_number = 22;
2235  break;
2236  case _lev_ctrl_CC23_EXT:
2237  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2238  decodedcontroller.controller_number = 23;
2239  break;
2240  case _lev_ctrl_CC24_EXT:
2241  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2242  decodedcontroller.controller_number = 24;
2243  break;
2244  case _lev_ctrl_CC25_EXT:
2245  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2246  decodedcontroller.controller_number = 25;
2247  break;
2248  case _lev_ctrl_CC26_EXT:
2249  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2250  decodedcontroller.controller_number = 26;
2251  break;
2252  case _lev_ctrl_CC27_EXT:
2253  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2254  decodedcontroller.controller_number = 27;
2255  break;
2256  case _lev_ctrl_CC28_EXT:
2257  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2258  decodedcontroller.controller_number = 28;
2259  break;
2260  case _lev_ctrl_CC29_EXT:
2261  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2262  decodedcontroller.controller_number = 29;
2263  break;
2264  case _lev_ctrl_CC30_EXT:
2265  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2266  decodedcontroller.controller_number = 30;
2267  break;
2268  case _lev_ctrl_CC31_EXT:
2269  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2270  decodedcontroller.controller_number = 31;
2271  break;
2272  case _lev_ctrl_CC68_EXT:
2273  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2274  decodedcontroller.controller_number = 68;
2275  break;
2276  case _lev_ctrl_CC69_EXT:
2277  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2278  decodedcontroller.controller_number = 69;
2279  break;
2280  case _lev_ctrl_CC70_EXT:
2281  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2282  decodedcontroller.controller_number = 70;
2283  break;
2284  case _lev_ctrl_CC71_EXT:
2285  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2286  decodedcontroller.controller_number = 71;
2287  break;
2288  case _lev_ctrl_CC72_EXT:
2289  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2290  decodedcontroller.controller_number = 72;
2291  break;
2292  case _lev_ctrl_CC73_EXT:
2293  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2294  decodedcontroller.controller_number = 73;
2295  break;
2296  case _lev_ctrl_CC74_EXT:
2297  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2298  decodedcontroller.controller_number = 74;
2299  break;
2300  case _lev_ctrl_CC75_EXT:
2301  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2302  decodedcontroller.controller_number = 75;
2303  break;
2304  case _lev_ctrl_CC76_EXT:
2305  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2306  decodedcontroller.controller_number = 76;
2307  break;
2308  case _lev_ctrl_CC77_EXT:
2309  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2310  decodedcontroller.controller_number = 77;
2311  break;
2312  case _lev_ctrl_CC78_EXT:
2313  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2314  decodedcontroller.controller_number = 78;
2315  break;
2316  case _lev_ctrl_CC79_EXT:
2317  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2318  decodedcontroller.controller_number = 79;
2319  break;
2320  case _lev_ctrl_CC84_EXT:
2321  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2322  decodedcontroller.controller_number = 84;
2323  break;
2324  case _lev_ctrl_CC85_EXT:
2325  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2326  decodedcontroller.controller_number = 85;
2327  break;
2328  case _lev_ctrl_CC86_EXT:
2329  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2330  decodedcontroller.controller_number = 86;
2331  break;
2332  case _lev_ctrl_CC87_EXT:
2333  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2334  decodedcontroller.controller_number = 87;
2335  break;
2336  case _lev_ctrl_CC89_EXT:
2337  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2338  decodedcontroller.controller_number = 89;
2339  break;
2340  case _lev_ctrl_CC90_EXT:
2341  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2342  decodedcontroller.controller_number = 90;
2343  break;
2344  case _lev_ctrl_CC96_EXT:
2345  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2346  decodedcontroller.controller_number = 96;
2347  break;
2348  case _lev_ctrl_CC97_EXT:
2349  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2350  decodedcontroller.controller_number = 97;
2351  break;
2352  case _lev_ctrl_CC102_EXT:
2353  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2354  decodedcontroller.controller_number = 102;
2355  break;
2356  case _lev_ctrl_CC103_EXT:
2357  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2358  decodedcontroller.controller_number = 103;
2359  break;
2360  case _lev_ctrl_CC104_EXT:
2361  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2362  decodedcontroller.controller_number = 104;
2363  break;
2364  case _lev_ctrl_CC105_EXT:
2365  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2366  decodedcontroller.controller_number = 105;
2367  break;
2368  case _lev_ctrl_CC106_EXT:
2369  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2370  decodedcontroller.controller_number = 106;
2371  break;
2372  case _lev_ctrl_CC107_EXT:
2373  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2374  decodedcontroller.controller_number = 107;
2375  break;
2376  case _lev_ctrl_CC108_EXT:
2377  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2378  decodedcontroller.controller_number = 108;
2379  break;
2380  case _lev_ctrl_CC109_EXT:
2381  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2382  decodedcontroller.controller_number = 109;
2383  break;
2384  case _lev_ctrl_CC110_EXT:
2385  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2386  decodedcontroller.controller_number = 110;
2387  break;
2388  case _lev_ctrl_CC111_EXT:
2389  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2390  decodedcontroller.controller_number = 111;
2391  break;
2392  case _lev_ctrl_CC112_EXT:
2393  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2394  decodedcontroller.controller_number = 112;
2395  break;
2396  case _lev_ctrl_CC113_EXT:
2397  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2398  decodedcontroller.controller_number = 113;
2399  break;
2400  case _lev_ctrl_CC114_EXT:
2401  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2402  decodedcontroller.controller_number = 114;
2403  break;
2404  case _lev_ctrl_CC115_EXT:
2405  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2406  decodedcontroller.controller_number = 115;
2407  break;
2408  case _lev_ctrl_CC116_EXT:
2409  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2410  decodedcontroller.controller_number = 116;
2411  break;
2412  case _lev_ctrl_CC117_EXT:
2413  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2414  decodedcontroller.controller_number = 117;
2415  break;
2416  case _lev_ctrl_CC118_EXT:
2417  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2418  decodedcontroller.controller_number = 118;
2419  break;
2420  case _lev_ctrl_CC119_EXT:
2421  decodedcontroller.type = leverage_ctrl_t::type_controlchange;
2422  decodedcontroller.controller_number = 119;
2423  break;
2424 
2425  // unknown controller type
2426  default:
2427  throw gig::Exception("Unknown leverage controller type.");
2428  }
2429  return decodedcontroller;
2430  }
2431 
2432 // see above (diagnostic push not supported prior GCC 4.6)
2433 //#pragma GCC diagnostic pop
2434 
2435  DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2436  _lev_ctrl_t encodedcontroller;
2437  switch (DecodedController.type) {
2438  // special controller
2440  encodedcontroller = _lev_ctrl_none;
2441  break;
2443  encodedcontroller = _lev_ctrl_velocity;
2444  break;
2446  encodedcontroller = _lev_ctrl_channelaftertouch;
2447  break;
2448 
2449  // ordinary MIDI control change controller
2451  switch (DecodedController.controller_number) {
2452  case 1:
2453  encodedcontroller = _lev_ctrl_modwheel;
2454  break;
2455  case 2:
2456  encodedcontroller = _lev_ctrl_breath;
2457  break;
2458  case 4:
2459  encodedcontroller = _lev_ctrl_foot;
2460  break;
2461  case 12:
2462  encodedcontroller = _lev_ctrl_effect1;
2463  break;
2464  case 13:
2465  encodedcontroller = _lev_ctrl_effect2;
2466  break;
2467  case 16:
2468  encodedcontroller = _lev_ctrl_genpurpose1;
2469  break;
2470  case 17:
2471  encodedcontroller = _lev_ctrl_genpurpose2;
2472  break;
2473  case 18:
2474  encodedcontroller = _lev_ctrl_genpurpose3;
2475  break;
2476  case 19:
2477  encodedcontroller = _lev_ctrl_genpurpose4;
2478  break;
2479  case 5:
2480  encodedcontroller = _lev_ctrl_portamentotime;
2481  break;
2482  case 64:
2483  encodedcontroller = _lev_ctrl_sustainpedal;
2484  break;
2485  case 65:
2486  encodedcontroller = _lev_ctrl_portamento;
2487  break;
2488  case 66:
2489  encodedcontroller = _lev_ctrl_sostenutopedal;
2490  break;
2491  case 67:
2492  encodedcontroller = _lev_ctrl_softpedal;
2493  break;
2494  case 80:
2495  encodedcontroller = _lev_ctrl_genpurpose5;
2496  break;
2497  case 81:
2498  encodedcontroller = _lev_ctrl_genpurpose6;
2499  break;
2500  case 82:
2501  encodedcontroller = _lev_ctrl_genpurpose7;
2502  break;
2503  case 83:
2504  encodedcontroller = _lev_ctrl_genpurpose8;
2505  break;
2506  case 91:
2507  encodedcontroller = _lev_ctrl_effect1depth;
2508  break;
2509  case 92:
2510  encodedcontroller = _lev_ctrl_effect2depth;
2511  break;
2512  case 93:
2513  encodedcontroller = _lev_ctrl_effect3depth;
2514  break;
2515  case 94:
2516  encodedcontroller = _lev_ctrl_effect4depth;
2517  break;
2518  case 95:
2519  encodedcontroller = _lev_ctrl_effect5depth;
2520  break;
2521 
2522  // format extension (these controllers are so far only
2523  // supported by LinuxSampler & gigedit) they will *NOT*
2524  // work with Gigasampler/GigaStudio !
2525  case 3:
2526  encodedcontroller = _lev_ctrl_CC3_EXT;
2527  break;
2528  case 6:
2529  encodedcontroller = _lev_ctrl_CC6_EXT;
2530  break;
2531  case 7:
2532  encodedcontroller = _lev_ctrl_CC7_EXT;
2533  break;
2534  case 8:
2535  encodedcontroller = _lev_ctrl_CC8_EXT;
2536  break;
2537  case 9:
2538  encodedcontroller = _lev_ctrl_CC9_EXT;
2539  break;
2540  case 10:
2541  encodedcontroller = _lev_ctrl_CC10_EXT;
2542  break;
2543  case 11:
2544  encodedcontroller = _lev_ctrl_CC11_EXT;
2545  break;
2546  case 14:
2547  encodedcontroller = _lev_ctrl_CC14_EXT;
2548  break;
2549  case 15:
2550  encodedcontroller = _lev_ctrl_CC15_EXT;
2551  break;
2552  case 20:
2553  encodedcontroller = _lev_ctrl_CC20_EXT;
2554  break;
2555  case 21:
2556  encodedcontroller = _lev_ctrl_CC21_EXT;
2557  break;
2558  case 22:
2559  encodedcontroller = _lev_ctrl_CC22_EXT;
2560  break;
2561  case 23:
2562  encodedcontroller = _lev_ctrl_CC23_EXT;
2563  break;
2564  case 24:
2565  encodedcontroller = _lev_ctrl_CC24_EXT;
2566  break;
2567  case 25:
2568  encodedcontroller = _lev_ctrl_CC25_EXT;
2569  break;
2570  case 26:
2571  encodedcontroller = _lev_ctrl_CC26_EXT;
2572  break;
2573  case 27:
2574  encodedcontroller = _lev_ctrl_CC27_EXT;
2575  break;
2576  case 28:
2577  encodedcontroller = _lev_ctrl_CC28_EXT;
2578  break;
2579  case 29:
2580  encodedcontroller = _lev_ctrl_CC29_EXT;
2581  break;
2582  case 30:
2583  encodedcontroller = _lev_ctrl_CC30_EXT;
2584  break;
2585  case 31:
2586  encodedcontroller = _lev_ctrl_CC31_EXT;
2587  break;
2588  case 68:
2589  encodedcontroller = _lev_ctrl_CC68_EXT;
2590  break;
2591  case 69:
2592  encodedcontroller = _lev_ctrl_CC69_EXT;
2593  break;
2594  case 70:
2595  encodedcontroller = _lev_ctrl_CC70_EXT;
2596  break;
2597  case 71:
2598  encodedcontroller = _lev_ctrl_CC71_EXT;
2599  break;
2600  case 72:
2601  encodedcontroller = _lev_ctrl_CC72_EXT;
2602  break;
2603  case 73:
2604  encodedcontroller = _lev_ctrl_CC73_EXT;
2605  break;
2606  case 74:
2607  encodedcontroller = _lev_ctrl_CC74_EXT;
2608  break;
2609  case 75:
2610  encodedcontroller = _lev_ctrl_CC75_EXT;
2611  break;
2612  case 76:
2613  encodedcontroller = _lev_ctrl_CC76_EXT;
2614  break;
2615  case 77:
2616  encodedcontroller = _lev_ctrl_CC77_EXT;
2617  break;
2618  case 78:
2619  encodedcontroller = _lev_ctrl_CC78_EXT;
2620  break;
2621  case 79:
2622  encodedcontroller = _lev_ctrl_CC79_EXT;
2623  break;
2624  case 84:
2625  encodedcontroller = _lev_ctrl_CC84_EXT;
2626  break;
2627  case 85:
2628  encodedcontroller = _lev_ctrl_CC85_EXT;
2629  break;
2630  case 86:
2631  encodedcontroller = _lev_ctrl_CC86_EXT;
2632  break;
2633  case 87:
2634  encodedcontroller = _lev_ctrl_CC87_EXT;
2635  break;
2636  case 89:
2637  encodedcontroller = _lev_ctrl_CC89_EXT;
2638  break;
2639  case 90:
2640  encodedcontroller = _lev_ctrl_CC90_EXT;
2641  break;
2642  case 96:
2643  encodedcontroller = _lev_ctrl_CC96_EXT;
2644  break;
2645  case 97:
2646  encodedcontroller = _lev_ctrl_CC97_EXT;
2647  break;
2648  case 102:
2649  encodedcontroller = _lev_ctrl_CC102_EXT;
2650  break;
2651  case 103:
2652  encodedcontroller = _lev_ctrl_CC103_EXT;
2653  break;
2654  case 104:
2655  encodedcontroller = _lev_ctrl_CC104_EXT;
2656  break;
2657  case 105:
2658  encodedcontroller = _lev_ctrl_CC105_EXT;
2659  break;
2660  case 106:
2661  encodedcontroller = _lev_ctrl_CC106_EXT;
2662  break;
2663  case 107:
2664  encodedcontroller = _lev_ctrl_CC107_EXT;
2665  break;
2666  case 108:
2667  encodedcontroller = _lev_ctrl_CC108_EXT;
2668  break;
2669  case 109:
2670  encodedcontroller = _lev_ctrl_CC109_EXT;
2671  break;
2672  case 110:
2673  encodedcontroller = _lev_ctrl_CC110_EXT;
2674  break;
2675  case 111:
2676  encodedcontroller = _lev_ctrl_CC111_EXT;
2677  break;
2678  case 112:
2679  encodedcontroller = _lev_ctrl_CC112_EXT;
2680  break;
2681  case 113:
2682  encodedcontroller = _lev_ctrl_CC113_EXT;
2683  break;
2684  case 114:
2685  encodedcontroller = _lev_ctrl_CC114_EXT;
2686  break;
2687  case 115:
2688  encodedcontroller = _lev_ctrl_CC115_EXT;
2689  break;
2690  case 116:
2691  encodedcontroller = _lev_ctrl_CC116_EXT;
2692  break;
2693  case 117:
2694  encodedcontroller = _lev_ctrl_CC117_EXT;
2695  break;
2696  case 118:
2697  encodedcontroller = _lev_ctrl_CC118_EXT;
2698  break;
2699  case 119:
2700  encodedcontroller = _lev_ctrl_CC119_EXT;
2701  break;
2702 
2703  default:
2704  throw gig::Exception("leverage controller number is not supported by the gig format");
2705  }
2706  break;
2707  default:
2708  throw gig::Exception("Unknown leverage controller type.");
2709  }
2710  return encodedcontroller;
2711  }
2712 
2714  Instances--;
2715  if (!Instances) {
2716  // delete the velocity->volume tables
2717  VelocityTableMap::iterator iter;
2718  for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
2719  double* pTable = iter->second;
2720  if (pTable) delete[] pTable;
2721  }
2722  pVelocityTables->clear();
2723  delete pVelocityTables;
2724  pVelocityTables = NULL;
2725  }
2726  if (VelocityTable) delete[] VelocityTable;
2727  }
2728 
2740  double DimensionRegion::GetVelocityAttenuation(uint8_t MIDIKeyVelocity) {
2741  return pVelocityAttenuationTable[MIDIKeyVelocity];
2742  }
2743 
2744  double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
2745  return pVelocityReleaseTable[MIDIKeyVelocity];
2746  }
2747 
2748  double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
2749  return pVelocityCutoffTable[MIDIKeyVelocity];
2750  }
2751 
2757  pVelocityAttenuationTable =
2758  GetVelocityTable(
2760  );
2761  VelocityResponseCurve = curve;
2762  }
2763 
2769  pVelocityAttenuationTable =
2770  GetVelocityTable(
2772  );
2773  VelocityResponseDepth = depth;
2774  }
2775 
2781  pVelocityAttenuationTable =
2782  GetVelocityTable(
2784  );
2785  VelocityResponseCurveScaling = scaling;
2786  }
2787 
2793  pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
2795  }
2796 
2802  pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
2804  }
2805 
2811  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
2812  VCFCutoffController = controller;
2813  }
2814 
2820  pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
2821  VCFVelocityCurve = curve;
2822  }
2823 
2829  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
2830  VCFVelocityDynamicRange = range;
2831  }
2832 
2838  pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
2839  VCFVelocityScale = scaling;
2840  }
2841 
2842  double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
2843 
2844  // line-segment approximations of the 15 velocity curves
2845 
2846  // linear
2847  const int lin0[] = { 1, 1, 127, 127 };
2848  const int lin1[] = { 1, 21, 127, 127 };
2849  const int lin2[] = { 1, 45, 127, 127 };
2850  const int lin3[] = { 1, 74, 127, 127 };
2851  const int lin4[] = { 1, 127, 127, 127 };
2852 
2853  // non-linear
2854  const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
2855  const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
2856  127, 127 };
2857  const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
2858  127, 127 };
2859  const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
2860  127, 127 };
2861  const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
2862 
2863  // special
2864  const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
2865  113, 127, 127, 127 };
2866  const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
2867  118, 127, 127, 127 };
2868  const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
2869  85, 90, 91, 127, 127, 127 };
2870  const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
2871  117, 127, 127, 127 };
2872  const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
2873  127, 127 };
2874 
2875  // this is only used by the VCF velocity curve
2876  const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
2877  91, 127, 127, 127 };
2878 
2879  const int* const curves[] = { non0, non1, non2, non3, non4,
2880  lin0, lin1, lin2, lin3, lin4,
2881  spe0, spe1, spe2, spe3, spe4, spe5 };
2882 
2883  double* const table = new double[128];
2884 
2885  const int* curve = curves[curveType * 5 + depth];
2886  const int s = scaling == 0 ? 20 : scaling; // 0 or 20 means no scaling
2887 
2888  table[0] = 0;
2889  for (int x = 1 ; x < 128 ; x++) {
2890 
2891  if (x > curve[2]) curve += 2;
2892  double y = curve[1] + (x - curve[0]) *
2893  (double(curve[3] - curve[1]) / (curve[2] - curve[0]));
2894  y = y / 127;
2895 
2896  // Scale up for s > 20, down for s < 20. When
2897  // down-scaling, the curve still ends at 1.0.
2898  if (s < 20 && y >= 0.5)
2899  y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
2900  else
2901  y = y * (s / 20.0);
2902  if (y > 1) y = 1;
2903 
2904  table[x] = y;
2905  }
2906  return table;
2907  }
2908 
2909 
2910 // *************** Region ***************
2911 // *
2912 
2913  Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
2914  // Initialization
2915  Dimensions = 0;
2916  for (int i = 0; i < 256; i++) {
2917  pDimensionRegions[i] = NULL;
2918  }
2919  Layers = 1;
2920  File* file = (File*) GetParent()->GetParent();
2921  int dimensionBits = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
2922 
2923  // Actual Loading
2924 
2925  if (!file->GetAutoLoad()) return;
2926 
2927  LoadDimensionRegions(rgnList);
2928 
2929  RIFF::Chunk* _3lnk = rgnList->GetSubChunk(CHUNK_ID_3LNK);
2930  if (_3lnk) {
2931  DimensionRegions = _3lnk->ReadUint32();
2932  for (int i = 0; i < dimensionBits; i++) {
2933  dimension_t dimension = static_cast<dimension_t>(_3lnk->ReadUint8());
2934  uint8_t bits = _3lnk->ReadUint8();
2935  _3lnk->ReadUint8(); // bit position of the dimension (bits[0] + bits[1] + ... + bits[i-1])
2936  _3lnk->ReadUint8(); // (1 << bit position of next dimension) - (1 << bit position of this dimension)
2937  uint8_t zones = _3lnk->ReadUint8(); // new for v3: number of zones doesn't have to be == pow(2,bits)
2938  if (dimension == dimension_none) { // inactive dimension
2940  pDimensionDefinitions[i].bits = 0;
2944  }
2945  else { // active dimension
2946  pDimensionDefinitions[i].dimension = dimension;
2947  pDimensionDefinitions[i].bits = bits;
2948  pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits; // = pow(2,bits)
2949  pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
2950  pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
2951  Dimensions++;
2952 
2953  // if this is a layer dimension, remember the amount of layers
2954  if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
2955  }
2956  _3lnk->SetPos(3, RIFF::stream_curpos); // jump forward to next dimension definition
2957  }
2958  for (int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
2959 
2960  // if there's a velocity dimension and custom velocity zone splits are used,
2961  // update the VelocityTables in the dimension regions
2963 
2964  // jump to start of the wave pool indices (if not already there)
2965  if (file->pVersion && file->pVersion->major == 3)
2966  _3lnk->SetPos(68); // version 3 has a different 3lnk structure
2967  else
2968  _3lnk->SetPos(44);
2969 
2970  // load sample references (if auto loading is enabled)
2971  if (file->GetAutoLoad()) {
2972  for (uint i = 0; i < DimensionRegions; i++) {
2973  uint32_t wavepoolindex = _3lnk->ReadUint32();
2974  if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
2975  }
2976  GetSample(); // load global region sample reference
2977  }
2978  } else {
2979  DimensionRegions = 0;
2980  for (int i = 0 ; i < 8 ; i++) {
2982  pDimensionDefinitions[i].bits = 0;
2984  }
2985  }
2986 
2987  // make sure there is at least one dimension region
2988  if (!DimensionRegions) {
2989  RIFF::List* _3prg = rgnList->GetSubList(LIST_TYPE_3PRG);
2990  if (!_3prg) _3prg = rgnList->AddSubList(LIST_TYPE_3PRG);
2991  RIFF::List* _3ewl = _3prg->AddSubList(LIST_TYPE_3EWL);
2992  pDimensionRegions[0] = new DimensionRegion(this, _3ewl);
2993  DimensionRegions = 1;
2994  }
2995  }
2996 
3008  // in the gig format we don't care about the Region's sample reference
3009  // but we still have to provide some existing one to not corrupt the
3010  // file, so to avoid the latter we simply always assign the sample of
3011  // the first dimension region of this region
3013 
3014  // first update base class's chunks
3015  DLS::Region::UpdateChunks(pProgress);
3016 
3017  // update dimension region's chunks
3018  for (int i = 0; i < DimensionRegions; i++) {
3019  pDimensionRegions[i]->UpdateChunks(pProgress);
3020  }
3021 
3022  File* pFile = (File*) GetParent()->GetParent();
3023  bool version3 = pFile->pVersion && pFile->pVersion->major == 3;
3024  const int iMaxDimensions = version3 ? 8 : 5;
3025  const int iMaxDimensionRegions = version3 ? 256 : 32;
3026 
3027  // make sure '3lnk' chunk exists
3029  if (!_3lnk) {
3030  const int _3lnkChunkSize = version3 ? 1092 : 172;
3031  _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3032  memset(_3lnk->LoadChunkData(), 0, _3lnkChunkSize);
3033 
3034  // move 3prg to last position
3036  }
3037 
3038  // update dimension definitions in '3lnk' chunk
3039  uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
3040  store32(&pData[0], DimensionRegions);
3041  int shift = 0;
3042  for (int i = 0; i < iMaxDimensions; i++) {
3043  pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3044  pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3045  pData[6 + i * 8] = pDimensionDefinitions[i].dimension == dimension_none ? 0 : shift;
3046  pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3047  pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3048  // next 3 bytes unknown, always zero?
3049 
3050  shift += pDimensionDefinitions[i].bits;
3051  }
3052 
3053  // update wave pool table in '3lnk' chunk
3054  const int iWavePoolOffset = version3 ? 68 : 44;
3055  for (uint i = 0; i < iMaxDimensionRegions; i++) {
3056  int iWaveIndex = -1;
3057  if (i < DimensionRegions) {
3058  if (!pFile->pSamples || !pFile->pSamples->size()) throw gig::Exception("Could not update gig::Region, there are no samples");
3059  File::SampleList::iterator iter = pFile->pSamples->begin();
3060  File::SampleList::iterator end = pFile->pSamples->end();
3061  for (int index = 0; iter != end; ++iter, ++index) {
3062  if (*iter == pDimensionRegions[i]->pSample) {
3063  iWaveIndex = index;
3064  break;
3065  }
3066  }
3067  }
3068  store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3069  }
3070  }
3071 
3073  RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG);
3074  if (_3prg) {
3075  int dimensionRegionNr = 0;
3076  RIFF::List* _3ewl = _3prg->GetFirstSubList();
3077  while (_3ewl) {
3078  if (_3ewl->GetListType() == LIST_TYPE_3EWL) {
3079  pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl);
3080  dimensionRegionNr++;
3081  }
3082  _3ewl = _3prg->GetNextSubList();
3083  }
3084  if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found.");
3085  }
3086  }
3087 
3088  void Region::SetKeyRange(uint16_t Low, uint16_t High) {
3089  // update KeyRange struct and make sure regions are in correct order
3090  DLS::Region::SetKeyRange(Low, High);
3091  // update Region key table for fast lookup
3092  ((gig::Instrument*)GetParent())->UpdateRegionKeyTable();
3093  }
3094 
3096  // get velocity dimension's index
3097  int veldim = -1;
3098  for (int i = 0 ; i < Dimensions ; i++) {
3099  if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3100  veldim = i;
3101  break;
3102  }
3103  }
3104  if (veldim == -1) return;
3105 
3106  int step = 1;
3107  for (int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3108  int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3109 
3110  // loop through all dimension regions for all dimensions except the velocity dimension
3111  int dim[8] = { 0 };
3112  for (int i = 0 ; i < DimensionRegions ; i++) {
3113  const int end = i + step * pDimensionDefinitions[veldim].zones;
3114 
3115  // create a velocity table for all cases where the velocity zone is zero
3116  if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3117  pDimensionRegions[i]->VelocityUpperLimit) {
3118  // create the velocity table
3119  uint8_t* table = pDimensionRegions[i]->VelocityTable;
3120  if (!table) {
3121  table = new uint8_t[128];
3122  pDimensionRegions[i]->VelocityTable = table;
3123  }
3124  int tableidx = 0;
3125  int velocityZone = 0;
3126  if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) { // gig3
3127  for (int k = i ; k < end ; k += step) {
3129  for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3130  velocityZone++;
3131  }
3132  } else { // gig2
3133  for (int k = i ; k < end ; k += step) {
3135  for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3136  velocityZone++;
3137  }
3138  }
3139  } else {
3140  if (pDimensionRegions[i]->VelocityTable) {
3141  delete[] pDimensionRegions[i]->VelocityTable;
3143  }
3144  }
3145 
3146  // jump to the next case where the velocity zone is zero
3147  int j;
3148  int shift = 0;
3149  for (j = 0 ; j < Dimensions ; j++) {
3150  if (j == veldim) i += skipveldim; // skip velocity dimension
3151  else {
3152  dim[j]++;
3153  if (dim[j] < pDimensionDefinitions[j].zones) break;
3154  else {
3155  // skip unused dimension regions
3156  dim[j] = 0;
3157  i += ((1 << pDimensionDefinitions[j].bits) -
3158  pDimensionDefinitions[j].zones) << shift;
3159  }
3160  }
3161  shift += pDimensionDefinitions[j].bits;
3162  }
3163  if (j == Dimensions) break;
3164  }
3165  }
3166 
3183  // some initial sanity checks of the given dimension definition
3184  if (pDimDef->zones < 2)
3185  throw gig::Exception("Could not add new dimension, amount of requested zones must always be at least two");
3186  if (pDimDef->bits < 1)
3187  throw gig::Exception("Could not add new dimension, amount of requested requested zone bits must always be at least one");
3188  if (pDimDef->dimension == dimension_samplechannel) {
3189  if (pDimDef->zones != 2)
3190  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3191  if (pDimDef->bits != 1)
3192  throw gig::Exception("Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3193  }
3194 
3195  // check if max. amount of dimensions reached
3196  File* file = (File*) GetParent()->GetParent();
3197  const int iMaxDimensions = (file->pVersion && file->pVersion->major == 3) ? 8 : 5;
3198  if (Dimensions >= iMaxDimensions)
3199  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimensions already reached");
3200  // check if max. amount of dimension bits reached
3201  int iCurrentBits = 0;
3202  for (int i = 0; i < Dimensions; i++)
3203  iCurrentBits += pDimensionDefinitions[i].bits;
3204  if (iCurrentBits >= iMaxDimensions)
3205  throw gig::Exception("Could not add new dimension, max. amount of " + ToString(iMaxDimensions) + " dimension bits already reached");
3206  const int iNewBits = iCurrentBits + pDimDef->bits;
3207  if (iNewBits > iMaxDimensions)
3208  throw gig::Exception("Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) + " dimension bits");
3209  // check if there's already a dimensions of the same type
3210  for (int i = 0; i < Dimensions; i++)
3211  if (pDimensionDefinitions[i].dimension == pDimDef->dimension)
3212  throw gig::Exception("Could not add new dimension, there is already a dimension of the same type");
3213 
3214  // pos is where the new dimension should be placed, normally
3215  // last in list, except for the samplechannel dimension which
3216  // has to be first in list
3217  int pos = pDimDef->dimension == dimension_samplechannel ? 0 : Dimensions;
3218  int bitpos = 0;
3219  for (int i = 0 ; i < pos ; i++)
3220  bitpos += pDimensionDefinitions[i].bits;
3221 
3222  // make room for the new dimension
3223  for (int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3224  for (int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3225  for (int j = Dimensions ; j > pos ; j--) {
3228  }
3229  }
3230 
3231  // assign definition of new dimension
3232  pDimensionDefinitions[pos] = *pDimDef;
3233 
3234  // auto correct certain dimension definition fields (where possible)
3236  __resolveSplitType(pDimensionDefinitions[pos].dimension);
3238  __resolveZoneSize(pDimensionDefinitions[pos]);
3239 
3240  // create new dimension region(s) for this new dimension, and make
3241  // sure that the dimension regions are placed correctly in both the
3242  // RIFF list and the pDimensionRegions array
3243  RIFF::Chunk* moveTo = NULL;
3245  for (int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3246  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3247  pDimensionRegions[(i << pDimDef->bits) + k] = pDimensionRegions[i + k];
3248  }
3249  for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) {
3250  for (int k = 0 ; k < (1 << bitpos) ; k++) {
3251  RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL);
3252  if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo);
3253  // create a new dimension region and copy all parameter values from
3254  // an existing dimension region
3255  pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] =
3256  new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]);
3257 
3258  DimensionRegions++;
3259  }
3260  }
3261  moveTo = pDimensionRegions[i]->pParentList;
3262  }
3263 
3264  // initialize the upper limits for this dimension
3265  int mask = (1 << bitpos) - 1;
3266  for (int z = 0 ; z < pDimDef->zones ; z++) {
3267  uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->zones - 1);
3268  for (int i = 0 ; i < 1 << iCurrentBits ; i++) {
3269  pDimensionRegions[((i & ~mask) << pDimDef->bits) |
3270  (z << bitpos) |
3271  (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3272  }
3273  }
3274 
3275  Dimensions++;
3276 
3277  // if this is a layer dimension, update 'Layers' attribute
3278  if (pDimDef->dimension == dimension_layer) Layers = pDimDef->zones;
3279 
3281  }
3282 
3295  // get dimension's index
3296  int iDimensionNr = -1;
3297  for (int i = 0; i < Dimensions; i++) {
3298  if (&pDimensionDefinitions[i] == pDimDef) {
3299  iDimensionNr = i;
3300  break;
3301  }
3302  }
3303  if (iDimensionNr < 0) throw gig::Exception("Invalid dimension_def_t pointer");
3304 
3305  // get amount of bits below the dimension to delete
3306  int iLowerBits = 0;
3307  for (int i = 0; i < iDimensionNr; i++)
3308  iLowerBits += pDimensionDefinitions[i].bits;
3309 
3310  // get amount ot bits above the dimension to delete
3311  int iUpperBits = 0;
3312  for (int i = iDimensionNr + 1; i < Dimensions; i++)
3313  iUpperBits += pDimensionDefinitions[i].bits;
3314 
3316 
3317  // delete dimension regions which belong to the given dimension
3318  // (that is where the dimension's bit > 0)
3319  for (int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3320  for (int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3321  for (int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3322  int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3323  iObsoleteBit << iLowerBits |
3324  iLowerBit;
3325 
3326  _3prg->DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3327  delete pDimensionRegions[iToDelete];
3328  pDimensionRegions[iToDelete] = NULL;
3329  DimensionRegions--;
3330  }
3331  }
3332  }
3333 
3334  // defrag pDimensionRegions array
3335  // (that is remove the NULL spaces within the pDimensionRegions array)
3336  for (int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3337  if (!pDimensionRegions[iTo]) {
3338  if (iFrom <= iTo) iFrom = iTo + 1;
3339  while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3340  if (iFrom < 256 && pDimensionRegions[iFrom]) {
3341  pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3342  pDimensionRegions[iFrom] = NULL;
3343  }
3344  }
3345  }
3346 
3347  // remove the this dimension from the upper limits arrays
3348  for (int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3349  DimensionRegion* d = pDimensionRegions[j];
3350  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3351  d->DimensionUpperLimits[i - 1] = d->DimensionUpperLimits[i];
3352  }
3353  d->DimensionUpperLimits[Dimensions - 1] = 127;
3354  }
3355 
3356  // 'remove' dimension definition
3357  for (int i = iDimensionNr + 1; i < Dimensions; i++) {
3359  }
3361  pDimensionDefinitions[Dimensions - 1].bits = 0;
3362  pDimensionDefinitions[Dimensions - 1].zones = 0;
3363 
3364  Dimensions--;
3365 
3366  // if this was a layer dimension, update 'Layers' attribute
3367  if (pDimDef->dimension == dimension_layer) Layers = 1;
3368  }
3369 
3385  dimension_def_t* oldDef = GetDimensionDefinition(type);
3386  if (!oldDef)
3387  throw gig::Exception("Could not delete dimension zone, no such dimension of given type");
3388  if (oldDef->zones <= 2)
3389  throw gig::Exception("Could not delete dimension zone, because it would end up with only one zone.");
3390  if (zone < 0 || zone >= oldDef->zones)
3391  throw gig::Exception("Could not delete dimension zone, requested zone index out of bounds.");
3392 
3393  const int newZoneSize = oldDef->zones - 1;
3394 
3395  // create a temporary Region which just acts as a temporary copy
3396  // container and will be deleted at the end of this function and will
3397  // also not be visible through the API during this process
3398  gig::Region* tempRgn = NULL;
3399  {
3400  // adding these temporary chunks is probably not even necessary
3401  Instrument* instr = static_cast<Instrument*>(GetParent());
3402  RIFF::List* pCkInstrument = instr->pCkInstrument;
3403  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3404  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3405  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3406  tempRgn = new Region(instr, rgn);
3407  }
3408 
3409  // copy this region's dimensions (with already the dimension split size
3410  // requested by the arguments of this method call) to the temporary
3411  // region, and don't use Region::CopyAssign() here for this task, since
3412  // it would also alter fast lookup helper variables here and there
3413  dimension_def_t newDef;
3414  for (int i = 0; i < Dimensions; ++i) {
3415  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3416  // is this the dimension requested by the method arguments? ...
3417  if (def.dimension == type) { // ... if yes, decrement zone amount by one
3418  def.zones = newZoneSize;
3419  if ((1 << (def.bits - 1)) == def.zones) def.bits--;
3420  newDef = def;
3421  }
3422  tempRgn->AddDimension(&def);
3423  }
3424 
3425  // find the dimension index in the tempRegion which is the dimension
3426  // type passed to this method (paranoidly expecting different order)
3427  int tempReducedDimensionIndex = -1;
3428  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3429  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3430  tempReducedDimensionIndex = d;
3431  break;
3432  }
3433  }
3434 
3435  // copy dimension regions from this region to the temporary region
3436  for (int iDst = 0; iDst < 256; ++iDst) {
3437  DimensionRegion* dstDimRgn = tempRgn->pDimensionRegions[iDst];
3438  if (!dstDimRgn) continue;
3439  std::map<dimension_t,int> dimCase;
3440  bool isValidZone = true;
3441  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3442  const int dstBits = tempRgn->pDimensionDefinitions[d].bits;
3443  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3444  (iDst >> baseBits) & ((1 << dstBits) - 1);
3445  baseBits += dstBits;
3446  // there are also DimensionRegion objects of unused zones, skip them
3447  if (dimCase[tempRgn->pDimensionDefinitions[d].dimension] >= tempRgn->pDimensionDefinitions[d].zones) {
3448  isValidZone = false;
3449  break;
3450  }
3451  }
3452  if (!isValidZone) continue;
3453  // a bit paranoid: cope with the chance that the dimensions would
3454  // have different order in source and destination regions
3455  const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3456  if (dimCase[type] >= zone) dimCase[type]++;
3457  DimensionRegion* srcDimRgn = GetDimensionRegionByBit(dimCase);
3458  dstDimRgn->CopyAssign(srcDimRgn);
3459  // if this is the upper most zone of the dimension passed to this
3460  // method, then correct (raise) its upper limit to 127
3461  if (newDef.split_type == split_type_normal && isLastZone)
3462  dstDimRgn->DimensionUpperLimits[tempReducedDimensionIndex] = 127;
3463  }
3464 
3465  // now tempRegion's dimensions and DimensionRegions basically reflect
3466  // what we wanted to get for this actual Region here, so we now just
3467  // delete and recreate the dimension in question with the new amount
3468  // zones and then copy back from tempRegion
3469  DeleteDimension(oldDef);
3470  AddDimension(&newDef);
3471  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3472  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3473  if (!srcDimRgn) continue;
3474  std::map<dimension_t,int> dimCase;
3475  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3476  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3477  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3478  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3479  baseBits += srcBits;
3480  }
3481  // a bit paranoid: cope with the chance that the dimensions would
3482  // have different order in source and destination regions
3483  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3484  if (!dstDimRgn) continue;
3485  dstDimRgn->CopyAssign(srcDimRgn);
3486  }
3487 
3488  // delete temporary region
3489  delete tempRgn;
3490 
3492  }
3493 
3509  dimension_def_t* oldDef = GetDimensionDefinition(type);
3510  if (!oldDef)
3511  throw gig::Exception("Could not split dimension zone, no such dimension of given type");
3512  if (zone < 0 || zone >= oldDef->zones)
3513  throw gig::Exception("Could not split dimension zone, requested zone index out of bounds.");
3514 
3515  const int newZoneSize = oldDef->zones + 1;
3516 
3517  // create a temporary Region which just acts as a temporary copy
3518  // container and will be deleted at the end of this function and will
3519  // also not be visible through the API during this process
3520  gig::Region* tempRgn = NULL;
3521  {
3522  // adding these temporary chunks is probably not even necessary
3523  Instrument* instr = static_cast<Instrument*>(GetParent());
3524  RIFF::List* pCkInstrument = instr->pCkInstrument;
3525  RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
3526  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
3527  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
3528  tempRgn = new Region(instr, rgn);
3529  }
3530 
3531  // copy this region's dimensions (with already the dimension split size
3532  // requested by the arguments of this method call) to the temporary
3533  // region, and don't use Region::CopyAssign() here for this task, since
3534  // it would also alter fast lookup helper variables here and there
3535  dimension_def_t newDef;
3536  for (int i = 0; i < Dimensions; ++i) {
3537  dimension_def_t def = pDimensionDefinitions[i]; // copy, don't reference
3538  // is this the dimension requested by the method arguments? ...
3539  if (def.dimension == type) { // ... if yes, increment zone amount by one
3540  def.zones = newZoneSize;
3541  if ((1 << oldDef->bits) < newZoneSize) def.bits++;
3542  newDef = def;
3543  }
3544  tempRgn->AddDimension(&def);
3545  }
3546 
3547  // find the dimension index in the tempRegion which is the dimension
3548  // type passed to this method (paranoidly expecting different order)
3549  int tempIncreasedDimensionIndex = -1;
3550  for (int d = 0; d < tempRgn->Dimensions; ++d) {
3551  if (tempRgn->pDimensionDefinitions[d].dimension == type) {
3552  tempIncreasedDimensionIndex = d;
3553  break;
3554  }
3555  }
3556 
3557  // copy dimension regions from this region to the temporary region
3558  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3559  DimensionRegion* srcDimRgn = pDimensionRegions[iSrc];
3560  if (!srcDimRgn) continue;
3561  std::map<dimension_t,int> dimCase;
3562  bool isValidZone = true;
3563  for (int d = 0, baseBits = 0; d < Dimensions; ++d) {
3564  const int srcBits = pDimensionDefinitions[d].bits;
3565  dimCase[pDimensionDefinitions[d].dimension] =
3566  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3567  // there are also DimensionRegion objects for unused zones, skip them
3568  if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
3569  isValidZone = false;
3570  break;
3571  }
3572  baseBits += srcBits;
3573  }
3574  if (!isValidZone) continue;
3575  // a bit paranoid: cope with the chance that the dimensions would
3576  // have different order in source and destination regions
3577  if (dimCase[type] > zone) dimCase[type]++;
3578  DimensionRegion* dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3579  dstDimRgn->CopyAssign(srcDimRgn);
3580  // if this is the requested zone to be splitted, then also copy
3581  // the source DimensionRegion to the newly created target zone
3582  // and set the old zones upper limit lower
3583  if (dimCase[type] == zone) {
3584  // lower old zones upper limit
3585  if (newDef.split_type == split_type_normal) {
3586  const int high =
3587  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex];
3588  int low = 0;
3589  if (zone > 0) {
3590  std::map<dimension_t,int> lowerCase = dimCase;
3591  lowerCase[type]--;
3592  DimensionRegion* dstDimRgnLow = tempRgn->GetDimensionRegionByBit(lowerCase);
3593  low = dstDimRgnLow->DimensionUpperLimits[tempIncreasedDimensionIndex];
3594  }
3595  dstDimRgn->DimensionUpperLimits[tempIncreasedDimensionIndex] = low + (high - low) / 2;
3596  }
3597  // fill the newly created zone of the divided zone as well
3598  dimCase[type]++;
3599  dstDimRgn = tempRgn->GetDimensionRegionByBit(dimCase);
3600  dstDimRgn->CopyAssign(srcDimRgn);
3601  }
3602  }
3603 
3604  // now tempRegion's dimensions and DimensionRegions basically reflect
3605  // what we wanted to get for this actual Region here, so we now just
3606  // delete and recreate the dimension in question with the new amount
3607  // zones and then copy back from tempRegion
3608  DeleteDimension(oldDef);
3609  AddDimension(&newDef);
3610  for (int iSrc = 0; iSrc < 256; ++iSrc) {
3611  DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc];
3612  if (!srcDimRgn) continue;
3613  std::map<dimension_t,int> dimCase;
3614  for (int d = 0, baseBits = 0; d < tempRgn->Dimensions; ++d) {
3615  const int srcBits = tempRgn->pDimensionDefinitions[d].bits;
3616  dimCase[tempRgn->pDimensionDefinitions[d].dimension] =
3617  (iSrc >> baseBits) & ((1 << srcBits) - 1);
3618  baseBits += srcBits;
3619  }
3620  // a bit paranoid: cope with the chance that the dimensions would
3621  // have different order in source and destination regions
3622  DimensionRegion* dstDimRgn = GetDimensionRegionByBit(dimCase);
3623  if (!dstDimRgn) continue;
3624  dstDimRgn->CopyAssign(srcDimRgn);
3625  }
3626 
3627  // delete temporary region
3628  delete tempRgn;
3629 
3631  }
3632 
3648  if (oldType == newType) return;
3649  dimension_def_t* def = GetDimensionDefinition(oldType);
3650  if (!def)
3651  throw gig::Exception("No dimension with provided old dimension type exists on this region");
3652  if (newType == dimension_samplechannel && def->zones != 2)
3653  throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
3654  if (GetDimensionDefinition(newType))
3655  throw gig::Exception("There is already a dimension with requested new dimension type on this region");
3656  def->dimension = newType;
3657  def->split_type = __resolveSplitType(newType);
3658  }
3659 
3660  DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) {
3661  uint8_t bits[8] = {};
3662  for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3663  it != DimCase.end(); ++it)
3664  {
3665  for (int d = 0; d < Dimensions; ++d) {
3666  if (pDimensionDefinitions[d].dimension == it->first) {
3667  bits[d] = it->second;
3668  goto nextDimCaseSlice;
3669  }
3670  }
3671  assert(false); // do crash ... too harsh maybe ? ignore it instead ?
3672  nextDimCaseSlice:
3673  ; // noop
3674  }
3675  return GetDimensionRegionByBit(bits);
3676  }
3677 
3688  for (int i = 0; i < Dimensions; ++i)
3689  if (pDimensionDefinitions[i].dimension == type)
3690  return &pDimensionDefinitions[i];
3691  return NULL;
3692  }
3693 
3695  for (int i = 0; i < 256; i++) {
3696  if (pDimensionRegions[i]) delete pDimensionRegions[i];
3697  }
3698  }
3699 
3719  uint8_t bits;
3720  int veldim = -1;
3721  int velbitpos;
3722  int bitpos = 0;
3723  int dimregidx = 0;
3724  for (uint i = 0; i < Dimensions; i++) {
3725  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
3726  // the velocity dimension must be handled after the other dimensions
3727  veldim = i;
3728  velbitpos = bitpos;
3729  } else {
3730  switch (pDimensionDefinitions[i].split_type) {
3731  case split_type_normal:
3732  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
3733  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
3734  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
3735  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
3736  }
3737  } else {
3738  // gig2: evenly sized zones
3739  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
3740  }
3741  break;
3742  case split_type_bit: // the value is already the sought dimension bit number
3743  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
3744  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
3745  break;
3746  }
3747  dimregidx |= bits << bitpos;
3748  }
3749  bitpos += pDimensionDefinitions[i].bits;
3750  }
3751  DimensionRegion* dimreg = pDimensionRegions[dimregidx & 255];
3752  if (!dimreg) return NULL;
3753  if (veldim != -1) {
3754  // (dimreg is now the dimension region for the lowest velocity)
3755  if (dimreg->VelocityTable) // custom defined zone ranges
3756  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
3757  else // normal split type
3758  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
3759 
3760  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
3761  dimregidx |= (bits & limiter_mask) << velbitpos;
3762  dimreg = pDimensionRegions[dimregidx & 255];
3763  }
3764  return dimreg;
3765  }
3766 
3767  int Region::GetDimensionRegionIndexByValue(const uint DimValues[8]) {
3768  uint8_t bits;
3769  int veldim = -1;
3770  int velbitpos;
3771  int bitpos = 0;
3772  int dimregidx = 0;
3773  for (uint i = 0; i < Dimensions; i++) {
3774  if (pDimensionDefinitions[i].dimension == dimension_velocity) {
3775  // the velocity dimension must be handled after the other dimensions
3776  veldim = i;
3777  velbitpos = bitpos;
3778  } else {
3779  switch (pDimensionDefinitions[i].split_type) {
3780  case split_type_normal:
3781  if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
3782  // gig3: all normal dimensions (not just the velocity dimension) have custom zone ranges
3783  for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
3784  if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i]) break;
3785  }
3786  } else {
3787  // gig2: evenly sized zones
3788  bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
3789  }
3790  break;
3791  case split_type_bit: // the value is already the sought dimension bit number
3792  const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
3793  bits = DimValues[i] & limiter_mask; // just make sure the value doesn't use more bits than allowed
3794  break;
3795  }
3796  dimregidx |= bits << bitpos;
3797  }
3798  bitpos += pDimensionDefinitions[i].bits;
3799  }
3800  dimregidx &= 255;
3801  DimensionRegion* dimreg = pDimensionRegions[dimregidx];
3802  if (!dimreg) return -1;
3803  if (veldim != -1) {
3804  // (dimreg is now the dimension region for the lowest velocity)
3805  if (dimreg->VelocityTable) // custom defined zone ranges
3806  bits = dimreg->VelocityTable[DimValues[veldim] & 127];
3807  else // normal split type
3808  bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
3809 
3810  const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
3811  dimregidx |= (bits & limiter_mask) << velbitpos;
3812  dimregidx &= 255;
3813  }
3814  return dimregidx;
3815  }
3816 
3828  return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
3829  << pDimensionDefinitions[5].bits | DimBits[5])
3830  << pDimensionDefinitions[4].bits | DimBits[4])
3831  << pDimensionDefinitions[3].bits | DimBits[3])
3832  << pDimensionDefinitions[2].bits | DimBits[2])
3833  << pDimensionDefinitions[1].bits | DimBits[1])
3834  << pDimensionDefinitions[0].bits | DimBits[0]];
3835  }
3836 
3847  if (pSample) return static_cast<gig::Sample*>(pSample);
3848  else return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
3849  }
3850 
3852  if ((int32_t)WavePoolTableIndex == -1) return NULL;
3853  File* file = (File*) GetParent()->GetParent();
3854  if (!file->pWavePoolTable) return NULL;
3855  // for new files or files >= 2 GB use 64 bit wave pool offsets
3856  if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
3857  // use 64 bit wave pool offsets (treating this as large file)
3858  uint64_t soughtoffset =
3859  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
3860  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
3861  Sample* sample = file->GetFirstSample(pProgress);
3862  while (sample) {
3863  if (sample->ullWavePoolOffset == soughtoffset)
3864  return static_cast<gig::Sample*>(sample);
3865  sample = file->GetNextSample();
3866  }
3867  } else {
3868  // use extension files and 32 bit wave pool offsets
3869  file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
3870  file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
3871  Sample* sample = file->GetFirstSample(pProgress);
3872  while (sample) {
3873  if (sample->ullWavePoolOffset == soughtoffset &&
3874  sample->FileNo == soughtfileno) return static_cast<gig::Sample*>(sample);
3875  sample = file->GetNextSample();
3876  }
3877  }
3878  return NULL;
3879  }
3880 
3890  void Region::CopyAssign(const Region* orig) {
3891  CopyAssign(orig, NULL);
3892  }
3893 
3901  void Region::CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples) {
3902  // handle base classes
3904 
3905  if (mSamples && mSamples->count((gig::Sample*)orig->pSample)) {
3906  pSample = mSamples->find((gig::Sample*)orig->pSample)->second;
3907  }
3908 
3909  // handle own member variables
3910  for (int i = Dimensions - 1; i >= 0; --i) {
3912  }
3913  Layers = 0; // just to be sure
3914  for (int i = 0; i < orig->Dimensions; i++) {
3915  // we need to copy the dim definition here, to avoid the compiler
3916  // complaining about const-ness issue
3917  dimension_def_t def = orig->pDimensionDefinitions[i];
3918  AddDimension(&def);
3919  }
3920  for (int i = 0; i < 256; i++) {
3921  if (pDimensionRegions[i] && orig->pDimensionRegions[i]) {
3923  orig->pDimensionRegions[i],
3924  mSamples
3925  );
3926  }
3927  }
3928  Layers = orig->Layers;
3929  }
3930 
3931 
3932 // *************** MidiRule ***************
3933 // *
3934 
3936  _3ewg->SetPos(36);
3937  Triggers = _3ewg->ReadUint8();
3938  _3ewg->SetPos(40);
3939  ControllerNumber = _3ewg->ReadUint8();
3940  _3ewg->SetPos(46);
3941  for (int i = 0 ; i < Triggers ; i++) {
3942  pTriggers[i].TriggerPoint = _3ewg->ReadUint8();
3943  pTriggers[i].Descending = _3ewg->ReadUint8();
3944  pTriggers[i].VelSensitivity = _3ewg->ReadUint8();
3945  pTriggers[i].Key = _3ewg->ReadUint8();
3946  pTriggers[i].NoteOff = _3ewg->ReadUint8();
3947  pTriggers[i].Velocity = _3ewg->ReadUint8();
3948  pTriggers[i].OverridePedal = _3ewg->ReadUint8();
3949  _3ewg->ReadUint8();
3950  }
3951  }
3952 
3954  ControllerNumber(0),
3955  Triggers(0) {
3956  }
3957 
3958  void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData) const {
3959  pData[32] = 4;
3960  pData[33] = 16;
3961  pData[36] = Triggers;
3962  pData[40] = ControllerNumber;
3963  for (int i = 0 ; i < Triggers ; i++) {
3964  pData[46 + i * 8] = pTriggers[i].TriggerPoint;
3965  pData[47 + i * 8] = pTriggers[i].Descending;
3966  pData[48 + i * 8] = pTriggers[i].VelSensitivity;
3967  pData[49 + i * 8] = pTriggers[i].Key;
3968  pData[50 + i * 8] = pTriggers[i].NoteOff;
3969  pData[51 + i * 8] = pTriggers[i].Velocity;
3970  pData[52 + i * 8] = pTriggers[i].OverridePedal;
3971  }
3972  }
3973 
3975  _3ewg->SetPos(36);
3976  LegatoSamples = _3ewg->ReadUint8(); // always 12
3977  _3ewg->SetPos(40);
3978  BypassUseController = _3ewg->ReadUint8();
3979  BypassKey = _3ewg->ReadUint8();
3980  BypassController = _3ewg->ReadUint8();
3981  ThresholdTime = _3ewg->ReadUint16();
3982  _3ewg->ReadInt16();
3983  ReleaseTime = _3ewg->ReadUint16();
3984  _3ewg->ReadInt16();
3985  KeyRange.low = _3ewg->ReadUint8();
3986  KeyRange.high = _3ewg->ReadUint8();
3987  _3ewg->SetPos(64);
3988  ReleaseTriggerKey = _3ewg->ReadUint8();
3989  AltSustain1Key = _3ewg->ReadUint8();
3990  AltSustain2Key = _3ewg->ReadUint8();
3991  }
3992 
3994  LegatoSamples(12),
3995  BypassUseController(false),
3996  BypassKey(0),
3997  BypassController(1),
3998  ThresholdTime(20),
3999  ReleaseTime(20),
4000  ReleaseTriggerKey(0),
4001  AltSustain1Key(0),
4002  AltSustain2Key(0)
4003  {
4004  KeyRange.low = KeyRange.high = 0;
4005  }
4006 
4007  void MidiRuleLegato::UpdateChunks(uint8_t* pData) const {
4008  pData[32] = 0;
4009  pData[33] = 16;
4010  pData[36] = LegatoSamples;
4011  pData[40] = BypassUseController;
4012  pData[41] = BypassKey;
4013  pData[42] = BypassController;
4014  store16(&pData[43], ThresholdTime);
4015  store16(&pData[47], ReleaseTime);
4016  pData[51] = KeyRange.low;
4017  pData[52] = KeyRange.high;
4018  pData[64] = ReleaseTriggerKey;
4019  pData[65] = AltSustain1Key;
4020  pData[66] = AltSustain2Key;
4021  }
4022 
4024  _3ewg->SetPos(36);
4025  Articulations = _3ewg->ReadUint8();
4026  int flags = _3ewg->ReadUint8();
4027  Polyphonic = flags & 8;
4028  Chained = flags & 4;
4029  Selector = (flags & 2) ? selector_controller :
4030  (flags & 1) ? selector_key_switch : selector_none;
4031  Patterns = _3ewg->ReadUint8();
4032  _3ewg->ReadUint8(); // chosen row
4033  _3ewg->ReadUint8(); // unknown
4034  _3ewg->ReadUint8(); // unknown
4035  _3ewg->ReadUint8(); // unknown
4036  KeySwitchRange.low = _3ewg->ReadUint8();
4037  KeySwitchRange.high = _3ewg->ReadUint8();
4038  Controller = _3ewg->ReadUint8();
4039  PlayRange.low = _3ewg->ReadUint8();
4040  PlayRange.high = _3ewg->ReadUint8();
4041 
4042  int n = std::min(int(Articulations), 32);
4043  for (int i = 0 ; i < n ; i++) {
4044  _3ewg->ReadString(pArticulations[i], 32);
4045  }
4046  _3ewg->SetPos(1072);
4047  n = std::min(int(Patterns), 32);
4048  for (int i = 0 ; i < n ; i++) {
4049  _3ewg->ReadString(pPatterns[i].Name, 16);
4050  pPatterns[i].Size = _3ewg->ReadUint8();
4051  _3ewg->Read(&pPatterns[i][0], 1, 32);
4052  }
4053  }
4054 
4056  Articulations(0),
4057  Patterns(0),
4058  Selector(selector_none),
4059  Controller(0),
4060  Polyphonic(false),
4061  Chained(false)
4062  {
4063  PlayRange.low = PlayRange.high = 0;
4065  }
4066 
4067  void MidiRuleAlternator::UpdateChunks(uint8_t* pData) const {
4068  pData[32] = 3;
4069  pData[33] = 16;
4070  pData[36] = Articulations;
4071  pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4072  (Selector == selector_controller ? 2 :
4073  (Selector == selector_key_switch ? 1 : 0));
4074  pData[38] = Patterns;
4075 
4076  pData[43] = KeySwitchRange.low;
4077  pData[44] = KeySwitchRange.high;
4078  pData[45] = Controller;
4079  pData[46] = PlayRange.low;
4080  pData[47] = PlayRange.high;
4081 
4082  char* str = reinterpret_cast<char*>(pData);
4083  int pos = 48;
4084  int n = std::min(int(Articulations), 32);
4085  for (int i = 0 ; i < n ; i++, pos += 32) {
4086  strncpy(&str[pos], pArticulations[i].c_str(), 32);
4087  }
4088 
4089  pos = 1072;
4090  n = std::min(int(Patterns), 32);
4091  for (int i = 0 ; i < n ; i++, pos += 49) {
4092  strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4093  pData[pos + 16] = pPatterns[i].Size;
4094  memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4095  }
4096  }
4097 
4098 // *************** Script ***************
4099 // *
4100 
4102  pGroup = group;
4103  pChunk = ckScri;
4104  if (ckScri) { // object is loaded from file ...
4105  // read header
4106  uint32_t headerSize = ckScri->ReadUint32();
4107  Compression = (Compression_t) ckScri->ReadUint32();
4108  Encoding = (Encoding_t) ckScri->ReadUint32();
4109  Language = (Language_t) ckScri->ReadUint32();
4110  Bypass = (Language_t) ckScri->ReadUint32() & 1;
4111  crc = ckScri->ReadUint32();
4112  uint32_t nameSize = ckScri->ReadUint32();
4113  Name.resize(nameSize, ' ');
4114  for (int i = 0; i < nameSize; ++i)
4115  Name[i] = ckScri->ReadUint8();
4116  // to handle potential future extensions of the header
4117  ckScri->SetPos(sizeof(int32_t) + headerSize);
4118  // read actual script data
4119  uint32_t scriptSize = ckScri->GetSize() - ckScri->GetPos();
4120  data.resize(scriptSize);
4121  for (int i = 0; i < scriptSize; ++i)
4122  data[i] = ckScri->ReadUint8();
4123  } else { // this is a new script object, so just initialize it as such ...
4124  Compression = COMPRESSION_NONE;
4125  Encoding = ENCODING_ASCII;
4126  Language = LANGUAGE_NKSP;
4127  Bypass = false;
4128  crc = 0;
4129  Name = "Unnamed Script";
4130  }
4131  }
4132 
4134  }
4135 
4140  String s;
4141  s.resize(data.size(), ' ');
4142  memcpy(&s[0], &data[0], data.size());
4143  return s;
4144  }
4145 
4152  void Script::SetScriptAsText(const String& text) {
4153  data.resize(text.size());
4154  memcpy(&data[0], &text[0], text.size());
4155  }
4156 
4167  // recalculate CRC32 check sum
4168  __resetCRC(crc);
4169  __calculateCRC(&data[0], data.size(), crc);
4170  __encodeCRC(crc);
4171  // make sure chunk exists and has the required size
4172  const int chunkSize = 7*sizeof(int32_t) + Name.size() + data.size();
4173  if (!pChunk) pChunk = pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4174  else pChunk->Resize(chunkSize);
4175  // fill the chunk data to be written to disk
4176  uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4177  int pos = 0;
4178  store32(&pData[pos], 6*sizeof(int32_t) + Name.size()); // total header size
4179  pos += sizeof(int32_t);
4180  store32(&pData[pos], Compression);
4181  pos += sizeof(int32_t);
4182  store32(&pData[pos], Encoding);
4183  pos += sizeof(int32_t);
4184  store32(&pData[pos], Language);
4185  pos += sizeof(int32_t);
4186  store32(&pData[pos], Bypass ? 1 : 0);
4187  pos += sizeof(int32_t);
4188  store32(&pData[pos], crc);
4189  pos += sizeof(int32_t);
4190  store32(&pData[pos], Name.size());
4191  pos += sizeof(int32_t);
4192  for (int i = 0; i < Name.size(); ++i, ++pos)
4193  pData[pos] = Name[i];
4194  for (int i = 0; i < data.size(); ++i, ++pos)
4195  pData[pos] = data[i];
4196  }
4197 
4205  if (this->pGroup == pGroup) return;
4206  if (pChunk)
4207  pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4208  this->pGroup = pGroup;
4209  }
4210 
4218  return pGroup;
4219  }
4220 
4222  File* pFile = pGroup->pFile;
4223  for (int i = 0; pFile->GetInstrument(i); ++i) {
4224  Instrument* instr = pFile->GetInstrument(i);
4225  instr->RemoveScript(this);
4226  }
4227  }
4228 
4229 // *************** ScriptGroup ***************
4230 // *
4231 
4233  pFile = file;
4234  pList = lstRTIS;
4235  pScripts = NULL;
4236  if (lstRTIS) {
4237  RIFF::Chunk* ckName = lstRTIS->GetSubChunk(CHUNK_ID_LSNM);
4238  ::LoadString(ckName, Name);
4239  } else {
4240  Name = "Default Group";
4241  }
4242  }
4243 
4245  if (pScripts) {
4246  std::list<Script*>::iterator iter = pScripts->begin();
4247  std::list<Script*>::iterator end = pScripts->end();
4248  while (iter != end) {
4249  delete *iter;
4250  ++iter;
4251  }
4252  delete pScripts;
4253  }
4254  }
4255 
4266  if (pScripts) {
4267  if (!pList)
4268  pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4269 
4270  // now store the name of this group as <LSNM> chunk as subchunk of the <RTIS> list chunk
4271  ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String("Unnamed Group"), true, 64);
4272 
4273  for (std::list<Script*>::iterator it = pScripts->begin();
4274  it != pScripts->end(); ++it)
4275  {
4276  (*it)->UpdateChunks(pProgress);
4277  }
4278  }
4279  }
4280 
4289  if (!pScripts) LoadScripts();
4290  std::list<Script*>::iterator it = pScripts->begin();
4291  for (uint i = 0; it != pScripts->end(); ++i, ++it)
4292  if (i == index) return *it;
4293  return NULL;
4294  }
4295 
4308  if (!pScripts) LoadScripts();
4309  Script* pScript = new Script(this, NULL);
4310  pScripts->push_back(pScript);
4311  return pScript;
4312  }
4313 
4325  if (!pScripts) LoadScripts();
4326  std::list<Script*>::iterator iter =
4327  find(pScripts->begin(), pScripts->end(), pScript);
4328  if (iter == pScripts->end())
4329  throw gig::Exception("Could not delete script, could not find given script");
4330  pScripts->erase(iter);
4331  pScript->RemoveAllScriptReferences();
4332  if (pScript->pChunk)
4333  pScript->pChunk->GetParent()->DeleteSubChunk(pScript->pChunk);
4334  delete pScript;
4335  }
4336 
4338  if (pScripts) return;
4339  pScripts = new std::list<Script*>;
4340  if (!pList) return;
4341 
4342  for (RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4343  ck = pList->GetNextSubChunk())
4344  {
4345  if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4346  pScripts->push_back(new Script(this, ck));
4347  }
4348  }
4349  }
4350 
4351 // *************** Instrument ***************
4352 // *
4353 
4354  Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
4355  static const DLS::Info::string_length_t fixedStringLengths[] = {
4356  { CHUNK_ID_INAM, 64 },
4357  { CHUNK_ID_ISFT, 12 },
4358  { 0, 0 }
4359  };
4360  pInfo->SetFixedStringLengths(fixedStringLengths);
4361 
4362  // Initialization
4363  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4364  EffectSend = 0;
4365  Attenuation = 0;
4366  FineTune = 0;
4367  PitchbendRange = 0;
4368  PianoReleaseMode = false;
4369  DimensionKeyRange.low = 0;
4370  DimensionKeyRange.high = 0;
4371  pMidiRules = new MidiRule*[3];
4372  pMidiRules[0] = NULL;
4373  pScriptRefs = NULL;
4374 
4375  // Loading
4376  RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART);
4377  if (lart) {
4378  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4379  if (_3ewg) {
4380  EffectSend = _3ewg->ReadUint16();
4381  Attenuation = _3ewg->ReadInt32();
4382  FineTune = _3ewg->ReadInt16();
4383  PitchbendRange = _3ewg->ReadInt16();
4384  uint8_t dimkeystart = _3ewg->ReadUint8();
4385  PianoReleaseMode = dimkeystart & 0x01;
4386  DimensionKeyRange.low = dimkeystart >> 1;
4387  DimensionKeyRange.high = _3ewg->ReadUint8();
4388 
4389  if (_3ewg->GetSize() > 32) {
4390  // read MIDI rules
4391  int i = 0;
4392  _3ewg->SetPos(32);
4393  uint8_t id1 = _3ewg->ReadUint8();
4394  uint8_t id2 = _3ewg->ReadUint8();
4395 
4396  if (id2 == 16) {
4397  if (id1 == 4) {
4398  pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg);
4399  } else if (id1 == 0) {
4400  pMidiRules[i++] = new MidiRuleLegato(_3ewg);
4401  } else if (id1 == 3) {
4402  pMidiRules[i++] = new MidiRuleAlternator(_3ewg);
4403  } else {
4404  pMidiRules[i++] = new MidiRuleUnknown;
4405  }
4406  }
4407  else if (id1 != 0 || id2 != 0) {
4408  pMidiRules[i++] = new MidiRuleUnknown;
4409  }
4410  //TODO: all the other types of rules
4411 
4412  pMidiRules[i] = NULL;
4413  }
4414  }
4415  }
4416 
4417  if (pFile->GetAutoLoad()) {
4418  if (!pRegions) pRegions = new RegionList;
4419  RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN);
4420  if (lrgn) {
4421  RIFF::List* rgn = lrgn->GetFirstSubList();
4422  while (rgn) {
4423  if (rgn->GetListType() == LIST_TYPE_RGN) {
4424  __notify_progress(pProgress, (float) pRegions->size() / (float) Regions);
4425  pRegions->push_back(new Region(this, rgn));
4426  }
4427  rgn = lrgn->GetNextSubList();
4428  }
4429  // Creating Region Key Table for fast lookup
4431  }
4432  }
4433 
4434  // own gig format extensions
4435  RIFF::List* lst3LS = insList->GetSubList(LIST_TYPE_3LS);
4436  if (lst3LS) {
4437  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4438  if (ckSCSL) {
4439  int headerSize = ckSCSL->ReadUint32();
4440  int slotCount = ckSCSL->ReadUint32();
4441  if (slotCount) {
4442  int slotSize = ckSCSL->ReadUint32();
4443  ckSCSL->SetPos(headerSize); // in case of future header extensions
4444  int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions
4445  for (int i = 0; i < slotCount; ++i) {
4446  _ScriptPooolEntry e;
4447  e.fileOffset = ckSCSL->ReadUint32();
4448  e.bypass = ckSCSL->ReadUint32() & 1;
4449  if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions
4450  scriptPoolFileOffsets.push_back(e);
4451  }
4452  }
4453  }
4454  }
4455 
4456  __notify_progress(pProgress, 1.0f); // notify done
4457  }
4458 
4460  for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4461  RegionList::iterator iter = pRegions->begin();
4462  RegionList::iterator end = pRegions->end();
4463  for (; iter != end; ++iter) {
4464  gig::Region* pRegion = static_cast<gig::Region*>(*iter);
4465  for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
4466  RegionKeyTable[iKey] = pRegion;
4467  }
4468  }
4469  }
4470 
4472  for (int i = 0 ; pMidiRules[i] ; i++) {
4473  delete pMidiRules[i];
4474  }
4475  delete[] pMidiRules;
4476  if (pScriptRefs) delete pScriptRefs;
4477  }
4478 
4490  // first update base classes' chunks
4491  DLS::Instrument::UpdateChunks(pProgress);
4492 
4493  // update Regions' chunks
4494  {
4495  RegionList::iterator iter = pRegions->begin();
4496  RegionList::iterator end = pRegions->end();
4497  for (; iter != end; ++iter)
4498  (*iter)->UpdateChunks(pProgress);
4499  }
4500 
4501  // make sure 'lart' RIFF list chunk exists
4503  if (!lart) lart = pCkInstrument->AddSubList(LIST_TYPE_LART);
4504  // make sure '3ewg' RIFF chunk exists
4505  RIFF::Chunk* _3ewg = lart->GetSubChunk(CHUNK_ID_3EWG);
4506  if (!_3ewg) {
4507  File* pFile = (File*) GetParent();
4508 
4509  // 3ewg is bigger in gig3, as it includes the iMIDI rules
4510  int size = (pFile->pVersion && pFile->pVersion->major == 3) ? 16416 : 12;
4511  _3ewg = lart->AddSubChunk(CHUNK_ID_3EWG, size);
4512  memset(_3ewg->LoadChunkData(), 0, size);
4513  }
4514  // update '3ewg' RIFF chunk
4515  uint8_t* pData = (uint8_t*) _3ewg->LoadChunkData();
4516  store16(&pData[0], EffectSend);
4517  store32(&pData[2], Attenuation);
4518  store16(&pData[6], FineTune);
4519  store16(&pData[8], PitchbendRange);
4520  const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4521  DimensionKeyRange.low << 1;
4522  pData[10] = dimkeystart;
4523  pData[11] = DimensionKeyRange.high;
4524 
4525  if (pMidiRules[0] == 0 && _3ewg->GetSize() >= 34) {
4526  pData[32] = 0;
4527  pData[33] = 0;
4528  } else {
4529  for (int i = 0 ; pMidiRules[i] ; i++) {
4530  pMidiRules[i]->UpdateChunks(pData);
4531  }
4532  }
4533 
4534  // own gig format extensions
4535  if (ScriptSlotCount()) {
4536  // make sure we have converted the original loaded script file
4537  // offsets into valid Script object pointers
4538  LoadScripts();
4539 
4541  if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS);
4542  const int slotCount = pScriptRefs->size();
4543  const int headerSize = 3 * sizeof(uint32_t);
4544  const int slotSize = 2 * sizeof(uint32_t);
4545  const int totalChunkSize = headerSize + slotCount * slotSize;
4546  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4547  if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
4548  else ckSCSL->Resize(totalChunkSize);
4549  uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData();
4550  int pos = 0;
4551  store32(&pData[pos], headerSize);
4552  pos += sizeof(uint32_t);
4553  store32(&pData[pos], slotCount);
4554  pos += sizeof(uint32_t);
4555  store32(&pData[pos], slotSize);
4556  pos += sizeof(uint32_t);
4557  for (int i = 0; i < slotCount; ++i) {
4558  // arbitrary value, the actual file offset will be updated in
4559  // UpdateScriptFileOffsets() after the file has been resized
4560  int bogusFileOffset = 0;
4561  store32(&pData[pos], bogusFileOffset);
4562  pos += sizeof(uint32_t);
4563  store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
4564  pos += sizeof(uint32_t);
4565  }
4566  } else {
4567  // no script slots, so get rid of any LS custom RIFF chunks (if any)
4569  if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS);
4570  }
4571  }
4572 
4574  // own gig format extensions
4575  if (pScriptRefs && pScriptRefs->size() > 0) {
4577  RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL);
4578  const int slotCount = pScriptRefs->size();
4579  const int headerSize = 3 * sizeof(uint32_t);
4580  ckSCSL->SetPos(headerSize);
4581  for (int i = 0; i < slotCount; ++i) {
4582  uint32_t fileOffset =
4583  (*pScriptRefs)[i].script->pChunk->GetFilePos() -
4584  (*pScriptRefs)[i].script->pChunk->GetPos() -
4586  ckSCSL->WriteUint32(&fileOffset);
4587  // jump over flags entry (containing the bypass flag)
4588  ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos);
4589  }
4590  }
4591  }
4592 
4600  Region* Instrument::GetRegion(unsigned int Key) {
4601  if (!pRegions || pRegions->empty() || Key > 127) return NULL;
4602  return RegionKeyTable[Key];
4603 
4604  /*for (int i = 0; i < Regions; i++) {
4605  if (Key <= pRegions[i]->KeyRange.high &&
4606  Key >= pRegions[i]->KeyRange.low) return pRegions[i];
4607  }
4608  return NULL;*/
4609  }
4610 
4619  if (!pRegions) return NULL;
4620  RegionsIterator = pRegions->begin();
4621  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4622  }
4623 
4633  if (!pRegions) return NULL;
4634  RegionsIterator++;
4635  return static_cast<gig::Region*>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4636  }
4637 
4639  // create new Region object (and its RIFF chunks)
4641  if (!lrgn) lrgn = pCkInstrument->AddSubList(LIST_TYPE_LRGN);
4642  RIFF::List* rgn = lrgn->AddSubList(LIST_TYPE_RGN);
4643  Region* pNewRegion = new Region(this, rgn);
4644  pRegions->push_back(pNewRegion);
4645  Regions = pRegions->size();
4646  // update Region key table for fast lookup
4648  // done
4649  return pNewRegion;
4650  }
4651 
4653  if (!pRegions) return;
4655  // update Region key table for fast lookup
4657  }
4658 
4687  if (dst && GetParent() != dst->GetParent())
4688  throw Exception(
4689  "gig::Instrument::MoveTo() can only be used for moving within "
4690  "the same gig file."
4691  );
4692 
4693  File* pFile = (File*) GetParent();
4694 
4695  // move this instrument within the instrument list
4696  {
4697  File::InstrumentList& list = *pFile->pInstruments;
4698 
4699  File::InstrumentList::iterator itFrom =
4700  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(this));
4701 
4702  File::InstrumentList::iterator itTo =
4703  std::find(list.begin(), list.end(), static_cast<DLS::Instrument*>(dst));
4704 
4705  list.splice(itTo, list, itFrom);
4706  }
4707 
4708  // move the instrument's actual list RIFF chunk appropriately
4709  RIFF::List* lstCkInstruments = pFile->pRIFF->GetSubList(LIST_TYPE_LINS);
4710  lstCkInstruments->MoveSubChunk(
4711  this->pCkInstrument,
4712  (RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
4713  );
4714  }
4715 
4727  return pMidiRules[i];
4728  }
4729 
4736  delete pMidiRules[0];
4738  pMidiRules[0] = r;
4739  pMidiRules[1] = 0;
4740  return r;
4741  }
4742 
4749  delete pMidiRules[0];
4750  MidiRuleLegato* r = new MidiRuleLegato;
4751  pMidiRules[0] = r;
4752  pMidiRules[1] = 0;
4753  return r;
4754  }
4755 
4762  delete pMidiRules[0];
4764  pMidiRules[0] = r;
4765  pMidiRules[1] = 0;
4766  return r;
4767  }
4768 
4775  delete pMidiRules[i];
4776  pMidiRules[i] = 0;
4777  }
4778 
4780  if (pScriptRefs) return;
4781  pScriptRefs = new std::vector<_ScriptPooolRef>;
4782  if (scriptPoolFileOffsets.empty()) return;
4783  File* pFile = (File*) GetParent();
4784  for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
4785  uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
4786  for (uint i = 0; pFile->GetScriptGroup(i); ++i) {
4787  ScriptGroup* group = pFile->GetScriptGroup(i);
4788  for (uint s = 0; group->GetScript(s); ++s) {
4789  Script* script = group->GetScript(s);
4790  if (script->pChunk) {
4791  uint32_t offset = script->pChunk->GetFilePos() -
4792  script->pChunk->GetPos() -
4793  CHUNK_HEADER_SIZE(script->pChunk->GetFile()->GetFileOffsetSize());
4794  if (offset == soughtOffset)
4795  {
4796  _ScriptPooolRef ref;
4797  ref.script = script;
4798  ref.bypass = scriptPoolFileOffsets[k].bypass;
4799  pScriptRefs->push_back(ref);
4800  break;
4801  }
4802  }
4803  }
4804  }
4805  }
4806  // we don't need that anymore
4807  scriptPoolFileOffsets.clear();
4808  }
4809 
4823  LoadScripts();
4824  if (index >= pScriptRefs->size()) return NULL;
4825  return pScriptRefs->at(index).script;
4826  }
4827 
4863  void Instrument::AddScriptSlot(Script* pScript, bool bypass) {
4864  LoadScripts();
4865  _ScriptPooolRef ref = { pScript, bypass };
4866  pScriptRefs->push_back(ref);
4867  }
4868 
4883  void Instrument::SwapScriptSlots(uint index1, uint index2) {
4884  LoadScripts();
4885  if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
4886  return;
4887  _ScriptPooolRef tmp = (*pScriptRefs)[index1];
4888  (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
4889  (*pScriptRefs)[index2] = tmp;
4890  }
4891 
4898  void Instrument::RemoveScriptSlot(uint index) {
4899  LoadScripts();
4900  if (index >= pScriptRefs->size()) return;
4901  pScriptRefs->erase( pScriptRefs->begin() + index );
4902  }
4903 
4917  LoadScripts();
4918  for (int i = pScriptRefs->size() - 1; i >= 0; --i) {
4919  if ((*pScriptRefs)[i].script == pScript) {
4920  pScriptRefs->erase( pScriptRefs->begin() + i );
4921  }
4922  }
4923  }
4924 
4940  return pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size();
4941  }
4942 
4960  if (index >= ScriptSlotCount()) return false;
4961  return pScriptRefs ? pScriptRefs->at(index).bypass
4962  : scriptPoolFileOffsets.at(index).bypass;
4963 
4964  }
4965 
4979  void Instrument::SetScriptSlotBypassed(uint index, bool bBypass) {
4980  if (index >= ScriptSlotCount()) return;
4981  if (pScriptRefs)
4982  pScriptRefs->at(index).bypass = bBypass;
4983  else
4984  scriptPoolFileOffsets.at(index).bypass = bBypass;
4985  }
4986 
4997  CopyAssign(orig, NULL);
4998  }
4999 
5008  void Instrument::CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples) {
5009  // handle base class
5010  // (without copying DLS region stuff)
5012 
5013  // handle own member variables
5014  Attenuation = orig->Attenuation;
5015  EffectSend = orig->EffectSend;
5016  FineTune = orig->FineTune;
5020  scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5021  pScriptRefs = orig->pScriptRefs;
5022 
5023  // free old midi rules
5024  for (int i = 0 ; pMidiRules[i] ; i++) {
5025  delete pMidiRules[i];
5026  }
5027  //TODO: MIDI rule copying
5028  pMidiRules[0] = NULL;
5029 
5030  // delete all old regions
5031  while (Regions) DeleteRegion(GetFirstRegion());
5032  // create new regions and copy them from original
5033  {
5034  RegionList::const_iterator it = orig->pRegions->begin();
5035  for (int i = 0; i < orig->Regions; ++i, ++it) {
5036  Region* dstRgn = AddRegion();
5037  //NOTE: Region does semi-deep copy !
5038  dstRgn->CopyAssign(
5039  static_cast<gig::Region*>(*it),
5040  mSamples
5041  );
5042  }
5043  }
5044 
5046  }
5047 
5048 
5049 // *************** Group ***************
5050 // *
5051 
5058  Group::Group(File* file, RIFF::Chunk* ck3gnm) {
5059  pFile = file;
5060  pNameChunk = ck3gnm;
5061  ::LoadString(pNameChunk, Name);
5062  }
5063 
5065  // remove the chunk associated with this group (if any)
5066  if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
5067  }
5068 
5079  void Group::UpdateChunks(progress_t* pProgress) {
5080  // make sure <3gri> and <3gnl> list chunks exist
5081  RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI);
5082  if (!_3gri) {
5083  _3gri = pFile->pRIFF->AddSubList(LIST_TYPE_3GRI);
5084  pFile->pRIFF->MoveSubChunk(_3gri, pFile->pRIFF->GetSubChunk(CHUNK_ID_PTBL));
5085  }
5086  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
5087  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
5088 
5089  if (!pNameChunk && pFile->pVersion && pFile->pVersion->major == 3) {
5090  // v3 has a fixed list of 128 strings, find a free one
5091  for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) {
5092  if (strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) {
5093  pNameChunk = ck;
5094  break;
5095  }
5096  }
5097  }
5098 
5099  // now store the name of this group as <3gnm> chunk as subchunk of the <3gnl> list chunk
5100  ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String("Unnamed Group"), true, 64);
5101  }
5102 
5115  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5116  for (Sample* pSample = pFile->GetFirstSample(); pSample; pSample = pFile->GetNextSample()) {
5117  if (pSample->GetGroup() == this) return pSample;
5118  }
5119  return NULL;
5120  }
5121 
5133  // FIXME: lazy und unsafe implementation, should be an autonomous iterator
5134  for (Sample* pSample = pFile->GetNextSample(); pSample; pSample = pFile->GetNextSample()) {
5135  if (pSample->GetGroup() == this) return pSample;
5136  }
5137  return NULL;
5138  }
5139 
5143  void Group::AddSample(Sample* pSample) {
5144  pSample->pGroup = this;
5145  }
5146 
5154  // get "that" other group first
5155  Group* pOtherGroup = NULL;
5156  for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
5157  if (pOtherGroup != this) break;
5158  }
5159  if (!pOtherGroup) throw Exception(
5160  "Could not move samples to another group, since there is no "
5161  "other Group. This is a bug, report it!"
5162  );
5163  // now move all samples of this group to the other group
5164  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
5165  pOtherGroup->AddSample(pSample);
5166  }
5167  }
5168 
5169 
5170 
5171 // *************** File ***************
5172 // *
5173 
5176  0, 2, 19980628 & 0xffff, 19980628 >> 16
5177  };
5178 
5181  0, 3, 20030331 & 0xffff, 20030331 >> 16
5182  };
5183 
5184  static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
5185  { CHUNK_ID_IARL, 256 },
5186  { CHUNK_ID_IART, 128 },
5187  { CHUNK_ID_ICMS, 128 },
5188  { CHUNK_ID_ICMT, 1024 },
5189  { CHUNK_ID_ICOP, 128 },
5190  { CHUNK_ID_ICRD, 128 },
5191  { CHUNK_ID_IENG, 128 },
5192  { CHUNK_ID_IGNR, 128 },
5193  { CHUNK_ID_IKEY, 128 },
5194  { CHUNK_ID_IMED, 128 },
5195  { CHUNK_ID_INAM, 128 },
5196  { CHUNK_ID_IPRD, 128 },
5197  { CHUNK_ID_ISBJ, 128 },
5198  { CHUNK_ID_ISFT, 128 },
5199  { CHUNK_ID_ISRC, 128 },
5200  { CHUNK_ID_ISRF, 128 },
5201  { CHUNK_ID_ITCH, 128 },
5202  { 0, 0 }
5203  };
5204 
5206  bAutoLoad = true;
5207  *pVersion = VERSION_3;
5208  pGroups = NULL;
5209  pScriptGroups = NULL;
5210  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5211  pInfo->ArchivalLocation = String(256, ' ');
5212 
5213  // add some mandatory chunks to get the file chunks in right
5214  // order (INFO chunk will be moved to first position later)
5218 
5219  GenerateDLSID();
5220  }
5221 
5223  bAutoLoad = true;
5224  pGroups = NULL;
5225  pScriptGroups = NULL;
5226  pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5227  }
5228 
5230  if (pGroups) {
5231  std::list<Group*>::iterator iter = pGroups->begin();
5232  std::list<Group*>::iterator end = pGroups->end();
5233  while (iter != end) {
5234  delete *iter;
5235  ++iter;
5236  }
5237  delete pGroups;
5238  }
5239  if (pScriptGroups) {
5240  std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
5241  std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
5242  while (iter != end) {
5243  delete *iter;
5244  ++iter;
5245  }
5246  delete pScriptGroups;
5247  }
5248  }
5249 
5251  if (!pSamples) LoadSamples(pProgress);
5252  if (!pSamples) return NULL;
5253  SamplesIterator = pSamples->begin();
5254  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5255  }
5256 
5258  if (!pSamples) return NULL;
5259  SamplesIterator++;
5260  return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5261  }
5262 
5268  Sample* File::GetSample(uint index) {
5269  if (!pSamples) LoadSamples();
5270  if (!pSamples) return NULL;
5271  DLS::File::SampleList::iterator it = pSamples->begin();
5272  for (int i = 0; i < index; ++i) {
5273  ++it;
5274  if (it == pSamples->end()) return NULL;
5275  }
5276  if (it == pSamples->end()) return NULL;
5277  return static_cast<gig::Sample*>( *it );
5278  }
5279 
5288  if (!pSamples) LoadSamples();
5291  // create new Sample object and its respective 'wave' list chunk
5292  RIFF::List* wave = wvpl->AddSubList(LIST_TYPE_WAVE);
5293  Sample* pSample = new Sample(this, wave, 0 /*arbitrary value, we update offsets when we save*/);
5294 
5295  // add mandatory chunks to get the chunks in right order
5296  wave->AddSubChunk(CHUNK_ID_FMT, 16);
5297  wave->AddSubList(LIST_TYPE_INFO);
5298 
5299  pSamples->push_back(pSample);
5300  return pSample;
5301  }
5302 
5312  void File::DeleteSample(Sample* pSample) {
5313  if (!pSamples || !pSamples->size()) throw gig::Exception("Could not delete sample as there are no samples");
5314  SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (DLS::Sample*) pSample);
5315  if (iter == pSamples->end()) throw gig::Exception("Could not delete sample, could not find given sample");
5316  if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator; // avoid iterator invalidation
5317  pSamples->erase(iter);
5318  delete pSample;
5319 
5320  SampleList::iterator tmp = SamplesIterator;
5321  // remove all references to the sample
5322  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
5323  instrument = GetNextInstrument()) {
5324  for (Region* region = instrument->GetFirstRegion() ; region ;
5325  region = instrument->GetNextRegion()) {
5326 
5327  if (region->GetSample() == pSample) region->SetSample(NULL);
5328 
5329  for (int i = 0 ; i < region->DimensionRegions ; i++) {
5330  gig::DimensionRegion *d = region->pDimensionRegions[i];
5331  if (d->pSample == pSample) d->pSample = NULL;
5332  }
5333  }
5334  }
5335  SamplesIterator = tmp; // restore iterator
5336  }
5337 
5339  LoadSamples(NULL);
5340  }
5341 
5342  void File::LoadSamples(progress_t* pProgress) {
5343  // Groups must be loaded before samples, because samples will try
5344  // to resolve the group they belong to
5345  if (!pGroups) LoadGroups();
5346 
5347  if (!pSamples) pSamples = new SampleList;
5348 
5349  RIFF::File* file = pRIFF;
5350 
5351  // just for progress calculation
5352  int iSampleIndex = 0;
5353  int iTotalSamples = WavePoolCount;
5354 
5355  // check if samples should be loaded from extension files
5356  // (only for old gig files < 2 GB)
5357  int lastFileNo = 0;
5358  if (!file->IsNew() && !(file->GetCurrentFileSize() >> 31)) {
5359  for (int i = 0 ; i < WavePoolCount ; i++) {
5360  if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
5361  }
5362  }
5363  String name(pRIFF->GetFileName());
5364  int nameLen = name.length();
5365  char suffix[6];
5366  if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;
5367 
5368  for (int fileNo = 0 ; ; ) {
5369  RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
5370  if (wvpl) {
5371  file_offset_t wvplFileOffset = wvpl->GetFilePos();
5372  RIFF::List* wave = wvpl->GetFirstSubList();
5373  while (wave) {
5374  if (wave->GetListType() == LIST_TYPE_WAVE) {
5375  // notify current progress
5376  const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
5377  __notify_progress(pProgress, subprogress);
5378 
5379  file_offset_t waveFileOffset = wave->GetFilePos();
5380  pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo));
5381 
5382  iSampleIndex++;
5383  }
5384  wave = wvpl->GetNextSubList();
5385  }
5386 
5387  if (fileNo == lastFileNo) break;
5388 
5389  // open extension file (*.gx01, *.gx02, ...)
5390  fileNo++;
5391  sprintf(suffix, ".gx%02d", fileNo);
5392  name.replace(nameLen, 5, suffix);
5393  file = new RIFF::File(name);
5394  ExtensionFiles.push_back(file);
5395  } else break;
5396  }
5397 
5398  __notify_progress(pProgress, 1.0); // notify done
5399  }
5400 
5402  if (!pInstruments) LoadInstruments();
5403  if (!pInstruments) return NULL;
5404  InstrumentsIterator = pInstruments->begin();
5405  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5406  }
5407 
5409  if (!pInstruments) return NULL;
5411  return static_cast<gig::Instrument*>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5412  }
5413 
5421  Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
5422  if (!pInstruments) {
5423  // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
5424 
5425  // sample loading subtask
5426  progress_t subprogress;
5427  __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
5428  __notify_progress(&subprogress, 0.0f);
5429  if (GetAutoLoad())
5430  GetFirstSample(&subprogress); // now force all samples to be loaded
5431  __notify_progress(&subprogress, 1.0f);
5432 
5433  // instrument loading subtask
5434  if (pProgress && pProgress->callback) {
5435  subprogress.__range_min = subprogress.__range_max;
5436  subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
5437  }
5438  __notify_progress(&subprogress, 0.0f);
5439  LoadInstruments(&subprogress);
5440  __notify_progress(&subprogress, 1.0f);
5441  }
5442  if (!pInstruments) return NULL;
5443  InstrumentsIterator = pInstruments->begin();
5444  for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
5445  if (i == index) return static_cast<gig::Instrument*>( *InstrumentsIterator );
5447  }
5448  return NULL;
5449  }
5450 
5459  if (!pInstruments) LoadInstruments();
5461  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
5462  RIFF::List* lstInstr = lstInstruments->AddSubList(LIST_TYPE_INS);
5463 
5464  // add mandatory chunks to get the chunks in right order
5465  lstInstr->AddSubList(LIST_TYPE_INFO);
5466  lstInstr->AddSubChunk(CHUNK_ID_DLID, 16);
5467 
5468  Instrument* pInstrument = new Instrument(this, lstInstr);
5469  pInstrument->GenerateDLSID();
5470 
5471  lstInstr->AddSubChunk(CHUNK_ID_INSH, 12);
5472 
5473  // this string is needed for the gig to be loadable in GSt:
5474  pInstrument->pInfo->Software = "Endless Wave";
5475 
5476  pInstruments->push_back(pInstrument);
5477  return pInstrument;
5478  }
5479 
5496  Instrument* instr = AddInstrument();
5497  instr->CopyAssign(orig);
5498  return instr;
5499  }
5500 
5512  void File::AddContentOf(File* pFile) {
5513  static int iCallCount = -1;
5514  iCallCount++;
5515  std::map<Group*,Group*> mGroups;
5516  std::map<Sample*,Sample*> mSamples;
5517 
5518  // clone sample groups
5519  for (int i = 0; pFile->GetGroup(i); ++i) {
5520  Group* g = AddGroup();
5521  g->Name =
5522  "COPY" + ToString(iCallCount) + "_" + pFile->GetGroup(i)->Name;
5523  mGroups[pFile->GetGroup(i)] = g;
5524  }
5525 
5526  // clone samples (not waveform data here yet)
5527  for (int i = 0; pFile->GetSample(i); ++i) {
5528  Sample* s = AddSample();
5529  s->CopyAssignMeta(pFile->GetSample(i));
5530  mGroups[pFile->GetSample(i)->GetGroup()]->AddSample(s);
5531  mSamples[pFile->GetSample(i)] = s;
5532  }
5533 
5534  //BUG: For some reason this method only works with this additional
5535  // Save() call in between here.
5536  //
5537  // Important: The correct one of the 2 Save() methods has to be called
5538  // here, depending on whether the file is completely new or has been
5539  // saved to disk already, otherwise it will result in data corruption.
5540  if (pRIFF->IsNew())
5541  Save(GetFileName());
5542  else
5543  Save();
5544 
5545  // clone instruments
5546  // (passing the crosslink table here for the cloned samples)
5547  for (int i = 0; pFile->GetInstrument(i); ++i) {
5548  Instrument* instr = AddInstrument();
5549  instr->CopyAssign(pFile->GetInstrument(i), &mSamples);
5550  }
5551 
5552  // Mandatory: file needs to be saved to disk at this point, so this
5553  // file has the correct size and data layout for writing the samples'
5554  // waveform data to disk.
5555  Save();
5556 
5557  // clone samples' waveform data
5558  // (using direct read & write disk streaming)
5559  for (int i = 0; pFile->GetSample(i); ++i) {
5560  mSamples[pFile->GetSample(i)]->CopyAssignWave(pFile->GetSample(i));
5561  }
5562  }
5563 
5572  void File::DeleteInstrument(Instrument* pInstrument) {
5573  if (!pInstruments) throw gig::Exception("Could not delete instrument as there are no instruments");
5574  InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (DLS::Instrument*) pInstrument);
5575  if (iter == pInstruments->end()) throw gig::Exception("Could not delete instrument, could not find given instrument");
5576  pInstruments->erase(iter);
5577  delete pInstrument;
5578  }
5579 
5581  LoadInstruments(NULL);
5582  }
5583 
5586  RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
5587  if (lstInstruments) {
5588  int iInstrumentIndex = 0;
5589  RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
5590  while (lstInstr) {
5591  if (lstInstr->GetListType() == LIST_TYPE_INS) {
5592  // notify current progress
5593  const float localProgress = (float) iInstrumentIndex / (float) Instruments;
5594  __notify_progress(pProgress, localProgress);
5595 
5596  // divide local progress into subprogress for loading current Instrument
5597  progress_t subprogress;
5598  __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
5599 
5600  pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
5601 
5602  iInstrumentIndex++;
5603  }
5604  lstInstr = lstInstruments->GetNextSubList();
5605  }
5606  __notify_progress(pProgress, 1.0); // notify done
5607  }
5608  }
5609 
5613  void File::SetSampleChecksum(Sample* pSample, uint32_t crc) {
5615  if (!_3crc) return;
5616 
5617  // get the index of the sample
5618  int iWaveIndex = -1;
5619  File::SampleList::iterator iter = pSamples->begin();
5620  File::SampleList::iterator end = pSamples->end();
5621  for (int index = 0; iter != end; ++iter, ++index) {
5622  if (*iter == pSample) {
5623  iWaveIndex = index;
5624  break;
5625  }
5626  }
5627  if (iWaveIndex < 0) throw gig::Exception("Could not update crc, could not find sample");
5628 
5629  // write the CRC-32 checksum to disk
5630  _3crc->SetPos(iWaveIndex * 8);
5631  uint32_t tmp = 1;
5632  _3crc->WriteUint32(&tmp); // unknown, always 1?
5633  _3crc->WriteUint32(&crc);
5634  }
5635 
5637  if (!pGroups) LoadGroups();
5638  // there must always be at least one group
5639  GroupsIterator = pGroups->begin();
5640  return *GroupsIterator;
5641  }
5642 
5644  if (!pGroups) return NULL;
5645  ++GroupsIterator;
5646  return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
5647  }
5648 
5655  Group* File::GetGroup(uint index) {
5656  if (!pGroups) LoadGroups();
5657  GroupsIterator = pGroups->begin();
5658  for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
5659  if (i == index) return *GroupsIterator;
5660  ++GroupsIterator;
5661  }
5662  return NULL;
5663  }
5664 
5676  if (!pGroups) LoadGroups();
5677  GroupsIterator = pGroups->begin();
5678  for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
5679  if ((*GroupsIterator)->Name == name) return *GroupsIterator;
5680  return NULL;
5681  }
5682 
5684  if (!pGroups) LoadGroups();
5685  // there must always be at least one group
5687  Group* pGroup = new Group(this, NULL);
5688  pGroups->push_back(pGroup);
5689  return pGroup;
5690  }
5691 
5701  void File::DeleteGroup(Group* pGroup) {
5702  if (!pGroups) LoadGroups();
5703  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
5704  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
5705  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
5706  // delete all members of this group
5707  for (Sample* pSample = pGroup->GetFirstSample(); pSample; pSample = pGroup->GetNextSample()) {
5708  DeleteSample(pSample);
5709  }
5710  // now delete this group object
5711  pGroups->erase(iter);
5712  delete pGroup;
5713  }
5714 
5726  if (!pGroups) LoadGroups();
5727  std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
5728  if (iter == pGroups->end()) throw gig::Exception("Could not delete group, could not find given group");
5729  if (pGroups->size() == 1) throw gig::Exception("Cannot delete group, there must be at least one default group!");
5730  // move all members of this group to another group
5731  pGroup->MoveAll();
5732  pGroups->erase(iter);
5733  delete pGroup;
5734  }
5735 
5737  if (!pGroups) pGroups = new std::list<Group*>;
5738  // try to read defined groups from file
5740  if (lst3gri) {
5741  RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL);
5742  if (lst3gnl) {
5743  RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk();
5744  while (ck) {
5745  if (ck->GetChunkID() == CHUNK_ID_3GNM) {
5746  if (pVersion && pVersion->major == 3 &&
5747  strcmp(static_cast<char*>(ck->LoadChunkData()), "") == 0) break;
5748 
5749  pGroups->push_back(new Group(this, ck));
5750  }
5751  ck = lst3gnl->GetNextSubChunk();
5752  }
5753  }
5754  }
5755  // if there were no group(s), create at least the mandatory default group
5756  if (!pGroups->size()) {
5757  Group* pGroup = new Group(this, NULL);
5758  pGroup->Name = "Default Group";
5759  pGroups->push_back(pGroup);
5760  }
5761  }
5762 
5771  if (!pScriptGroups) LoadScriptGroups();
5772  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
5773  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
5774  if (i == index) return *it;
5775  return NULL;
5776  }
5777 
5787  if (!pScriptGroups) LoadScriptGroups();
5788  std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
5789  for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
5790  if ((*it)->Name == name) return *it;
5791  return NULL;
5792  }
5793 
5803  if (!pScriptGroups) LoadScriptGroups();
5804  ScriptGroup* pScriptGroup = new ScriptGroup(this, NULL);
5805  pScriptGroups->push_back(pScriptGroup);
5806  return pScriptGroup;
5807  }
5808 
5821  void File::DeleteScriptGroup(ScriptGroup* pScriptGroup) {
5822  if (!pScriptGroups) LoadScriptGroups();
5823  std::list<ScriptGroup*>::iterator iter =
5824  find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
5825  if (iter == pScriptGroups->end())
5826  throw gig::Exception("Could not delete script group, could not find given script group");
5827  pScriptGroups->erase(iter);
5828  for (int i = 0; pScriptGroup->GetScript(i); ++i)
5829  pScriptGroup->DeleteScript(pScriptGroup->GetScript(i));
5830  if (pScriptGroup->pList)
5831  pScriptGroup->pList->GetParent()->DeleteSubChunk(pScriptGroup->pList);
5832  delete pScriptGroup;
5833  }
5834 
5836  if (pScriptGroups) return;
5837  pScriptGroups = new std::list<ScriptGroup*>;
5839  if (lstLS) {
5840  for (RIFF::List* lst = lstLS->GetFirstSubList(); lst;
5841  lst = lstLS->GetNextSubList())
5842  {
5843  if (lst->GetListType() == LIST_TYPE_RTIS) {
5844  pScriptGroups->push_back(new ScriptGroup(this, lst));
5845  }
5846  }
5847  }
5848  }
5849 
5861  void File::UpdateChunks(progress_t* pProgress) {
5862  bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
5863 
5864  // update own gig format extension chunks
5865  // (not part of the GigaStudio 4 format)
5867  if (!lst3LS) {
5868  lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
5869  }
5870  // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
5871  // location of <3LS > is irrelevant, however it should be located
5872  // before the actual wave data
5874  pRIFF->MoveSubChunk(lst3LS, ckPTBL);
5875 
5876  // This must be performed before writing the chunks for instruments,
5877  // because the instruments' script slots will write the file offsets
5878  // of the respective instrument script chunk as reference.
5879  if (pScriptGroups) {
5880  // Update instrument script (group) chunks.
5881  for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
5882  it != pScriptGroups->end(); ++it)
5883  {
5884  (*it)->UpdateChunks(pProgress);
5885  }
5886  }
5887 
5888  // in case no libgig custom format data was added, then remove the
5889  // custom "3LS " chunk again
5890  if (!lst3LS->CountSubChunks()) {
5891  pRIFF->DeleteSubChunk(lst3LS);
5892  lst3LS = NULL;
5893  }
5894 
5895  // first update base class's chunks
5896  DLS::File::UpdateChunks(pProgress);
5897 
5898  if (newFile) {
5899  // INFO was added by Resource::UpdateChunks - make sure it
5900  // is placed first in file
5902  RIFF::Chunk* first = pRIFF->GetFirstSubChunk();
5903  if (first != info) {
5904  pRIFF->MoveSubChunk(info, first);
5905  }
5906  }
5907 
5908  // update group's chunks
5909  if (pGroups) {
5910  // make sure '3gri' and '3gnl' list chunks exist
5911  // (before updating the Group chunks)
5913  if (!_3gri) {
5914  _3gri = pRIFF->AddSubList(LIST_TYPE_3GRI);
5916  }
5917  RIFF::List* _3gnl = _3gri->GetSubList(LIST_TYPE_3GNL);
5918  if (!_3gnl) _3gnl = _3gri->AddSubList(LIST_TYPE_3GNL);
5919 
5920  // v3: make sure the file has 128 3gnm chunks
5921  // (before updating the Group chunks)
5922  if (pVersion && pVersion->major == 3) {
5923  RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk();
5924  for (int i = 0 ; i < 128 ; i++) {
5925  if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64);
5926  if (_3gnm) _3gnm = _3gnl->GetNextSubChunk();
5927  }
5928  }
5929 
5930  std::list<Group*>::iterator iter = pGroups->begin();
5931  std::list<Group*>::iterator end = pGroups->end();
5932  for (; iter != end; ++iter) {
5933  (*iter)->UpdateChunks(pProgress);
5934  }
5935  }
5936 
5937  // update einf chunk
5938 
5939  // The einf chunk contains statistics about the gig file, such
5940  // as the number of regions and samples used by each
5941  // instrument. It is divided in equally sized parts, where the
5942  // first part contains information about the whole gig file,
5943  // and the rest of the parts map to each instrument in the
5944  // file.
5945  //
5946  // At the end of each part there is a bit map of each sample
5947  // in the file, where a set bit means that the sample is used
5948  // by the file/instrument.
5949  //
5950  // Note that there are several fields with unknown use. These
5951  // are set to zero.
5952 
5953  int sublen = pSamples->size() / 8 + 49;
5954  int einfSize = (Instruments + 1) * sublen;
5955 
5957  if (einf) {
5958  if (einf->GetSize() != einfSize) {
5959  einf->Resize(einfSize);
5960  memset(einf->LoadChunkData(), 0, einfSize);
5961  }
5962  } else if (newFile) {
5963  einf = pRIFF->AddSubChunk(CHUNK_ID_EINF, einfSize);
5964  }
5965  if (einf) {
5966  uint8_t* pData = (uint8_t*) einf->LoadChunkData();
5967 
5968  std::map<gig::Sample*,int> sampleMap;
5969  int sampleIdx = 0;
5970  for (Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
5971  sampleMap[pSample] = sampleIdx++;
5972  }
5973 
5974  int totnbusedsamples = 0;
5975  int totnbusedchannels = 0;
5976  int totnbregions = 0;
5977  int totnbdimregions = 0;
5978  int totnbloops = 0;
5979  int instrumentIdx = 0;
5980 
5981  memset(&pData[48], 0, sublen - 48);
5982 
5983  for (Instrument* instrument = GetFirstInstrument() ; instrument ;
5984  instrument = GetNextInstrument()) {
5985  int nbusedsamples = 0;
5986  int nbusedchannels = 0;
5987  int nbdimregions = 0;
5988  int nbloops = 0;
5989 
5990  memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
5991 
5992  for (Region* region = instrument->GetFirstRegion() ; region ;
5993  region = instrument->GetNextRegion()) {
5994  for (int i = 0 ; i < region->DimensionRegions ; i++) {
5995  gig::DimensionRegion *d = region->pDimensionRegions[i];
5996  if (d->pSample) {
5997  int sampleIdx = sampleMap[d->pSample];
5998  int byte = 48 + sampleIdx / 8;
5999  int bit = 1 << (sampleIdx & 7);
6000  if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
6001  pData[(instrumentIdx + 1) * sublen + byte] |= bit;
6002  nbusedsamples++;
6003  nbusedchannels += d->pSample->Channels;
6004 
6005  if ((pData[byte] & bit) == 0) {
6006  pData[byte] |= bit;
6007  totnbusedsamples++;
6008  totnbusedchannels += d->pSample->Channels;
6009  }
6010  }
6011  }
6012  if (d->SampleLoops) nbloops++;
6013  }
6014  nbdimregions += region->DimensionRegions;
6015  }
6016  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6017  // store32(&pData[(instrumentIdx + 1) * sublen], sublen);
6018  store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
6019  store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
6020  store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
6021  store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
6022  store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
6023  store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
6024  // next 8 bytes unknown
6025  store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
6026  store32(&pData[(instrumentIdx + 1) * sublen + 40], pSamples->size());
6027  // next 4 bytes unknown
6028 
6029  totnbregions += instrument->Regions;
6030  totnbdimregions += nbdimregions;
6031  totnbloops += nbloops;
6032  instrumentIdx++;
6033  }
6034  // first 4 bytes unknown - sometimes 0, sometimes length of einf part
6035  // store32(&pData[0], sublen);
6036  store32(&pData[4], totnbusedchannels);
6037  store32(&pData[8], totnbusedsamples);
6038  store32(&pData[12], Instruments);
6039  store32(&pData[16], totnbregions);
6040  store32(&pData[20], totnbdimregions);
6041  store32(&pData[24], totnbloops);
6042  // next 8 bytes unknown
6043  // next 4 bytes unknown, not always 0
6044  store32(&pData[40], pSamples->size());
6045  // next 4 bytes unknown
6046  }
6047 
6048  // update 3crc chunk
6049 
6050  // The 3crc chunk contains CRC-32 checksums for the
6051  // samples. The actual checksum values will be filled in
6052  // later, by Sample::Write.
6053 
6055  if (_3crc) {
6056  _3crc->Resize(pSamples->size() * 8);
6057  } else if (newFile) {
6058  _3crc = pRIFF->AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6059  _3crc->LoadChunkData();
6060 
6061  // the order of einf and 3crc is not the same in v2 and v3
6062  if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf);
6063  }
6064  }
6065 
6068 
6069  for (Instrument* instrument = GetFirstInstrument(); instrument;
6070  instrument = GetNextInstrument())
6071  {
6072  instrument->UpdateScriptFileOffsets();
6073  }
6074  }
6075 
6091  void File::SetAutoLoad(bool b) {
6092  bAutoLoad = b;
6093  }
6094 
6100  return bAutoLoad;
6101  }
6102 
6103 
6104 
6105 // *************** Exception ***************
6106 // *
6107 
6108  Exception::Exception(String Message) : DLS::Exception(Message) {
6109  }
6110 
6112  std::cout << "gig::Exception: " << Message << std::endl;
6113  }
6114 
6115 
6116 // *************** functions ***************
6117 // *
6118 
6125  return PACKAGE;
6126  }
6127 
6133  return VERSION;
6134  }
6135 
6136 } // namespace gig
range_t KeySwitchRange
Key range for key switch selector.
Definition: gig.h:939
file_offset_t WriteUint32(uint32_t *pData, file_offset_t WordCount=1)
Writes WordCount number of 32 Bit unsigned integer words from the buffer pointed by pData to the chun...
Definition: RIFF.cpp:684
bool LFO2FlipPhase
Inverts phase of the filter cutoff LFO wave.
Definition: gig.h:408
void UpdateRegionKeyTable()
Definition: gig.cpp:4459
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
Definition: gig.cpp:4152
void AddContentOf(File *pFile)
Add content of another existing file.
Definition: gig.cpp:5512
#define CHUNK_ID_3GIX
Definition: gig.h:55
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
Definition: gig.cpp:5153
#define LIST_TYPE_3GNL
Definition: gig.h:52
dim_bypass_ctrl_t DimensionBypass
If defined, the MIDI controller can switch on/off the dimension in realtime.
Definition: gig.h:442
~Instrument()
Destructor.
Definition: gig.cpp:4471
file_offset_t position
Current position within the sample.
Definition: gig.h:311
Encapsulates articulation informations of a dimension region.
Definition: gig.h:367
void LoadScripts()
Definition: gig.cpp:4779
file_offset_t GetFilePos() const
Current, actual offset of chunk data body start in file.
Definition: RIFF.h:227
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
Definition: gig.h:1092
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
Definition: DLS.h:373
#define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x)
Definition: gig.cpp:53
file_offset_t GetNewSize() const
New chunk size if it was modified with Resize(), otherwise value returned will be equal to GetSize()...
Definition: RIFF.h:225
uint8_t VCFVelocityScale
(0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defi...
Definition: gig.h:425
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
Definition: gig.cpp:3647
#define CHUNK_HEADER_SIZE(fileOffsetSize)
Definition: RIFF.h:114
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Definition: gig.h:312
uint8_t AltSustain2Key
Key triggering a second set of alternate sustain samples.
Definition: gig.h:891
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
Definition: gig.h:678
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Definition: DLS.h:468
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
Definition: gig.cpp:4600
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
Definition: gig.cpp:5143
String GetScriptAsText()
Returns the current script (i.e.
Definition: gig.cpp:4139
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
Definition: gig.h:680
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
Definition: gig.cpp:4761
File * GetFile() const
Returns pointer to the chunk&#39;s File object.
Definition: RIFF.h:222
Sample * AddSample()
Add a new sample.
Definition: gig.cpp:5287
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:826
bool VCFEnabled
If filter should be used.
Definition: gig.h:419
no SMPTE offset
Definition: gig.h:102
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
Definition: gig.cpp:3182
file_offset_t ReadUint16(uint16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit unsigned integer words and copies it into the buffer pointed by pDat...
Definition: RIFF.cpp:572
stream_whence_t
File stream position dependent to these relations.
Definition: RIFF.h:164
void LoadScripts()
Definition: gig.cpp:4337
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Definition: gig.h:638
uint8_t BypassKey
Key to be used to bypass the sustain note.
Definition: gig.h:884
uint16_t LFO1ControlDepth
Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents).
Definition: gig.h:387
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
Definition: RIFF.cpp:1116
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
Definition: gig.h:683
lfo1_ctrl_t
Defines how LFO1 is controlled by.
Definition: gig.h:143
Group of Gigasampler samples.
Definition: gig.h:1157
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
Definition: DLS.h:233
uint8_t VCFVelocityDynamicRange
0x04 = lowest, 0x00 = highest .
Definition: gig.h:426
String Name
Stores the name of this Group.
Definition: gig.h:1159
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index)...
Definition: gig.cpp:3827
Special dimension for triggering samples on releasing a key.
Definition: gig.h:230
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Definition: gig.h:1090
double EG1Release
Release time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:378
#define CHUNK_ID_SMPL
Definition: RIFF.h:110
virtual ~File()
Definition: gig.cpp:5229
#define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x)
Definition: gig.cpp:51
uint8_t Triggers
Number of triggers.
Definition: gig.h:842
#define LIST_TYPE_WAVE
Definition: DLS.h:67
uint ScriptSlotCount() const
Instrument&#39;s amount of script slots.
Definition: gig.cpp:4939
#define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x)
Definition: gig.cpp:56
String GetFileName() const
Definition: RIFF.cpp:1711
#define CHUNK_ID_ISBJ
Definition: DLS.h:81
vcf_type_t VCFType
Defines the general filter characteristic (lowpass, highpass, bandpass, etc.).
Definition: gig.h:420
Script * AddScript()
Add new instrument script.
Definition: gig.cpp:4307
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order...
Definition: DLS.cpp:1078
void __ensureMandatoryChunksExist()
Checks if all (for DLS) mandatory chunks exist, if not they will be created.
Definition: DLS.cpp:1871
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Definition: gig.h:646
Instrument * AddInstrument()
Add a new instrument definition.
Definition: gig.cpp:5458
virtual void LoadScriptGroups()
Definition: gig.cpp:5835
Script * GetScript(uint index)
Get instrument script.
Definition: gig.cpp:4288
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:643
lfo1_ctrl_t LFO1Controller
MIDI Controller which controls sample amplitude LFO.
Definition: gig.h:388
Group * AddGroup()
Definition: gig.cpp:5683
#define CHUNK_ID_ISRF
Definition: DLS.h:83
#define LIST_TYPE_LART
Definition: DLS.h:71
Only internally controlled.
Definition: gig.h:135
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: DLS.cpp:1514
uint8_t low
Low value of range.
Definition: gig.h:77
void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Definition: gig.cpp:4265
uint16_t SampleStartOffset
Number of samples the sample start should be moved (0 - 2000).
Definition: gig.h:451
MIDI rule for triggering notes by control change events.
Definition: gig.h:839
file_offset_t ReadInt32(int32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:609
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
Definition: DLS.cpp:1175
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
Definition: RIFF.h:204
#define CHUNK_ID_PTBL
Definition: DLS.h:92
uint8_t Key
Key to trigger.
Definition: gig.h:847
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
Definition: gig.h:682
#define LIST_TYPE_WVPL
Definition: DLS.h:65
file_offset_t Size
Size of the actual data in the buffer in bytes.
Definition: gig.h:84
RIFF::List * pCkRegion
Definition: DLS.h:449
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
Definition: gig.cpp:4863
bool EG1Hold
If true, Decay1 stage should be postponed until the sample reached the sample loop start...
Definition: gig.h:379
range_t PlayRange
Key range of the playable keys in the instrument.
Definition: gig.h:917
file_offset_t ullWavePoolOffset
Definition: DLS.h:421
uint16_t ThresholdTime
Maximum time (ms) between two notes that should be played legato.
Definition: gig.h:886
RIFF::Chunk * pCk3gix
Definition: gig.h:686
static size_t Instances
Number of instances of class Sample.
Definition: gig.h:675
dimension values are already the sought bit number
Definition: gig.h:267
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0)
Constructor.
Definition: gig.cpp:342
uint8_t VelocityResponseCurveScaling
0 - 127 (usually you don&#39;t have to interpret this parameter, use GetVelocityAttenuation() instead)...
Definition: gig.h:435
bool Descending
If the change in CC value should be downwards.
Definition: gig.h:845
double GetVelocityCutoff(uint8_t MIDIKeyVelocity)
Definition: gig.cpp:2748
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5401
#define CHUNK_ID_ICMT
Definition: RIFF.h:102
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
Definition: RIFF.cpp:663
#define CHUNK_ID_ISFT
Definition: RIFF.h:108
Region * RegionKeyTable[128]
fast lookup for the corresponding Region of a MIDI key
Definition: gig.h:1122
List * GetParent() const
Returns pointer to the chunk&#39;s parent list chunk.
Definition: RIFF.h:223
uint8_t ReleaseTriggerKey
Key triggering release samples.
Definition: gig.h:889
#define CHUNK_ID_3EWA
Definition: gig.h:56
uint32_t * pWavePoolTable
Definition: DLS.h:532
For MIDI tools like legato and repetition mode.
Definition: gig.h:234
bool VCFKeyboardTracking
If true: VCF cutoff frequence will be dependend to the note key position relative to the defined brea...
Definition: gig.h:430
#define CHUNK_ID_IMED
Definition: DLS.h:80
uint32_t WavePoolTableIndex
Definition: DLS.h:450
uint8_t Velocity
Velocity of the note to trigger. 255 means that velocity should depend on the speed of the controller...
Definition: gig.h:849
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
Definition: gig.cpp:480
Defines a controller that has a certain contrained influence on a particular synthesis parameter (use...
Definition: gig.h:184
#define CHUNK_ID_IPRD
Definition: RIFF.h:107
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
Definition: DLS.h:399
uint8_t Controller
CC number for controller selector.
Definition: gig.h:940
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2837
RIFF::List * pCkInstrument
Definition: DLS.h:483
Defines Region information of a Gigasampler/GigaStudio instrument.
Definition: gig.h:742
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise)...
Definition: DLS.h:404
uint32_t SamplerOptions
Definition: DLS.h:383
void UpdateVelocityTable()
Definition: gig.cpp:3095
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
Definition: gig.h:648
uint8_t ReleaseTriggerDecay
0 - 8
Definition: gig.h:438
lfo3_ctrl_t LFO3Controller
MIDI Controller which controls the sample pitch LFO.
Definition: gig.h:416
bool Chained
If all patterns should be chained together.
Definition: gig.h:943
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it&#39;s original sample rate...
Definition: gig.h:637
uint8_t ControllerNumber
MIDI controller number.
Definition: gig.h:841
Sampler(RIFF::List *ParentList)
Definition: DLS.cpp:550
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
Definition: RIFF.cpp:1090
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Definition: RIFF.cpp:1342
uint8_t ChannelOffset
Audio output where the audio signal of the dimension region should be routed to (0 - 9)...
Definition: gig.h:448
file_offset_t GetCurrentFileSize() const
Returns the current size of this file (in bytes) as it is currently yet stored on disk...
Definition: RIFF.cpp:2114
Defines Sample Loop Points.
Definition: DLS.h:231
uint8_t VCFResonance
Firm internal filter resonance weight.
Definition: gig.h:427
bool VCFResonanceDynamic
If true: Increases the resonance Q according to changes of controllers that actually control the VCF ...
Definition: gig.h:428
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
Definition: gig.cpp:4774
unsigned int Dimensions
Number of defined dimensions, do not alter!
Definition: gig.h:744
Only controlled by external modulation wheel.
Definition: gig.h:127
void UpdateChunks(uint8_t *pData) const
Definition: gig.cpp:4067
#define CHUNK_ID_SCSL
Definition: gig.h:65
vcf_cutoff_ctrl_t VCFCutoffController
Specifies which external controller has influence on the filter cutoff frequency. ...
Definition: gig.h:421
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:313
virtual void SetGain(int32_t gain)
Definition: DLS.cpp:586
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
Definition: gig.cpp:4735
void LoadString(RIFF::Chunk *ck, std::string &s, int strLength)
Definition: SF.cpp:60
double EG1Decay1
Decay time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:374
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
Definition: RIFF.cpp:1151
file_offset_t GetPos() const
Position within the chunk data body (starting with 0).
Definition: RIFF.h:226
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it&#39;s articulation d...
Definition: gig.cpp:3718
#define COPY_ONE(x)
void UpdateScriptFileOffsets()
Definition: gig.cpp:4573
lfo2_ctrl_t LFO2Controller
MIDI Controlle which controls the filter cutoff LFO.
Definition: gig.h:407
RIFF::List * pParentList
Definition: DLS.h:381
void LoadDimensionRegions(RIFF::List *rgn)
Definition: gig.cpp:3072
Different samples triggered each time a note is played, any key advances the counter.
Definition: gig.h:235
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction...
Definition: gig.h:651
Region * GetFirstRegion()
Returns the first Region of the instrument.
Definition: gig.cpp:4618
#define GIG_VCF_RESONANCE_CTRL_ENCODE(x)
Definition: gig.cpp:50
String libraryVersion()
Returns version of this C++ library.
Definition: gig.cpp:6132
#define CHUNK_ID_IKEY
Definition: DLS.h:79
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set...
Definition: gig.h:369
uint8_t ReleaseVelocityResponseDepth
Dynamic range of release velocity affecting envelope time (0 - 4).
Definition: gig.h:437
#define GET_PARAMS(params)
RIFF::List * pParentList
Definition: DLS.h:297
void RemoveAllScriptReferences()
Definition: gig.cpp:4221
std::list< Sample * > SampleList
Definition: DLS.h:521
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File...
Definition: gig.h:1290
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:689
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
Definition: gig.cpp:4166
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Definition: gig.cpp:1340
InstrumentList::iterator InstrumentsIterator
Definition: DLS.h:529
Instrument(File *pFile, RIFF::List *insList, progress_t *pProgress=NULL)
Definition: gig.cpp:4354
void GenerateDLSID()
Generates a new DLSID for the resource.
Definition: DLS.cpp:495
uint8_t in_end
End position of fade in.
Definition: gig.h:303
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:2810
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Definition: gig.h:1213
Sample * pSample
Points to the Sample which is assigned to the dimension region.
Definition: gig.h:370
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used...
Definition: DLS.h:405
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
Definition: gig.cpp:640
uint16_t ReleaseTime
Release time.
Definition: gig.h:887
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:644
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
Definition: gig.cpp:5643
Loop forward (normal)
Definition: gig.h:95
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2819
#define CHUNK_ID_IENG
Definition: RIFF.h:105
double EG2Decay1
Decay time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:394
#define LIST_TYPE_3PRG
Definition: gig.h:49
uint8_t EG1ControllerAttackInfluence
Amount EG1 Controller has influence on the EG1 Attack time (0 - 3, where 0 means off).
Definition: gig.h:382
#define INITIAL_SAMPLE_BUFFER_SIZE
Initial size of the sample buffer which is used for decompression of compressed sample wave streams -...
Definition: gig.cpp:42
String pArticulations[32]
Names of the articulations.
Definition: gig.h:915
crossfade_t Crossfade
Definition: gig.h:440
Compression_t
Definition: gig.h:997
void SetAutoLoad(bool b)
Enable / disable automatic loading.
Definition: gig.cpp:6091
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
Definition: gig.cpp:4726
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
Definition: gig.h:639
uint16_t low
Low value of range.
Definition: DLS.h:207
double SampleAttenuation
Sample volume (calculated from DLS::Sampler::Gain)
Definition: gig.h:452
File()
Definition: gig.cpp:5205
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Definition: gig.cpp:860
lfo3_ctrl_t
Defines how LFO3 is controlled by.
Definition: gig.h:125
file_offset_t GuessSize(file_offset_t samples)
Definition: gig.h:694
RIFF List Chunk.
Definition: RIFF.h:293
#define CHUNK_ID_WSMP
Definition: DLS.h:93
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
Definition: RIFF.cpp:256
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
Definition: gig.cpp:4217
double EG1Decay2
Only if EG1InfiniteSustain == false: 2nd decay stage time of the sample amplitude EG (0...
Definition: gig.h:375
bool PianoReleaseMode
Definition: gig.h:1091
RIFF::Chunk * pCkData
Definition: DLS.h:419
#define CHUNK_ID_VERS
Definition: DLS.h:85
#define LIST_TYPE_3EWL
Definition: gig.h:50
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
Definition: DLS.cpp:296
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
Definition: gig.cpp:4916
RegionList * pRegions
Definition: DLS.h:484
uint8_t BypassController
Controller to be used to bypass the sustain note.
Definition: gig.h:885
attenuation_ctrl_t AttenuationController
MIDI Controller which has influence on the volume level of the sample (or entire sample group)...
Definition: gig.h:445
file_offset_t Read(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
Definition: RIFF.cpp:318
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
Definition: gig.h:676
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Definition: gig.cpp:1323
Pointer address and size of a buffer.
Definition: gig.h:82
virtual void LoadSamples()
Definition: gig.cpp:5338
friend class ScriptGroup
Definition: gig.h:1274
uint8_t in_start
Start position of fade in.
Definition: gig.h:302
file_offset_t WorstCaseMaxSamples(buffer_t *pDecompressionBuffer)
Definition: gig.h:711
uint8_t Patterns
Number of alternator patterns.
Definition: gig.h:919
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
Definition: RIFF.h:224
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
Definition: gig.h:272
range_t KeyRange
Key range for legato notes.
Definition: gig.h:888
friend class Sample
Definition: gig.h:1271
bool EG2ControllerInvert
Invert values coming from defined EG2 controller.
Definition: gig.h:400
uint8_t Articulations
Number of articulations in the instrument.
Definition: gig.h:914
friend class Region
Definition: gig.h:1131
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
Definition: gig.cpp:5636
file_offset_t SetPos(file_offset_t Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes)...
Definition: RIFF.cpp:224
Group * GetGroup(uint index)
Returns the group with the given index.
Definition: gig.cpp:5655
uint8_t VelSensitivity
How sensitive the velocity should be to the speed of the controller change.
Definition: gig.h:846
#define LIST_TYPE_3GRI
Definition: gig.h:51
uint32_t DimensionRegions
Total number of DimensionRegions this Region contains, do not alter!
Definition: gig.h:746
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
Definition: gig.cpp:5495
std::string String
Definition: gig.h:71
bool MSDecode
Gigastudio flag: defines if Mid Side Recordings should be decoded.
Definition: gig.h:450
Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
Definition: gig.h:228
bool EG1InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released...
Definition: gig.h:376
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors...
Definition: gig.h:649
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
Definition: gig.cpp:763
uint32_t SampleLoops
Reflects the number of sample loops.
Definition: DLS.h:372
More poles than normal lowpass.
Definition: gig.h:282
virtual void Save(const String &Path, progress_t *pProgress=NULL)
Save changes to another file.
Definition: DLS.cpp:1803
Resource * pParent
Definition: DLS.h:357
uint16_t LFO2InternalDepth
Firm pitch of the filter cutoff LFO (0 - 1200 cents).
Definition: gig.h:405
SampleList * pSamples
Definition: DLS.h:526
#define CHUNK_ID_FMT
Definition: DLS.h:87
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
Definition: gig.cpp:3384
void Resize(file_offset_t NewSize)
Resize sample.
Definition: DLS.cpp:891
uint16_t LFO1InternalDepth
Firm pitch of the sample amplitude LFO (0 - 1200 cents).
Definition: gig.h:386
#define CHUNK_ID_3CRC
Definition: gig.h:62
The difference between none and none2 is unknown.
Definition: gig.h:154
virtual void LoadInstruments()
Definition: gig.cpp:5580
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
Definition: gig.cpp:1306
float zone_size
Intended for internal usage: reflects the size of each zone (128/zones) for normal split types only...
Definition: gig.h:276
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: gig.cpp:6066
String Message
Definition: RIFF.h:405
void Resize(file_offset_t NewSize)
Resize sample.
Definition: gig.cpp:800
bool PitchTrack
If true: sample will be pitched according to the key position (this will be disabled for drums for ex...
Definition: gig.h:441
double GetVelocityRelease(uint8_t MIDIKeyVelocity)
Definition: gig.cpp:2744
#define CHUNK_ID_LSNM
Definition: gig.h:64
Encoding_t
Definition: gig.h:994
friend class Instrument
Definition: gig.h:1272
bool BypassUseController
If a controller should be used to bypass the sustain note.
Definition: gig.h:883
float __range_min
Only for internal usage, do not modify!
Definition: RIFF.h:207
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:748
void * pStart
Points to the beginning of the buffer.
Definition: gig.h:83
file_offset_t ReadUint32(uint32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
Definition: RIFF.cpp:646
bool EG2InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released...
Definition: gig.h:396
Region * AddRegion()
Definition: gig.cpp:4638
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Definition: gig.h:677
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
Definition: RIFF.cpp:1071
Script(ScriptGroup *group, RIFF::Chunk *ckScri)
Definition: gig.cpp:4101
struct gig::MidiRuleAlternator::pattern_t pPatterns[32]
A pattern is a sequence of articulation numbers.
#define LIST_TYPE_3LS
Definition: gig.h:53
#define LIST_TYPE_INS
Definition: DLS.h:69
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
Definition: RIFF.cpp:1133
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
Definition: gig.cpp:4748
std::list< Instrument * > InstrumentList
Definition: DLS.h:522
uint8_t EG2ControllerAttackInfluence
Amount EG2 Controller has influence on the EG2 Attack time (0 - 3, where 0 means off).
Definition: gig.h:401
Exception(String Message)
Definition: gig.cpp:6108
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:444
#define CHUNK_ID_ICRD
Definition: RIFF.h:104
#define LIST_TYPE_RTIS
Definition: gig.h:54
int16_t LFO3ControlDepth
Controller depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:415
RIFF::Chunk * pCkSmpl
Definition: gig.h:687
void RemoveScriptSlot(uint index)
Remove script slot.
Definition: gig.cpp:4898
double EG3Attack
Attack time of the sample pitch EG (0.000 - 10.000s).
Definition: gig.h:411
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Definition: gig.cpp:3294
#define CHUNK_ID_DLID
Definition: DLS.h:86
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
Definition: gig.cpp:5408
uint8_t LegatoSamples
Number of legato samples per key in each direction (always 12)
Definition: gig.h:882
uint8_t out_end
End postition of fade out.
Definition: gig.h:305
void DeleteGroupOnly(Group *pGroup)
Delete a group.
Definition: gig.cpp:5725
double EG2Attack
Attack time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:393
#define GIG_EXP_DECODE(x)
(so far) every exponential paramater in the gig format has a basis of 1.000000008813822 ...
Definition: gig.cpp:45
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
Definition: DLS.h:403
bool InvertAttenuationController
Inverts the values coming from the defined Attenuation Controller.
Definition: gig.h:446
double LFO1Frequency
Frequency of the sample amplitude LFO (0.10 - 10.00 Hz).
Definition: gig.h:385
Ordinary RIFF Chunk.
Definition: RIFF.h:217
DimensionRegion(Region *pParent, RIFF::List *_3ewl)
Definition: gig.cpp:1363
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:642
uint16_t EffectSend
Definition: gig.h:1088
#define CHUNK_ID_ICMS
Definition: DLS.h:77
bool LFO1FlipPhase
Inverts phase of the sample amplitude LFO wave.
Definition: gig.h:389
uint8_t AltSustain1Key
Key triggering alternate sustain samples.
Definition: gig.h:890
void DeleteSample(Sample *pSample)
Delete a sample.
Definition: gig.cpp:5312
int16_t FineTune
in cents
Definition: gig.h:1089
Region(Instrument *pInstrument, RIFF::List *rgnList)
Definition: gig.cpp:2913
#define LIST_TYPE_RGN
Definition: DLS.h:73
bool LFO3Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:417
#define CHUNK_ID_INAM
Definition: RIFF.h:106
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
Definition: gig.cpp:4959
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
Definition: RIFF.h:221
double LFO3Frequency
Frequency of the sample pitch LFO (0.10 - 10.00 Hz).
Definition: gig.h:413
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
Definition: gig.h:1214
uint32_t LoopLength
Length of the looping area (in sample points).
Definition: DLS.h:235
void DeleteRegion(Region *pRegion)
Definition: gig.cpp:4652
#define CHUNK_ID_ITCH
Definition: DLS.h:84
virtual ~ScriptGroup()
Definition: gig.cpp:4244
ScriptGroup * AddScriptGroup()
Add new instrument script group.
Definition: gig.cpp:5802
#define CHUNK_ID_EINF
Definition: gig.h:61
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
Definition: gig.h:747
#define CHUNK_ID_3EWG
Definition: gig.h:58
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field...
Definition: gig.h:635
bool LFO1Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:390
split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:265
Alternating loop (forward/backward, also known as Ping Pong)
Definition: gig.h:96
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
Definition: gig.cpp:5770
~Sample()
Destructor.
Definition: gig.cpp:1344
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Definition: gig.cpp:5613
Sample * GetNextSample()
Returns the next Sample of the Group.
Definition: gig.cpp:5132
uint8_t EG2ControllerReleaseInfluence
Amount EG2 Controller has influence on the EG2 Release time (0 - 3, where 0 means off)...
Definition: gig.h:403
Used for indicating the progress of a certain task.
Definition: RIFF.h:203
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:899
SampleList::iterator SamplesIterator
Definition: DLS.h:527
uint16_t EG2PreAttack
Preattack value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:392
file_offset_t Write(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Writes WordCount number of data words with given WordSize from the buffer pointed by pData...
Definition: RIFF.cpp:388
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
Definition: gig.h:641
bool LFO2Sync
If set to true only one LFO should be used for all voices.
Definition: gig.h:409
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
Definition: gig.h:640
file_offset_t ReadInt8(int8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:461
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it&#39;s in the gig) ...
Definition: gig.h:685
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Definition: gig.cpp:3508
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
Definition: gig.cpp:5250
bool EG1ControllerInvert
Invert values coming from defined EG1 controller.
Definition: gig.h:381
void UpdateChunks(uint8_t *pData) const
Definition: gig.cpp:3958
friend class Group
Definition: gig.h:1273
Ordinary MIDI control change controller, see field &#39;controller_number&#39;.
Definition: gig.h:189
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: DLS.cpp:1309
vcf_type_t
Defines which frequencies are filtered by the VCF.
Definition: gig.h:280
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file...
Definition: RIFF.cpp:2207
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL...
Definition: DLS.h:500
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
Definition: gig.cpp:5572
uint16_t LFO2ControlDepth
Controller depth influencing filter cutoff LFO pitch (0 - 1200).
Definition: gig.h:406
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
Definition: DLS.h:234
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
Definition: gig.cpp:5079
uint16_t major
Definition: DLS.h:113
RegionList::iterator RegionsIterator
Definition: DLS.h:485
int GetDimensionRegionIndexByValue(const uint DimValues[8])
Definition: gig.cpp:3767
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame...
Definition: gig.h:679
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
Definition: gig.cpp:1263
Loop backward (reverse)
Definition: gig.h:97
int16_t EG3Depth
Depth of the sample pitch EG (-1200 - +1200).
Definition: gig.h:412
bool GetAutoLoad()
Returns whether automatic loading is enabled.
Definition: gig.cpp:6099
uint8_t VCFKeyboardTrackingBreakpoint
See VCFKeyboardTracking (0 - 127).
Definition: gig.h:431
eg2_ctrl_t EG2Controller
MIDI Controller which has influence on filter cutoff EG parameters (attack, decay, release).
Definition: gig.h:399
#define CHUNK_ID_INSH
Definition: DLS.h:89
For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers).
Definition: gig.h:227
file_offset_t GetSize() const
Returns sample size.
Definition: DLS.cpp:858
void * LoadChunkData()
Load chunk body into RAM.
Definition: RIFF.cpp:809
bool VCFCutoffControllerInvert
Inverts values coming from the defined cutoff controller.
Definition: gig.h:422
Different samples triggered each time a note is played, random order.
Definition: gig.h:233
file_offset_t NullExtensionSize
The buffer might be bigger than the actual data, if that&#39;s the case that unused space at the end of t...
Definition: gig.h:85
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:3890
#define LIST_TYPE_LRGN
Definition: DLS.h:70
#define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x)
Definition: gig.cpp:54
#define CHUNK_ID_IGNR
Definition: DLS.h:78
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
Definition: gig.cpp:4883
double EG2Release
Release time of the filter cutoff EG (0.000 - 60.000s).
Definition: gig.h:398
uint8_t EG1ControllerReleaseInfluence
Amount EG1 Controller has influence on the EG1 Release time (0 - 3, where 0 means off)...
Definition: gig.h:384
#define CHUNK_ID_IART
Definition: DLS.h:76
uint8_t EG2ControllerDecayInfluence
Amount EG2 Controller has influence on the EG2 Decay time (0 - 3, where 0 means off).
Definition: gig.h:402
~Region()
Destructor.
Definition: gig.cpp:3694
bool Polyphonic
If alternator should step forward only when all notes are off.
Definition: gig.h:942
Abstract base class for all MIDI rules.
Definition: gig.h:818
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2780
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file&#39;s current instruments, samples, groups and settings to the respective RIFF chu...
Definition: gig.cpp:5861
#define CHUNK_ID_3LNK
Definition: gig.h:57
dimension_t
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
Definition: gig.h:224
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
Definition: gig.h:681
ScriptGroup(File *file, RIFF::List *lstRTIS)
Definition: gig.cpp:4232
gig::buffer_t buffer_t
Definition: Korg.h:79
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Definition: gig.h:645
curve_type_t ReleaseVelocityResponseCurve
Defines a transformation curve to the incoming release veloctiy values affecting envelope times...
Definition: gig.h:436
Different samples triggered each time a note is played, dimension regions selected in sequence...
Definition: gig.h:232
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension&#39;s controller and number of...
Definition: gig.h:745
#define CHUNK_ID_COLH
Definition: DLS.h:94
uint8_t zones
Number of zones the dimension has.
Definition: gig.h:274
Effect 5 Depth (MIDI Controller 95)
Definition: gig.h:121
#define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x)
Definition: gig.cpp:52
uint8_t AttenuationControllerThreshold
0-127
Definition: gig.h:447
#define CHUNK_ID_ICOP
Definition: RIFF.h:103
RIFF::File * pRIFF
Definition: DLS.h:524
buffer_t GetCache()
Returns current cached sample points.
Definition: gig.cpp:748
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2828
vcf_cutoff_ctrl_t
Defines how the filter cutoff frequency is controlled by.
Definition: gig.h:152
void Resize(file_offset_t NewSize)
Resize chunk.
Definition: RIFF.cpp:880
No controller defined.
Definition: gig.h:186
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
Definition: gig.h:632
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value...
Definition: gig.cpp:1717
#define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x)
Definition: gig.cpp:55
RIFF File.
Definition: RIFF.h:343
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Definition: RIFF.cpp:1323
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
Definition: gig.cpp:5058
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:1074
InstrumentList * pInstruments
Definition: DLS.h:528
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
Definition: DLS.cpp:596
dimension value between 0-127
Definition: gig.h:266
int16_t LFO3InternalDepth
Firm depth of the sample pitch LFO (-1200 - +1200 cents).
Definition: gig.h:414
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
Definition: gig.cpp:1731
bool IsNew() const
Returns true if this file has been created new from scratch and has not been stored to disk yet...
Definition: RIFF.cpp:2092
#define SKIP_ONE(x)
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
Definition: DLS.h:319
#define GIG_PITCH_TRACK_EXTRACT(x)
Definition: gig.cpp:47
String ArchivalLocation
<IARL-ck>. Indicates where the subject of the file is stored.
Definition: DLS.h:309
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
Definition: gig.cpp:5257
virtual ~Script()
Definition: gig.cpp:4133
double EG2Decay2
Only if EG2InfiniteSustain == false: 2nd stage decay time of the filter cutoff EG (0...
Definition: gig.h:395
int32_t Attenuation
in dB
Definition: gig.h:1087
Encapsulates sample waves used for playback.
Definition: DLS.h:396
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Definition: gig.cpp:4489
type_t type
Controller type.
Definition: gig.h:192
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
Definition: gig.h:193
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
Definition: gig.h:484
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
Definition: RIFF.cpp:1275
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
Definition: DLS.h:400
curve_type_t VelocityResponseCurve
Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don&#39;t...
Definition: gig.h:433
A MIDI rule not yet implemented by libgig.
Definition: gig.h:965
void PrintMessage()
Definition: gig.cpp:6111
uint16_t EG1Sustain
Sustain value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:377
Sample * GetSample(uint index)
Returns Sample object of index.
Definition: gig.cpp:5268
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Definition: RIFF.cpp:1191
uint32_t WavePoolCount
Definition: DLS.h:531
String GetFileName()
File name of this DLS file.
Definition: DLS.cpp:1678
Real-time instrument script (gig format extension).
Definition: gig.h:992
#define CHUNK_ID_3GNM
Definition: gig.h:60
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2768
RIFF::List * pWaveList
Definition: DLS.h:418
Sample * GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t *pProgress=NULL)
Definition: gig.cpp:3851
Gigasampler/GigaStudio specific classes and definitions.
Definition: gig.h:69
float __range_max
Only for internal usage, do not modify!
Definition: RIFF.h:208
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
Definition: gig.h:453
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:1659
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks. ...
Definition: gig.cpp:3007
uint8_t TriggerPoint
The CC value to pass for the note to be triggered.
Definition: gig.h:844
uint8_t VelocityResponseDepth
Dynamic range of velocity affecting amplitude (0 - 4) (usually you don&#39;t have to interpret this param...
Definition: gig.h:434
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:647
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0, 4 or 6)
Definition: gig.h:650
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
Definition: gig.cpp:5421
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
Definition: DLS.cpp:769
#define LIST_TYPE_LINS
Definition: DLS.h:68
Resource * GetParent()
Definition: DLS.h:351
#define CHUNK_ID_IARL
Definition: DLS.h:75
Group of instrument scripts (gig format extension).
Definition: gig.h:1039
#define GIG_VCF_RESONANCE_CTRL_EXTRACT(x)
Definition: gig.cpp:49
Language_t
Definition: gig.h:1000
#define GIG_PITCH_TRACK_ENCODE(x)
Definition: gig.cpp:48
int8_t Pan
Panorama / Balance (-64..0..63 <-> left..middle..right)
Definition: gig.h:443
Only internally controlled.
Definition: gig.h:144
Provides convenient access to Gigasampler/GigaStudio .gig files.
Definition: gig.h:1211
void DeleteRegion(Region *pRegion)
Definition: DLS.cpp:1293
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
Definition: gig.cpp:4204
lfo2_ctrl_t
Defines how LFO2 is controlled by.
Definition: gig.h:134
Dimension for keyswitching.
Definition: gig.h:231
Sample * pSample
Definition: DLS.h:451
#define LIST_TYPE_INFO
Definition: RIFF.h:101
MIDI rule for instruments with legato samples.
Definition: gig.h:880
virtual ~Group()
Definition: gig.cpp:5064
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2801
range_t KeyRange
Definition: DLS.h:433
#define CHUNK_ID_ISRC
Definition: DLS.h:82
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: DLS.cpp:970
Sample * GetFirstSample()
Returns the first Sample of this Group.
Definition: gig.cpp:5114
struct gig::MidiRuleCtrlTrigger::trigger_t pTriggers[32]
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:3687
RIFF::file_offset_t file_offset_t
Definition: gig.h:73
uint16_t EG2Sustain
Sustain value of the filter cutoff EG (0 - 1000 permille).
Definition: gig.h:397
uint32_t Instruments
Reflects the number of available Instrument objects.
Definition: DLS.h:501
Provides all neccessary information for the synthesis of a DLS Instrument.
Definition: DLS.h:461
Provides access to a Gigasampler/GigaStudio instrument.
Definition: gig.h:1074
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
Definition: gig.cpp:4979
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Definition: gig.cpp:5701
bool SustainDefeat
If true: Sustain pedal will not hold a note.
Definition: gig.h:449
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
Definition: gig.h:684
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:4996
bool NoteOff
If a note off should be triggered instead of a note on.
Definition: gig.h:848
String libraryName()
Returns the name of this C++ library.
Definition: gig.cpp:6124
int32_t Gain
Definition: DLS.h:369
virtual void LoadGroups()
Definition: gig.cpp:5736
Quadtuple version number ("major.minor.release.build").
Definition: DLS.h:111
void MoveTo(Instrument *dst)
Move this instrument at the position before.
Definition: gig.cpp:4686
double LFO2Frequency
Frequency of the filter cutoff LFO (0.10 - 10.00 Hz).
Definition: gig.h:404
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Definition: gig.h:636
uint16_t EG1PreAttack
Preattack value of the sample amplitude EG (0 - 1000 permille).
Definition: gig.h:372
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
Definition: gig.cpp:4822
Dimension not in use.
Definition: gig.h:225
void CopyAssignCore(const Instrument *orig)
Definition: DLS.cpp:1361
curve_type_t
Defines the shape of a function graph.
Definition: gig.h:110
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
Definition: gig.h:273
selector_t Selector
Method by which pattern is chosen.
Definition: gig.h:938
virtual void UpdateChunks(uint8_t *pData) const =0
uint32_t GetListType() const
Returns unsigned integer representation of the list&#39;s ID.
Definition: RIFF.h:297
uint8_t out_start
Start position of fade out.
Definition: gig.h:304
uint8_t VCFCutoff
Max. cutoff frequency.
Definition: gig.h:423
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:3088
DLS specific classes and definitions.
Definition: DLS.h:104
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
Definition: DLS.h:348
uint32_t Manufacturer
Specifies the MIDI Manufacturer&#39;s Association (MMA) Manufacturer code for the sampler intended to rec...
Definition: gig.h:634
uint8_t high
High value of range.
Definition: gig.h:78
bool OverridePedal
If a note off should be triggered even if the sustain pedal is down.
Definition: gig.h:850
file_offset_t ReadInt16(int16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit signed integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:535
MIDI rule to automatically cycle through specified sequences of different articulations.
Definition: gig.h:912
Reflects the current playback state for a sample.
Definition: gig.h:310
Region * GetParent() const
Definition: gig.cpp:2064
General dimension definition.
Definition: gig.h:271
int Size
Number of steps in the pattern.
Definition: gig.h:922
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:444
eg1_ctrl_t EG1Controller
MIDI Controller which has influence on sample amplitude EG parameters (attack, decay, release).
Definition: gig.h:380
uint32_t * pWavePoolTableHi
Definition: DLS.h:533
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
Definition: DLS.cpp:1113
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Definition: gig.h:275
void DeleteScript(Script *pScript)
Delete an instrument script.
Definition: gig.cpp:4324
If used sample has more than one channel (thus is not mono).
Definition: gig.h:226
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Definition: gig.cpp:508
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2792
vcf_res_ctrl_t VCFResonanceController
Specifies which external controller has influence on the filter resonance Q.
Definition: gig.h:429
curve_type_t VCFVelocityCurve
Defines a transformation curve for the incoming velocity values, affecting the VCF.
Definition: gig.h:424
file_offset_t ReadUint8(uint8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...
Definition: RIFF.cpp:498
uint8_t EG1ControllerDecayInfluence
Amount EG1 Controller has influence on the EG1 Decay time (0 - 3, where 0 means off).
Definition: gig.h:383
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Definition: RIFF.cpp:1173
Defines Region information of an Instrument.
Definition: DLS.h:431
Effect 4 Depth (MIDI Controller 94)
Definition: gig.h:120
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Definition: gig.cpp:2740
std::list< RIFF::File * > ExtensionFiles
Definition: DLS.h:525
void UpdateChunks(uint8_t *pData) const
Definition: gig.cpp:4007
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
Definition: gig.cpp:3846
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Definition: gig.cpp:2756
double EG1Attack
Attack time of the sample amplitude EG (0.000 - 60.000s).
Definition: gig.h:373
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Definition: RIFF.cpp:1253
#define GIG_EXP_ENCODE(x)
Definition: gig.cpp:46
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Definition: gig.cpp:5821
std::list< Region * > RegionList
Definition: DLS.h:477
Region * GetNextRegion()
Returns the next Region of the instrument.
Definition: gig.cpp:4632
#define CHUNK_ID_SCRI
Definition: gig.h:63
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file&#39;s current instruments, samples and settings to the respective RIFF chunks...
Definition: DLS.cpp:1698
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
Definition: DLS.cpp:1862
#define CHUNK_ID_EWAV
Definition: gig.h:59