2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file access library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2014 by Christian Schoenebeck * |
* Copyright (C) 2003-2019 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 * |
60 |
# define CHUNK_ID_COLH 0x636F6C68 |
# define CHUNK_ID_COLH 0x636F6C68 |
61 |
# define CHUNK_ID_ARTL 0x6172746C |
# define CHUNK_ID_ARTL 0x6172746C |
62 |
# define CHUNK_ID_ART2 0x61727432 |
# define CHUNK_ID_ART2 0x61727432 |
63 |
|
# define CHUNK_ID_XFIL 0x7866696C |
64 |
|
# define CHUNK_ID_DOXF 0x646F7866 |
65 |
#else // little endian |
#else // little endian |
66 |
# define RIFF_TYPE_DLS 0x20534C44 |
# define RIFF_TYPE_DLS 0x20534C44 |
67 |
# define LIST_TYPE_WVPL 0x6C707677 |
# define LIST_TYPE_WVPL 0x6C707677 |
96 |
# define CHUNK_ID_COLH 0x686C6F63 |
# define CHUNK_ID_COLH 0x686C6F63 |
97 |
# define CHUNK_ID_ARTL 0x6C747261 |
# define CHUNK_ID_ARTL 0x6C747261 |
98 |
# define CHUNK_ID_ART2 0x32747261 |
# define CHUNK_ID_ART2 0x32747261 |
99 |
|
# define CHUNK_ID_XFIL 0x6C696678 |
100 |
|
# define CHUNK_ID_DOXF 0x66786F64 |
101 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
102 |
|
|
103 |
#define DLS_WAVE_FORMAT_PCM 0x0001 |
#define DLS_WAVE_FORMAT_PCM 0x0001 |
108 |
namespace DLS { |
namespace DLS { |
109 |
|
|
110 |
typedef std::string String; |
typedef std::string String; |
111 |
|
typedef RIFF::progress_t progress_t; |
112 |
|
typedef RIFF::file_offset_t file_offset_t; |
113 |
|
|
114 |
/** Quadtuple version number ("major.minor.release.build"). */ |
/** Quadtuple version number ("major.minor.release.build"). */ |
115 |
struct version_t { |
struct version_t { |
128 |
}; |
}; |
129 |
|
|
130 |
/** Connection Sources */ |
/** Connection Sources */ |
131 |
typedef enum { |
enum conn_src_t { |
132 |
// Modulator Sources |
// Modulator Sources |
133 |
conn_src_none = 0x0000, |
conn_src_none = 0x0000, |
134 |
conn_src_lfo = 0x0001, |
conn_src_lfo = 0x0001, |
151 |
conn_src_rpn0 = 0x0100, |
conn_src_rpn0 = 0x0100, |
152 |
conn_src_rpn1 = 0x0101, |
conn_src_rpn1 = 0x0101, |
153 |
conn_src_rpn2 = 0x0102 |
conn_src_rpn2 = 0x0102 |
154 |
} conn_src_t; |
}; |
155 |
|
|
156 |
/** Connection Destinations */ |
/** Connection Destinations */ |
157 |
typedef enum { |
enum conn_dst_t { |
158 |
// Generic Destinations |
// Generic Destinations |
159 |
conn_dst_none = 0x0000, |
conn_dst_none = 0x0000, |
160 |
conn_dst_gain = 0x0001, |
conn_dst_gain = 0x0001, |
196 |
// Filter Destinations |
// Filter Destinations |
197 |
conn_dst_filter_cutoff = 0x0500, |
conn_dst_filter_cutoff = 0x0500, |
198 |
conn_dst_filter_q = 0x0501 |
conn_dst_filter_q = 0x0501 |
199 |
} conn_dst_t; |
}; |
200 |
|
|
201 |
/** Connection Transforms */ |
/** Connection Transforms */ |
202 |
typedef enum { |
enum conn_trn_t { |
203 |
conn_trn_none = 0x0000, |
conn_trn_none = 0x0000, |
204 |
conn_trn_concave = 0x0001, |
conn_trn_concave = 0x0001, |
205 |
conn_trn_convex = 0x0002, |
conn_trn_convex = 0x0002, |
206 |
conn_trn_switch = 0x0003 |
conn_trn_switch = 0x0003 |
207 |
} conn_trn_t; |
}; |
208 |
|
|
209 |
/** Lower and upper limit of a range. */ |
/** Lower and upper limit of a range. */ |
210 |
struct range_t { |
struct range_t { |
282 |
|
|
283 |
Articulation(RIFF::Chunk* artl); |
Articulation(RIFF::Chunk* artl); |
284 |
virtual ~Articulation(); |
virtual ~Articulation(); |
285 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
286 |
protected: |
protected: |
287 |
RIFF::Chunk* pArticulationCk; |
RIFF::Chunk* pArticulationCk; |
288 |
uint32_t HeaderSize; |
uint32_t HeaderSize; |
294 |
Articulator(RIFF::List* ParentList); |
Articulator(RIFF::List* ParentList); |
295 |
Articulation* GetFirstArticulation(); |
Articulation* GetFirstArticulation(); |
296 |
Articulation* GetNextArticulation(); |
Articulation* GetNextArticulation(); |
297 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
298 |
virtual void CopyAssign(const Articulator* orig); |
virtual void CopyAssign(const Articulator* orig); |
299 |
protected: |
protected: |
300 |
typedef std::list<Articulation*> ArticulationList; |
typedef std::list<Articulation*> ArticulationList; |
336 |
Info(RIFF::List* list); |
Info(RIFF::List* list); |
337 |
void SetFixedStringLengths(const string_length_t* lengths); |
void SetFixedStringLengths(const string_length_t* lengths); |
338 |
virtual ~Info(); |
virtual ~Info(); |
339 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
340 |
virtual void CopyAssign(const Info* orig); |
virtual void CopyAssign(const Info* orig); |
341 |
private: |
private: |
342 |
RIFF::List* pResourceListChunk; |
RIFF::List* pResourceListChunk; |
354 |
|
|
355 |
Resource* GetParent() { return pParent; } |
Resource* GetParent() { return pParent; } |
356 |
const Resource* GetParent() const { return pParent; } |
const Resource* GetParent() const { return pParent; } |
357 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
358 |
void GenerateDLSID(); |
void GenerateDLSID(); |
359 |
|
static void GenerateDLSID(dlsid_t* pDLSID); |
360 |
virtual void CopyAssign(const Resource* orig); |
virtual void CopyAssign(const Resource* orig); |
361 |
protected: |
protected: |
362 |
Resource* pParent; |
Resource* pParent; |
380 |
void AddSampleLoop(sample_loop_t* pLoopDef); |
void AddSampleLoop(sample_loop_t* pLoopDef); |
381 |
void DeleteSampleLoop(sample_loop_t* pLoopDef); |
void DeleteSampleLoop(sample_loop_t* pLoopDef); |
382 |
virtual void SetGain(int32_t gain); |
virtual void SetGain(int32_t gain); |
383 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
384 |
virtual void CopyAssign(const Sampler* orig); |
virtual void CopyAssign(const Sampler* orig); |
385 |
protected: |
protected: |
386 |
RIFF::List* pParentList; |
RIFF::List* pParentList; |
406 |
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). |
407 |
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. |
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. |
408 |
uint16_t BitDepth; ///< Size of each sample per channel (only if known sample data format is used, 0 otherwise). |
uint16_t BitDepth; ///< Size of each sample per channel (only if known sample data format is used, 0 otherwise). |
409 |
unsigned long SamplesTotal; ///< Reflects total number of sample points (only if known sample data format is used, 0 otherwise), do not bother to change this value, it will not be saved. |
file_offset_t SamplesTotal; ///< Reflects total number of sample points (only if known sample data format is used, 0 otherwise), do not bother to change this value, it will not be saved. |
410 |
uint FrameSize; ///< Reflects the size (in bytes) of one single sample point (only if known sample data format is used, 0 otherwise). <b>Caution:</b> with the current version of libgig you have to upate this field by yourself whenever you change one of the following fields: Channels, BitDepth ! Ignoring this might lead to undesired behavior when i.e. calling Resize(), SetPos(), Write() or Read(). |
uint FrameSize; ///< Reflects the size (in bytes) of one single sample point (only if known sample data format is used, 0 otherwise). <b>Caution:</b> with the current version of libgig you have to upate this field by yourself whenever you change one of the following fields: Channels, BitDepth ! Ignoring this might lead to undesired behavior when i.e. calling Resize(), SetPos(), Write() or Read(). |
411 |
|
|
412 |
void* LoadSampleData(); |
void* LoadSampleData(); |
413 |
void ReleaseSampleData(); |
void ReleaseSampleData(); |
414 |
unsigned long GetSize() const; |
file_offset_t GetSize() const; |
415 |
void Resize(int iNewSize); |
void Resize(file_offset_t NewSize); |
416 |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
file_offset_t SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
417 |
unsigned long Read(void* pBuffer, unsigned long SampleCount); |
file_offset_t Read(void* pBuffer, file_offset_t SampleCount); |
418 |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
file_offset_t Write(void* pBuffer, file_offset_t SampleCount); |
419 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
420 |
virtual void CopyAssign(const Sample* orig); |
virtual void CopyAssign(const Sample* orig); |
421 |
|
|
422 |
protected: |
protected: |
423 |
RIFF::List* pWaveList; |
RIFF::List* pWaveList; |
424 |
RIFF::Chunk* pCkData; |
RIFF::Chunk* pCkData; |
425 |
RIFF::Chunk* pCkFormat; |
RIFF::Chunk* pCkFormat; |
426 |
unsigned long ulWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments |
file_offset_t ullWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments |
427 |
|
|
428 |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset); |
Sample(File* pFile, RIFF::List* waveList, file_offset_t WavePoolOffset); |
429 |
virtual ~Sample(); |
virtual ~Sample(); |
430 |
void CopyAssignCore(const Sample* orig); |
void CopyAssignCore(const Sample* orig); |
431 |
friend class File; |
friend class File; |
448 |
Sample* GetSample(); |
Sample* GetSample(); |
449 |
void SetSample(Sample* pSample); |
void SetSample(Sample* pSample); |
450 |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
451 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
452 |
virtual void CopyAssign(const Region* orig); |
virtual void CopyAssign(const Region* orig); |
453 |
protected: |
protected: |
454 |
RIFF::List* pCkRegion; |
RIFF::List* pCkRegion; |
476 |
Region* GetNextRegion(); |
Region* GetNextRegion(); |
477 |
Region* AddRegion(); |
Region* AddRegion(); |
478 |
void DeleteRegion(Region* pRegion); |
void DeleteRegion(Region* pRegion); |
479 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
480 |
virtual void CopyAssign(const Instrument* orig); |
virtual void CopyAssign(const Instrument* orig); |
481 |
protected: |
protected: |
482 |
typedef std::list<Region*> RegionList; |
typedef std::list<Region*> RegionList; |
518 |
Instrument* AddInstrument(); |
Instrument* AddInstrument(); |
519 |
void DeleteInstrument(Instrument* pInstrument); |
void DeleteInstrument(Instrument* pInstrument); |
520 |
RIFF::File* GetExtensionFile(int index); |
RIFF::File* GetExtensionFile(int index); |
521 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
522 |
virtual void Save(const String& Path); |
virtual void Save(const String& Path, progress_t* pProgress = NULL); |
523 |
virtual void Save(); |
virtual void Save(progress_t* pProgress = NULL); |
524 |
virtual ~File(); |
virtual ~File(); |
525 |
protected: |
protected: |
526 |
typedef std::list<Sample*> SampleList; |
typedef std::list<Sample*> SampleList; |
527 |
typedef std::list<Instrument*> InstrumentList; |
typedef std::list<Instrument*> InstrumentList; |
528 |
|
|
529 |
RIFF::File* pRIFF; |
RIFF::File* pRIFF; |
530 |
std::list<RIFF::File*> ExtensionFiles; |
std::list<RIFF::File*> ExtensionFiles; //FIXME: These should automatically be freed, since implicitly allocated. |
531 |
SampleList* pSamples; |
SampleList* pSamples; |
532 |
SampleList::iterator SamplesIterator; |
SampleList::iterator SamplesIterator; |
533 |
InstrumentList* pInstruments; |
InstrumentList* pInstruments; |
537 |
uint32_t* pWavePoolTable; |
uint32_t* pWavePoolTable; |
538 |
uint32_t* pWavePoolTableHi; |
uint32_t* pWavePoolTableHi; |
539 |
bool b64BitWavePoolOffsets; |
bool b64BitWavePoolOffsets; |
540 |
|
bool bOwningRiff; ///< If @c true then @c pRIFF was implicitly allocated by this class and hence pRIFF will automatically be freed by the @c DLS::File destructor in that case. |
541 |
|
|
542 |
virtual void LoadSamples(); |
virtual void LoadSamples(); |
543 |
virtual void LoadInstruments(); |
virtual void LoadInstruments(); |
558 |
*/ |
*/ |
559 |
class Exception : public RIFF::Exception { |
class Exception : public RIFF::Exception { |
560 |
public: |
public: |
561 |
Exception(String Message); |
Exception(String format, ...); |
562 |
|
Exception(String format, va_list arg); |
563 |
void PrintMessage(); |
void PrintMessage(); |
564 |
|
protected: |
565 |
|
Exception(); |
566 |
}; |
}; |
567 |
|
|
568 |
String libraryName(); |
String libraryName(); |