libgig  3.3.0.svn4
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-2013 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  virtual void CopyAssign(const DimensionRegion* orig);
459  protected:
460  uint8_t* VelocityTable;
461  DimensionRegion(Region* pParent, RIFF::List* _3ewl);
462  DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src);
464  friend class Region;
465  private:
466  typedef enum {
467  _lev_ctrl_none = 0x00,
468  _lev_ctrl_modwheel = 0x03,
469  _lev_ctrl_breath = 0x05,
470  _lev_ctrl_foot = 0x07,
471  _lev_ctrl_effect1 = 0x0d,
472  _lev_ctrl_effect2 = 0x0f,
473  _lev_ctrl_genpurpose1 = 0x11,
474  _lev_ctrl_genpurpose2 = 0x13,
475  _lev_ctrl_genpurpose3 = 0x15,
476  _lev_ctrl_genpurpose4 = 0x17,
477  _lev_ctrl_portamentotime = 0x0b,
478  _lev_ctrl_sustainpedal = 0x01,
479  _lev_ctrl_portamento = 0x19,
480  _lev_ctrl_sostenutopedal = 0x1b,
481  _lev_ctrl_softpedal = 0x09,
482  _lev_ctrl_genpurpose5 = 0x1d,
483  _lev_ctrl_genpurpose6 = 0x1f,
484  _lev_ctrl_genpurpose7 = 0x21,
485  _lev_ctrl_genpurpose8 = 0x23,
486  _lev_ctrl_effect1depth = 0x25,
487  _lev_ctrl_effect2depth = 0x27,
488  _lev_ctrl_effect3depth = 0x29,
489  _lev_ctrl_effect4depth = 0x2b,
490  _lev_ctrl_effect5depth = 0x2d,
491  _lev_ctrl_channelaftertouch = 0x2f,
492  _lev_ctrl_velocity = 0xff
493  } _lev_ctrl_t;
494  typedef std::map<uint32_t, double*> VelocityTableMap;
495 
496  static uint Instances;
497  static VelocityTableMap* pVelocityTables;
498  double* pVelocityAttenuationTable;
499  double* pVelocityReleaseTable;
500  double* pVelocityCutoffTable;
501  Region* pRegion;
502 
503  leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController);
504  _lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController);
505  double* GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth);
506  double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, uint8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t vcfCutoffController);
507  double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
508  double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
509  };
510 
526  class Sample : public DLS::Sample {
527  public:
528  uint32_t Manufacturer;
529  uint32_t Product;
530  uint32_t SamplePeriod;
531  uint32_t MIDIUnityNote;
532  uint32_t FineTune;
534  uint32_t SMPTEOffset;
535  uint32_t Loops;
536  uint32_t LoopID;
538  uint32_t LoopStart;
539  uint32_t LoopEnd;
540  uint32_t LoopSize;
541  uint32_t LoopFraction;
542  uint32_t LoopPlayCount;
543  bool Compressed;
544  uint32_t TruncatedBits;
545  bool Dithered;
546 
547  // own methods
549  buffer_t LoadSampleData(unsigned long SampleCount);
550  buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
551  buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
552  buffer_t GetCache();
553  // own static methods
554  static buffer_t CreateDecompressionBuffer(unsigned long MaxReadSize);
555  static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer);
556  // overridden methods
557  void ReleaseSampleData();
558  void Resize(int iNewSize);
559  unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
560  unsigned long GetPos();
561  unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL);
562  unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL);
563  unsigned long Write(void* pBuffer, unsigned long SampleCount);
564  Group* GetGroup() const;
565  virtual void UpdateChunks();
566  protected:
567  static unsigned int Instances;
570  unsigned long FrameOffset;
571  unsigned long* FrameTable;
572  unsigned long SamplePos;
573  unsigned long SamplesInLastFrame;
574  unsigned long WorstCaseFrameSize;
575  unsigned long SamplesPerFrame;
577  unsigned long FileNo;
580  uint32_t crc;
581 
582  Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0);
583  ~Sample();
584 
585  // Guess size (in bytes) of a compressed sample
586  inline unsigned long GuessSize(unsigned long samples) {
587  // 16 bit: assume all frames are compressed - 1 byte
588  // per sample and 5 bytes header per 2048 samples
589 
590  // 24 bit: assume next best compression rate - 1.5
591  // bytes per sample and 13 bytes header per 256
592  // samples
593  const unsigned long size =
594  BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13
595  : samples + (samples >> 10) * 5;
596  // Double for stereo and add one worst case sample
597  // frame
598  return (Channels == 2 ? size << 1 : size) + WorstCaseFrameSize;
599  }
600 
601  // Worst case amount of sample points that can be read with the
602  // given decompression buffer.
603  inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) {
604  return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame);
605  }
606  private:
607  void ScanCompressedSample();
608  friend class File;
609  friend class Region;
610  friend class Group; // allow to modify protected member pGroup
611  };
612 
613  // TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions)
615  class Region : public DLS::Region {
616  public:
617  unsigned int Dimensions;
619  uint32_t DimensionRegions;
621  unsigned int Layers;
622 
623  // own methods
624  DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]);
625  DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]);
626  Sample* GetSample();
627  void AddDimension(dimension_def_t* pDimDef);
628  void DeleteDimension(dimension_def_t* pDimDef);
629  // overridden methods
630  virtual void SetKeyRange(uint16_t Low, uint16_t High);
631  virtual void UpdateChunks();
632  virtual void CopyAssign(const Region* orig);
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
672  using DLS::Resource::pInfo;
673  using DLS::Resource::pDLSID;
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  virtual void CopyAssign(const Instrument* orig);
699  // own methods
700  Region* GetRegion(unsigned int Key);
701  MidiRule* GetMidiRule(int i);
702  protected:
704 
705  Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL);
706  ~Instrument();
707  void UpdateRegionKeyTable();
708  friend class File;
709  friend class Region; // so Region can call UpdateRegionKeyTable()
710  private:
711  MidiRule** pMidiRules;
712  };
713 
729  class Group {
730  public:
732 
735  void AddSample(Sample* pSample);
736  protected:
737  Group(File* file, RIFF::Chunk* ck3gnm);
738  virtual ~Group();
739  virtual void UpdateChunks();
740  void MoveAll();
741  friend class File;
742  private:
743  File* pFile;
744  RIFF::Chunk* pNameChunk;
745  };
746 
748  class File : protected DLS::File {
749  public:
750  static const DLS::version_t VERSION_2;
751  static const DLS::version_t VERSION_3;
752 
753  // derived attributes from DLS::Resource
754  using DLS::Resource::pInfo;
755  using DLS::Resource::pDLSID;
756  // derived attributes from DLS::File
757  using DLS::File::pVersion;
759 
760  // derived methods from DLS::Resource
762  // derived methods from DLS::File
763  using DLS::File::Save;
765  // overridden methods
766  File();
768  Sample* GetFirstSample(progress_t* pProgress = NULL);
769  Sample* GetNextSample();
770  Sample* AddSample();
771  void DeleteSample(Sample* pSample);
774  Instrument* GetInstrument(uint index, progress_t* pProgress = NULL);
777  void DeleteInstrument(Instrument* pInstrument);
778  Group* GetFirstGroup();
779  Group* GetNextGroup();
780  Group* GetGroup(uint index);
781  Group* AddGroup();
782  void DeleteGroup(Group* pGroup);
783  void DeleteGroupOnly(Group* pGroup);
784  void SetAutoLoad(bool b);
785  bool GetAutoLoad();
786  virtual ~File();
787  virtual void UpdateChunks();
788  protected:
789  // overridden protected methods from DLS::File
790  virtual void LoadSamples();
791  virtual void LoadInstruments();
792  virtual void LoadGroups();
793  // own protected methods
794  virtual void LoadSamples(progress_t* pProgress);
795  virtual void LoadInstruments(progress_t* pProgress);
796  void SetSampleChecksum(Sample* pSample, uint32_t crc);
797  friend class Region;
798  friend class Sample;
799  friend class Group; // so Group can access protected member pRIFF
800  private:
801  std::list<Group*>* pGroups;
802  std::list<Group*>::iterator GroupsIterator;
803  bool bAutoLoad;
804  };
805 
814  class Exception : public DLS::Exception {
815  public:
817  void PrintMessage();
818  };
819 
822 
823 } // namespace gig
824 
825 #endif // __GIG_H__