1 |
/*************************************************************************** |
/*************************************************************************** |
2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file loader library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2005 by Christian Schoenebeck * |
* Copyright (C) 2003-2010 by Christian Schoenebeck * |
6 |
* <cuse@users.sourceforge.net> * |
* <cuse@users.sourceforge.net> * |
7 |
* * |
* * |
8 |
* This library is free software; you can redistribute it and/or modify * |
* This library is free software; you can redistribute it and/or modify * |
28 |
|
|
29 |
#if WORDS_BIGENDIAN |
#if WORDS_BIGENDIAN |
30 |
# define RIFF_TYPE_DLS 0x444C5320 |
# define RIFF_TYPE_DLS 0x444C5320 |
|
# define LIST_TYPE_INFO 0x494E464F |
|
31 |
# define LIST_TYPE_WVPL 0x7776706C |
# define LIST_TYPE_WVPL 0x7776706C |
32 |
# define LIST_TYPE_DWPL 0x6477706C ///< Seen on some files instead of a wvpl list chunk. |
# define LIST_TYPE_DWPL 0x6477706C ///< Seen on some files instead of a wvpl list chunk. |
33 |
# define LIST_TYPE_WAVE 0x77617665 |
# define LIST_TYPE_WAVE 0x77617665 |
41 |
# define CHUNK_ID_IARL 0x4941524C |
# define CHUNK_ID_IARL 0x4941524C |
42 |
# define CHUNK_ID_IART 0x49415254 |
# define CHUNK_ID_IART 0x49415254 |
43 |
# define CHUNK_ID_ICMS 0x49434D53 |
# define CHUNK_ID_ICMS 0x49434D53 |
|
# define CHUNK_ID_ICMT 0x49434D54 |
|
|
# define CHUNK_ID_ICOP 0x49434F50 |
|
|
# define CHUNK_ID_ICRD 0x49435244 |
|
|
# define CHUNK_ID_IENG 0x49454E47 |
|
44 |
# define CHUNK_ID_IGNR 0x49474E52 |
# define CHUNK_ID_IGNR 0x49474E52 |
45 |
# define CHUNK_ID_IKEY 0x494B4559 |
# define CHUNK_ID_IKEY 0x494B4559 |
46 |
# define CHUNK_ID_IMED 0x494D4544 |
# define CHUNK_ID_IMED 0x494D4544 |
|
# define CHUNK_ID_INAM 0x494E414D |
|
|
# define CHUNK_ID_IPRD 0x49505244 |
|
47 |
# define CHUNK_ID_ISBJ 0x4953424A |
# define CHUNK_ID_ISBJ 0x4953424A |
|
# define CHUNK_ID_ISFT 0x49534654 |
|
48 |
# define CHUNK_ID_ISRC 0x49535243 |
# define CHUNK_ID_ISRC 0x49535243 |
49 |
# define CHUNK_ID_ISRF 0x49535246 |
# define CHUNK_ID_ISRF 0x49535246 |
50 |
# define CHUNK_ID_ITCH 0x49544348 |
# define CHUNK_ID_ITCH 0x49544348 |
62 |
# define CHUNK_ID_ART2 0x61727432 |
# define CHUNK_ID_ART2 0x61727432 |
63 |
#else // little endian |
#else // little endian |
64 |
# define RIFF_TYPE_DLS 0x20534C44 |
# define RIFF_TYPE_DLS 0x20534C44 |
|
# define LIST_TYPE_INFO 0x4F464E49 |
|
65 |
# define LIST_TYPE_WVPL 0x6C707677 |
# define LIST_TYPE_WVPL 0x6C707677 |
66 |
# define LIST_TYPE_DWPL 0x6C707764 ///< Seen on some files instead of a wvpl list chunk. |
# define LIST_TYPE_DWPL 0x6C707764 ///< Seen on some files instead of a wvpl list chunk. |
67 |
# define LIST_TYPE_WAVE 0x65766177 |
# define LIST_TYPE_WAVE 0x65766177 |
75 |
# define CHUNK_ID_IARL 0x4C524149 |
# define CHUNK_ID_IARL 0x4C524149 |
76 |
# define CHUNK_ID_IART 0x54524149 |
# define CHUNK_ID_IART 0x54524149 |
77 |
# define CHUNK_ID_ICMS 0x534D4349 |
# define CHUNK_ID_ICMS 0x534D4349 |
|
# define CHUNK_ID_ICMT 0x544D4349 |
|
|
# define CHUNK_ID_ICOP 0x504F4349 |
|
|
# define CHUNK_ID_ICRD 0x44524349 |
|
|
# define CHUNK_ID_IENG 0x474E4549 |
|
78 |
# define CHUNK_ID_IGNR 0x524E4749 |
# define CHUNK_ID_IGNR 0x524E4749 |
79 |
# define CHUNK_ID_IKEY 0x59454B49 |
# define CHUNK_ID_IKEY 0x59454B49 |
80 |
# define CHUNK_ID_IMED 0x44454D49 |
# define CHUNK_ID_IMED 0x44454D49 |
|
# define CHUNK_ID_INAM 0x4D414E49 |
|
|
# define CHUNK_ID_IPRD 0x44525049 |
|
81 |
# define CHUNK_ID_ISBJ 0x4A425349 |
# define CHUNK_ID_ISBJ 0x4A425349 |
|
# define CHUNK_ID_ISFT 0x54465349 |
|
82 |
# define CHUNK_ID_ISRC 0x43525349 |
# define CHUNK_ID_ISRC 0x43525349 |
83 |
# define CHUNK_ID_ISRF 0x46525349 |
# define CHUNK_ID_ISRF 0x46525349 |
84 |
# define CHUNK_ID_ITCH 0x48435449 |
# define CHUNK_ID_ITCH 0x48435449 |
96 |
# define CHUNK_ID_ART2 0x32747261 |
# define CHUNK_ID_ART2 0x32747261 |
97 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
98 |
|
|
99 |
#define WAVE_FORMAT_PCM 0x0001 |
#define DLS_WAVE_FORMAT_PCM 0x0001 |
100 |
|
|
101 |
//TODO: no support for conditional chunks <cdl> yet |
//TODO: no support for conditional chunks <cdl> yet |
102 |
|
|
208 |
|
|
209 |
/** Defines Sample Loop Points. */ |
/** Defines Sample Loop Points. */ |
210 |
struct sample_loop_t { |
struct sample_loop_t { |
211 |
uint32_t Size; |
uint32_t Size; ///< For internal usage only: usually reflects exactly @c sizeof(sample_loop_t), otherwise if the value is larger then the DLS format was extended! |
212 |
uint32_t LoopType; |
uint32_t LoopType; ///< Defines how the waveform samples will be looped (appropriate loop types for the gig format are defined by gig::loop_type_t). |
213 |
uint32_t LoopStart; |
uint32_t LoopStart; ///< The start value specifies the offset (in sample points) in the waveform data of the first sample point to be played in the loop. |
214 |
uint32_t LoopLength; |
uint32_t LoopLength; ///< Length of the looping area (in sample points). |
215 |
}; |
}; |
216 |
|
|
217 |
// just symbol prototyping |
// just symbol prototyping |
242 |
uint16_t transform; |
uint16_t transform; |
243 |
uint32_t scale; |
uint32_t scale; |
244 |
}; |
}; |
245 |
Connection() {}; |
Connection() {} |
246 |
void Init(conn_block_t* Header); |
void Init(conn_block_t* Header); |
247 |
conn_block_t ToConnBlock(); |
conn_block_t ToConnBlock(); |
248 |
virtual ~Connection() {}; |
virtual ~Connection() {} |
249 |
friend class Articulation; |
friend class Articulation; |
250 |
}; |
}; |
251 |
|
|
300 |
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>. |
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>. |
301 |
String Commissioned; ///< <ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file, e.g., Pope Julian II. |
String Commissioned; ///< <ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file, e.g., Pope Julian II. |
302 |
String Subject; ///< <ISBJ-ck>. Describes the contents of the file. |
String Subject; ///< <ISBJ-ck>. Describes the contents of the file. |
303 |
bool UseFixedLengthStrings; ///< Set this to true if the info strings should be stored with a fixed length format. This is used for gig files, not for ordinary DLS files. |
bool UseFixedLengthStrings; ///< @deprecated Not used anymore, use SetFixedStringLengths() instead. |
304 |
|
|
305 |
|
struct string_length_t { |
306 |
|
uint32_t chunkId; |
307 |
|
int length; |
308 |
|
}; |
309 |
|
|
310 |
Info(RIFF::List* list); |
Info(RIFF::List* list); |
311 |
|
void SetFixedStringLengths(const string_length_t* lengths); |
312 |
virtual ~Info(); |
virtual ~Info(); |
313 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
314 |
private: |
private: |
315 |
RIFF::List* pResourceListChunk; |
RIFF::List* pResourceListChunk; |
316 |
|
const string_length_t* pFixedStringLengths; ///< List of IDs and string lengths for strings that should be stored in a fixed length format. This is used for gig files, not for ordinary DLS files. |
317 |
|
|
318 |
void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s); |
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, int size); |
void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault); |
320 |
}; |
}; |
321 |
|
|
322 |
/** Abstract base class which encapsulates data structures which all DLS resources are able to provide. */ |
/** Abstract base class which encapsulates data structures which all DLS resources are able to provide. */ |
325 |
Info* pInfo; ///< Points (in any case) to an <i>Info</i> object, providing additional, optional infos and comments. |
Info* pInfo; ///< Points (in any case) to an <i>Info</i> object, providing additional, optional infos and comments. |
326 |
dlsid_t* pDLSID; ///< Points to a <i>dlsid_t</i> structure if the file provided a DLS ID else is <i>NULL</i>. |
dlsid_t* pDLSID; ///< Points to a <i>dlsid_t</i> structure if the file provided a DLS ID else is <i>NULL</i>. |
327 |
|
|
328 |
Resource* GetParent() { return pParent; }; |
Resource* GetParent() { return pParent; } |
329 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
330 |
|
void GenerateDLSID(); |
331 |
protected: |
protected: |
332 |
Resource* pParent; |
Resource* pParent; |
333 |
RIFF::List* pResourceList; |
RIFF::List* pResourceList; |
341 |
public: |
public: |
342 |
uint8_t UnityNote; |
uint8_t UnityNote; |
343 |
int16_t FineTune; |
int16_t FineTune; |
344 |
int32_t Gain; |
int32_t Gain; ///< @deprecated Don't alter directly, use SetGain() instead! |
345 |
bool NoSampleDepthTruncation; |
bool NoSampleDepthTruncation; |
346 |
bool NoSampleCompression; |
bool NoSampleCompression; |
347 |
uint32_t SampleLoops; ///< Reflects the number of sample loops. |
uint32_t SampleLoops; ///< Reflects the number of sample loops. |
348 |
sample_loop_t* pSampleLoops; ///< Points to the beginning of a sample loop array, or is NULL if there are no loops defined. |
sample_loop_t* pSampleLoops; ///< Points to the beginning of a sample loop array, or is NULL if there are no loops defined. |
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(); |
virtual void UpdateChunks(); |
354 |
protected: |
protected: |
355 |
RIFF::List* pParentList; |
RIFF::List* pParentList; |
369 |
*/ |
*/ |
370 |
class Sample : public Resource { |
class Sample : public Resource { |
371 |
public: |
public: |
372 |
uint16_t FormatTag; ///< Format ID of the waveform data (should be WAVE_FORMAT_PCM for DLS1 compliant files, this is also the default value if Sample was created with Instrument::AddSample()). |
uint16_t FormatTag; ///< Format ID of the waveform data (should be DLS_WAVE_FORMAT_PCM for DLS1 compliant files, this is also the default value if Sample was created with Instrument::AddSample()). |
373 |
uint16_t Channels; ///< Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mono if Sample was created with Instrument::AddSample() previously). |
uint16_t Channels; ///< Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mono if Sample was created with Instrument::AddSample() previously). |
374 |
uint32_t SamplesPerSecond; ///< Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with Instrument::AddSample() previously). |
uint32_t SamplesPerSecond; ///< Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with Instrument::AddSample() previously). |
375 |
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). |
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). |
401 |
/** Defines <i>Region</i> information of an <i>Instrument</i>. */ |
/** Defines <i>Region</i> information of an <i>Instrument</i>. */ |
402 |
class Region : public Resource, public Articulator, public Sampler { |
class Region : public Resource, public Articulator, public Sampler { |
403 |
public: |
public: |
404 |
range_t KeyRange; |
range_t KeyRange; ///< @deprecated Only read, don't write! Use SetKeyRange() instead. |
405 |
range_t VelocityRange; |
range_t VelocityRange; |
406 |
uint16_t KeyGroup; |
uint16_t KeyGroup; |
407 |
uint16_t Layer; |
uint16_t Layer; |
413 |
|
|
414 |
Sample* GetSample(); |
Sample* GetSample(); |
415 |
void SetSample(Sample* pSample); |
void SetSample(Sample* pSample); |
416 |
|
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
417 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
418 |
protected: |
protected: |
419 |
RIFF::List* pCkRegion; |
RIFF::List* pCkRegion; |
457 |
virtual void LoadRegions(); |
virtual void LoadRegions(); |
458 |
virtual ~Instrument(); |
virtual ~Instrument(); |
459 |
friend class File; |
friend class File; |
460 |
|
friend class Region; |
461 |
|
private: |
462 |
|
void MoveRegion(Region* pSrc, Region* pDst); |
463 |
}; |
}; |
464 |
|
|
465 |
/** Parses DLS Level 1 and 2 compliant files and provides abstract access to the data. */ |
/** Parses DLS Level 1 and 2 compliant files and provides abstract access to the data. */ |
470 |
|
|
471 |
File(); |
File(); |
472 |
File(RIFF::File* pRIFF); |
File(RIFF::File* pRIFF); |
473 |
|
String GetFileName(); |
474 |
Sample* GetFirstSample(); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
Sample* GetFirstSample(); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
475 |
Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
476 |
Sample* AddSample(); |
Sample* AddSample(); |
479 |
Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
480 |
Instrument* AddInstrument(); |
Instrument* AddInstrument(); |
481 |
void DeleteInstrument(Instrument* pInstrument); |
void DeleteInstrument(Instrument* pInstrument); |
482 |
|
RIFF::File* GetExtensionFile(int index); |
483 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
484 |
virtual void Save(const String& Path); |
virtual void Save(const String& Path); |
485 |
virtual void Save(); |
virtual void Save(); |
509 |
void __UpdateWavePoolTable(); |
void __UpdateWavePoolTable(); |
510 |
}; |
}; |
511 |
|
|
512 |
/** Will be thrown whenever a DLS specific error occurs while trying to access a DLS File. */ |
/** |
513 |
|
* Will be thrown whenever a DLS specific error occurs while trying to |
514 |
|
* access a DLS File. Note: In your application you should better catch |
515 |
|
* for RIFF::Exception rather than this one, except you explicitly want |
516 |
|
* to catch and handle DLS::Exception and RIFF::Exception independently, |
517 |
|
* which usually shouldn't be necessary though. |
518 |
|
*/ |
519 |
class Exception : public RIFF::Exception { |
class Exception : public RIFF::Exception { |
520 |
public: |
public: |
521 |
Exception(String Message); |
Exception(String Message); |