libgig  3.3.0.svn3
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-2010 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_WVPL 0x7776706C
32 # define LIST_TYPE_DWPL 0x6477706C
33 # define LIST_TYPE_WAVE 0x77617665
34 # define LIST_TYPE_LINS 0X6C696E73
35 # define LIST_TYPE_INS 0X696E7320
36 # define LIST_TYPE_LRGN 0x6C72676E
37 # define LIST_TYPE_LART 0x6C617274
38 # define LIST_TYPE_LAR2 0x6C617232
39 # define LIST_TYPE_RGN 0x72676E20
40 # define LIST_TYPE_RGN2 0x72676E32
41 # define CHUNK_ID_IARL 0x4941524C
42 # define CHUNK_ID_IART 0x49415254
43 # define CHUNK_ID_ICMS 0x49434D53
44 # define CHUNK_ID_IGNR 0x49474E52
45 # define CHUNK_ID_IKEY 0x494B4559
46 # define CHUNK_ID_IMED 0x494D4544
47 # define CHUNK_ID_ISBJ 0x4953424A
48 # define CHUNK_ID_ISRC 0x49535243
49 # define CHUNK_ID_ISRF 0x49535246
50 # define CHUNK_ID_ITCH 0x49544348
51 # define CHUNK_ID_VERS 0x76657273
52 # define CHUNK_ID_DLID 0x646C6964
53 # define CHUNK_ID_FMT 0x666D7420
54 # define CHUNK_ID_DATA 0x64617461
55 # define CHUNK_ID_INSH 0x696E7368
56 # define CHUNK_ID_RGNH 0x72676E68
57 # define CHUNK_ID_WLNK 0x776C6E6B
58 # define CHUNK_ID_PTBL 0x7074626C
59 # define CHUNK_ID_WSMP 0x77736D70
60 # define CHUNK_ID_COLH 0x636F6C68
61 # define CHUNK_ID_ARTL 0x6172746C
62 # define CHUNK_ID_ART2 0x61727432
63 #else // little endian
64 # define RIFF_TYPE_DLS 0x20534C44
65 # define LIST_TYPE_WVPL 0x6C707677
66 # define LIST_TYPE_DWPL 0x6C707764
67 # define LIST_TYPE_WAVE 0x65766177
68 # define LIST_TYPE_LINS 0X736E696C
69 # define LIST_TYPE_INS 0X20736E69
70 # define LIST_TYPE_LRGN 0x6E67726C
71 # define LIST_TYPE_LART 0x7472616C
72 # define LIST_TYPE_LAR2 0x3272616C
73 # define LIST_TYPE_RGN 0x206E6772
74 # define LIST_TYPE_RGN2 0x326E6772
75 # define CHUNK_ID_IARL 0x4C524149
76 # define CHUNK_ID_IART 0x54524149
77 # define CHUNK_ID_ICMS 0x534D4349
78 # define CHUNK_ID_IGNR 0x524E4749
79 # define CHUNK_ID_IKEY 0x59454B49
80 # define CHUNK_ID_IMED 0x44454D49
81 # define CHUNK_ID_ISBJ 0x4A425349
82 # define CHUNK_ID_ISRC 0x43525349
83 # define CHUNK_ID_ISRF 0x46525349
84 # define CHUNK_ID_ITCH 0x48435449
85 # define CHUNK_ID_VERS 0x73726576
86 # define CHUNK_ID_DLID 0x64696C64
87 # define CHUNK_ID_FMT 0x20746D66
88 # define CHUNK_ID_DATA 0x61746164
89 # define CHUNK_ID_INSH 0x68736E69
90 # define CHUNK_ID_RGNH 0x686E6772
91 # define CHUNK_ID_WLNK 0x6B6E6C77
92 # define CHUNK_ID_PTBL 0x6C627470
93 # define CHUNK_ID_WSMP 0x706D7377
94 # define CHUNK_ID_COLH 0x686C6F63
95 # define CHUNK_ID_ARTL 0x6C747261
96 # define CHUNK_ID_ART2 0x32747261
97 #endif // WORDS_BIGENDIAN
98 
99 #define DLS_WAVE_FORMAT_PCM 0x0001
100 
101 //TODO: no support for conditional chunks <cdl> yet
102 
104 namespace DLS {
105 
106  typedef std::string String;
107 
109  struct version_t {
110  uint16_t minor;
111  uint16_t major;
112  uint16_t build;
113  uint16_t release;
114  };
115 
117  struct dlsid_t {
118  uint32_t ulData1;
119  uint16_t usData2;
120  uint16_t usData3;
121  uint8_t abData[8];
122  };
123 
125  typedef enum {
126  // Modulator Sources
127  conn_src_none = 0x0000,
128  conn_src_lfo = 0x0001,
131  conn_src_eg1 = 0x0004,
132  conn_src_eg2 = 0x0005,
137  // MIDI Controller Sources
138  conn_src_cc1 = 0x0081,
139  conn_src_cc7 = 0x0087,
140  conn_src_cc10 = 0x008A,
141  conn_src_cc11 = 0x008B,
142  conn_src_cc91 = 0x00DB,
143  conn_src_cc93 = 0x00DD,
144  // Registered Parameter Numbers
145  conn_src_rpn0 = 0x0100,
146  conn_src_rpn1 = 0x0101,
147  conn_src_rpn2 = 0x0102
148  } conn_src_t;
149 
151  typedef enum {
152  // Generic Destinations
153  conn_dst_none = 0x0000,
154  conn_dst_gain = 0x0001,
156  conn_dst_pitch = 0x0003,
157  conn_dst_pan = 0x0004,
159  // Channel Output Destinations
160  conn_dst_left = 0x0010,
161  conn_dst_right = 0x0011,
162  conn_dst_center = 0x0012,
166  conn_dst_chorus = 0x0080,
167  conn_dst_reverb = 0x0081,
168  // Modulator LFO Destinations
171  // Vibrato LFO Destinations
174  // EG Destinations
190  // Filter Destinations
193  } conn_dst_t;
194 
196  typedef enum {
197  conn_trn_none = 0x0000,
199  conn_trn_convex = 0x0002,
201  } conn_trn_t;
202 
204  struct range_t {
205  uint16_t low;
206  uint16_t high;
207  };
208 
210  struct sample_loop_t {
211  uint32_t Size;
212  uint32_t LoopType;
213  uint32_t LoopStart;
214  uint32_t LoopLength;
215  };
216 
217  // just symbol prototyping
218  class File;
219  class Instrument;
220  class Region;
221  class Sample;
222 
224  class Connection {
225  public:
236  uint32_t Scale;
237  protected:
238  struct conn_block_t {
239  uint16_t source;
240  uint16_t control;
241  uint16_t destination;
242  uint16_t transform;
243  uint32_t scale;
244  };
246  void Init(conn_block_t* Header);
247  conn_block_t ToConnBlock();
248  virtual ~Connection() {}
249  friend class Articulation;
250  };
251 
253  class Articulation {
254  public:
256  uint32_t Connections;
257 
258  Articulation(RIFF::Chunk* artl);
259  virtual ~Articulation();
260  virtual void UpdateChunks();
261  protected:
263  uint32_t HeaderSize;
264  };
265 
267  class Articulator {
268  public:
269  Articulator(RIFF::List* ParentList);
272  virtual void UpdateChunks();
273  protected:
274  typedef std::list<Articulation*> ArticulationList;
277  ArticulationList::iterator ArticulationsIterator;
278 
279  void LoadArticulations();
280  virtual ~Articulator();
281  };
282 
284  class Info {
285  public:
304 
306  uint32_t chunkId;
307  int length;
308  };
309 
310  Info(RIFF::List* list);
311  void SetFixedStringLengths(const string_length_t* lengths);
312  virtual ~Info();
313  virtual void UpdateChunks();
314  private:
315  RIFF::List* pResourceListChunk;
316  const string_length_t* pFixedStringLengths;
317 
318  static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
319  void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault);
320  };
321 
323  class Resource {
324  public:
327 
328  Resource* GetParent() { return pParent; }
329  virtual void UpdateChunks();
330  void GenerateDLSID();
331  protected:
334 
335  Resource(Resource* Parent, RIFF::List* lstResource);
336  virtual ~Resource();
337  };
338 
340  class Sampler {
341  public:
342  uint8_t UnityNote;
343  int16_t FineTune;
344  int32_t Gain;
347  uint32_t SampleLoops;
349 
350  void AddSampleLoop(sample_loop_t* pLoopDef);
351  void DeleteSampleLoop(sample_loop_t* pLoopDef);
352  virtual void SetGain(int32_t gain);
353  virtual void UpdateChunks();
354  protected:
356  uint32_t uiHeaderSize;
357  uint32_t SamplerOptions;
358  Sampler(RIFF::List* ParentList);
359  virtual ~Sampler();
360  };
361 
370  class Sample : public Resource {
371  public:
372  uint16_t FormatTag;
373  uint16_t Channels;
374  uint32_t SamplesPerSecond;
376  uint16_t BlockAlign;
377  uint16_t BitDepth;
378  unsigned long SamplesTotal;
379  uint FrameSize;
380 
381  void* LoadSampleData();
382  void ReleaseSampleData();
383  unsigned long GetSize();
384  void Resize(int iNewSize);
385  unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
386  unsigned long Read(void* pBuffer, unsigned long SampleCount);
387  unsigned long Write(void* pBuffer, unsigned long SampleCount);
388  virtual void UpdateChunks();
389  protected:
393  unsigned long ulWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments
394 
395  Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset);
396  virtual ~Sample();
397  friend class File;
398  friend class Region; // Region has to compare the wave pool offset to get its sample
399  };
400 
402  class Region : public Resource, public Articulator, public Sampler {
403  public:
406  uint16_t KeyGroup;
407  uint16_t Layer;
410  uint16_t PhaseGroup;
412  uint32_t Channel;
413 
414  Sample* GetSample();
415  void SetSample(Sample* pSample);
416  virtual void SetKeyRange(uint16_t Low, uint16_t High);
417  virtual void UpdateChunks();
418  protected:
420  uint32_t WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to
421  Sample* pSample; // every region refers to exactly one sample
424 
425  Region(Instrument* pInstrument, RIFF::List* rgnList);
426  virtual ~Region();
427  friend class Instrument;
428  };
429 
431  class Instrument : public Resource, public Articulator {
432  public:
433  bool IsDrum;
434  uint16_t MIDIBank;
435  uint8_t MIDIBankCoarse;
436  uint8_t MIDIBankFine;
437  uint32_t MIDIProgram;
438  uint32_t Regions;
439 
442  Region* AddRegion();
443  void DeleteRegion(Region* pRegion);
444  virtual void UpdateChunks();
445  protected:
446  typedef std::list<Region*> RegionList;
447  struct midi_locale_t {
448  uint32_t bank;
449  uint32_t instrument;
450  };
451 
454  RegionList::iterator RegionsIterator;
455 
456  Instrument(File* pFile, RIFF::List* insList);
457  virtual void LoadRegions();
458  virtual ~Instrument();
459  friend class File;
460  friend class Region;
461  private:
462  void MoveRegion(Region* pSrc, Region* pDst);
463  };
464 
466  class File : public Resource {
467  public:
469  uint32_t Instruments;
470 
471  File();
475  Sample* GetNextSample();
476  Sample* AddSample();
477  void DeleteSample(Sample* pSample);
481  void DeleteInstrument(Instrument* pInstrument);
482  RIFF::File* GetExtensionFile(int index);
483  virtual void UpdateChunks();
484  virtual void Save(const String& Path);
485  virtual void Save();
486  virtual ~File();
487  protected:
488  typedef std::list<Sample*> SampleList;
489  typedef std::list<Instrument*> InstrumentList;
490 
492  std::list<RIFF::File*> ExtensionFiles;
494  SampleList::iterator SamplesIterator;
496  InstrumentList::iterator InstrumentsIterator;
498  uint32_t WavePoolCount;
499  uint32_t* pWavePoolTable;
500  uint32_t* pWavePoolTableHi;
502 
503  virtual void LoadSamples();
504  virtual void LoadInstruments();
506  friend class Region; // Region has to look in the wave pool table to get its sample
507  private:
508  void __UpdateWavePoolTableChunk();
509  void __UpdateWavePoolTable();
510  };
511 
519  class Exception : public RIFF::Exception {
520  public:
522  void PrintMessage();
523  };
524 
527 
528 } // namespace DLS
529 
530 #endif // __DLS_H__