libgig  3.3.0.svn3
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-2012 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_3GIX 0x33676978
35 # define CHUNK_ID_3EWA 0x33657761
36 # define CHUNK_ID_3LNK 0x336C6E6B
37 # define CHUNK_ID_3EWG 0x33657767
38 # define CHUNK_ID_EWAV 0x65776176
39 # define CHUNK_ID_3GNM 0x33676E6D
40 # define CHUNK_ID_EINF 0x65696E66
41 # define CHUNK_ID_3CRC 0x33637263
42 #else // little endian
43 # define LIST_TYPE_3PRG 0x67727033
44 # define LIST_TYPE_3EWL 0x6C776533
45 # define LIST_TYPE_3GRI 0x69726733
46 # define LIST_TYPE_3GNL 0x6C6E6733
47 # define CHUNK_ID_3GIX 0x78696733
48 # define CHUNK_ID_3EWA 0x61776533
49 # define CHUNK_ID_3LNK 0x6B6E6C33
50 # define CHUNK_ID_3EWG 0x67776533
51 # define CHUNK_ID_EWAV 0x76617765
52 # define CHUNK_ID_3GNM 0x6D6E6733
53 # define CHUNK_ID_EINF 0x666E6965
54 # define CHUNK_ID_3CRC 0x63726333
55 #endif // WORDS_BIGENDIAN
56 
58 namespace gig {
59 
60  typedef std::string String;
61 
63  struct range_t {
64  uint8_t low;
65  uint8_t high;
66  };
67 
69  struct buffer_t {
70  void* pStart;
71  unsigned long Size;
72  unsigned long NullExtensionSize;
74  pStart = NULL;
75  Size = 0;
77  }
78  };
79 
81  typedef enum {
82  loop_type_normal = 0x00000000,
83  loop_type_bidirectional = 0x00000001,
84  loop_type_backward = 0x00000002
85  } loop_type_t;
86 
88  typedef enum {
89  smpte_format_no_offset = 0x00000000,
90  smpte_format_24_frames = 0x00000018,
91  smpte_format_25_frames = 0x00000019,
93  smpte_format_30_frames = 0x0000001E
95 
97  typedef enum {
101  curve_type_unknown = 0xffffffff
102  } curve_type_t;
103 
105  typedef enum {
110 
112  typedef enum {
118  } lfo3_ctrl_t;
119 
121  typedef enum {
124  lfo2_ctrl_foot = 0x02,
127  } lfo2_ctrl_t;
128 
130  typedef enum {
136  } lfo1_ctrl_t;
137 
139  typedef enum {
153 
155  typedef enum {
156  vcf_res_ctrl_none = 0xffffffff,
161  } vcf_res_ctrl_t;
162 
172  typedef enum {
173  type_none = 0x00,
175  type_velocity = 0xff,
177  } type_t;
178 
181  };
182 
189 
196 
203 
211  typedef enum {
212  dimension_none = 0x00,
225  dimension_foot = 0x04,
246  } dimension_t;
247 
252  typedef enum {
255  } split_type_t;
256 
260  uint8_t bits;
261  uint8_t zones;
263  float zone_size;
264  };
265 
267  typedef enum {
273  } vcf_type_t;
274 
282  struct crossfade_t {
283  #if WORDS_BIGENDIAN
284  uint8_t out_end;
285  uint8_t out_start;
286  uint8_t in_end;
287  uint8_t in_start;
288  #else // little endian
289  uint8_t in_start;
290  uint8_t in_end;
291  uint8_t out_start;
292  uint8_t out_end;
293  #endif // WORDS_BIGENDIAN
294  };
295 
298  unsigned long position;
299  bool reverse;
300  unsigned long loop_cycles_left;
301  };
302 
315  struct progress_t {
316  void (*callback)(progress_t*);
317  float factor;
318  void* custom;
319  float __range_min;
320  float __range_max;
321  progress_t();
322  };
323 
324  // just symbol prototyping
325  class File;
326  class Instrument;
327  class Sample;
328  class Region;
329  class Group;
330 
343  class DimensionRegion : protected DLS::Sampler {
344  public:
347  // Sample Amplitude EG/LFO
348  uint16_t EG1PreAttack;
349  double EG1Attack;
350  double EG1Decay1;
351  double EG1Decay2;
353  uint16_t EG1Sustain;
354  double EG1Release;
355  bool EG1Hold;
361  double LFO1Frequency;
362  uint16_t LFO1InternalDepth;
363  uint16_t LFO1ControlDepth;
366  bool LFO1Sync;
367  // Filter Cutoff Frequency EG/LFO
368  uint16_t EG2PreAttack;
369  double EG2Attack;
370  double EG2Decay1;
371  double EG2Decay2;
373  uint16_t EG2Sustain;
374  double EG2Release;
380  double LFO2Frequency;
381  uint16_t LFO2InternalDepth;
382  uint16_t LFO2ControlDepth;
385  bool LFO2Sync;
386  // Sample Pitch EG/LFO
387  double EG3Attack;
388  int16_t EG3Depth;
389  double LFO3Frequency;
393  bool LFO3Sync;
394  // Filter
395  bool VCFEnabled;
399  uint8_t VCFCutoff;
403  uint8_t VCFResonance;
408  // Key Velocity Transformations
415  // Mix / Layer
417  bool PitchTrack;
419  int8_t Pan;
420  bool SelfMask;
424  uint8_t ChannelOffset;
426  bool MSDecode;
427  uint16_t SampleStartOffset;
429  uint8_t DimensionUpperLimits[8];
430 
431  // derived attributes from DLS::Sampler
434  using DLS::Sampler::Gain;
437 
438  // own methods
439  double GetVelocityAttenuation(uint8_t MIDIKeyVelocity);
440  double GetVelocityRelease(uint8_t MIDIKeyVelocity);
441  double GetVelocityCutoff(uint8_t MIDIKeyVelocity);
443  void SetVelocityResponseDepth(uint8_t depth);
444  void SetVelocityResponseCurveScaling(uint8_t scaling);
446  void SetReleaseVelocityResponseDepth(uint8_t depth);
447  void SetVCFCutoffController(vcf_cutoff_ctrl_t controller);
448  void SetVCFVelocityCurve(curve_type_t curve);
449  void SetVCFVelocityDynamicRange(uint8_t range);
450  void SetVCFVelocityScale(uint8_t scaling);
451  Region* GetParent() const;
452  // derived methods
455  // overridden methods
456  virtual void SetGain(int32_t gain);
457  virtual void UpdateChunks();
458  protected:
459  uint8_t* VelocityTable;
460  DimensionRegion(Region* pParent, RIFF::List* _3ewl);
461  DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src);
463  friend class Region;
464  private:
465  typedef enum {
466  _lev_ctrl_none = 0x00,
467  _lev_ctrl_modwheel = 0x03,
468  _lev_ctrl_breath = 0x05,
469  _lev_ctrl_foot = 0x07,
470  _lev_ctrl_effect1 = 0x0d,
471  _lev_ctrl_effect2 = 0x0f,
472  _lev_ctrl_genpurpose1 = 0x11,
473  _lev_ctrl_genpurpose2 = 0x13,
474  _lev_ctrl_genpurpose3 = 0x15,
475  _lev_ctrl_genpurpose4 = 0x17,
476  _lev_ctrl_portamentotime = 0x0b,
477  _lev_ctrl_sustainpedal = 0x01,
478  _lev_ctrl_portamento = 0x19,
479  _lev_ctrl_sostenutopedal = 0x1b,
480  _lev_ctrl_softpedal = 0x09,
481  _lev_ctrl_genpurpose5 = 0x1d,
482  _lev_ctrl_genpurpose6 = 0x1f,
483  _lev_ctrl_genpurpose7 = 0x21,
484  _lev_ctrl_genpurpose8 = 0x23,
485  _lev_ctrl_effect1depth = 0x25,
486  _lev_ctrl_effect2depth = 0x27,
487  _lev_ctrl_effect3depth = 0x29,
488  _lev_ctrl_effect4depth = 0x2b,
489  _lev_ctrl_effect5depth = 0x2d,
490  _lev_ctrl_channelaftertouch = 0x2f,
491  _lev_ctrl_velocity = 0xff
492  } _lev_ctrl_t;
493  typedef std::map<uint32_t, double*> VelocityTableMap;
494 
495  static uint Instances;
496  static VelocityTableMap* pVelocityTables;
497  double* pVelocityAttenuationTable;
498  double* pVelocityReleaseTable;
499  double* pVelocityCutoffTable;
500  Region* pRegion;
501 
502  leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController);
503  _lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController);
504  double* GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth);
505  double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, uint8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t vcfCutoffController);
506  double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
507  double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
508  };
509 
525  class Sample : public DLS::Sample {
526  public:
527  uint32_t Manufacturer;
528  uint32_t Product;
529  uint32_t SamplePeriod;
530  uint32_t MIDIUnityNote;
531  uint32_t FineTune;
533  uint32_t SMPTEOffset;
534  uint32_t Loops;
535  uint32_t LoopID;
537  uint32_t LoopStart;
538  uint32_t LoopEnd;
539  uint32_t LoopSize;
540  uint32_t LoopFraction;
541  uint32_t LoopPlayCount;
542  bool Compressed;
543  uint32_t TruncatedBits;
544  bool Dithered;
545 
546  // own methods
548  buffer_t LoadSampleData(unsigned long SampleCount);
549  buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
550  buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
551  buffer_t GetCache();
552  // own static methods
553  static buffer_t CreateDecompressionBuffer(unsigned long MaxReadSize);
554  static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer);
555  // overridden methods
556  void ReleaseSampleData();
557  void Resize(int iNewSize);
558  unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
559  unsigned long GetPos();
560  unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL);
561  unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL);
562  unsigned long Write(void* pBuffer, unsigned long SampleCount);
563  Group* GetGroup() const;
564  virtual void UpdateChunks();
565  protected:
566  static unsigned int Instances;
569  unsigned long FrameOffset;
570  unsigned long* FrameTable;
571  unsigned long SamplePos;
572  unsigned long SamplesInLastFrame;
573  unsigned long WorstCaseFrameSize;
574  unsigned long SamplesPerFrame;
576  unsigned long FileNo;
579  uint32_t crc;
580 
581  Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0);
582  ~Sample();
583 
584  // Guess size (in bytes) of a compressed sample
585  inline unsigned long GuessSize(unsigned long samples) {
586  // 16 bit: assume all frames are compressed - 1 byte
587  // per sample and 5 bytes header per 2048 samples
588 
589  // 24 bit: assume next best compression rate - 1.5
590  // bytes per sample and 13 bytes header per 256
591  // samples
592  const unsigned long size =
593  BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13
594  : samples + (samples >> 10) * 5;
595  // Double for stereo and add one worst case sample
596  // frame
597  return (Channels == 2 ? size << 1 : size) + WorstCaseFrameSize;
598  }
599 
600  // Worst case amount of sample points that can be read with the
601  // given decompression buffer.
602  inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) {
603  return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame);
604  }
605  private:
606  void ScanCompressedSample();
607  friend class File;
608  friend class Region;
609  friend class Group; // allow to modify protected member pGroup
610  };
611 
612  // TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions)
614  class Region : public DLS::Region {
615  public:
616  unsigned int Dimensions;
618  uint32_t DimensionRegions;
620  unsigned int Layers;
621 
622  // own methods
623  DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]);
624  DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]);
625  Sample* GetSample();
626  void AddDimension(dimension_def_t* pDimDef);
627  void DeleteDimension(dimension_def_t* pDimDef);
628  // overridden methods
629  virtual void SetKeyRange(uint16_t Low, uint16_t High);
630  virtual void UpdateChunks();
631  protected:
632  Region(Instrument* pInstrument, RIFF::List* rgnList);
633  void LoadDimensionRegions(RIFF::List* rgn);
634  void UpdateVelocityTable();
635  Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL);
636  ~Region();
637  friend class Instrument;
638  };
639 
641  class MidiRule {
642  public:
643  virtual ~MidiRule() { }
644  };
645 
647  class MidiRuleCtrlTrigger : public MidiRule {
648  public:
650  uint8_t Triggers;
651  struct trigger_t {
652  uint8_t TriggerPoint;
653  bool Descending;
654  uint8_t VelSensitivity;
655  uint8_t Key;
656  bool NoteOff;
657  uint8_t Velocity;
659  } pTriggers[32];
660 
661  protected:
663  friend class Instrument;
664  };
665 
667  class Instrument : protected DLS::Instrument {
668  public:
669  // derived attributes from DLS::Resource
670  using DLS::Resource::pInfo;
671  using DLS::Resource::pDLSID;
672  // derived attributes from DLS::Instrument
679  // own attributes
680  int32_t Attenuation;
681  uint16_t EffectSend;
682  int16_t FineTune;
683  uint16_t PitchbendRange;
686 
687 
688  // derived methods from DLS::Resource
690  // overridden methods
693  Region* AddRegion();
694  void DeleteRegion(Region* pRegion);
695  virtual void UpdateChunks();
696  // own methods
697  Region* GetRegion(unsigned int Key);
698  MidiRule* GetMidiRule(int i);
699  protected:
701 
702  Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL);
703  ~Instrument();
704  void UpdateRegionKeyTable();
705  friend class File;
706  friend class Region; // so Region can call UpdateRegionKeyTable()
707  private:
708  MidiRule** pMidiRules;
709  };
710 
726  class Group {
727  public:
729 
732  void AddSample(Sample* pSample);
733  protected:
734  Group(File* file, RIFF::Chunk* ck3gnm);
735  virtual ~Group();
736  virtual void UpdateChunks();
737  void MoveAll();
738  friend class File;
739  private:
740  File* pFile;
741  RIFF::Chunk* pNameChunk;
742  };
743 
745  class File : protected DLS::File {
746  public:
747  static const DLS::version_t VERSION_2;
748  static const DLS::version_t VERSION_3;
749 
750  // derived attributes from DLS::Resource
751  using DLS::Resource::pInfo;
752  using DLS::Resource::pDLSID;
753  // derived attributes from DLS::File
754  using DLS::File::pVersion;
756 
757  // derived methods from DLS::Resource
759  // derived methods from DLS::File
760  using DLS::File::Save;
762  // overridden methods
763  File();
765  Sample* GetFirstSample(progress_t* pProgress = NULL);
766  Sample* GetNextSample();
767  Sample* AddSample();
768  void DeleteSample(Sample* pSample);
771  Instrument* GetInstrument(uint index, progress_t* pProgress = NULL);
773  void DeleteInstrument(Instrument* pInstrument);
774  Group* GetFirstGroup();
775  Group* GetNextGroup();
776  Group* GetGroup(uint index);
777  Group* AddGroup();
778  void DeleteGroup(Group* pGroup);
779  void DeleteGroupOnly(Group* pGroup);
780  void SetAutoLoad(bool b);
781  bool GetAutoLoad();
782  virtual ~File();
783  virtual void UpdateChunks();
784  protected:
785  // overridden protected methods from DLS::File
786  virtual void LoadSamples();
787  virtual void LoadInstruments();
788  virtual void LoadGroups();
789  // own protected methods
790  virtual void LoadSamples(progress_t* pProgress);
791  virtual void LoadInstruments(progress_t* pProgress);
792  void SetSampleChecksum(Sample* pSample, uint32_t crc);
793  friend class Region;
794  friend class Sample;
795  friend class Group; // so Group can access protected member pRIFF
796  private:
797  std::list<Group*>* pGroups;
798  std::list<Group*>::iterator GroupsIterator;
799  bool bAutoLoad;
800  };
801 
810  class Exception : public DLS::Exception {
811  public:
813  void PrintMessage();
814  };
815 
818 
819 } // namespace gig
820 
821 #endif // __GIG_H__