libgig  3.3.0
DLS.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 __DLS_H__
25 #define __DLS_H__
26 
27 #include "RIFF.h"
28 
29 #if WORDS_BIGENDIAN
30 # define RIFF_TYPE_DLS 0x444C5320
31 # define LIST_TYPE_INFO 0x494E464F
32 # define LIST_TYPE_WVPL 0x7776706C
33 # define LIST_TYPE_DWPL 0x6477706C
34 # define LIST_TYPE_WAVE 0x77617665
35 # define LIST_TYPE_LINS 0X6C696E73
36 # define LIST_TYPE_INS 0X696E7320
37 # define LIST_TYPE_LRGN 0x6C72676E
38 # define LIST_TYPE_LART 0x6C617274
39 # define LIST_TYPE_LAR2 0x6C617232
40 # define LIST_TYPE_RGN 0x72676E20
41 # define LIST_TYPE_RGN2 0x72676E32
42 # define CHUNK_ID_IARL 0x4941524C
43 # define CHUNK_ID_IART 0x49415254
44 # define CHUNK_ID_ICMS 0x49434D53
45 # define CHUNK_ID_ICMT 0x49434D54
46 # define CHUNK_ID_ICOP 0x49434F50
47 # define CHUNK_ID_ICRD 0x49435244
48 # define CHUNK_ID_IENG 0x49454E47
49 # define CHUNK_ID_IGNR 0x49474E52
50 # define CHUNK_ID_IKEY 0x494B4559
51 # define CHUNK_ID_IMED 0x494D4544
52 # define CHUNK_ID_INAM 0x494E414D
53 # define CHUNK_ID_IPRD 0x49505244
54 # define CHUNK_ID_ISBJ 0x4953424A
55 # define CHUNK_ID_ISFT 0x49534654
56 # define CHUNK_ID_ISRC 0x49535243
57 # define CHUNK_ID_ISRF 0x49535246
58 # define CHUNK_ID_ITCH 0x49544348
59 # define CHUNK_ID_VERS 0x76657273
60 # define CHUNK_ID_DLID 0x646C6964
61 # define CHUNK_ID_FMT 0x666D7420
62 # define CHUNK_ID_DATA 0x64617461
63 # define CHUNK_ID_INSH 0x696E7368
64 # define CHUNK_ID_RGNH 0x72676E68
65 # define CHUNK_ID_WLNK 0x776C6E6B
66 # define CHUNK_ID_PTBL 0x7074626C
67 # define CHUNK_ID_WSMP 0x77736D70
68 # define CHUNK_ID_COLH 0x636F6C68
69 # define CHUNK_ID_ARTL 0x6172746C
70 # define CHUNK_ID_ART2 0x61727432
71 #else // little endian
72 # define RIFF_TYPE_DLS 0x20534C44
73 # define LIST_TYPE_INFO 0x4F464E49
74 # define LIST_TYPE_WVPL 0x6C707677
75 # define LIST_TYPE_DWPL 0x6C707764
76 # define LIST_TYPE_WAVE 0x65766177
77 # define LIST_TYPE_LINS 0X736E696C
78 # define LIST_TYPE_INS 0X20736E69
79 # define LIST_TYPE_LRGN 0x6E67726C
80 # define LIST_TYPE_LART 0x7472616C
81 # define LIST_TYPE_LAR2 0x3272616C
82 # define LIST_TYPE_RGN 0x206E6772
83 # define LIST_TYPE_RGN2 0x326E6772
84 # define CHUNK_ID_IARL 0x4C524149
85 # define CHUNK_ID_IART 0x54524149
86 # define CHUNK_ID_ICMS 0x534D4349
87 # define CHUNK_ID_ICMT 0x544D4349
88 # define CHUNK_ID_ICOP 0x504F4349
89 # define CHUNK_ID_ICRD 0x44524349
90 # define CHUNK_ID_IENG 0x474E4549
91 # define CHUNK_ID_IGNR 0x524E4749
92 # define CHUNK_ID_IKEY 0x59454B49
93 # define CHUNK_ID_IMED 0x44454D49
94 # define CHUNK_ID_INAM 0x4D414E49
95 # define CHUNK_ID_IPRD 0x44525049
96 # define CHUNK_ID_ISBJ 0x4A425349
97 # define CHUNK_ID_ISFT 0x54465349
98 # define CHUNK_ID_ISRC 0x43525349
99 # define CHUNK_ID_ISRF 0x46525349
100 # define CHUNK_ID_ITCH 0x48435449
101 # define CHUNK_ID_VERS 0x73726576
102 # define CHUNK_ID_DLID 0x64696C64
103 # define CHUNK_ID_FMT 0x20746D66
104 # define CHUNK_ID_DATA 0x61746164
105 # define CHUNK_ID_INSH 0x68736E69
106 # define CHUNK_ID_RGNH 0x686E6772
107 # define CHUNK_ID_WLNK 0x6B6E6C77
108 # define CHUNK_ID_PTBL 0x6C627470
109 # define CHUNK_ID_WSMP 0x706D7377
110 # define CHUNK_ID_COLH 0x686C6F63
111 # define CHUNK_ID_ARTL 0x6C747261
112 # define CHUNK_ID_ART2 0x32747261
113 #endif // WORDS_BIGENDIAN
114 
115 #define DLS_WAVE_FORMAT_PCM 0x0001
116 
117 //TODO: no support for conditional chunks <cdl> yet
118 
120 namespace DLS {
121 
122  typedef std::string String;
123 
125  struct version_t {
126  uint16_t minor;
127  uint16_t major;
128  uint16_t build;
129  uint16_t release;
130  };
131 
133  struct dlsid_t {
134  uint32_t ulData1;
135  uint16_t usData2;
136  uint16_t usData3;
137  uint8_t abData[8];
138  };
139 
141  typedef enum {
142  // Modulator Sources
143  conn_src_none = 0x0000,
144  conn_src_lfo = 0x0001,
147  conn_src_eg1 = 0x0004,
148  conn_src_eg2 = 0x0005,
153  // MIDI Controller Sources
154  conn_src_cc1 = 0x0081,
155  conn_src_cc7 = 0x0087,
156  conn_src_cc10 = 0x008A,
157  conn_src_cc11 = 0x008B,
158  conn_src_cc91 = 0x00DB,
159  conn_src_cc93 = 0x00DD,
160  // Registered Parameter Numbers
161  conn_src_rpn0 = 0x0100,
162  conn_src_rpn1 = 0x0101,
163  conn_src_rpn2 = 0x0102
164  } conn_src_t;
165 
167  typedef enum {
168  // Generic Destinations
169  conn_dst_none = 0x0000,
170  conn_dst_gain = 0x0001,
172  conn_dst_pitch = 0x0003,
173  conn_dst_pan = 0x0004,
175  // Channel Output Destinations
176  conn_dst_left = 0x0010,
177  conn_dst_right = 0x0011,
178  conn_dst_center = 0x0012,
182  conn_dst_chorus = 0x0080,
183  conn_dst_reverb = 0x0081,
184  // Modulator LFO Destinations
187  // Vibrato LFO Destinations
190  // EG Destinations
206  // Filter Destinations
209  } conn_dst_t;
210 
212  typedef enum {
213  conn_trn_none = 0x0000,
215  conn_trn_convex = 0x0002,
217  } conn_trn_t;
218 
220  struct range_t {
221  uint16_t low;
222  uint16_t high;
223  };
224 
226  struct sample_loop_t {
227  uint32_t Size;
228  uint32_t LoopType;
229  uint32_t LoopStart;
230  uint32_t LoopLength;
231  };
232 
233  // just symbol prototyping
234  class File;
235  class Instrument;
236  class Region;
237  class Sample;
238 
240  class Connection {
241  public:
252  uint32_t Scale;
253  protected:
254  struct conn_block_t {
255  uint16_t source;
256  uint16_t control;
257  uint16_t destination;
258  uint16_t transform;
259  uint32_t scale;
260  };
262  void Init(conn_block_t* Header);
263  conn_block_t ToConnBlock();
264  virtual ~Connection() {}
265  friend class Articulation;
266  };
267 
269  class Articulation {
270  public:
272  uint32_t Connections;
273 
274  Articulation(RIFF::Chunk* artl);
275  virtual ~Articulation();
276  virtual void UpdateChunks();
277  protected:
279  uint32_t HeaderSize;
280  };
281 
283  class Articulator {
284  public:
285  Articulator(RIFF::List* ParentList);
288  virtual void UpdateChunks();
289  protected:
290  typedef std::list<Articulation*> ArticulationList;
293  ArticulationList::iterator ArticulationsIterator;
294 
295  void LoadArticulations();
296  virtual ~Articulator();
297  };
298 
300  class Info {
301  public:
320 
322  uint32_t chunkId;
323  int length;
324  };
325 
326  Info(RIFF::List* list);
327  void SetFixedStringLengths(const string_length_t* lengths);
328  virtual ~Info();
329  virtual void UpdateChunks();
330  private:
331  RIFF::List* pResourceListChunk;
332  const string_length_t* pFixedStringLengths;
333 
334  static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
335  void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault);
336  };
337 
339  class Resource {
340  public:
343 
344  Resource* GetParent() { return pParent; }
345  virtual void UpdateChunks();
346  void GenerateDLSID();
347  protected:
350 
351  Resource(Resource* Parent, RIFF::List* lstResource);
352  virtual ~Resource();
353  };
354 
356  class Sampler {
357  public:
358  uint8_t UnityNote;
359  int16_t FineTune;
360  int32_t Gain;
363  uint32_t SampleLoops;
365 
366  void AddSampleLoop(sample_loop_t* pLoopDef);
367  void DeleteSampleLoop(sample_loop_t* pLoopDef);
368  virtual void SetGain(int32_t gain);
369  virtual void UpdateChunks();
370  protected:
372  uint32_t uiHeaderSize;
373  uint32_t SamplerOptions;
374  Sampler(RIFF::List* ParentList);
375  virtual ~Sampler();
376  };
377 
386  class Sample : public Resource {
387  public:
388  uint16_t FormatTag;
389  uint16_t Channels;
390  uint32_t SamplesPerSecond;
392  uint16_t BlockAlign;
393  uint16_t BitDepth;
394  unsigned long SamplesTotal;
395  uint FrameSize;
396 
397  void* LoadSampleData();
398  void ReleaseSampleData();
399  unsigned long GetSize();
400  void Resize(int iNewSize);
401  unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
402  unsigned long Read(void* pBuffer, unsigned long SampleCount);
403  unsigned long Write(void* pBuffer, unsigned long SampleCount);
404  virtual void UpdateChunks();
405  protected:
409  unsigned long ulWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments
410 
411  Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset);
412  virtual ~Sample();
413  friend class File;
414  friend class Region; // Region has to compare the wave pool offset to get its sample
415  };
416 
418  class Region : public Resource, public Articulator, public Sampler {
419  public:
422  uint16_t KeyGroup;
423  uint16_t Layer;
426  uint16_t PhaseGroup;
428  uint32_t Channel;
429 
430  Sample* GetSample();
431  void SetSample(Sample* pSample);
432  virtual void SetKeyRange(uint16_t Low, uint16_t High);
433  virtual void UpdateChunks();
434  protected:
436  uint32_t WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to
437  Sample* pSample; // every region refers to exactly one sample
440 
441  Region(Instrument* pInstrument, RIFF::List* rgnList);
442  virtual ~Region();
443  friend class Instrument;
444  };
445 
447  class Instrument : public Resource, public Articulator {
448  public:
449  bool IsDrum;
450  uint16_t MIDIBank;
451  uint8_t MIDIBankCoarse;
452  uint8_t MIDIBankFine;
453  uint32_t MIDIProgram;
454  uint32_t Regions;
455 
458  Region* AddRegion();
459  void DeleteRegion(Region* pRegion);
460  virtual void UpdateChunks();
461  protected:
462  typedef std::list<Region*> RegionList;
463  struct midi_locale_t {
464  uint32_t bank;
465  uint32_t instrument;
466  };
467 
470  RegionList::iterator RegionsIterator;
471 
472  Instrument(File* pFile, RIFF::List* insList);
473  virtual void LoadRegions();
474  virtual ~Instrument();
475  friend class File;
476  friend class Region;
477  private:
478  void MoveRegion(Region* pSrc, Region* pDst);
479  };
480 
482  class File : public Resource {
483  public:
485  uint32_t Instruments;
486 
487  File();
490  Sample* GetNextSample();
491  Sample* AddSample();
492  void DeleteSample(Sample* pSample);
496  void DeleteInstrument(Instrument* pInstrument);
497  virtual void UpdateChunks();
498  virtual void Save(const String& Path);
499  virtual void Save();
500  virtual ~File();
501  protected:
502  typedef std::list<Sample*> SampleList;
503  typedef std::list<Instrument*> InstrumentList;
504 
506  std::list<RIFF::File*> ExtensionFiles;
508  SampleList::iterator SamplesIterator;
510  InstrumentList::iterator InstrumentsIterator;
512  uint32_t WavePoolCount;
513  uint32_t* pWavePoolTable;
514  uint32_t* pWavePoolTableHi;
516 
517  virtual void LoadSamples();
518  virtual void LoadInstruments();
520  friend class Region; // Region has to look in the wave pool table to get its sample
521  private:
522  void __UpdateWavePoolTableChunk();
523  void __UpdateWavePoolTable();
524  };
525 
533  class Exception : public RIFF::Exception {
534  public:
536  void PrintMessage();
537  };
538 
541 
542 } // namespace DLS
543 
544 #endif // __DLS_H__