libgig  3.3.0
gig.h
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * libgig - C++ cross-platform Gigasampler format file access library *
4  * *
5  * Copyright (C) 2003-2009 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 #ifndef __GIG_H__
25 #define __GIG_H__
26 
27 #include "DLS.h"
28 
29 #if WORDS_BIGENDIAN
30 # define LIST_TYPE_3PRG 0x33707267
31 # define LIST_TYPE_3EWL 0x3365776C
32 # define LIST_TYPE_3GRI 0x33677269
33 # define LIST_TYPE_3GNL 0x33676E6C
34 # define CHUNK_ID_SMPL 0x736D706C
35 # define CHUNK_ID_3GIX 0x33676978
36 # define CHUNK_ID_3EWA 0x33657761
37 # define CHUNK_ID_3LNK 0x336C6E6B
38 # define CHUNK_ID_3EWG 0x33657767
39 # define CHUNK_ID_EWAV 0x65776176
40 # define CHUNK_ID_3GNM 0x33676E6D
41 # define CHUNK_ID_EINF 0x65696E66
42 # define CHUNK_ID_3CRC 0x33637263
43 #else // little endian
44 # define LIST_TYPE_3PRG 0x67727033
45 # define LIST_TYPE_3EWL 0x6C776533
46 # define LIST_TYPE_3GRI 0x69726733
47 # define LIST_TYPE_3GNL 0x6C6E6733
48 # define CHUNK_ID_SMPL 0x6C706D73
49 # define CHUNK_ID_3GIX 0x78696733
50 # define CHUNK_ID_3EWA 0x61776533
51 # define CHUNK_ID_3LNK 0x6B6E6C33
52 # define CHUNK_ID_3EWG 0x67776533
53 # define CHUNK_ID_EWAV 0x76617765
54 # define CHUNK_ID_3GNM 0x6D6E6733
55 # define CHUNK_ID_EINF 0x666E6965
56 # define CHUNK_ID_3CRC 0x63726333
57 #endif // WORDS_BIGENDIAN
58 
60 namespace gig {
61 
62  typedef std::string String;
63 
65  struct range_t {
66  uint8_t low;
67  uint8_t high;
68  };
69 
71  struct buffer_t {
72  void* pStart;
73  unsigned long Size;
74  unsigned long NullExtensionSize;
76  pStart = NULL;
77  Size = 0;
79  }
80  };
81 
83  typedef enum {
84  loop_type_normal = 0x00000000,
85  loop_type_bidirectional = 0x00000001,
86  loop_type_backward = 0x00000002
87  } loop_type_t;
88 
90  typedef enum {
91  smpte_format_no_offset = 0x00000000,
92  smpte_format_24_frames = 0x00000018,
93  smpte_format_25_frames = 0x00000019,
95  smpte_format_30_frames = 0x0000001E
97 
99  typedef enum {
103  curve_type_unknown = 0xffffffff
104  } curve_type_t;
105 
107  typedef enum {
112 
114  typedef enum {
120  } lfo3_ctrl_t;
121 
123  typedef enum {
126  lfo2_ctrl_foot = 0x02,
129  } lfo2_ctrl_t;
130 
132  typedef enum {
138  } lfo1_ctrl_t;
139 
141  typedef enum {
155 
157  typedef enum {
158  vcf_res_ctrl_none = 0xffffffff,
163  } vcf_res_ctrl_t;
164 
174  typedef enum {
175  type_none = 0x00,
177  type_velocity = 0xff,
179  } type_t;
180 
183  };
184 
191 
198 
205 
213  typedef enum {
214  dimension_none = 0x00,
227  dimension_foot = 0x04,
248  } dimension_t;
249 
254  typedef enum {
257  } split_type_t;
258 
262  uint8_t bits;
263  uint8_t zones;
265  float zone_size;
266  };
267 
269  typedef enum {
275  } vcf_type_t;
276 
284  struct crossfade_t {
285  #if WORDS_BIGENDIAN
286  uint8_t out_end;
287  uint8_t out_start;
288  uint8_t in_end;
289  uint8_t in_start;
290  #else // little endian
291  uint8_t in_start;
292  uint8_t in_end;
293  uint8_t out_start;
294  uint8_t out_end;
295  #endif // WORDS_BIGENDIAN
296  };
297 
300  unsigned long position;
301  bool reverse;
302  unsigned long loop_cycles_left;
303  };
304 
317  struct progress_t {
318  void (*callback)(progress_t*);
319  float factor;
320  void* custom;
321  float __range_min;
322  float __range_max;
323  progress_t();
324  };
325 
326  // just symbol prototyping
327  class File;
328  class Instrument;
329  class Sample;
330  class Region;
331  class Group;
332 
345  class DimensionRegion : protected DLS::Sampler {
346  public:
349  // Sample Amplitude EG/LFO
350  uint16_t EG1PreAttack;
351  double EG1Attack;
352  double EG1Decay1;
353  double EG1Decay2;
355  uint16_t EG1Sustain;
356  double EG1Release;
357  bool EG1Hold;
363  double LFO1Frequency;
364  uint16_t LFO1InternalDepth;
365  uint16_t LFO1ControlDepth;
368  bool LFO1Sync;
369  // Filter Cutoff Frequency EG/LFO
370  uint16_t EG2PreAttack;
371  double EG2Attack;
372  double EG2Decay1;
373  double EG2Decay2;
375  uint16_t EG2Sustain;
376  double EG2Release;
382  double LFO2Frequency;
383  uint16_t LFO2InternalDepth;
384  uint16_t LFO2ControlDepth;
387  bool LFO2Sync;
388  // Sample Pitch EG/LFO
389  double EG3Attack;
390  int16_t EG3Depth;
391  double LFO3Frequency;
395  bool LFO3Sync;
396  // Filter
397  bool VCFEnabled;
401  uint8_t VCFCutoff;
405  uint8_t VCFResonance;
410  // Key Velocity Transformations
417  // Mix / Layer
419  bool PitchTrack;
421  int8_t Pan;
422  bool SelfMask;
426  uint8_t ChannelOffset;
428  bool MSDecode;
429  uint16_t SampleStartOffset;
431  uint8_t DimensionUpperLimits[8];
432 
433  // derived attributes from DLS::Sampler
439 
440  // own methods
441  double GetVelocityAttenuation(uint8_t MIDIKeyVelocity);
442  double GetVelocityRelease(uint8_t MIDIKeyVelocity);
443  double GetVelocityCutoff(uint8_t MIDIKeyVelocity);
445  void SetVelocityResponseDepth(uint8_t depth);
446  void SetVelocityResponseCurveScaling(uint8_t scaling);
448  void SetReleaseVelocityResponseDepth(uint8_t depth);
449  void SetVCFCutoffController(vcf_cutoff_ctrl_t controller);
450  void SetVCFVelocityCurve(curve_type_t curve);
451  void SetVCFVelocityDynamicRange(uint8_t range);
452  void SetVCFVelocityScale(uint8_t scaling);
453  Region* GetParent() const;
454  // derived methods
457  // overridden methods
458  virtual void SetGain(int32_t gain);
459  virtual void UpdateChunks();
460  protected:
461  uint8_t* VelocityTable;
462  DimensionRegion(Region* pParent, RIFF::List* _3ewl);
463  DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src);
465  friend class Region;
466  private:
467  typedef enum {
468  _lev_ctrl_none = 0x00,
469  _lev_ctrl_modwheel = 0x03,
470  _lev_ctrl_breath = 0x05,
471  _lev_ctrl_foot = 0x07,
472  _lev_ctrl_effect1 = 0x0d,
473  _lev_ctrl_effect2 = 0x0f,
474  _lev_ctrl_genpurpose1 = 0x11,
475  _lev_ctrl_genpurpose2 = 0x13,
476  _lev_ctrl_genpurpose3 = 0x15,
477  _lev_ctrl_genpurpose4 = 0x17,
478  _lev_ctrl_portamentotime = 0x0b,
479  _lev_ctrl_sustainpedal = 0x01,
480  _lev_ctrl_portamento = 0x19,
481  _lev_ctrl_sostenutopedal = 0x1b,
482  _lev_ctrl_softpedal = 0x09,
483  _lev_ctrl_genpurpose5 = 0x1d,
484  _lev_ctrl_genpurpose6 = 0x1f,
485  _lev_ctrl_genpurpose7 = 0x21,
486  _lev_ctrl_genpurpose8 = 0x23,
487  _lev_ctrl_effect1depth = 0x25,
488  _lev_ctrl_effect2depth = 0x27,
489  _lev_ctrl_effect3depth = 0x29,
490  _lev_ctrl_effect4depth = 0x2b,
491  _lev_ctrl_effect5depth = 0x2d,
492  _lev_ctrl_channelaftertouch = 0x2f,
493  _lev_ctrl_velocity = 0xff
494  } _lev_ctrl_t;
495  typedef std::map<uint32_t, double*> VelocityTableMap;
496 
497  static uint Instances;
498  static VelocityTableMap* pVelocityTables;
499  double* pVelocityAttenuationTable;
500  double* pVelocityReleaseTable;
501  double* pVelocityCutoffTable;
502  Region* pRegion;
503 
504  leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController);
505  _lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController);
506  double* GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth);
507  double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, uint8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t vcfCutoffController);
508  double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
509  double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
510  };
511 
527  class Sample : public DLS::Sample {
528  public:
529  uint32_t Manufacturer;
530  uint32_t Product;
531  uint32_t SamplePeriod;
532  uint32_t MIDIUnityNote;
533  uint32_t FineTune;
535  uint32_t SMPTEOffset;
536  uint32_t Loops;
537  uint32_t LoopID;
539  uint32_t LoopStart;
540  uint32_t LoopEnd;
541  uint32_t LoopSize;
542  uint32_t LoopFraction;
543  uint32_t LoopPlayCount;
544  bool Compressed;
545  uint32_t TruncatedBits;
546  bool Dithered;
547 
548  // own methods
550  buffer_t LoadSampleData(unsigned long SampleCount);
551  buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
552  buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
553  buffer_t GetCache();
554  // own static methods
555  static buffer_t CreateDecompressionBuffer(unsigned long MaxReadSize);
556  static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer);
557  // overridden methods
558  void ReleaseSampleData();
559  void Resize(int iNewSize);
560  unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
561  unsigned long GetPos();
562  unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL);
563  unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL);
564  unsigned long Write(void* pBuffer, unsigned long SampleCount);
565  Group* GetGroup() const;
566  virtual void UpdateChunks();
567  protected:
568  static unsigned int Instances;
571  unsigned long FrameOffset;
572  unsigned long* FrameTable;
573  unsigned long SamplePos;
574  unsigned long SamplesInLastFrame;
575  unsigned long WorstCaseFrameSize;
576  unsigned long SamplesPerFrame;
578  unsigned long FileNo;
581  uint32_t crc;
582 
583  Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0);
584  ~Sample();
585 
586  // Guess size (in bytes) of a compressed sample
587  inline unsigned long GuessSize(unsigned long samples) {
588  // 16 bit: assume all frames are compressed - 1 byte
589  // per sample and 5 bytes header per 2048 samples
590 
591  // 24 bit: assume next best compression rate - 1.5
592  // bytes per sample and 13 bytes header per 256
593  // samples
594  const unsigned long size =
595  BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13
596  : samples + (samples >> 10) * 5;
597  // Double for stereo and add one worst case sample
598  // frame
599  return (Channels == 2 ? size << 1 : size) + WorstCaseFrameSize;
600  }
601 
602  // Worst case amount of sample points that can be read with the
603  // given decompression buffer.
604  inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) {
605  return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame);
606  }
607  private:
608  void ScanCompressedSample();
609  friend class File;
610  friend class Region;
611  friend class Group; // allow to modify protected member pGroup
612  };
613 
614  // TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions)
616  class Region : public DLS::Region {
617  public:
618  unsigned int Dimensions;
620  uint32_t DimensionRegions;
622  unsigned int Layers;
623 
624  // own methods
625  DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]);
626  DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]);
627  Sample* GetSample();
628  void AddDimension(dimension_def_t* pDimDef);
629  void DeleteDimension(dimension_def_t* pDimDef);
630  // overridden methods
631  virtual void SetKeyRange(uint16_t Low, uint16_t High);
632  virtual void UpdateChunks();
633  protected:
634  Region(Instrument* pInstrument, RIFF::List* rgnList);
635  void LoadDimensionRegions(RIFF::List* rgn);
636  void UpdateVelocityTable();
637  Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL);
638  ~Region();
639  friend class Instrument;
640  };
641 
643  class MidiRule {
644  public:
645  virtual ~MidiRule() { }
646  };
647 
649  class MidiRuleCtrlTrigger : public MidiRule {
650  public:
652  uint8_t Triggers;
653  struct trigger_t {
654  uint8_t TriggerPoint;
655  bool Descending;
656  uint8_t VelSensitivity;
657  uint8_t Key;
658  bool NoteOff;
659  uint8_t Velocity;
661  } pTriggers[32];
662 
663  protected:
665  friend class Instrument;
666  };
667 
669  class Instrument : protected DLS::Instrument {
670  public:
671  // derived attributes from DLS::Resource
674  // derived attributes from DLS::Instrument
681  // own attributes
682  int32_t Attenuation;
683  uint16_t EffectSend;
684  int16_t FineTune;
685  uint16_t PitchbendRange;
688 
689 
690  // derived methods from DLS::Resource
692  // overridden methods
695  Region* AddRegion();
696  void DeleteRegion(Region* pRegion);
697  virtual void UpdateChunks();
698  // own methods
699  Region* GetRegion(unsigned int Key);
700  MidiRule* GetMidiRule(int i);
701  protected:
703 
704  Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL);
705  ~Instrument();
706  void UpdateRegionKeyTable();
707  friend class File;
708  friend class Region; // so Region can call UpdateRegionKeyTable()
709  private:
710  MidiRule** pMidiRules;
711  };
712 
728  class Group {
729  public:
731 
734  void AddSample(Sample* pSample);
735  protected:
736  Group(File* file, RIFF::Chunk* ck3gnm);
737  virtual ~Group();
738  virtual void UpdateChunks();
739  void MoveAll();
740  friend class File;
741  private:
742  File* pFile;
743  RIFF::Chunk* pNameChunk;
744  };
745 
747  class File : protected DLS::File {
748  public:
749  static const DLS::version_t VERSION_2;
750  static const DLS::version_t VERSION_3;
751 
752  // derived attributes from DLS::Resource
755  // derived attributes from DLS::File
758 
759  // derived methods from DLS::Resource
761  // derived methods from DLS::File
763  // overridden methods
764  File();
766  Sample* GetFirstSample(progress_t* pProgress = NULL);
767  Sample* GetNextSample();
768  Sample* AddSample();
769  void DeleteSample(Sample* pSample);
772  Instrument* GetInstrument(uint index, progress_t* pProgress = NULL);
774  void DeleteInstrument(Instrument* pInstrument);
775  Group* GetFirstGroup();
776  Group* GetNextGroup();
777  Group* GetGroup(uint index);
778  Group* AddGroup();
779  void DeleteGroup(Group* pGroup);
780  void DeleteGroupOnly(Group* pGroup);
781  void SetAutoLoad(bool b);
782  bool GetAutoLoad();
783  virtual ~File();
784  virtual void UpdateChunks();
785  protected:
786  // overridden protected methods from DLS::File
787  virtual void LoadSamples();
788  virtual void LoadInstruments();
789  virtual void LoadGroups();
790  // own protected methods
791  virtual void LoadSamples(progress_t* pProgress);
792  virtual void LoadInstruments(progress_t* pProgress);
793  void SetSampleChecksum(Sample* pSample, uint32_t crc);
794  friend class Region;
795  friend class Sample;
796  friend class Group; // so Group can access protected member pRIFF
797  private:
798  std::list<Group*>* pGroups;
799  std::list<Group*>::iterator GroupsIterator;
800  bool bAutoLoad;
801  };
802 
811  class Exception : public DLS::Exception {
812  public:
814  void PrintMessage();
815  };
816 
819 
820 } // namespace gig
821 
822 #endif // __GIG_H__