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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations) (download) (as text)
Sun Nov 16 17:47:00 2003 UTC (20 years, 4 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 22439 byte(s)
* src/gig.cpp: fixed bug in decompression algorithm which caused it not to
  detect the end of a stream
* various endian corrections (successfully tested now on ppc)
* minor adjustments to avoid compile errors on some systems
  (using now pow() instead of powl() and --pedantic g++ compiler switch)
* src/RIFF.cpp, src/RIFF.h: added additional API documentation

1 /***************************************************************************
2 * *
3 * libgig - C++ cross-platform Gigasampler format file loader library *
4 * *
5 * Copyright (C) 2003 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 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 ~Articulation();
294 };
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 ~Articulator();
310 };
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 ~Resource();
356 };
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 ~Sampler();
372 };
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 ~Region();
421 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 ~Instrument();
450 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 ~File();
465 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
477 void LoadSamples();
478 void LoadInstruments();
479 friend class Region; // Region has to look in the wave pool table to get its sample
480 };
481
482 /** Will be thrown whenever a DLS specific error occurs while trying to access a DLS File. */
483 class Exception : public RIFF::Exception {
484 public:
485 Exception(String Message);
486 void PrintMessage();
487 };
488
489 } // namespace DLS
490
491 #endif // __DLS_H__

  ViewVC Help
Powered by ViewVC