/[svn]/libgig/trunk/src/DLS.h
ViewVC logotype

Annotation of /libgig/trunk/src/DLS.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 666 - (hide annotations) (download) (as text)
Sun Jun 19 15:18:59 2005 UTC (18 years, 9 months ago) by persson
File MIME type: text/x-c++hdr
File size: 22613 byte(s)
* added support for gig v3 multi-file format

1 schoenebeck 2 /***************************************************************************
2     * *
3     * libgig - C++ cross-platform Gigasampler format file loader library *
4     * *
5 schoenebeck 384 * Copyright (C) 2003-2005 by Christian Schoenebeck *
6     * <cuse@users.sourceforge.net> *
7 schoenebeck 2 * *
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 schoenebeck 11 #if WORDS_BIGENDIAN
30 schoenebeck 2 # define LIST_TYPE_INFO 0x494E464F
31     # define LIST_TYPE_WVPL 0x7776706C
32     # define LIST_TYPE_DWPL 0x6477706C ///< Seen on some files instead of a wvpl list chunk.
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 LIST_TYPE_ART1 0x61727431
42     # define LIST_TYPE_ART2 0x61727432
43     # define CHUNK_ID_IARL 0x4941524C
44     # define CHUNK_ID_IART 0x49415254
45     # define CHUNK_ID_ICMS 0x49434D53
46     # define CHUNK_ID_ICMT 0x49434D54
47     # define CHUNK_ID_ICOP 0x49434F50
48     # define CHUNK_ID_ICRD 0x49435244
49     # define CHUNK_ID_IENG 0x49454E47
50     # define CHUNK_ID_IGNR 0x49474E52
51     # define CHUNK_ID_IKEY 0x494B4559
52     # define CHUNK_ID_IMED 0x494D4544
53     # define CHUNK_ID_INAM 0x494E414D
54     # define CHUNK_ID_IPRD 0x49505244
55     # define CHUNK_ID_ISBJ 0x4953424A
56     # define CHUNK_ID_ISFT 0x49534654
57     # define CHUNK_ID_ISRC 0x49535243
58     # define CHUNK_ID_ISRF 0x49535246
59     # define CHUNK_ID_ITCH 0x49544348
60     # define CHUNK_ID_VERS 0x76657273
61     # define CHUNK_ID_DLID 0x646C6964
62     # define CHUNK_ID_FMT 0x666D7420
63     # define CHUNK_ID_DATA 0x64617461
64     # define CHUNK_ID_INSH 0x696E7368
65     # define CHUNK_ID_RGNH 0x72676E68
66     # define CHUNK_ID_WLNK 0x776C6E6B
67     # define CHUNK_ID_PTBL 0x7074626C
68     # define CHUNK_ID_WSMP 0x77736D70
69     # define CHUNK_ID_COLH 0x636F6C68
70     #else // little endian
71     # define LIST_TYPE_INFO 0x4F464E49
72     # define LIST_TYPE_WVPL 0x6C707677
73     # define LIST_TYPE_DWPL 0x6C707764 ///< Seen on some files instead of a wvpl list chunk.
74     # define LIST_TYPE_WAVE 0x65766177
75     # define LIST_TYPE_LINS 0X736E696C
76     # define LIST_TYPE_INS 0X20736E69
77     # define LIST_TYPE_LRGN 0x6E67726C
78     # define LIST_TYPE_LART 0x7472616C
79     # define LIST_TYPE_LAR2 0x3272616C
80     # define LIST_TYPE_RGN 0x206E6772
81     # define LIST_TYPE_RGN2 0x326E6772
82     # define LIST_TYPE_ART1 0x31747261
83     # define LIST_TYPE_ART2 0x32747261
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 0x44525049
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     #endif // WORDS_BIGENDIAN
112    
113     #define WAVE_FORMAT_PCM 0x0001
114    
115     #define DRUM_TYPE_MASK 0x00000001
116    
117     #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
118    
119     #define F_WAVELINK_PHASE_MASTER 0x0001
120     #define F_WAVELINK_MULTICHANNEL 0x0002
121    
122     #define F_WSMP_NO_TRUNCATION 0x0001
123     #define F_WSMP_NO_COMPRESSION 0x0002
124    
125     #define MIDI_BANK_COARSE(x) ((x & 0x00007F00) >> 8) // CC0
126     #define MIDI_BANK_FINE(x) (x & 0x0000007F) // CC32
127     #define MIDI_BANK_MERGE(coarse, fine) ((((uint16_t) coarse) << 7) | fine) // CC0 + CC32
128     #define CONN_TRANSFORM_SRC(x) ((x >> 10) & 0x000F)
129     #define CONN_TRANSFORM_CTL(x) ((x >> 4) & 0x000F)
130     #define CONN_TRANSFORM_DST(x) (x & 0x000F)
131     #define CONN_TRANSFORM_BIPOLAR_SRC(x) (x & 0x4000)
132     #define CONN_TRANSFORM_BIPOLAR_CTL(x) (x & 0x0100)
133     #define CONN_TRANSFORM_INVERT_SRC(x) (x & 0x8000)
134     #define CONN_TRANSFORM_INVERT_CTL(x) (x & 0x0200)
135    
136    
137     //TODO: no support for conditional chunks <cdl> yet
138    
139     /** DLS specific classes and definitions */
140     namespace DLS {
141    
142     typedef std::string String;
143    
144     /** Quadtuple version number ("major.minor.release.build"). */
145     struct version_t {
146     uint16_t minor;
147     uint16_t major;
148     uint16_t build;
149     uint16_t release;
150     };
151    
152     /** Every subject of an DLS file and the file itself can have an unique, computer generated ID. */
153     struct dlsid_t {
154     uint32_t ulData1;
155     uint16_t usData2;
156     uint16_t usData3;
157     uint8_t abData[8];
158     };
159    
160     /** Connection Sources */
161     typedef enum {
162     // Modulator Sources
163     conn_src_none = 0x0000,
164     conn_src_lfo = 0x0001,
165     conn_src_keyonvelocity = 0x0002,
166     conn_src_keynumber = 0x0003,
167     conn_src_eg1 = 0x0004,
168     conn_src_eg2 = 0x0005,
169     conn_src_pitchwheel = 0x0006,
170     conn_src_polypressure = 0x0007,
171     conn_src_channelpressure = 0x0008,
172     conn_src_vibrato = 0x0009,
173     // MIDI Controller Sources
174     conn_src_cc1 = 0x0081,
175     conn_src_cc7 = 0x0087,
176     conn_src_cc10 = 0x008A,
177     conn_src_cc11 = 0x008B,
178     conn_src_cc91 = 0x00DB,
179     conn_src_cc93 = 0x00DD,
180     // Registered Parameter Numbers
181     conn_src_rpn0 = 0x0100,
182     conn_src_rpn1 = 0x0101,
183     conn_src_rpn2 = 0x0102
184     } conn_src_t;
185    
186     /** Connection Destinations */
187     typedef enum {
188     // Generic Destinations
189     conn_dst_none = 0x0000,
190     conn_dst_gain = 0x0001,
191     conn_dst_reserved = 0x0002,
192     conn_dst_pitch = 0x0003,
193     conn_dst_pan = 0x0004,
194     conn_dst_keynumber = 0x0005,
195     // Channel Output Destinations
196     conn_dst_left = 0x0010,
197     conn_dst_right = 0x0011,
198     conn_dst_center = 0x0012,
199     conn_dst_lfe_channel = 0x0013,
200     conn_dst_leftrear = 0x0014,
201     conn_dst_rightrear = 0x0015,
202     conn_dst_chorus = 0x0080,
203     conn_dst_reverb = 0x0081,
204     // Modulator LFO Destinations
205     conn_dst_lfo_frequency = 0x0104,
206     conn_dst_lfo_startdelay = 0x0105,
207     // Vibrato LFO Destinations
208     conn_dst_vib_frequency = 0x0114,
209     conn_dst_vib_startdelay = 0x0115,
210     // EG Destinations
211     conn_dst_eg1_attacktime = 0x0206,
212     conn_dst_eg1_decaytime = 0x0207,
213     conn_dst_eg1_reserved = 0x0208,
214     conn_dst_eg1_releasetime = 0x0209,
215     conn_dst_eg1_sustainlevel = 0x020A,
216     conn_dst_eg1_delaytime = 0x020B,
217     conn_dst_eg1_holdtime = 0x020C,
218     conn_dst_eg1_shutdowntime = 0x020D,
219     conn_dst_eg2_attacktime = 0x030A,
220     conn_dst_eg2_decaytime = 0x030B,
221     conn_dst_eg2_reserved = 0x030C,
222     conn_dst_eg2_releasetime = 0x030D,
223     conn_dst_eg2_sustainlevel = 0x030E,
224     conn_dst_eg2_delaytime = 0x030F,
225     conn_dst_eg2_holdtime = 0x0310,
226     // Filter Destinations
227     conn_dst_filter_cutoff = 0x0500,
228     conn_dst_filter_q = 0x0501
229     } conn_dst_t;
230    
231     /** Connection Transforms */
232     typedef enum {
233     conn_trn_none = 0x0000,
234     conn_trn_concave = 0x0001,
235     conn_trn_convex = 0x0002,
236     conn_trn_switch = 0x0003
237     } conn_trn_t;
238    
239     /** Lower and upper limit of a range. */
240     struct range_t {
241     uint16_t low; ///< Low value of range.
242     uint16_t high; ///< High value of range.
243     };
244    
245     /** Defines Sample Loop Points. */
246     struct sample_loop_t {
247     uint32_t Size;
248     uint32_t LoopType;
249     uint32_t LoopStart;
250     uint32_t LoopLength;
251     };
252    
253     // just symbol prototyping
254     class File;
255     class Instrument;
256     class Region;
257     class Sample;
258    
259     /** Defines a connection within the synthesis model. */
260     class Connection {
261     public:
262     conn_src_t Source;
263     conn_trn_t SourceTransform;
264     bool SourceInvert;
265     bool SourceBipolar;
266     conn_src_t Control;
267     conn_trn_t ControlTransform;
268     bool ControlInvert;
269     bool ControlBipolar;
270     conn_dst_t Destination;
271     conn_trn_t DestinationTransform;
272     uint32_t Scale;
273     protected:
274     struct conn_block_t {
275     uint16_t source;
276     uint16_t control;
277     uint16_t destination;
278     uint16_t transform;
279     uint32_t scale;
280     };
281     Connection() {};
282     void Init(conn_block_t* Header);
283     virtual ~Connection() {};
284     friend class Articulation;
285     };
286    
287     /** Provides access to the defined connections used for the synthesis model. */
288     class Articulation {
289     public:
290     Connection* pConnections; ///< Points to the beginning of a <i>Connection</i> array.
291     uint32_t Connections; ///< Reflects the number of Connections.
292     Articulation(RIFF::List* artList);
293 schoenebeck 384 virtual ~Articulation();
294 schoenebeck 2 };
295    
296     /** Abstract base class for classes that provide articulation information (thus for <i>Instrument</i> and <i>Region</i> class). */
297     class Articulator {
298     public:
299     Articulator(RIFF::List* ParentList);
300     Articulation* GetFirstArticulation();
301     Articulation* GetNextArticulation();
302     protected:
303     typedef std::list<Articulation*> ArticulationList;
304     RIFF::List* pParentList;
305     ArticulationList* pArticulations;
306     ArticulationList::iterator ArticulationsIterator;
307    
308     void LoadArticulations();
309 schoenebeck 384 virtual ~Articulator();
310 schoenebeck 2 };
311    
312     /** Optional information for DLS files, instruments, samples, etc. */
313     class Info {
314     public:
315     String Name; ///< <INAM-ck>. Stores the title of the subject of the file, such as, Seattle From Above.
316     String ArchivalLocation; ///< <IARL-ck>. Indicates where the subject of the file is stored.
317     String CreationDate; ///< <ICRD-ck>. Specifies the date the subject of the file was created. List dates in yyyy-mm-dd format.
318     String Comments; ///< <ICMT-ck>. Provides general comments about the file or the subject of the file. Sentences might end with semicolon.
319     String Product; ///< <IPRD-ck>. Specifies the name of the title the file was originally intended for, such as World Ruler V.
320     String Copyright; ///< <ICOP-ck>. Records the copyright information for the file.
321     String Artists; ///< <IART-ck>. Lists the artist of the original subject of the file.
322     String Genre; ///< <IGNR-ck>. Descirbes the original work, such as, Jazz, Classic, Rock, Techno, Rave, etc.
323     String Keywords; ///< <IKEY-ck>. Provides a list of keywords that refer to the file or subject of the file. Keywords are separated with semicolon and blank, e.g., FX; death; murder.
324     String Engineer; ///< <IENG-ck>. Stores the name of the engineer who worked on the file. Multiple engineer names are separated by semicolon and blank, e.g, Smith, John; Adams, Joe.
325     String Technician; ///< <ITCH-ck>. Identifies the technician who sampled the subject file.
326     String Software; ///< <ISFT-ck>. Identifies the name of the sofware package used to create the file.
327     String Medium; ///< <IMED-ck>. Describes the original subject of the file, such as, record, CD, and so forth.
328     String Source; ///< <ISRC-ck>. Identifies the name of the person or organization who supplied the original subject of the file.
329     String SourceForm; ///< <ISRF-ck>. Identifies the original form of the material that was digitized, such as record, sampling CD, TV sound track. This is not neccessarily the same as <i>Medium</i>.
330     String Commissioned; ///< <ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file, e.g., Pope Julian II.
331    
332     Info(RIFF::List* list);
333     private:
334     inline void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s) {
335     RIFF::Chunk* ck = lstINFO->GetSubChunk(ChunkID);
336     if (ck) {
337     // TODO: no check for ZSTR terminated strings yet
338     s = (char*) ck->LoadChunkData();
339     ck->ReleaseChunkData();
340     }
341     }
342     };
343    
344     /** Abstract base class which encapsulates data structures which all DLS resources are able to provide. */
345     class Resource {
346     public:
347     Info* pInfo; ///< Points (in any case) to an <i>Info</i> object, providing additional, optional infos and comments.
348     dlsid_t* pDLSID; ///< Points to a <i>dlsid_t</i> structure if the file provided a DLS ID else is <i>NULL</i>.
349    
350     Resource* GetParent() { return pParent; };
351     protected:
352     Resource* pParent;
353    
354     Resource(Resource* Parent, RIFF::List* lstResource);
355 schoenebeck 384 virtual ~Resource();
356 schoenebeck 2 };
357    
358     /** Abstract base class which provides mandatory informations about sample players in general. */
359     class Sampler {
360     public:
361     uint8_t UnityNote;
362     int16_t FineTune;
363     int32_t Gain;
364     bool NoSampleDepthTruncation;
365     bool NoSampleCompression;
366     uint32_t SampleLoops; ///< Reflects the number of sample loops.
367     sample_loop_t* pSampleLoops; ///< Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
368     protected:
369     uint32_t SamplerOptions;
370     Sampler(RIFF::List* ParentList);
371 schoenebeck 384 virtual ~Sampler();
372 schoenebeck 2 };
373    
374     /** Encapsulates sample waves used for playback. */
375     class Sample : public Resource {
376     public:
377     uint16_t FormatTag; ///< Format ID of the waveform data (should be WAVE_FORMAT_PCM for DLS1 compliant files).
378     uint16_t Channels; ///< Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo ().
379     uint32_t SamplesPerSecond; ///< Sampling rate at which each channel should be played.
380     uint32_t AverageBytesPerSecond; ///< The average number of bytes per second at which the waveform data should be transferred (Playback software can estimate the buffer size using this value).
381     uint16_t BlockAlign; ///< The block alignment (in bytes) of the waveform data. Playback software needs to process a multiple of <i>BlockAlign</i> bytes of data at a time, so the value of <i>BlockAlign</i> can be used for buffer alignment.
382     uint16_t BitDepth; ///< Size of each sample per channel (only if known sample data format is used, 0 otherwise).
383     unsigned long SamplesTotal; ///< Reflects total number of samples (only if known sample data format is used, 0 otherwise).
384     uint FrameSize; ///< Reflects the size (in bytes) of one single sample (only if known sample data format is used, 0 otherwise).
385    
386     void* LoadSampleData(); ///< Load sample data into RAM. Returns a pointer to the data in RAM on success, <i>NULL</i> otherwise.
387     void ReleaseSampleData(); ///< Release the samples once you used them if you don't want to be bothered to.
388     unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
389     unsigned long Read(void* pBuffer, unsigned long SampleCount);
390     protected:
391     RIFF::Chunk* pCkData;
392     RIFF::Chunk* pCkFormat;
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     friend class File;
397     friend class Region; // Region has to compare the wave pool offset to get its sample
398     };
399    
400     /** Defines <i>Region</i> information of an <i>Instrument</i>. */
401     class Region : public Resource, public Articulator, public Sampler {
402     public:
403     range_t KeyRange;
404     range_t VelocityRange;
405     uint16_t KeyGroup;
406     uint16_t Layer;
407     bool SelfNonExclusive;
408     bool PhaseMaster;
409     uint16_t PhaseGroup;
410     bool MultiChannel;
411     uint32_t Channel;
412    
413     Sample* GetSample();
414     protected:
415     RIFF::List* pCkRegion;
416     uint32_t WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to
417     Sample* pSample; // every region refers to exactly one sample
418    
419     Region(Instrument* pInstrument, RIFF::List* rgnList);
420 schoenebeck 384 virtual ~Region();
421 schoenebeck 2 friend class Instrument;
422     };
423    
424     /** Provides all neccessary information for the synthesis of a DLS <i>Instrument</i>. */
425     class Instrument : public Resource, public Articulator {
426     public:
427     bool IsDrum; ///< Indicates if the <i>Instrument</i> is a drum type, as they differ in the synthesis model of DLS from melodic instruments.
428     uint16_t MIDIBank; ///< Reflects combination of <i>MIDIBankCoarse</i> and <i>MIDIBankFine</i> (bank 1 - bank 16384).
429     uint8_t MIDIBankCoarse; ///< Reflects the MIDI Bank number for MIDI Control Change 0 (bank 1 - 128).
430     uint8_t MIDIBankFine; ///< Reflects the MIDI Bank number for MIDI Control Change 32 (bank 1 - 128).
431     uint32_t MIDIProgram; ///< Specifies the MIDI Program Change Number this Instrument should be assigned to.
432     uint32_t Regions; ///< Reflects the number of <i>Region</i> defintions this Instrument has.
433    
434     Region* GetFirstRegion();
435     Region* GetNextRegion();
436     protected:
437     typedef std::list<Region*> RegionList;
438     struct midi_locale_t {
439     uint32_t bank;
440     uint32_t instrument;
441     };
442    
443     RIFF::List* pCkInstrument;
444     RegionList* pRegions;
445     RegionList::iterator RegionsIterator;
446    
447     Instrument(File* pFile, RIFF::List* insList);
448     void LoadRegions();
449 schoenebeck 384 virtual ~Instrument();
450 schoenebeck 2 friend class File;
451     };
452    
453     /** Parses DLS Level 1 and 2 compliant files and provides abstract access to the data. */
454     class File : public Resource {
455     public:
456     version_t* pVersion; ///< Points to a <i>version_t</i> structure if the file provided a version number else is set to <i>NULL</i>.
457     uint32_t Instruments; ///< Reflects the number of available <i>Instrument</i> objects.
458    
459     File(RIFF::File* pRIFF);
460     Sample* GetFirstSample(); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i> otherwise.
461     Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise.
462     Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <i>Instrument</i> object of the file, <i>NULL</i> otherwise.
463     Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise.
464 schoenebeck 384 virtual ~File();
465 schoenebeck 2 protected:
466     typedef std::list<Sample*> SampleList;
467     typedef std::list<Instrument*> InstrumentList;
468    
469     RIFF::File* pRIFF;
470     SampleList* pSamples;
471     SampleList::iterator SamplesIterator;
472     InstrumentList* pInstruments;
473     InstrumentList::iterator InstrumentsIterator;
474     uint32_t WavePoolCount;
475     uint32_t* pWavePoolTable;
476 persson 666 uint32_t* pWavePoolTableHi;
477 schoenebeck 2
478     void LoadSamples();
479     void LoadInstruments();
480     friend class Region; // Region has to look in the wave pool table to get its sample
481     };
482    
483     /** Will be thrown whenever a DLS specific error occurs while trying to access a DLS File. */
484     class Exception : public RIFF::Exception {
485     public:
486     Exception(String Message);
487     void PrintMessage();
488     };
489    
490 schoenebeck 518 String libraryName();
491     String libraryVersion();
492    
493 schoenebeck 2 } // namespace DLS
494    
495     #endif // __DLS_H__

  ViewVC Help
Powered by ViewVC