DLS.h   DLS.h 
/************************************************************************** * /************************************************************************** *
* * * *
* libgig - C++ cross-platform Gigasampler format file loader library * * libgig - C++ cross-platform Gigasampler format file access library *
* * * *
* Copyright (C) 2003-2005 by Christian Schoenebeck * * Copyright (C) 2003-2009 by Christian Schoenebeck *
* <cuse@users.sourceforge.net> * * <cuse@users.sourceforge.net> *
* * * *
* This library is free software; you can redistribute it and/or modify * * This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This library is distributed in the hope that it will be useful, * * This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
skipping to change at line 30 skipping to change at line 30
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA * * MA 02111-1307 USA *
************************************************************************** */ ************************************************************************** */
#ifndef __DLS_H__ #ifndef __DLS_H__
#define __DLS_H__ #define __DLS_H__
#include "RIFF.h" #include "RIFF.h"
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
# define RIFF_TYPE_DLS 0x444C5320
# define LIST_TYPE_INFO 0x494E464F # define LIST_TYPE_INFO 0x494E464F
# define LIST_TYPE_WVPL 0x7776706C # define LIST_TYPE_WVPL 0x7776706C
# define LIST_TYPE_DWPL 0x6477706C ///< Seen on some files instead of a wv pl list chunk. # define LIST_TYPE_DWPL 0x6477706C ///< Seen on some files instead of a wv pl list chunk.
# define LIST_TYPE_WAVE 0x77617665 # define LIST_TYPE_WAVE 0x77617665
# define LIST_TYPE_LINS 0X6C696E73 # define LIST_TYPE_LINS 0X6C696E73
# define LIST_TYPE_INS 0X696E7320 # define LIST_TYPE_INS 0X696E7320
# define LIST_TYPE_LRGN 0x6C72676E # define LIST_TYPE_LRGN 0x6C72676E
# define LIST_TYPE_LART 0x6C617274 # define LIST_TYPE_LART 0x6C617274
# define LIST_TYPE_LAR2 0x6C617232 # define LIST_TYPE_LAR2 0x6C617232
# define LIST_TYPE_RGN 0x72676E20 # define LIST_TYPE_RGN 0x72676E20
# define LIST_TYPE_RGN2 0x72676E32 # define LIST_TYPE_RGN2 0x72676E32
# define LIST_TYPE_ART1 0x61727431
# define LIST_TYPE_ART2 0x61727432
# define CHUNK_ID_IARL 0x4941524C # define CHUNK_ID_IARL 0x4941524C
# define CHUNK_ID_IART 0x49415254 # define CHUNK_ID_IART 0x49415254
# define CHUNK_ID_ICMS 0x49434D53 # define CHUNK_ID_ICMS 0x49434D53
# define CHUNK_ID_ICMT 0x49434D54 # define CHUNK_ID_ICMT 0x49434D54
# define CHUNK_ID_ICOP 0x49434F50 # define CHUNK_ID_ICOP 0x49434F50
# define CHUNK_ID_ICRD 0x49435244 # define CHUNK_ID_ICRD 0x49435244
# define CHUNK_ID_IENG 0x49454E47 # define CHUNK_ID_IENG 0x49454E47
# define CHUNK_ID_IGNR 0x49474E52 # define CHUNK_ID_IGNR 0x49474E52
# define CHUNK_ID_IKEY 0x494B4559 # define CHUNK_ID_IKEY 0x494B4559
# define CHUNK_ID_IMED 0x494D4544 # define CHUNK_ID_IMED 0x494D4544
skipping to change at line 70 skipping to change at line 69
# define CHUNK_ID_VERS 0x76657273 # define CHUNK_ID_VERS 0x76657273
# define CHUNK_ID_DLID 0x646C6964 # define CHUNK_ID_DLID 0x646C6964
# define CHUNK_ID_FMT 0x666D7420 # define CHUNK_ID_FMT 0x666D7420
# define CHUNK_ID_DATA 0x64617461 # define CHUNK_ID_DATA 0x64617461
# define CHUNK_ID_INSH 0x696E7368 # define CHUNK_ID_INSH 0x696E7368
# define CHUNK_ID_RGNH 0x72676E68 # define CHUNK_ID_RGNH 0x72676E68
# define CHUNK_ID_WLNK 0x776C6E6B # define CHUNK_ID_WLNK 0x776C6E6B
# define CHUNK_ID_PTBL 0x7074626C # define CHUNK_ID_PTBL 0x7074626C
# define CHUNK_ID_WSMP 0x77736D70 # define CHUNK_ID_WSMP 0x77736D70
# define CHUNK_ID_COLH 0x636F6C68 # define CHUNK_ID_COLH 0x636F6C68
# define CHUNK_ID_ARTL 0x6172746C
# define CHUNK_ID_ART2 0x61727432
#else // little endian #else // little endian
# define RIFF_TYPE_DLS 0x20534C44
# define LIST_TYPE_INFO 0x4F464E49 # define LIST_TYPE_INFO 0x4F464E49
# define LIST_TYPE_WVPL 0x6C707677 # define LIST_TYPE_WVPL 0x6C707677
# define LIST_TYPE_DWPL 0x6C707764 ///< Seen on some files instead of a wv pl list chunk. # define LIST_TYPE_DWPL 0x6C707764 ///< Seen on some files instead of a wv pl list chunk.
# define LIST_TYPE_WAVE 0x65766177 # define LIST_TYPE_WAVE 0x65766177
# define LIST_TYPE_LINS 0X736E696C # define LIST_TYPE_LINS 0X736E696C
# define LIST_TYPE_INS 0X20736E69 # define LIST_TYPE_INS 0X20736E69
# define LIST_TYPE_LRGN 0x6E67726C # define LIST_TYPE_LRGN 0x6E67726C
# define LIST_TYPE_LART 0x7472616C # define LIST_TYPE_LART 0x7472616C
# define LIST_TYPE_LAR2 0x3272616C # define LIST_TYPE_LAR2 0x3272616C
# define LIST_TYPE_RGN 0x206E6772 # define LIST_TYPE_RGN 0x206E6772
# define LIST_TYPE_RGN2 0x326E6772 # define LIST_TYPE_RGN2 0x326E6772
# define LIST_TYPE_ART1 0x31747261
# define LIST_TYPE_ART2 0x32747261
# define CHUNK_ID_IARL 0x4C524149 # define CHUNK_ID_IARL 0x4C524149
# define CHUNK_ID_IART 0x54524149 # define CHUNK_ID_IART 0x54524149
# define CHUNK_ID_ICMS 0x534D4349 # define CHUNK_ID_ICMS 0x534D4349
# define CHUNK_ID_ICMT 0x544D4349 # define CHUNK_ID_ICMT 0x544D4349
# define CHUNK_ID_ICOP 0x504F4349 # define CHUNK_ID_ICOP 0x504F4349
# define CHUNK_ID_ICRD 0x44524349 # define CHUNK_ID_ICRD 0x44524349
# define CHUNK_ID_IENG 0x474E4549 # define CHUNK_ID_IENG 0x474E4549
# define CHUNK_ID_IGNR 0x524E4749 # define CHUNK_ID_IGNR 0x524E4749
# define CHUNK_ID_IKEY 0x59454B49 # define CHUNK_ID_IKEY 0x59454B49
# define CHUNK_ID_IMED 0x44525049 # define CHUNK_ID_IMED 0x44454D49
# define CHUNK_ID_INAM 0x4D414E49 # define CHUNK_ID_INAM 0x4D414E49
# define CHUNK_ID_IPRD 0x44525049 # define CHUNK_ID_IPRD 0x44525049
# define CHUNK_ID_ISBJ 0x4A425349 # define CHUNK_ID_ISBJ 0x4A425349
# define CHUNK_ID_ISFT 0x54465349 # define CHUNK_ID_ISFT 0x54465349
# define CHUNK_ID_ISRC 0x43525349 # define CHUNK_ID_ISRC 0x43525349
# define CHUNK_ID_ISRF 0x46525349 # define CHUNK_ID_ISRF 0x46525349
# define CHUNK_ID_ITCH 0x48435449 # define CHUNK_ID_ITCH 0x48435449
# define CHUNK_ID_VERS 0x73726576 # define CHUNK_ID_VERS 0x73726576
# define CHUNK_ID_DLID 0x64696C64 # define CHUNK_ID_DLID 0x64696C64
# define CHUNK_ID_FMT 0x20746D66 # define CHUNK_ID_FMT 0x20746D66
# define CHUNK_ID_DATA 0x61746164 # define CHUNK_ID_DATA 0x61746164
# define CHUNK_ID_INSH 0x68736E69 # define CHUNK_ID_INSH 0x68736E69
# define CHUNK_ID_RGNH 0x686E6772 # define CHUNK_ID_RGNH 0x686E6772
# define CHUNK_ID_WLNK 0x6B6E6C77 # define CHUNK_ID_WLNK 0x6B6E6C77
# define CHUNK_ID_PTBL 0x6C627470 # define CHUNK_ID_PTBL 0x6C627470
# define CHUNK_ID_WSMP 0x706D7377 # define CHUNK_ID_WSMP 0x706D7377
# define CHUNK_ID_COLH 0x686C6F63 # define CHUNK_ID_COLH 0x686C6F63
# define CHUNK_ID_ARTL 0x6C747261
# define CHUNK_ID_ART2 0x32747261
#endif // WORDS_BIGENDIAN #endif // WORDS_BIGENDIAN
#define WAVE_FORMAT_PCM 0x0001 #define DLS_WAVE_FORMAT_PCM 0x0001
#define DRUM_TYPE_MASK 0x00000001
#define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
#define F_WAVELINK_PHASE_MASTER 0x0001
#define F_WAVELINK_MULTICHANNEL 0x0002
#define F_WSMP_NO_TRUNCATION 0x0001
#define F_WSMP_NO_COMPRESSION 0x0002
#define MIDI_BANK_COARSE(x) ((x & 0x00007F00) >> 8)
// CC0
#define MIDI_BANK_FINE(x) (x & 0x0000007F)
// CC32
#define MIDI_BANK_MERGE(coarse, fine) ((((uint16_t) coarse) << 7) | fine)
// CC0 + CC32
#define CONN_TRANSFORM_SRC(x) ((x >> 10) & 0x000F)
#define CONN_TRANSFORM_CTL(x) ((x >> 4) & 0x000F)
#define CONN_TRANSFORM_DST(x) (x & 0x000F)
#define CONN_TRANSFORM_BIPOLAR_SRC(x) (x & 0x4000)
#define CONN_TRANSFORM_BIPOLAR_CTL(x) (x & 0x0100)
#define CONN_TRANSFORM_INVERT_SRC(x) (x & 0x8000)
#define CONN_TRANSFORM_INVERT_CTL(x) (x & 0x0200)
//TODO: no support for conditional chunks <cdl> yet //TODO: no support for conditional chunks <cdl> yet
/** DLS specific classes and definitions */ /** DLS specific classes and definitions */
namespace DLS { namespace DLS {
typedef std::string String; typedef std::string String;
/** Quadtuple version number ("major.minor.release.build"). */ /** Quadtuple version number ("major.minor.release.build"). */
struct version_t { struct version_t {
skipping to change at line 246 skipping to change at line 227
} conn_trn_t; } conn_trn_t;
/** Lower and upper limit of a range. */ /** Lower and upper limit of a range. */
struct range_t { struct range_t {
uint16_t low; ///< Low value of range. uint16_t low; ///< Low value of range.
uint16_t high; ///< High value of range. uint16_t high; ///< High value of range.
}; };
/** Defines Sample Loop Points. */ /** Defines Sample Loop Points. */
struct sample_loop_t { struct sample_loop_t {
uint32_t Size; uint32_t Size; ///< For internal usage only: usually reflects
uint32_t LoopType; exactly @c sizeof(sample_loop_t), otherwise if the value is larger then th
uint32_t LoopStart; e DLS format was extended!
uint32_t LoopLength; 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).
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.
uint32_t LoopLength; ///< Length of the looping area (in sample poi
nts).
}; };
// just symbol prototyping // just symbol prototyping
class File; class File;
class Instrument; class Instrument;
class Region; class Region;
class Sample; class Sample;
/** Defines a connection within the synthesis model. */ /** Defines a connection within the synthesis model. */
class Connection { class Connection {
skipping to change at line 280 skipping to change at line 261
conn_trn_t DestinationTransform; conn_trn_t DestinationTransform;
uint32_t Scale; uint32_t Scale;
protected: protected:
struct conn_block_t { struct conn_block_t {
uint16_t source; uint16_t source;
uint16_t control; uint16_t control;
uint16_t destination; uint16_t destination;
uint16_t transform; uint16_t transform;
uint32_t scale; uint32_t scale;
}; };
Connection() {}; Connection() {}
void Init(conn_block_t* Header); void Init(conn_block_t* Header);
virtual ~Connection() {}; conn_block_t ToConnBlock();
virtual ~Connection() {}
friend class Articulation; friend class Articulation;
}; };
/** Provides access to the defined connections used for the synthesis m odel. */ /** Provides access to the defined connections used for the synthesis m odel. */
class Articulation { class Articulation {
public: public:
Connection* pConnections; ///< Points to the beginning of a <i >Connection</i> array. Connection* pConnections; ///< Points to the beginning of a <i >Connection</i> array.
uint32_t Connections; ///< Reflects the number of Connecti ons. uint32_t Connections; ///< Reflects the number of Connecti ons.
Articulation(RIFF::List* artList);
Articulation(RIFF::Chunk* artl);
virtual ~Articulation(); virtual ~Articulation();
virtual void UpdateChunks();
protected:
RIFF::Chunk* pArticulationCk;
uint32_t HeaderSize;
}; };
/** Abstract base class for classes that provide articulation informati on (thus for <i>Instrument</i> and <i>Region</i> class). */ /** Abstract base class for classes that provide articulation informati on (thus for <i>Instrument</i> and <i>Region</i> class). */
class Articulator { class Articulator {
public: public:
Articulator(RIFF::List* ParentList); Articulator(RIFF::List* ParentList);
Articulation* GetFirstArticulation(); Articulation* GetFirstArticulation();
Articulation* GetNextArticulation(); Articulation* GetNextArticulation();
virtual void UpdateChunks();
protected: protected:
typedef std::list<Articulation*> ArticulationList; typedef std::list<Articulation*> ArticulationList;
RIFF::List* pParentList; RIFF::List* pParentList;
ArticulationList* pArticulations; ArticulationList* pArticulations;
ArticulationList::iterator ArticulationsIterator; ArticulationList::iterator ArticulationsIterator;
void LoadArticulations(); void LoadArticulations();
virtual ~Articulator(); virtual ~Articulator();
}; };
skipping to change at line 330 skipping to change at line 318
String Artists; ///< <IART-ck>. Lists the artist of th e original subject of the file. String Artists; ///< <IART-ck>. Lists the artist of th e original subject of the file.
String Genre; ///< <IGNR-ck>. Descirbes the original work, such as, Jazz, Classic, Rock, Techno, Rave, etc. String Genre; ///< <IGNR-ck>. Descirbes the original work, such as, Jazz, Classic, Rock, Techno, Rave, etc.
String Keywords; ///< <IKEY-ck>. Provides a list of key words that refer to the file or subject of the file. Keywords are separated with semicolon and blank, e.g., FX; death; murder. String Keywords; ///< <IKEY-ck>. Provides a list of key words that refer to the file or subject of the file. Keywords are separated with semicolon and blank, e.g., FX; death; murder.
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. 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.
String Technician; ///< <ITCH-ck>. Identifies the technic ian who sampled the subject file. String Technician; ///< <ITCH-ck>. Identifies the technic ian who sampled the subject file.
String Software; ///< <ISFT-ck>. Identifies the name of the sofware package used to create the file. String Software; ///< <ISFT-ck>. Identifies the name of the sofware package used to create the file.
String Medium; ///< <IMED-ck>. Describes the original subject of the file, such as, record, CD, and so forth. String Medium; ///< <IMED-ck>. Describes the original subject of the file, such as, record, CD, and so forth.
String Source; ///< <ISRC-ck>. Identifies the name of the person or organization who supplied the original subject of the file. String Source; ///< <ISRC-ck>. Identifies the name of the person or organization who supplied the original subject of the file.
String SourceForm; ///< <ISRF-ck>. Identifies the origina l 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 origina l 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 Commissioned; ///< <ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file, e.g., Pop e Julian II. String Commissioned; ///< <ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file, e.g., Pop e Julian II.
String Subject; ///< <ISBJ-ck>. Describes the contents
of the file.
bool UseFixedLengthStrings; ///< @deprecated Not used anymore,
use SetFixedStringLengths() instead.
struct string_length_t {
uint32_t chunkId;
int length;
};
Info(RIFF::List* list); Info(RIFF::List* list);
void SetFixedStringLengths(const string_length_t* lengths);
virtual ~Info();
virtual void UpdateChunks();
private: private:
inline void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, S RIFF::List* pResourceListChunk;
tring& s) { const string_length_t* pFixedStringLengths; ///< List of IDs an
RIFF::Chunk* ck = lstINFO->GetSubChunk(ChunkID); d string lengths for strings that should be stored in a fixed length format
if (ck) { . This is used for gig files, not for ordinary DLS files.
// TODO: no check for ZSTR terminated strings yet
s = (char*) ck->LoadChunkData(); static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, S
ck->ReleaseChunkData(); tring& s);
} void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const St
} ring& s, const String& sDefault);
}; };
/** Abstract base class which encapsulates data structures which all DL S resources are able to provide. */ /** Abstract base class which encapsulates data structures which all DL S resources are able to provide. */
class Resource { class Resource {
public: public:
Info* pInfo; ///< Points (in any case) to an <i>Info< Info* pInfo; ///< Points (in any case) to an <i>Info</i> ob
/i> object, providing additional, optional infos and comments. ject, providing additional, optional infos and comments.
dlsid_t* pDLSID; ///< Points to a <i>dlsid_t</i> structur dlsid_t* pDLSID; ///< Points to a <i>dlsid_t</i> structure if t
e if the file provided a DLS ID else is <i>NULL</i>. he file provided a DLS ID else is <i>NULL</i>.
Resource* GetParent() { return pParent; }; Resource* GetParent() { return pParent; }
virtual void UpdateChunks();
void GenerateDLSID();
protected: protected:
Resource* pParent; Resource* pParent;
RIFF::List* pResourceList;
Resource(Resource* Parent, RIFF::List* lstResource); Resource(Resource* Parent, RIFF::List* lstResource);
virtual ~Resource(); virtual ~Resource();
}; };
/** Abstract base class which provides mandatory informations about sam ple players in general. */ /** Abstract base class which provides mandatory informations about sam ple players in general. */
class Sampler { class Sampler {
public: public:
uint8_t UnityNote; uint8_t UnityNote;
int16_t FineTune; int16_t FineTune;
int32_t Gain; int32_t Gain; ///< @deprecated Don't alter directly, use SetGain() instead!
bool NoSampleDepthTruncation; bool NoSampleDepthTruncation;
bool NoSampleCompression; bool NoSampleCompression;
uint32_t SampleLoops; ///< Reflects the numb uint32_t SampleLoops; ///< Reflects the number of sample
er of sample loops. loops.
sample_loop_t* pSampleLoops; ///< Points to the beg sample_loop_t* pSampleLoops; ///< Points to the beginning of a
inning of a sample loop array, or is NULL if there are no loops defined. sample loop array, or is NULL if there are no loops defined.
void AddSampleLoop(sample_loop_t* pLoopDef);
void DeleteSampleLoop(sample_loop_t* pLoopDef);
virtual void SetGain(int32_t gain);
virtual void UpdateChunks();
protected: protected:
RIFF::List* pParentList;
uint32_t uiHeaderSize;
uint32_t SamplerOptions; uint32_t SamplerOptions;
Sampler(RIFF::List* ParentList); Sampler(RIFF::List* ParentList);
virtual ~Sampler(); virtual ~Sampler();
}; };
/** Encapsulates sample waves used for playback. */ /** @brief Encapsulates sample waves used for playback.
*
* In case you created a new sample with File::AddSample(), you should
* first update all attributes with the desired meta informations
* (amount of channels, bit depth, sample rate, etc.), then call
* Resize() with the desired sample size. The latter will create
* the mandatory RIFF chunk which will hold the sample wave data.
*/
class Sample : public Resource { class Sample : public Resource {
public: public:
uint16_t FormatTag; ///< Format ID of the wave uint16_t FormatTag; ///< Format ID of the wave
form data (should be WAVE_FORMAT_PCM for DLS1 compliant files). form data (should be DLS_WAVE_FORMAT_PCM for DLS1 compliant files, this is
uint16_t Channels; ///< Number of channels re also the default value if Sample was created with Instrument::AddSample()).
presented in the waveform data, e.g. 1 for mono, 2 for stereo (). uint16_t Channels; ///< Number of channels re
uint32_t SamplesPerSecond; ///< Sampling rate at whic presented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to
h each channel should be played. 1=mono if Sample was created with Instrument::AddSample() previously).
uint32_t SamplesPerSecond; ///< Sampling rate at whic
h each channel should be played (defaults to 44100 if Sample was created wi
th Instrument::AddSample() previously).
uint32_t AverageBytesPerSecond; ///< The average number of bytes per second at which the waveform data should be transferred (Playbac k 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 (Playbac k software can estimate the buffer size using this value).
uint16_t BlockAlign; ///< The block alignment ( in bytes) of the waveform data. Playback software needs to process a multip le of <i>BlockAlign</i> bytes of data at a time, so the value of <i>BlockAl ign</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 multip le of <i>BlockAlign</i> bytes of data at a time, so the value of <i>BlockAl ign</i> can be used for buffer alignment.
uint16_t BitDepth; ///< Size of each sample p er channel (only if known sample data format is used, 0 otherwise). uint16_t BitDepth; ///< Size of each sample p er channel (only if known sample data format is used, 0 otherwise).
unsigned long SamplesTotal; ///< Reflects total number unsigned long SamplesTotal; ///< Reflects total number
of samples (only if known sample data format is used, 0 otherwise). of sample points (only if known sample data format is used, 0 otherwise),
uint FrameSize; ///< Reflects the size (in do not bother to change this value, it will not be saved.
bytes) of one single sample (only if known sample data format is used, 0 o uint FrameSize; ///< Reflects the size (in
therwise). bytes) of one single sample point (only if known sample data format is use
d, 0 otherwise). <b>Caution:</b> with the current version of libgig you hav
e 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().
void* LoadSampleData(); ///< Load sample d void* LoadSampleData();
ata into RAM. Returns a pointer to the data in RAM on success, <i>NULL</i> void ReleaseSampleData();
otherwise. unsigned long GetSize();
void ReleaseSampleData(); ///< Release the s void Resize(int iNewSize);
amples once you used them if you don't want to be bothered to.
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_wh ence_t Whence = RIFF::stream_start); unsigned long SetPos(unsigned long SampleCount, RIFF::stream_wh ence_t Whence = RIFF::stream_start);
unsigned long Read(void* pBuffer, unsigned long SampleCount); unsigned long Read(void* pBuffer, unsigned long SampleCount);
unsigned long Write(void* pBuffer, unsigned long SampleCount);
virtual void UpdateChunks();
protected: protected:
RIFF::List* pWaveList;
RIFF::Chunk* pCkData; RIFF::Chunk* pCkData;
RIFF::Chunk* pCkFormat; RIFF::Chunk* pCkFormat;
unsigned long ulWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments unsigned long ulWavePoolOffset; // needed for comparison with the wave pool link table, thus the link to instruments
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoo lOffset); Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoo lOffset);
virtual ~Sample();
friend class File; friend class File;
friend class Region; // Region has to compare the wave pool off set to get its sample friend class Region; // Region has to compare the wave pool off set to get its sample
}; };
/** Defines <i>Region</i> information of an <i>Instrument</i>. */ /** Defines <i>Region</i> information of an <i>Instrument</i>. */
class Region : public Resource, public Articulator, public Sampler { class Region : public Resource, public Articulator, public Sampler {
public: public:
range_t KeyRange; range_t KeyRange; ///< @deprecated Only read, don't write! Use SetKeyRange() instead.
range_t VelocityRange; range_t VelocityRange;
uint16_t KeyGroup; uint16_t KeyGroup;
uint16_t Layer; uint16_t Layer;
bool SelfNonExclusive; bool SelfNonExclusive;
bool PhaseMaster; bool PhaseMaster;
uint16_t PhaseGroup; uint16_t PhaseGroup;
bool MultiChannel; bool MultiChannel;
uint32_t Channel; uint32_t Channel;
Sample* GetSample(); Sample* GetSample();
void SetSample(Sample* pSample);
virtual void SetKeyRange(uint16_t Low, uint16_t High);
virtual void UpdateChunks();
protected: protected:
RIFF::List* pCkRegion; RIFF::List* pCkRegion;
uint32_t WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to uint32_t WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to
Sample* pSample; // every region refers to exact ly one sample Sample* pSample; // every region refers to exact ly one sample
uint16_t FormatOptionFlags;
uint16_t WaveLinkOptionFlags;
Region(Instrument* pInstrument, RIFF::List* rgnList); Region(Instrument* pInstrument, RIFF::List* rgnList);
virtual ~Region(); virtual ~Region();
friend class Instrument; friend class Instrument;
}; };
/** Provides all neccessary information for the synthesis of a DLS <i>I nstrument</i>. */ /** Provides all neccessary information for the synthesis of a DLS <i>I nstrument</i>. */
class Instrument : public Resource, public Articulator { class Instrument : public Resource, public Articulator {
public: public:
bool IsDrum; ///< Indicates if the <i>Instrument</i > is a drum type, as they differ in the synthesis model of DLS from melodic instruments. bool IsDrum; ///< Indicates if the <i>Instrument</i > is a drum type, as they differ in the synthesis model of DLS from melodic instruments.
uint16_t MIDIBank; ///< Reflects combination of <i>MIDIBa nkCoarse</i> and <i>MIDIBankFine</i> (bank 1 - bank 16384). uint16_t MIDIBank; ///< Reflects combination of <i>MIDIBa nkCoarse</i> and <i>MIDIBankFine</i> (bank 1 - bank 16384). Do not change t his value, it will not be saved! Change MIDIBankCoarse and MIDIBankFine ins tead (we might change that in future).
uint8_t MIDIBankCoarse; ///< Reflects the MIDI Bank number for MIDI Control Change 0 (bank 1 - 128). uint8_t MIDIBankCoarse; ///< Reflects the MIDI Bank number for MIDI Control Change 0 (bank 1 - 128).
uint8_t MIDIBankFine; ///< Reflects the MIDI Bank number for MIDI Control Change 32 (bank 1 - 128). uint8_t MIDIBankFine; ///< Reflects the MIDI Bank number for MIDI Control Change 32 (bank 1 - 128).
uint32_t MIDIProgram; ///< Specifies the MIDI Program Change Number this Instrument should be assigned to. uint32_t MIDIProgram; ///< Specifies the MIDI Program Change Number this Instrument should be assigned to.
uint32_t Regions; ///< Reflects the number of <i>Region< /i> defintions this Instrument has. uint32_t Regions; ///< Reflects the number of <i>Region< /i> defintions this Instrument has.
Region* GetFirstRegion(); Region* GetFirstRegion();
Region* GetNextRegion(); Region* GetNextRegion();
Region* AddRegion();
void DeleteRegion(Region* pRegion);
virtual void UpdateChunks();
protected: protected:
typedef std::list<Region*> RegionList; typedef std::list<Region*> RegionList;
struct midi_locale_t { struct midi_locale_t {
uint32_t bank; uint32_t bank;
uint32_t instrument; uint32_t instrument;
}; };
RIFF::List* pCkInstrument; RIFF::List* pCkInstrument;
RegionList* pRegions; RegionList* pRegions;
RegionList::iterator RegionsIterator; RegionList::iterator RegionsIterator;
Instrument(File* pFile, RIFF::List* insList); Instrument(File* pFile, RIFF::List* insList);
void LoadRegions(); virtual void LoadRegions();
virtual ~Instrument(); virtual ~Instrument();
friend class File; friend class File;
friend class Region;
private:
void MoveRegion(Region* pSrc, Region* pDst);
}; };
/** Parses DLS Level 1 and 2 compliant files and provides abstract acce ss to the data. */ /** Parses DLS Level 1 and 2 compliant files and provides abstract acce ss to the data. */
class File : public Resource { class File : public Resource {
public: public:
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>. 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>.
uint32_t Instruments; ///< Reflects the number of a vailable <i>Instrument</i> objects. uint32_t Instruments; ///< Reflects the number of a vailable <i>Instrument</i> objects.
File();
File(RIFF::File* pRIFF); File(RIFF::File* pRIFF);
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.
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.
Sample* AddSample();
void DeleteSample(Sample* pSample);
Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <i>Instrument</i> object of the file, <i>NULL</i> otherwise. Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <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. Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise.
Instrument* AddInstrument();
void DeleteInstrument(Instrument* pInstrument);
virtual void UpdateChunks();
virtual void Save(const String& Path);
virtual void Save();
virtual ~File(); virtual ~File();
protected: protected:
typedef std::list<Sample*> SampleList; typedef std::list<Sample*> SampleList;
typedef std::list<Instrument*> InstrumentList; typedef std::list<Instrument*> InstrumentList;
RIFF::File* pRIFF; RIFF::File* pRIFF;
std::list<RIFF::File*> ExtensionFiles;
SampleList* pSamples; SampleList* pSamples;
SampleList::iterator SamplesIterator; SampleList::iterator SamplesIterator;
InstrumentList* pInstruments; InstrumentList* pInstruments;
InstrumentList::iterator InstrumentsIterator; InstrumentList::iterator InstrumentsIterator;
uint32_t WavePoolHeaderSize;
uint32_t WavePoolCount; uint32_t WavePoolCount;
uint32_t* pWavePoolTable; uint32_t* pWavePoolTable;
uint32_t* pWavePoolTableHi;
bool b64BitWavePoolOffsets;
void LoadSamples(); virtual void LoadSamples();
void LoadInstruments(); virtual void LoadInstruments();
void __ensureMandatoryChunksExist();
friend class Region; // Region has to look in the wave pool tab le to get its sample friend class Region; // Region has to look in the wave pool tab le to get its sample
private:
void __UpdateWavePoolTableChunk();
void __UpdateWavePoolTable();
}; };
/** Will be thrown whenever a DLS specific error occurs while trying to /**
access a DLS File. */ * Will be thrown whenever a DLS specific error occurs while trying to
* access a DLS File. Note: In your application you should better catch
* for RIFF::Exception rather than this one, except you explicitly want
* to catch and handle DLS::Exception and RIFF::Exception independently
,
* which usually shouldn't be necessary though.
*/
class Exception : public RIFF::Exception { class Exception : public RIFF::Exception {
public: public:
Exception(String Message); Exception(String Message);
void PrintMessage(); void PrintMessage();
}; };
String libraryName(); String libraryName();
String libraryVersion(); String libraryVersion();
} // namespace DLS } // namespace DLS
 End of changes. 48 change blocks. 
82 lines changed or deleted 146 lines changed or added


 RIFF.h   RIFF.h 
/************************************************************************** * /************************************************************************** *
* * * *
* libgig - C++ cross-platform Gigasampler format file loader library * * libgig - C++ cross-platform Gigasampler format file access library *
* * * *
* Copyright (C) 2003-2005 by Christian Schoenebeck * * Copyright (C) 2003-2009 by Christian Schoenebeck *
* <cuse@users.sourceforge.net> * * <cuse@users.sourceforge.net> *
* * * *
* This library is free software; you can redistribute it and/or modify * * This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This library is distributed in the hope that it will be useful, * * This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
skipping to change at line 27 skipping to change at line 27
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this library; if not, write to the Free Software * * along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA * * MA 02111-1307 USA *
************************************************************************** */ ************************************************************************** */
#ifndef __RIFF_H__ #ifndef __RIFF_H__
#define __RIFF_H__ #define __RIFF_H__
#define POSIX 1 #ifdef WIN32
#define DEBUG 0 # define POSIX 0
#endif
#ifndef POSIX
# define POSIX 1
#endif
#ifndef DEBUG
# define DEBUG 0
#endif
#include <string> #include <string>
#include <list> #include <list>
#include <map> #include <map>
#include <iostream> #include <iostream>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#if POSIX #if POSIX
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
#endif // POSIX #endif // POSIX
#ifdef _MSC_VER
// Visual C++ 2008 doesn't have stdint.h
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h> #include <stdint.h>
#endif
//typedef unsigned char uint8_t; #ifdef WIN32
//typedef unsigned short uint16_t; # include <windows.h>
//typedef unsigned int uint32_t; typedef unsigned int uint;
#endif // WIN32
#include <stdio.h> #include <stdio.h>
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
# define CHUNK_ID_RIFF 0x52494646 # define CHUNK_ID_RIFF 0x52494646
# define CHUNK_ID_RIFX 0x52494658 # define CHUNK_ID_RIFX 0x52494658
# define CHUNK_ID_LIST 0x4C495354 # define CHUNK_ID_LIST 0x4C495354
#else // little endian #else // little endian
# define CHUNK_ID_RIFF 0x46464952 # define CHUNK_ID_RIFF 0x46464952
# define CHUNK_ID_RIFX 0x58464952 # define CHUNK_ID_RIFX 0x58464952
# define CHUNK_ID_LIST 0x5453494C # define CHUNK_ID_LIST 0x5453494C
#endif // WORDS_BIGENDIAN #endif // WORDS_BIGENDIAN
#define CHUNK_HEADER_SIZE 8 #define CHUNK_HEADER_SIZE 8
#define LIST_HEADER_SIZE 12 #define LIST_HEADER_SIZE 12
#define RIFF_HEADER_SIZE 12 #define RIFF_HEADER_SIZE 12
/** RIFF specific classes and definitions */ /**
* @brief RIFF specific classes and definitions
*
* The Resource Interchange File Format (RIFF) is a generic tree-structured
* meta-format which stores data in so called "chunks". It can be compared
* to XML, but in contrast to XML, RIFF is entirely binary encoded, that is
* not ASCII based. RIFF is used as basis for many file formats like AVI,
* WAV, DLS and of course the Gigasampler file format. ;-)
*
* RIFF chunks can be seen as containers for data. There are two distinct
* types of chunks:
*
* - @e ordinary @e chunks are the leafs of the data tree which encapsulate
* the actual data of the file (i.e. the sample data of a .wav file)
*
* - @e list @e chunks are the nodes of the data tree which hold an
* arbitrary amount of subchunks (can be both, list chunks and/or ordinar
y
* chunks)
*/
namespace RIFF { namespace RIFF {
/* just symbol prototyping */ /* just symbol prototyping */
class Chunk; class Chunk;
class List; class List;
class File;
typedef std::string String; typedef std::string String;
/** Whether file stream is open in read or in read/write mode. */
typedef enum {
stream_mode_read = 0,
stream_mode_read_write = 1,
stream_mode_closed = 2
} stream_mode_t;
/** Current state of the file stream. */ /** Current state of the file stream. */
typedef enum { typedef enum {
stream_ready = 0, stream_ready = 0,
stream_end_reached = 1, stream_end_reached = 1,
stream_closed = 2 stream_closed = 2
} stream_state_t; } stream_state_t;
/** File stream position dependent to these relations. */ /** File stream position dependent to these relations. */
typedef enum { typedef enum {
stream_start = 0, stream_start = 0,
stream_curpos = 1, stream_curpos = 1,
stream_backward = 2, stream_backward = 2,
stream_end = 3 stream_end = 3
} stream_whence_t; } stream_whence_t;
/** Provides convenient methods to access data of RIFF chunks in genera /** Alignment of data bytes in memory (system dependant). */
l. */ typedef enum {
endian_little = 0,
endian_big = 1,
endian_native = 2
} endian_t;
/** @brief Ordinary RIFF Chunk
*
* Provides convenient methods to access data of ordinary RIFF chunks
* in general.
*/
class Chunk { class Chunk {
public: public:
#if POSIX Chunk(File* pFile, unsigned long StartPos, List* Parent);
Chunk(int hFile, unsigned long StartPos, bool EndianNative, Lis
t* Parent);
#else
Chunk(FILE* hFile, unsigned long StartPos, bool EndianNative, L
ist* Parent);
#endif // POSIX
String GetChunkIDString(); String GetChunkIDString();
uint32_t GetChunkID() { return ChunkID; }; /// uint32_t GetChunkID() { return ChunkID; } ///
< Chunk ID in unsigned integer representation. < Chunk ID in unsigned integer representation.
List* GetParent() { return pParent; }; /// List* GetParent() { return pParent; } ///
< Returns pointer to the chunk's parent list chunk. < Returns pointer to the chunk's parent list chunk.
unsigned long GetSize() { return ChunkSize; }; /// unsigned long GetSize() { return CurrentChunkSize; } ///
< Chunk size in bytes (without header, thus the chunk data body) < Chunk size in bytes (without header, thus the chunk data body)
unsigned long GetPos() { return ulPos; }; /// unsigned long GetNewSize() { return NewChunkSize; } ///
< Position within the chunk data body < New chunk size if it was modified with Resize().
unsigned long GetFilePos() { return ulStartPos + ulPos; }; /// unsigned long GetPos() { return ulPos; } ///
< Current, actual offset in file. < Position within the chunk data body
unsigned long GetFilePos() { return ulStartPos + ulPos; } ///
< Current, actual offset in file.
unsigned long SetPos(unsigned long Where, stream_whence_t When ce = stream_start); unsigned long SetPos(unsigned long Where, stream_whence_t When ce = stream_start);
unsigned long RemainingBytes(); unsigned long RemainingBytes();
stream_state_t GetState(); stream_state_t GetState();
unsigned long Read(void* pData, unsigned long WordCount, unsig ned long WordSize); unsigned long Read(void* pData, unsigned long WordCount, unsig ned long WordSize);
unsigned long ReadInt8(int8_t* pData, unsigned long WordCo unt = 1); unsigned long ReadInt8(int8_t* pData, unsigned long WordCo unt = 1);
unsigned long ReadUint8(uint8_t* pData, unsigned long WordCo unt = 1); unsigned long ReadUint8(uint8_t* pData, unsigned long WordCo unt = 1);
unsigned long ReadInt16(int16_t* pData, unsigned long WordCo unt = 1); unsigned long ReadInt16(int16_t* pData, unsigned long WordCo unt = 1);
unsigned long ReadUint16(uint16_t* pData, unsigned long WordCo unt = 1); unsigned long ReadUint16(uint16_t* pData, unsigned long WordCo unt = 1);
unsigned long ReadInt32(int32_t* pData, unsigned long WordCo unt = 1); unsigned long ReadInt32(int32_t* pData, unsigned long WordCo unt = 1);
unsigned long ReadUint32(uint32_t* pData, unsigned long WordCo unt = 1); unsigned long ReadUint32(uint32_t* pData, unsigned long WordCo unt = 1);
int8_t ReadInt8(); int8_t ReadInt8();
uint8_t ReadUint8(); uint8_t ReadUint8();
int16_t ReadInt16(); int16_t ReadInt16();
uint16_t ReadUint16(); uint16_t ReadUint16();
int32_t ReadInt32(); int32_t ReadInt32();
uint32_t ReadUint32(); uint32_t ReadUint32();
void* LoadChunkData(); ///< Load the whole chunk b unsigned long Write(void* pData, unsigned long WordCount, unsi
ody in memory (on success returns a pointer to the data in RAM, else NULL). gned long WordSize);
void ReleaseChunkData(); ///< Free loaded chunk body unsigned long WriteInt8(int8_t* pData, unsigned long WordC
data from memory (RAM). ount = 1);
unsigned long WriteUint8(uint8_t* pData, unsigned long WordC
ount = 1);
unsigned long WriteInt16(int16_t* pData, unsigned long WordC
ount = 1);
unsigned long WriteUint16(uint16_t* pData, unsigned long WordC
ount = 1);
unsigned long WriteInt32(int32_t* pData, unsigned long WordC
ount = 1);
unsigned long WriteUint32(uint32_t* pData, unsigned long WordC
ount = 1);
void* LoadChunkData();
void ReleaseChunkData();
void Resize(int iNewSize);
virtual ~Chunk(); virtual ~Chunk();
protected: protected:
uint32_t ChunkID; uint32_t ChunkID;
uint32_t ChunkSize; /* in bytes */ uint32_t CurrentChunkSize; /* in bytes */
uint32_t NewChunkSize; /* in bytes
(if chunk was scheduled to be resized) */
List* pParent; List* pParent;
#if POSIX File* pFile;
int hFile;
#else
FILE* hFile;
#endif // POSIX
unsigned long ulStartPos; /* actual position in file w here chunk (without header) starts */ unsigned long ulStartPos; /* actual position in file w here chunk (without header) starts */
unsigned long ulPos; /* # of bytes from ulStartPo s */ unsigned long ulPos; /* # of bytes from ulStartPo s */
bool bEndianNative;
uint8_t* pChunkData; uint8_t* pChunkData;
unsigned long ulChunkDataSize;
Chunk(); Chunk(File* pFile);
Chunk(File* pFile, List* pParent, uint32_t uiChunkID, uint uiBo
dySize);
void ReadHeader(unsigned long fPos); void ReadHeader(unsigned long fPos);
void WriteHeader(unsigned long fPos);
unsigned long ReadSceptical(void* pData, unsigned long WordCoun t, unsigned long WordSize); unsigned long ReadSceptical(void* pData, unsigned long WordCoun t, unsigned long WordSize);
inline void swapBytes_16(void* Word) { inline void swapBytes_16(void* Word) {
uint8_t byteCache = *((uint8_t*) Word); uint8_t byteCache = *((uint8_t*) Word);
*((uint8_t*) Word) = *((uint8_t*) Word + 1); *((uint8_t*) Word) = *((uint8_t*) Word + 1);
*((uint8_t*) Word + 1) = byteCache; *((uint8_t*) Word + 1) = byteCache;
} }
inline void swapBytes_32(void* Word) { inline void swapBytes_32(void* Word) {
uint8_t byteCache = *((uint8_t*) Word); uint8_t byteCache = *((uint8_t*) Word);
*((uint8_t*) Word) = *((uint8_t*) Word + 3); *((uint8_t*) Word) = *((uint8_t*) Word + 3);
*((uint8_t*) Word + 3) = byteCache; *((uint8_t*) Word + 3) = byteCache;
skipping to change at line 173 skipping to change at line 236
} }
inline String convertToString(uint32_t word) { inline String convertToString(uint32_t word) {
String result; String result;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
uint8_t byte = *((uint8_t*)(&word) + i); uint8_t byte = *((uint8_t*)(&word) + i);
char c = byte; char c = byte;
result += c; result += c;
} }
return result; return result;
} }
virtual unsigned long WriteChunk(unsigned long ulWritePos, unsi
gned long ulCurrentDataOffset);
virtual void __resetPos(); ///< Sets Chunk's read/write positio
n to zero.
friend class List;
}; };
/** Provides convenient methods to access data of RIFF list chunks and /** @brief RIFF List Chunk
their subchunks. */ *
* Provides convenient methods to access data of RIFF list chunks and
* their subchunks.
*/
class List : public Chunk { class List : public Chunk {
public: public:
#if POSIX List(File* pFile, unsigned long StartPos, List* Parent);
List(int hFile, unsigned long StartPos, bool EndianNative, List
* Parent);
#else
List(FILE* hFile, unsigned long StartPos, bool EndianNative, Li
st* Parent);
#endif // POSIX
String GetListTypeString(); String GetListTypeString();
uint32_t GetListType() { return ListType; } ///< Returns unsigned integer representation of the list's ID uint32_t GetListType() { return ListType; } ///< Returns unsigned integer representation of the list's ID
Chunk* GetSubChunk(uint32_t ChunkID); Chunk* GetSubChunk(uint32_t ChunkID);
List* GetSubList(uint32_t ListType); List* GetSubList(uint32_t ListType);
Chunk* GetFirstSubChunk(); Chunk* GetFirstSubChunk();
Chunk* GetNextSubChunk(); Chunk* GetNextSubChunk();
List* GetFirstSubList(); List* GetFirstSubList();
List* GetNextSubList(); List* GetNextSubList();
unsigned int CountSubChunks(); unsigned int CountSubChunks();
unsigned int CountSubChunks(uint32_t ChunkID); unsigned int CountSubChunks(uint32_t ChunkID);
unsigned int CountSubLists(); unsigned int CountSubLists();
unsigned int CountSubLists(uint32_t ListType); unsigned int CountSubLists(uint32_t ListType);
Chunk* AddSubChunk(uint32_t uiChunkID, uint uiBodySize);
List* AddSubList(uint32_t uiListType);
void DeleteSubChunk(Chunk* pSubChunk);
void MoveSubChunk(Chunk* pSrc, Chunk* pDst);
virtual ~List(); virtual ~List();
protected: protected:
typedef std::map<uint32_t, RIFF::Chunk*> ChunkMap; typedef std::map<uint32_t, RIFF::Chunk*> ChunkMap;
typedef std::list<Chunk*> ChunkList; typedef std::list<Chunk*> ChunkList;
uint32_t ListType; uint32_t ListType;
ChunkList* pSubChunks; ChunkList* pSubChunks;
ChunkMap* pSubChunksMap; ChunkMap* pSubChunksMap;
ChunkList::iterator ChunksIterator; ChunkList::iterator ChunksIterator;
ChunkList::iterator ListIterator; ChunkList::iterator ListIterator;
List(); List(File* pFile);
List(File* pFile, List* pParent, uint32_t uiListID);
void ReadHeader(unsigned long fPos); void ReadHeader(unsigned long fPos);
void WriteHeader(unsigned long fPos);
void LoadSubChunks(); void LoadSubChunks();
void LoadSubChunksRecursively();
virtual unsigned long WriteChunk(unsigned long ulWritePos, unsi
gned long ulCurrentDataOffset);
virtual void __resetPos(); ///< Sets List Chunk's read/write po
sition to zero and causes all sub chunks to do the same.
void DeleteChunkList();
}; };
/** Parses arbitrary RIFF files and provides together with it's base cl /** @brief RIFF File
asses convenient methods to walk through the RIFF tree. */ *
* Handles arbitrary RIFF files and provides together with its base
* classes convenient methods to walk through, read and modify the
* file's RIFF tree.
*/
class File : public List { class File : public List {
public: public:
File(uint32_t FileType);
File(const String& path); File(const String& path);
stream_mode_t GetMode();
bool SetMode(stream_mode_t NewMode);
void SetByteOrder(endian_t Endian);
String GetFileName();
virtual void Save();
virtual void Save(const String& path);
virtual ~File(); virtual ~File();
protected:
#if POSIX
int hFileRead; ///< handle / descriptor for reading from fi
le
int hFileWrite; ///< handle / descriptor for writing to (som
e) file
#elif defined(WIN32)
HANDLE hFileRead; ///< handle / descriptor for reading from fi
le
HANDLE hFileWrite; ///< handle / descriptor for writing to (som
e) file
#else
FILE* hFileRead; ///< handle / descriptor for reading from fi
le
FILE* hFileWrite; ///< handle / descriptor for writing to (som
e) file
#endif // POSIX
String Filename;
bool bEndianNative;
void LogAsResized(Chunk* pResizedChunk);
void UnlogResized(Chunk* pResizedChunk);
friend class Chunk;
friend class List;
private: private:
stream_mode_t Mode;
ChunkList ResizedChunks; ///< All chunks which have been resize
d (enlarged / shortened).
unsigned long GetFileSize(); unsigned long GetFileSize();
void ResizeFile(unsigned long ulNewSize);
#if POSIX
unsigned long __GetFileSize(int hFile);
#elif defined(WIN32)
unsigned long __GetFileSize(HANDLE hFile);
#else
unsigned long __GetFileSize(FILE* hFile);
#endif
}; };
/** Will be thrown whenever an error occurs while parsing a RIFF file. /**
*/ * Will be thrown whenever an error occurs while handling a RIFF file.
*/
class Exception { class Exception {
public: public:
String Message; String Message;
Exception(String Message) { Exception::Message = Message; }; Exception(String Message) { Exception::Message = Message; }
void PrintMessage(); void PrintMessage();
virtual ~Exception() {}; virtual ~Exception() {}
}; };
String libraryName(); String libraryName();
String libraryVersion(); String libraryVersion();
} // namespace RIFF } // namespace RIFF
#endif // __RIFF_H__ #endif // __RIFF_H__
 End of changes. 35 change blocks. 
55 lines changed or deleted 187 lines changed or added


 gig.h   gig.h 
/************************************************************************** * /************************************************************************** *
* * * *
* libgig - C++ cross-platform Gigasampler format file loader library * * libgig - C++ cross-platform Gigasampler format file access library *
* * * *
* Copyright (C) 2003-2005 by Christian Schoenebeck * * Copyright (C) 2003-2009 by Christian Schoenebeck *
* <cuse@users.sourceforge.net> * * <cuse@users.sourceforge.net> *
* * * *
* This library is free software; you can redistribute it and/or modify * * This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This library is distributed in the hope that it will be useful, * * This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
skipping to change at line 29 skipping to change at line 29
* along with this library; if not, write to the Free Software * * along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA * * MA 02111-1307 USA *
************************************************************************** */ ************************************************************************** */
#ifndef __GIG_H__ #ifndef __GIG_H__
#define __GIG_H__ #define __GIG_H__
#include "DLS.h" #include "DLS.h"
#include <math.h>
#include <string.h>
/// Initial size of the sample buffer which is used for decompression of
/// compressed sample wave streams - this value should always be bigger tha
n
/// the biggest sample piece expected to be read by the sampler engine,
/// otherwise the buffer size will be raised at runtime and thus the buffer
/// reallocated which is time consuming and unefficient.
#define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
# define LIST_TYPE_3PRG 0x33707267 # define LIST_TYPE_3PRG 0x33707267
# define LIST_TYPE_3EWL 0x3365776C # define LIST_TYPE_3EWL 0x3365776C
# define LIST_TYPE_3GRI 0x33677269
# define LIST_TYPE_3GNL 0x33676E6C
# define CHUNK_ID_SMPL 0x736D706C # define CHUNK_ID_SMPL 0x736D706C
# define CHUNK_ID_3GIX 0x33676978 # define CHUNK_ID_3GIX 0x33676978
# define CHUNK_ID_3EWA 0x33657761 # define CHUNK_ID_3EWA 0x33657761
# define CHUNK_ID_3LNK 0x336C6E6B # define CHUNK_ID_3LNK 0x336C6E6B
# define CHUNK_ID_3EWG 0x33657767 # define CHUNK_ID_3EWG 0x33657767
# define CHUNK_ID_EWAV 0x65776176 # define CHUNK_ID_EWAV 0x65776176
# define CHUNK_ID_3GNM 0x33676E6D
# define CHUNK_ID_EINF 0x65696E66
# define CHUNK_ID_3CRC 0x33637263
#else // little endian #else // little endian
# define LIST_TYPE_3PRG 0x67727033 # define LIST_TYPE_3PRG 0x67727033
# define LIST_TYPE_3EWL 0x6C776533 # define LIST_TYPE_3EWL 0x6C776533
# define LIST_TYPE_3GRI 0x69726733
# define LIST_TYPE_3GNL 0x6C6E6733
# define CHUNK_ID_SMPL 0x6C706D73 # define CHUNK_ID_SMPL 0x6C706D73
# define CHUNK_ID_3GIX 0x78696733 # define CHUNK_ID_3GIX 0x78696733
# define CHUNK_ID_3EWA 0x61776533 # define CHUNK_ID_3EWA 0x61776533
# define CHUNK_ID_3LNK 0x6B6E6C33 # define CHUNK_ID_3LNK 0x6B6E6C33
# define CHUNK_ID_3EWG 0x67776533 # define CHUNK_ID_3EWG 0x67776533
# define CHUNK_ID_EWAV 0x76617765 # define CHUNK_ID_EWAV 0x76617765
# define CHUNK_ID_3GNM 0x6D6E6733
# define CHUNK_ID_EINF 0x666E6965
# define CHUNK_ID_3CRC 0x63726333
#endif // WORDS_BIGENDIAN #endif // WORDS_BIGENDIAN
/** (so far) every exponential paramater in the gig format has a basis of 1
.000000008813822 */
#define GIG_EXP_DECODE(x) (pow(1.00000
0008813822, x))
#define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01)
)
#define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) &
0x03)
#define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) &
0x03)
#define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) &
0x03)
#define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x
>> 5) & 0x03)
/** Gigasampler specific classes and definitions */ /** Gigasampler specific classes and definitions */
namespace gig { namespace gig {
typedef std::string String; typedef std::string String;
/** Lower and upper limit of a range. */ /** Lower and upper limit of a range. */
struct range_t { struct range_t {
uint8_t low; ///< Low value of range. uint8_t low; ///< Low value of range.
uint8_t high; ///< High value of range. uint8_t high; ///< High value of range.
}; };
skipping to change at line 151 skipping to change at line 143
lfo1_ctrl_internal = 0x00, ///< Only internally controll ed. lfo1_ctrl_internal = 0x00, ///< Only internally controll ed.
lfo1_ctrl_modwheel = 0x01, ///< Only controlled by exter nal modulation wheel. lfo1_ctrl_modwheel = 0x01, ///< Only controlled by exter nal modulation wheel.
lfo1_ctrl_breath = 0x02, ///< Only controlled by exter nal breath controller. lfo1_ctrl_breath = 0x02, ///< Only controlled by exter nal breath controller.
lfo1_ctrl_internal_modwheel = 0x03, ///< Controlled internally an d by external modulation wheel. lfo1_ctrl_internal_modwheel = 0x03, ///< Controlled internally an d by external modulation wheel.
lfo1_ctrl_internal_breath = 0x04 ///< Controlled internally an d by external breath controller. lfo1_ctrl_internal_breath = 0x04 ///< Controlled internally an d by external breath controller.
} lfo1_ctrl_t; } lfo1_ctrl_t;
/** Defines how the filter cutoff frequency is controlled by. */ /** Defines how the filter cutoff frequency is controlled by. */
typedef enum { typedef enum {
vcf_cutoff_ctrl_none = 0x00, vcf_cutoff_ctrl_none = 0x00,
vcf_cutoff_ctrl_none2 = 0x01, ///< The difference between n one and none2 is unknown
vcf_cutoff_ctrl_modwheel = 0x81, ///< Modulation Wheel (MIDI C ontroller 1) vcf_cutoff_ctrl_modwheel = 0x81, ///< Modulation Wheel (MIDI C ontroller 1)
vcf_cutoff_ctrl_effect1 = 0x8c, ///< Effect Controller 1 (Coa rse, MIDI Controller 12) vcf_cutoff_ctrl_effect1 = 0x8c, ///< Effect Controller 1 (Coa rse, MIDI Controller 12)
vcf_cutoff_ctrl_effect2 = 0x8d, ///< Effect Controller 2 (Coa rse, MIDI Controller 13) vcf_cutoff_ctrl_effect2 = 0x8d, ///< Effect Controller 2 (Coa rse, MIDI Controller 13)
vcf_cutoff_ctrl_breath = 0x82, ///< Breath Controller (Coars e, MIDI Controller 2) vcf_cutoff_ctrl_breath = 0x82, ///< Breath Controller (Coars e, MIDI Controller 2)
vcf_cutoff_ctrl_foot = 0x84, ///< Foot Pedal (Coarse, MIDI Controller 4) vcf_cutoff_ctrl_foot = 0x84, ///< Foot Pedal (Coarse, MIDI Controller 4)
vcf_cutoff_ctrl_sustainpedal = 0xc0, ///< Sustain Pedal (MIDI Cont roller 64) vcf_cutoff_ctrl_sustainpedal = 0xc0, ///< Sustain Pedal (MIDI Cont roller 64)
vcf_cutoff_ctrl_softpedal = 0xc3, ///< Soft Pedal (MIDI Control ler 67) vcf_cutoff_ctrl_softpedal = 0xc3, ///< Soft Pedal (MIDI Control ler 67)
vcf_cutoff_ctrl_genpurpose7 = 0xd2, ///< General Purpose Controll er 7 (Button, MIDI Controller 82) vcf_cutoff_ctrl_genpurpose7 = 0xd2, ///< General Purpose Controll er 7 (Button, MIDI Controller 82)
vcf_cutoff_ctrl_genpurpose8 = 0xd3, ///< General Purpose Controll er 8 (Button, MIDI Controller 83) vcf_cutoff_ctrl_genpurpose8 = 0xd3, ///< General Purpose Controll er 8 (Button, MIDI Controller 83)
vcf_cutoff_ctrl_aftertouch = 0x80 ///< Key Pressure vcf_cutoff_ctrl_aftertouch = 0x80 ///< Key Pressure
skipping to change at line 224 skipping to change at line 217
* Defines the type of dimension, that is how the dimension zones (and * Defines the type of dimension, that is how the dimension zones (and
* thus how the dimension regions are selected by. The number of * thus how the dimension regions are selected by. The number of
* dimension zones is always a power of two. All dimensions can have up * dimension zones is always a power of two. All dimensions can have up
* to 32 zones (except the layer dimension with only up to 8 zones and * to 32 zones (except the layer dimension with only up to 8 zones and
* the samplechannel dimension which currently allows only 2 zones). * the samplechannel dimension which currently allows only 2 zones).
*/ */
typedef enum { typedef enum {
dimension_none = 0x00, ///< Dimension not in use. dimension_none = 0x00, ///< Dimension not in use.
dimension_samplechannel = 0x80, ///< If used sample has more th an one channel (thus is not mono). dimension_samplechannel = 0x80, ///< If used sample has more th an one channel (thus is not mono).
dimension_layer = 0x81, ///< For layering of up to 8 in struments (and eventually crossfading of 2 or 4 layers). dimension_layer = 0x81, ///< For layering of up to 8 in struments (and eventually crossfading of 2 or 4 layers).
dimension_velocity = 0x82, ///< Key Velocity (this is the only dimension where the ranges can exactly be defined). dimension_velocity = 0x82, ///< Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
dimension_channelaftertouch = 0x83, ///< Channel Key Pressure dimension_channelaftertouch = 0x83, ///< Channel Key Pressure
dimension_releasetrigger = 0x84, ///< Special dimension for trig gering samples on releasing a key. dimension_releasetrigger = 0x84, ///< Special dimension for trig gering samples on releasing a key.
dimension_keyboard = 0x85, ///< Dimension for keyswitching dimension_keyboard = 0x85, ///< Dimension for keyswitching
dimension_roundrobin = 0x86, ///< Different samples triggere d each time a note is played, dimension regions selected in sequence dimension_roundrobin = 0x86, ///< Different samples triggere d each time a note is played, dimension regions selected in sequence
dimension_random = 0x87, ///< Different samples triggere d each time a note is played, random order dimension_random = 0x87, ///< Different samples triggere d each time a note is played, random order
dimension_smartmidi = 0x88, ///< For MIDI tools like legato
and repetition mode
dimension_roundrobinkeyboard = 0x89, ///< Different samples trigger
ed each time a note is played, any key advances the counter
dimension_modwheel = 0x01, ///< Modulation Wheel (MIDI Con troller 1) dimension_modwheel = 0x01, ///< Modulation Wheel (MIDI Con troller 1)
dimension_breath = 0x02, ///< Breath Controller (Coarse, MIDI Controller 2) dimension_breath = 0x02, ///< Breath Controller (Coarse, MIDI Controller 2)
dimension_foot = 0x04, ///< Foot Pedal (Coarse, MIDI C ontroller 4) dimension_foot = 0x04, ///< Foot Pedal (Coarse, MIDI C ontroller 4)
dimension_portamentotime = 0x05, ///< Portamento Time (Coarse, M IDI Controller 5) dimension_portamentotime = 0x05, ///< Portamento Time (Coarse, M IDI Controller 5)
dimension_effect1 = 0x0c, ///< Effect Controller 1 (Coars e, MIDI Controller 12) dimension_effect1 = 0x0c, ///< Effect Controller 1 (Coars e, MIDI Controller 12)
dimension_effect2 = 0x0d, ///< Effect Controller 2 (Coars e, MIDI Controller 13) dimension_effect2 = 0x0d, ///< Effect Controller 2 (Coars e, MIDI Controller 13)
dimension_genpurpose1 = 0x10, ///< General Purpose Controller 1 (Slider, MIDI Controller 16) dimension_genpurpose1 = 0x10, ///< General Purpose Controller 1 (Slider, MIDI Controller 16)
dimension_genpurpose2 = 0x11, ///< General Purpose Controller 2 (Slider, MIDI Controller 17) dimension_genpurpose2 = 0x11, ///< General Purpose Controller 2 (Slider, MIDI Controller 17)
dimension_genpurpose3 = 0x12, ///< General Purpose Controller 3 (Slider, MIDI Controller 18) dimension_genpurpose3 = 0x12, ///< General Purpose Controller 3 (Slider, MIDI Controller 18)
dimension_genpurpose4 = 0x13, ///< General Purpose Controller 4 (Slider, MIDI Controller 19) dimension_genpurpose4 = 0x13, ///< General Purpose Controller 4 (Slider, MIDI Controller 19)
skipping to change at line 260 skipping to change at line 255
dimension_effect3depth = 0x5d, ///< Effect 3 Depth (MIDI Contr oller 93) dimension_effect3depth = 0x5d, ///< Effect 3 Depth (MIDI Contr oller 93)
dimension_effect4depth = 0x5e, ///< Effect 4 Depth (MIDI Contr oller 94) dimension_effect4depth = 0x5e, ///< Effect 4 Depth (MIDI Contr oller 94)
dimension_effect5depth = 0x5f ///< Effect 5 Depth (MIDI Contr oller 95) dimension_effect5depth = 0x5f ///< Effect 5 Depth (MIDI Contr oller 95)
} dimension_t; } dimension_t;
/** /**
* Intended for internal usage: will be used to convert a dimension val ue * Intended for internal usage: will be used to convert a dimension val ue
* into the corresponding dimension bit number. * into the corresponding dimension bit number.
*/ */
typedef enum { typedef enum {
split_type_normal, ///< dimension value between 0-127, no c split_type_normal, ///< dimension value between 0-127
ustom range of zones
split_type_customvelocity, ///< a velocity dimension split with cus
tom range definition for each zone (if a velocity dimension split has no cu
stom defined zone ranges then it's also just of type split_type_normal)
split_type_bit ///< dimension values are already the so ught bit number split_type_bit ///< dimension values are already the so ught bit number
} split_type_t; } split_type_t;
/** General dimension definition. */ /** General dimension definition. */
struct dimension_def_t { struct dimension_def_t {
dimension_t dimension; ///< Specifies which source (usually a MID I controller) is associated with the dimension. dimension_t dimension; ///< Specifies which source (usually a MID I controller) is associated with the dimension.
uint8_t bits; ///< Number of "bits" (1 bit = 2 splits/zo nes, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...). uint8_t bits; ///< Number of "bits" (1 bit = 2 splits/zo nes, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
uint8_t zones; ///< Number of zones the dimension has. uint8_t zones; ///< Number of zones the dimension has.
split_type_t split_type; ///< Intended for internal usage: will be used to convert a dimension value into the corresponding dimension bit numb er. split_type_t split_type; ///< Intended for internal usage: will be used to convert a dimension value into the corresponding dimension bit numb er.
range_t* ranges; ///< Intended for internal usage: Points t float zone_size; ///< Intended for internal usage: reflects
o the beginning of a range_t array which reflects the value ranges of each the size of each zone (128/zones) for normal split types only, 0 otherwise
dimension zone (only if custom defined ranges are defined, is NULL otherwis .
e).
unsigned int zone_size; ///< Intended for internal usage: reflects
the size of each zone (128/zones) for normal split types only, 0 otherwise
.
}; };
/** Defines which frequencies are filtered by the VCF. */ /** Defines which frequencies are filtered by the VCF. */
typedef enum { typedef enum {
vcf_type_lowpass = 0x00, vcf_type_lowpass = 0x00,
vcf_type_lowpassturbo = 0xff, ///< More poles than normal lowpass vcf_type_lowpassturbo = 0xff, ///< More poles than normal lowpass
vcf_type_bandpass = 0x01, vcf_type_bandpass = 0x01,
vcf_type_highpass = 0x02, vcf_type_highpass = 0x02,
vcf_type_bandreject = 0x03 vcf_type_bandreject = 0x03
} vcf_type_t; } vcf_type_t;
skipping to change at line 338 skipping to change at line 331
float __range_min; ///< Only for internal usage, do not modify! float __range_min; ///< Only for internal usage, do not modify!
float __range_max; ///< Only for internal usage, do not modify! float __range_max; ///< Only for internal usage, do not modify!
progress_t(); progress_t();
}; };
// just symbol prototyping // just symbol prototyping
class File; class File;
class Instrument; class Instrument;
class Sample; class Sample;
class Region; class Region;
class Group;
/** Encapsulates articulation information of a dimension region. /** @brief Encapsulates articulation information of a dimension region.
* *
* Every Gigasampler Instrument has at least one dimension region * Every Gigasampler Instrument has at least one dimension region
* (exactly then when it has no dimension defined). * (exactly then when it has no dimension defined).
* *
* Gigasampler provides three Envelope Generators and Low Frequency * Gigasampler provides three Envelope Generators and Low Frequency
* Oscillators: * Oscillators:
* *
* - EG1 and LFO1, both controlling sample amplitude * - EG1 and LFO1, both controlling sample amplitude
* - EG2 and LFO2, both controlling filter cutoff frequency * - EG2 and LFO2, both controlling filter cutoff frequency
* - EG3 and LFO3, both controlling sample pitch * - EG3 and LFO3, both controlling sample pitch
*/ */
class DimensionRegion : protected DLS::Sampler { class DimensionRegion : protected DLS::Sampler {
public: public:
uint8_t VelocityUpperLimit; ///< Defines the upper velocity value limit of a velocity split (only if an user defined limit was set, thus a value not equal to 128/NumberOfSplits, else this val ue is 0). uint8_t VelocityUpperLimit; ///< Defines the upper velocity value limit of a velocity split (only if an user defined limit was set, thus a value not equal to 128/NumberOfSplits, else this val ue is 0). Only for gig2, otherwise the DimensionUpperLimts are used instead .
Sample* pSample; ///< Points t o the Sample which is assigned to the dimension region. Sample* pSample; ///< Points t o the Sample which is assigned to the dimension region.
// Sample Amplitude EG/LFO // Sample Amplitude EG/LFO
uint16_t EG1PreAttack; ///< Preattac k value of the sample amplitude EG (0 - 1000 permille). uint16_t EG1PreAttack; ///< Preattac k value of the sample amplitude EG (0 - 1000 permille).
double EG1Attack; ///< Attack t ime of the sample amplitude EG (0.000 - 60.000s). double EG1Attack; ///< Attack t ime of the sample amplitude EG (0.000 - 60.000s).
double EG1Decay1; ///< Decay ti me of the sample amplitude EG (0.000 - 60.000s). double EG1Decay1; ///< Decay ti me of the sample amplitude EG (0.000 - 60.000s).
double EG1Decay2; ///< Only if <i>EG1InfiniteSustain == false</i>: 2nd decay stage time of the sample ampl itude EG (0.000 - 60.000s). double EG1Decay2; ///< Only if <i>EG1InfiniteSustain == false</i>: 2nd decay stage time of the sample ampl itude EG (0.000 - 60.000s).
bool EG1InfiniteSustain; ///< If <i>tr ue</i>, instead of going into Decay2 phase, Decay1 level will be hold until note will be released. bool EG1InfiniteSustain; ///< If <i>tr ue</i>, instead of going into Decay2 phase, Decay1 level will be hold until note will be released.
uint16_t EG1Sustain; ///< Sustain value of the sample amplitude EG (0 - 1000 permille). uint16_t EG1Sustain; ///< Sustain value of the sample amplitude EG (0 - 1000 permille).
double EG1Release; ///< Release time of the sample amplitude EG (0.000 - 60.000s). double EG1Release; ///< Release time of the sample amplitude EG (0.000 - 60.000s).
bool EG1Hold; ///< If <i>tr ue</i>, Decay1 stage should be postponed until the sample reached the sampl e loop start. bool EG1Hold; ///< If <i>tr ue</i>, Decay1 stage should be postponed until the sample reached the sampl e loop start.
skipping to change at line 405 skipping to change at line 399
double EG3Attack; ///< Attack t ime of the sample pitch EG (0.000 - 10.000s). double EG3Attack; ///< Attack t ime of the sample pitch EG (0.000 - 10.000s).
int16_t EG3Depth; ///< Depth of the sample pitch EG (-1200 - +1200). int16_t EG3Depth; ///< Depth of the sample pitch EG (-1200 - +1200).
double LFO3Frequency; ///< Frequenc y of the sample pitch LFO (0.10 - 10.00 Hz). double LFO3Frequency; ///< Frequenc y of the sample pitch LFO (0.10 - 10.00 Hz).
int16_t LFO3InternalDepth; ///< Firm dep th of the sample pitch LFO (-1200 - +1200 cents). int16_t LFO3InternalDepth; ///< Firm dep th of the sample pitch LFO (-1200 - +1200 cents).
int16_t LFO3ControlDepth; ///< Controll er depth of the sample pitch LFO (-1200 - +1200 cents). int16_t LFO3ControlDepth; ///< Controll er depth of the sample pitch LFO (-1200 - +1200 cents).
lfo3_ctrl_t LFO3Controller; ///< MIDI Con troller which controls the sample pitch LFO. lfo3_ctrl_t LFO3Controller; ///< MIDI Con troller which controls the sample pitch LFO.
bool LFO3Sync; ///< If set t o <i>true</i> only one LFO should be used for all voices. bool LFO3Sync; ///< If set t o <i>true</i> only one LFO should be used for all voices.
// Filter // Filter
bool VCFEnabled; ///< If filte r should be used. bool VCFEnabled; ///< If filte r should be used.
vcf_type_t VCFType; ///< Defines the general filter characteristic (lowpass, highpass, bandpass, etc.). vcf_type_t VCFType; ///< Defines the general filter characteristic (lowpass, highpass, bandpass, etc.).
vcf_cutoff_ctrl_t VCFCutoffController; ///< Specifie vcf_cutoff_ctrl_t VCFCutoffController; ///< Specifie
s which external controller has influence on the filter cutoff frequency. s which external controller has influence on the filter cutoff frequency. @
deprecated Don't alter directly, use SetVCFCutoffController() instead!
bool VCFCutoffControllerInvert; ///< Inverts
values coming from the defined cutoff controller
uint8_t VCFCutoff; ///< Max. cut off frequency. uint8_t VCFCutoff; ///< Max. cut off frequency.
curve_type_t VCFVelocityCurve; ///< Defines curve_type_t VCFVelocityCurve; ///< Defines
a transformation curve for the incoming velocity values, affecting the VCF. a transformation curve for the incoming velocity values, affecting the VCF.
uint8_t VCFVelocityScale; ///< (0-127) @deprecated Don't alter directly, use SetVCFVelocityCurve() instead!
Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff uint8_t VCFVelocityScale; ///< (0-127)
controller is defined). Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff
uint8_t VCFVelocityDynamicRange; ///< 0x04 = l controller is defined, otherwise this is the minimum cutoff). @deprecated D
owest, 0x00 = highest on't alter directly, use SetVCFVelocityScale() instead!
uint8_t VCFVelocityDynamicRange; ///< 0x04 = l
owest, 0x00 = highest . @deprecated Don't alter directly, use SetVCFVelocit
yDynamicRange() instead!
uint8_t VCFResonance; ///< Firm int ernal filter resonance weight. uint8_t VCFResonance; ///< Firm int ernal filter resonance weight.
bool VCFResonanceDynamic; ///< If <i>tr ue</i>: Increases the resonance Q according to changes of controllers that actually control the VCF cutoff frequency (EG2, ext. VCF MIDI controller). bool VCFResonanceDynamic; ///< If <i>tr ue</i>: Increases the resonance Q according to changes of controllers that actually control the VCF cutoff frequency (EG2, ext. VCF MIDI controller).
vcf_res_ctrl_t VCFResonanceController; ///< Specifie s which external controller has influence on the filter resonance Q. vcf_res_ctrl_t VCFResonanceController; ///< Specifie s which external controller has influence on the filter resonance Q.
bool VCFKeyboardTracking; ///< If <i>tr ue</i>: VCF cutoff frequence will be dependend to the note key position rel ative to the defined breakpoint value. bool VCFKeyboardTracking; ///< If <i>tr ue</i>: VCF cutoff frequence will be dependend to the note key position rel ative to the defined breakpoint value.
uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFK eyboardTracking (0 - 127). uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFK eyboardTracking (0 - 127).
// Key Velocity Transformations // Key Velocity Transformations
curve_type_t VelocityResponseCurve; ///< Defines curve_type_t VelocityResponseCurve; ///< Defines
a transformation curve to the incoming velocity values affecting amplitude a transformation curve to the incoming velocity values affecting amplitude
(usually you don't have to interpret this parameter, use GetVelocityAttenua (usually you don't have to interpret this parameter, use GetVelocityAttenua
tion() instead). tion() instead). @deprecated Don't alter directly, use SetVelocityResponseC
uint8_t VelocityResponseDepth; ///< Dynamic urve() instead!
range of velocity affecting amplitude (0 - 4) (usually you don't have to in uint8_t VelocityResponseDepth; ///< Dynamic
terpret this parameter, use GetVelocityAttenuation() instead). range of velocity affecting amplitude (0 - 4) (usually you don't have to in
uint8_t VelocityResponseCurveScaling; ///< 0 - 127 terpret this parameter, use GetVelocityAttenuation() instead). @deprecated
(usually you don't have to interpret this parameter, use GetVelocityAttenua Don't alter directly, use SetVelocityResponseDepth() instead!
tion() instead) uint8_t VelocityResponseCurveScaling; ///< 0 - 127
curve_type_t ReleaseVelocityResponseCurve; ///< Defines (usually you don't have to interpret this parameter, use GetVelocityAttenua
a transformation curve to the incoming release veloctiy values affecting en tion() instead). @deprecated Don't alter directly, use SetVelocityResponseC
velope times. urveScaling() instead!
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic curve_type_t ReleaseVelocityResponseCurve; ///< Defines
range of release velocity affecting envelope time (0 - 4). a transformation curve to the incoming release veloctiy values affecting en
velope times. @deprecated Don't alter directly, use SetReleaseVelocityRespo
nseCurve() instead!
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic
range of release velocity affecting envelope time (0 - 4). @deprecated Don'
t alter directly, use SetReleaseVelocityResponseDepth() instead!
uint8_t ReleaseTriggerDecay; ///< 0 - 8 uint8_t ReleaseTriggerDecay; ///< 0 - 8
// Mix / Layer // Mix / Layer
crossfade_t Crossfade; crossfade_t Crossfade;
bool PitchTrack; ///< If <i>tr ue</i>: sample will be pitched according to the key position (this will be disabled for drums for example). bool PitchTrack; ///< If <i>tr ue</i>: sample will be pitched according to the key position (this will be disabled for drums for example).
dim_bypass_ctrl_t DimensionBypass; ///< If defin ed, the MIDI controller can switch on/off the dimension in realtime. dim_bypass_ctrl_t DimensionBypass; ///< If defin ed, the MIDI controller can switch on/off the dimension in realtime.
int8_t Pan; ///< Panorama / Balance (-64..0..63 <-> left..middle..right) int8_t Pan; ///< Panorama / Balance (-64..0..63 <-> left..middle..right)
bool SelfMask; ///< If <i>tr ue</i>: high velocity notes will stop low velocity notes at the same note, with that you can save voices that wouldn't be audible anyway. bool SelfMask; ///< If <i>tr ue</i>: high velocity notes will stop low velocity notes at the same note, with that you can save voices that wouldn't be audible anyway.
attenuation_ctrl_t AttenuationController; ///< MIDI Con troller which has influence on the volume level of the sample (or entire sa mple group). attenuation_ctrl_t AttenuationController; ///< MIDI Con troller which has influence on the volume level of the sample (or entire sa mple group).
bool InvertAttenuationController; ///< Inverts the values coming from the defined Attenuation Controller. bool InvertAttenuationController; ///< Inverts the values coming from the defined Attenuation Controller.
uint8_t AttenuationControllerThreshold;///< 0-127 uint8_t AttenuationControllerThreshold;///< 0-127
uint8_t ChannelOffset; ///< Audio ou tput where the audio signal of the dimension region should be routed to (0 - 9). uint8_t ChannelOffset; ///< Audio ou tput where the audio signal of the dimension region should be routed to (0 - 9).
bool SustainDefeat; ///< If <i>tr ue</i>: Sustain pedal will not hold a note. bool SustainDefeat; ///< If <i>tr ue</i>: Sustain pedal will not hold a note.
bool MSDecode; ///< Gigastud io flag: defines if Mid Side Recordings should be decoded. bool MSDecode; ///< Gigastud io flag: defines if Mid Side Recordings should be decoded.
uint16_t SampleStartOffset; ///< Number o f samples the sample start should be moved (0 - 2000). uint16_t SampleStartOffset; ///< Number o f samples the sample start should be moved (0 - 2000).
double SampleAttenuation; ///< Sample v olume (calculated from DLS::Sampler::Gain) double SampleAttenuation; ///< Sample v olume (calculated from DLS::Sampler::Gain)
uint8_t DimensionUpperLimits[8]; ///< gig3: de fines the upper limit of the dimension values for this dimension region
// derived attributes from DLS::Sampler // derived attributes from DLS::Sampler
DLS::Sampler::UnityNote; DLS::Sampler::UnityNote;
DLS::Sampler::FineTune; DLS::Sampler::FineTune;
DLS::Sampler::Gain; DLS::Sampler::Gain;
DLS::Sampler::SampleLoops; DLS::Sampler::SampleLoops;
DLS::Sampler::pSampleLoops; DLS::Sampler::pSampleLoops;
// Methods // own methods
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity); double GetVelocityAttenuation(uint8_t MIDIKeyVelocity);
double GetVelocityRelease(uint8_t MIDIKeyVelocity); double GetVelocityRelease(uint8_t MIDIKeyVelocity);
double GetVelocityCutoff(uint8_t MIDIKeyVelocity);
void SetVelocityResponseCurve(curve_type_t curve);
void SetVelocityResponseDepth(uint8_t depth);
void SetVelocityResponseCurveScaling(uint8_t scaling);
void SetReleaseVelocityResponseCurve(curve_type_t curve);
void SetReleaseVelocityResponseDepth(uint8_t depth);
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller);
void SetVCFVelocityCurve(curve_type_t curve);
void SetVCFVelocityDynamicRange(uint8_t range);
void SetVCFVelocityScale(uint8_t scaling);
Region* GetParent() const;
// derived methods
DLS::Sampler::AddSampleLoop;
DLS::Sampler::DeleteSampleLoop;
// overridden methods
virtual void SetGain(int32_t gain);
virtual void UpdateChunks();
protected: protected:
DimensionRegion(RIFF::List* _3ewl); uint8_t* VelocityTable; ///< For velocity dimensions with custo
m defined zone ranges only: used for fast converting from velocity MIDI val
ue to dimension bit number.
DimensionRegion(Region* pParent, RIFF::List* _3ewl);
DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src);
~DimensionRegion(); ~DimensionRegion();
friend class Region; friend class Region;
private: private:
typedef enum { ///< Used to decode attenuation, EG1 and EG2 con troller typedef enum { ///< Used to decode attenuation, EG1 and EG2 con troller
_lev_ctrl_none = 0x00, _lev_ctrl_none = 0x00,
_lev_ctrl_modwheel = 0x03, ///< Modulation Wheel ( MIDI Controller 1) _lev_ctrl_modwheel = 0x03, ///< Modulation Wheel ( MIDI Controller 1)
_lev_ctrl_breath = 0x05, ///< Breath Controller (Coarse, MIDI Controller 2) _lev_ctrl_breath = 0x05, ///< Breath Controller (Coarse, MIDI Controller 2)
_lev_ctrl_foot = 0x07, ///< Foot Pedal (Coarse , MIDI Controller 4) _lev_ctrl_foot = 0x07, ///< Foot Pedal (Coarse , MIDI Controller 4)
_lev_ctrl_effect1 = 0x0d, ///< Effect Controller 1 (Coarse, MIDI Controller 12) _lev_ctrl_effect1 = 0x0d, ///< Effect Controller 1 (Coarse, MIDI Controller 12)
_lev_ctrl_effect2 = 0x0f, ///< Effect Controller 2 (Coarse, MIDI Controller 13) _lev_ctrl_effect2 = 0x0f, ///< Effect Controller 2 (Coarse, MIDI Controller 13)
skipping to change at line 487 skipping to change at line 501
_lev_ctrl_effect5depth = 0x2d, ///< Effect 5 Depth (MI DI Controller 95) _lev_ctrl_effect5depth = 0x2d, ///< Effect 5 Depth (MI DI Controller 95)
_lev_ctrl_channelaftertouch = 0x2f, ///< Channel Key Pressu re _lev_ctrl_channelaftertouch = 0x2f, ///< Channel Key Pressu re
_lev_ctrl_velocity = 0xff ///< Key Velocity _lev_ctrl_velocity = 0xff ///< Key Velocity
} _lev_ctrl_t; } _lev_ctrl_t;
typedef std::map<uint32_t, double*> VelocityTableMap; typedef std::map<uint32_t, double*> VelocityTableMap;
static uint Instances; ///< Numbe r of DimensionRegion instances. static uint Instances; ///< Numbe r of DimensionRegion instances.
static VelocityTableMap* pVelocityTables; ///< Conta ins the tables corresponding to the various velocity parameters (VelocityRe sponseCurve and VelocityResponseDepth). static VelocityTableMap* pVelocityTables; ///< Conta ins the tables corresponding to the various velocity parameters (VelocityRe sponseCurve and VelocityResponseDepth).
double* pVelocityAttenuationTable; ///< Point s to the velocity table corresponding to the velocity parameters of this Di mensionRegion. double* pVelocityAttenuationTable; ///< Point s to the velocity table corresponding to the velocity parameters of this Di mensionRegion.
double* pVelocityReleaseTable; ///< Point s to the velocity table corresponding to the release velocity parameters of this DimensionRegion double* pVelocityReleaseTable; ///< Point s to the velocity table corresponding to the release velocity parameters of this DimensionRegion
double* pVelocityCutoffTable; ///< Point
s to the velocity table corresponding to the filter velocity parameters of
this DimensionRegion
Region* pRegion;
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedCon troller); leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedCon troller);
_lev_ctrl_t EncodeLeverageController(leverage_ctrl_t Decode
dController);
double* GetReleaseVelocityTable(curve_type_t releaseVelocityRes
ponseCurve, uint8_t releaseVelocityResponseDepth);
double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, u
int8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t
vcfCutoffController);
double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
double* CreateVelocityTable(curve_type_t curveType, uint8_t dep th, uint8_t scaling); double* CreateVelocityTable(curve_type_t curveType, uint8_t dep th, uint8_t scaling);
}; };
/** Encapsulates sample waves used for playback. */ /** @brief Encapsulates sample waves used for playback.
*
* In case you created a new sample with File::AddSample(), you should
* first update all attributes with the desired meta informations
* (amount of channels, bit depth, sample rate, etc.), then call
* Resize() with the desired sample size, followed by File::Save(), thi
s
* will create the mandatory RIFF chunk which will hold the sample wave
* data and / or resize the file so you will be able to Write() the
* sample data directly to disk.
*
* @e Caution: for gig synthesis, most looping relevant information are
* retrieved from the respective DimensionRegon instead from the Sample
* itself. This was made for allowing different loop definitions for th
e
* same sample under different conditions.
*/
class Sample : public DLS::Sample { class Sample : public DLS::Sample {
public: public:
uint16_t SampleGroup;
uint32_t Manufacturer; ///< Specifies the MIDI Manuf acturer's Association (MMA) Manufacturer code for the sampler intended to r eceive this file's waveform. If no particular manufacturer is to be specifi ed, a value of 0 should be used. uint32_t Manufacturer; ///< Specifies the MIDI Manuf acturer's Association (MMA) Manufacturer code for the sampler intended to r eceive this file's waveform. If no particular manufacturer is to be specifi ed, a value of 0 should be used.
uint32_t Product; ///< Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field. If no particular manufacturer's product is to be specified, a value of 0 shou ld be used. uint32_t Product; ///< Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field. If no particular manufacturer's product is to be specified, a value of 0 shou ld be used.
uint32_t SamplePeriod; ///< Specifies the duration o f time that passes during the playback of one sample in nanoseconds (normal ly equal to 1 / Samplers Per Second, where Samples Per Second is the value found in the format chunk). uint32_t SamplePeriod; ///< Specifies the duration o f time that passes during the playback of one sample in nanoseconds (normal ly equal to 1 / Samples Per Second, where Samples Per Second is the value f ound in the format chunk), don't bother to update this attribute, it won't be saved.
uint32_t MIDIUnityNote; ///< Specifies the musical no te at which the sample will be played at it's original sample rate. uint32_t MIDIUnityNote; ///< Specifies the musical no te at which the sample will be played at it's original sample rate.
uint32_t FineTune; ///< Specifies the fraction o f a semitone up from the specified MIDI unity note field. A value of 0x8000 0000 means 1/2 semitone (50 cents) and a value of 0x00000000 means no fine tuning between semitones. uint32_t FineTune; ///< Specifies the fraction o f a semitone up from the specified MIDI unity note field. A value of 0x8000 0000 means 1/2 semitone (50 cents) and a value of 0x00000000 means no fine tuning between semitones.
smpte_format_t SMPTEFormat; ///< Specifies the Society of Motion Pictures and Television E time format used in the following <i>SMPT EOffset</i> field. If a value of 0 is set, <i>SMPTEOffset</i> should also b e set to 0. smpte_format_t SMPTEFormat; ///< Specifies the Society of Motion Pictures and Television E time format used in the following <i>SMPT EOffset</i> field. If a value of 0 is set, <i>SMPTEOffset</i> should also b e set to 0.
uint32_t SMPTEOffset; ///< The SMPTE Offset value s pecifies the time offset to be used for the synchronization / calibration t o the first sample in the waveform. This value uses a format of 0xhhmmssff where hh is a signed value that specifies the number of hours (-23 to 23), mm is an unsigned value that specifies the number of minutes (0 to 59), ss is an unsigned value that specifies the number of seconds (0 to 59) and ff is an unsigned value that specifies the number of frames (0 to -1). uint32_t SMPTEOffset; ///< The SMPTE Offset value s pecifies the time offset to be used for the synchronization / calibration t o the first sample in the waveform. This value uses a format of 0xhhmmssff where hh is a signed value that specifies the number of hours (-23 to 23), mm is an unsigned value that specifies the number of minutes (0 to 59), ss is an unsigned value that specifies the number of seconds (0 to 59) and ff is an unsigned value that specifies the number of frames (0 to -1).
uint32_t Loops; ///< Number of defined sample loops (so far only seen single loops in gig files - please report me if yo u encounter more!). uint32_t Loops; ///< @e Caution: Use the resp ective field in the DimensionRegion instead of this one! (Intended purpose: Number of defined sample loops. So far only seen single loops in gig files - please report if you encounter more!)
uint32_t LoopID; ///< Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (on ly if Loops > 0), as the Gigasampler format only allows one loop definition at the moment, this attribute isn't really useful for anything. uint32_t LoopID; ///< Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (on ly if Loops > 0), as the Gigasampler format only allows one loop definition at the moment, this attribute isn't really useful for anything.
loop_type_t LoopType; ///< The type field defines h loop_type_t LoopType; ///< @e Caution: Use the resp
ow the waveform samples will be looped (only if Loops > 0). ective field in the DimensionRegion instead of this one! (Intended purpose:
uint32_t LoopStart; ///< The start value specifie The type field defines how the waveform samples will be looped.)
s the offset (in sample points) in the waveform data of the first sample to uint32_t LoopStart; ///< @e Caution: Use the resp
be played in the loop (only if Loops > 0). ective field in the DimensionRegion instead of this one! (Intended purpose:
uint32_t LoopEnd; ///< The end value specifies The start value specifies the offset [in sample points] in the waveform da
the offset (in sample points) in the waveform data which represents the end ta of the first sample to be played in the loop [only if Loops > 0].)
of the loop (only if Loops > 0). uint32_t LoopEnd; ///< @e Caution: Use the resp
uint32_t LoopSize; ///< Length of the looping ar ective field in the DimensionRegion instead of this one! (Intended purpose:
ea (in sample points) which is equivalent to <i>LoopEnd - LoopStart</i>. The end value specifies the offset [in sample points] in the waveform data
uint32_t LoopFraction; ///< The fractional value spe which represents the end of the loop [only if Loops > 0].)
cifies a fraction of a sample at which to loop (only if Loops > 0). This al uint32_t LoopSize; ///< @e Caution: Use the resp
lows a loop to be fine tuned at a resolution greater than one sample. A val ective fields in the DimensionRegion instead of this one! (Intended purpose
ue of 0 means no fraction, a value of 0x80000000 means 1/2 of a sample leng : Length of the looping area [in sample points] which is equivalent to @cod
th. 0xFFFFFFFF is the smallest fraction of a sample that can be represented e LoopEnd - LoopStart @endcode.)
. uint32_t LoopFraction; ///< The fractional value spe
uint32_t LoopPlayCount; ///< Number of times the loop cifies a fraction of a sample at which to loop. This allows a loop to be fi
should be played (only if Loops > 0, a value of 0 = infinite). ne tuned at a resolution greater than one sample. A value of 0 means no fra
ction, a value of 0x80000000 means 1/2 of a sample length. 0xFFFFFFFF is th
e smallest fraction of a sample that can be represented.
uint32_t LoopPlayCount; ///< Number of times the loop
should be played (a value of 0 = infinite).
bool Compressed; ///< If the sample wave is co mpressed (probably just interesting for instrument and sample editors, as t his library already handles the decompression in it's sample access methods anyway). bool Compressed; ///< If the sample wave is co mpressed (probably just interesting for instrument and sample editors, as t his library already handles the decompression in it's sample access methods anyway).
uint32_t TruncatedBits; ///< For 24-bit compressed sa mples only: number of bits truncated during compression (0, 4 or 6) uint32_t TruncatedBits; ///< For 24-bit compressed sa mples only: number of bits truncated during compression (0, 4 or 6)
bool Dithered; ///< For 24-bit compressed sa mples only: if dithering was used during compression with bit reduction bool Dithered; ///< For 24-bit compressed sa mples only: if dithering was used during compression with bit reduction
// own methods // own methods
buffer_t LoadSampleData(); buffer_t LoadSampleData();
buffer_t LoadSampleData(unsigned long SampleCount); buffer_t LoadSampleData(unsigned long SampleCount);
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullS amplesCount); buffer_t LoadSampleDataWithNullSamplesExtension(uint NullS amplesCount);
buffer_t LoadSampleDataWithNullSamplesExtension(unsigned l ong SampleCount, uint NullSamplesCount); buffer_t LoadSampleDataWithNullSamplesExtension(unsigned l ong SampleCount, uint NullSamplesCount);
buffer_t GetCache(); buffer_t GetCache();
// own static methods // own static methods
static buffer_t CreateDecompressionBuffer(unsigned long MaxRead Size); static buffer_t CreateDecompressionBuffer(unsigned long MaxRead Size);
static void DestroyDecompressionBuffer(buffer_t& Decompress ionBuffer); static void DestroyDecompressionBuffer(buffer_t& Decompress ionBuffer);
// overridden methods // overridden methods
void ReleaseSampleData(); void ReleaseSampleData();
void Resize(int iNewSize);
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_wh ence_t Whence = RIFF::stream_start); unsigned long SetPos(unsigned long SampleCount, RIFF::stream_wh ence_t Whence = RIFF::stream_start);
unsigned long GetPos(); unsigned long GetPos();
unsigned long Read(void* pBuffer, unsigned long SampleCount, bu ffer_t* pExternalDecompressionBuffer = NULL); unsigned long Read(void* pBuffer, unsigned long SampleCount, bu ffer_t* pExternalDecompressionBuffer = NULL);
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCo unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCo
unt, playback_state_t* pPlaybackState, buffer_t* pExternalDecompressionBuff unt, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t*
er = NULL); pExternalDecompressionBuffer = NULL);
unsigned long Write(void* pBuffer, unsigned long SampleCount);
Group* GetGroup() const;
virtual void UpdateChunks();
protected: protected:
static unsigned int Instances; ///< Number of in stances of class Sample. static unsigned int Instances; ///< Number of in stances of class Sample.
static buffer_t InternalDecompressionBuffer; ///< Buffer u sed for decompression as well as for truncation of 24 Bit -> 16 Bit samples . static buffer_t InternalDecompressionBuffer; ///< Buffer u sed for decompression as well as for truncation of 24 Bit -> 16 Bit samples .
Group* pGroup; ///< pointer to t he Group this sample belongs to (always not-NULL)
unsigned long FrameOffset; ///< Current offs et (sample points) in current sample frame (for decompression only). unsigned long FrameOffset; ///< Current offs et (sample points) in current sample frame (for decompression only).
unsigned long* FrameTable; ///< For position ing within compressed samples only: stores the offset values for each frame . unsigned long* FrameTable; ///< For position ing within compressed samples only: stores the offset values for each frame .
unsigned long SamplePos; ///< For compress ed samples only: stores the current position (in sample points). unsigned long SamplePos; ///< For compress ed samples only: stores the current position (in sample points).
unsigned long SamplesInLastFrame; ///< For compress ed samples only: length of the last sample frame. unsigned long SamplesInLastFrame; ///< For compress ed samples only: length of the last sample frame.
unsigned long WorstCaseFrameSize; ///< For compress ed samples only: size (in bytes) of the largest possible sample frame. unsigned long WorstCaseFrameSize; ///< For compress ed samples only: size (in bytes) of the largest possible sample frame.
unsigned long SamplesPerFrame; ///< For compress ed samples only: number of samples in a full sample frame. unsigned long SamplesPerFrame; ///< For compress ed samples only: number of samples in a full sample frame.
buffer_t RAMCache; ///< Buffers samp les (already uncompressed) in RAM. buffer_t RAMCache; ///< Buffers samp les (already uncompressed) in RAM.
unsigned long FileNo; ///< File number
(> 0 when sample is stored in an extension file, 0 when it's in the gig)
RIFF::Chunk* pCk3gix;
RIFF::Chunk* pCkSmpl;
uint32_t crc; ///< CRC-32 check
sum of the raw sample data
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoo lOffset); Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoo lOffset, unsigned long fileNo = 0);
~Sample(); ~Sample();
/**
* Swaps the order of the data words in the given memory area
* with a granularity given by \a WordSize.
*
* @param pData - pointer to the memory area to be swapped
* @param AreaSize - size of the memory area to be swapped (in
bytes)
* @param WordSize - size of the data words (in bytes)
*/
inline void SwapMemoryArea(void* pData, unsigned long AreaSize,
uint WordSize) {
switch (WordSize) { // TODO: unefficient
case 1: {
uint8_t* pDst = (uint8_t*) pData;
uint8_t cache;
unsigned long lo = 0, hi = AreaSize - 1;
for (; lo < hi; hi--, lo++) {
cache = pDst[lo];
pDst[lo] = pDst[hi];
pDst[hi] = cache;
}
break;
}
case 2: {
uint16_t* pDst = (uint16_t*) pData;
uint16_t cache;
unsigned long lo = 0, hi = (AreaSize >> 1) - 1;
for (; lo < hi; hi--, lo++) {
cache = pDst[lo];
pDst[lo] = pDst[hi];
pDst[hi] = cache;
}
break;
}
case 4: {
uint32_t* pDst = (uint32_t*) pData;
uint32_t cache;
unsigned long lo = 0, hi = (AreaSize >> 2) - 1;
for (; lo < hi; hi--, lo++) {
cache = pDst[lo];
pDst[lo] = pDst[hi];
pDst[hi] = cache;
}
break;
}
default: {
uint8_t* pCache = new uint8_t[WordSize]; // TODO: u
nefficient
unsigned long lo = 0, hi = AreaSize - WordSize;
for (; lo < hi; hi -= WordSize, lo += WordSize) {
memcpy(pCache, (uint8_t*) pData + lo, WordSize)
;
memcpy((uint8_t*) pData + lo, (uint8_t*) pData
+ hi, WordSize);
memcpy((uint8_t*) pData + hi, pCache, WordSize)
;
}
delete[] pCache;
break;
}
}
}
inline long Min(long A, long B) {
return (A > B) ? B : A;
}
inline long Abs(long val) { return (val > 0) ? val : -val; }
// Guess size (in bytes) of a compressed sample // Guess size (in bytes) of a compressed sample
inline unsigned long GuessSize(unsigned long samples) { inline unsigned long GuessSize(unsigned long samples) {
// 16 bit: assume all frames are compressed - 1 byte // 16 bit: assume all frames are compressed - 1 byte
// per sample and 5 bytes header per 2048 samples // per sample and 5 bytes header per 2048 samples
// 24 bit: assume next best compression rate - 1.5 // 24 bit: assume next best compression rate - 1.5
// bytes per sample and 13 bytes header per 256 // bytes per sample and 13 bytes header per 256
// samples // samples
const unsigned long size = const unsigned long size =
skipping to change at line 630 skipping to change at line 611
// Worst case amount of sample points that can be read with the // Worst case amount of sample points that can be read with the
// given decompression buffer. // given decompression buffer.
inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressi onBuffer) { inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressi onBuffer) {
return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame); return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame);
} }
private: private:
void ScanCompressedSample(); void ScanCompressedSample();
friend class File; friend class File;
friend class Region; friend class Region;
friend class Group; // allow to modify protected member pGroup
}; };
// TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions) // TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions)
/** Defines <i>Region</i> information of an <i>Instrument</i>. */ /** Defines <i>Region</i> information of an <i>Instrument</i>. */
class Region : public DLS::Region { class Region : public DLS::Region {
public: public:
unsigned int Dimensions; ///< Number o unsigned int Dimensions; ///< Number o
f defined dimensions. f defined dimensions, do not alter!
dimension_def_t pDimensionDefinitions[8]; ///< Defines dimension_def_t pDimensionDefinitions[8]; ///< Defines
the five (gig2) or eight (gig3) possible dimensions (the dimension's contro the five (gig2) or eight (gig3) possible dimensions (the dimension's contro
ller and number of bits/splits). ller and number of bits/splits). Use AddDimension() and DeleteDimension() t
uint32_t DimensionRegions; ///< Total nu o create a new dimension or delete an existing one.
mber of DimensionRegions this Region contains. uint32_t DimensionRegions; ///< Total nu
DimensionRegion* pDimensionRegions[256]; ///< Pointer mber of DimensionRegions this Region contains, do not alter!
array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects N DimensionRegion* pDimensionRegions[256]; ///< Pointer
ULL for dimension regions not in use). Avoid to access the array directly a array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects N
nd better use GetDimensionRegionByValue() instead, but of course in some ca ULL for dimension regions not in use). Avoid to access the array directly a
ses it makes sense to use the array (e.g. iterating through all DimensionRe nd better use GetDimensionRegionByValue() instead, but of course in some ca
gions). ses it makes sense to use the array (e.g. iterating through all DimensionRe
unsigned int Layers; ///< Amount o gions). Use AddDimension() and DeleteDimension() to create a new dimension
f defined layers (1 - 32). A value of 1 actually means no layering, a value or delete an existing one (which will create or delete the respective dimen
> 1 means there is Layer dimension. The same information can of course als sion region(s) automatically).
o be obtained by accessing pDimensionDefinitions. unsigned int Layers; ///< Amount o
f defined layers (1 - 32). A value of 1 actually means no layering, a value
> 1 means there is Layer dimension. The same information can of course als
o be obtained by accessing pDimensionDefinitions. Do not alter this value!
// own methods
DimensionRegion* GetDimensionRegionByValue(const uint DimValues [8]); DimensionRegion* GetDimensionRegionByValue(const uint DimValues [8]);
DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[ 8]); DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[ 8]);
Sample* GetSample(); Sample* GetSample();
void AddDimension(dimension_def_t* pDimDef);
void DeleteDimension(dimension_def_t* pDimDef);
// overridden methods
virtual void SetKeyRange(uint16_t Low, uint16_t High);
virtual void UpdateChunks();
protected: protected:
uint8_t VelocityTable[128]; ///< For velocity dimensions with c
ustom defined zone ranges only: used for fast converting from velocity MIDI
value to dimension bit number.
Region(Instrument* pInstrument, RIFF::List* rgnList); Region(Instrument* pInstrument, RIFF::List* rgnList);
void LoadDimensionRegions(RIFF::List* rgn); void LoadDimensionRegions(RIFF::List* rgn);
void UpdateVelocityTable();
Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL); Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL);
~Region(); ~Region();
friend class Instrument; friend class Instrument;
}; };
/** Abstract base class for all MIDI rules. */
class MidiRule {
public:
virtual ~MidiRule() { }
};
/** MIDI rule for triggering notes by control change events. */
class MidiRuleCtrlTrigger : public MidiRule {
public:
uint8_t ControllerNumber; ///< MIDI controller number.
uint8_t Triggers; ///< Number of triggers.
struct trigger_t {
uint8_t TriggerPoint; ///< The CC value to pass for the n
ote to be triggered.
bool Descending; ///< If the change in CC value shou
ld be downwards.
uint8_t VelSensitivity; ///< How sensitive the velocity sho
uld be to the speed of the controller change.
uint8_t Key; ///< Key to trigger.
bool NoteOff; ///< If a note off should be trigge
red instead of a note on.
uint8_t Velocity; ///< Velocity of the note to trigge
r. 255 means that velocity should depend on the speed of the controller cha
nge.
bool OverridePedal; ///< If a note off should be trigge
red even if the sustain pedal is down.
} pTriggers[32];
protected:
MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg);
friend class Instrument;
};
/** Provides all neccessary information for the synthesis of an <i>Inst rument</i>. */ /** Provides all neccessary information for the synthesis of an <i>Inst rument</i>. */
class Instrument : protected DLS::Instrument { class Instrument : protected DLS::Instrument {
public: public:
// derived attributes from DLS::Resource // derived attributes from DLS::Resource
DLS::Resource::pInfo; DLS::Resource::pInfo;
DLS::Resource::pDLSID; DLS::Resource::pDLSID;
// derived attributes from DLS::Instrument // derived attributes from DLS::Instrument
DLS::Instrument::IsDrum; DLS::Instrument::IsDrum;
DLS::Instrument::MIDIBank; DLS::Instrument::MIDIBank;
DLS::Instrument::MIDIBankCoarse; DLS::Instrument::MIDIBankCoarse;
skipping to change at line 681 skipping to change at line 694
int16_t FineTune; ///< in cents int16_t FineTune; ///< in cents
uint16_t PitchbendRange; ///< Number of semitones pitchbend controller can pitch (default is 2). uint16_t PitchbendRange; ///< Number of semitones pitchbend controller can pitch (default is 2).
bool PianoReleaseMode; bool PianoReleaseMode;
range_t DimensionKeyRange; ///< 0-127 (where 0 means C1 and 1 27 means G9) range_t DimensionKeyRange; ///< 0-127 (where 0 means C1 and 1 27 means G9)
// derived methods from DLS::Resource // derived methods from DLS::Resource
DLS::Resource::GetParent; DLS::Resource::GetParent;
// overridden methods // overridden methods
Region* GetFirstRegion(); Region* GetFirstRegion();
Region* GetNextRegion(); Region* GetNextRegion();
Region* AddRegion();
void DeleteRegion(Region* pRegion);
virtual void UpdateChunks();
// own methods // own methods
Region* GetRegion(unsigned int Key); Region* GetRegion(unsigned int Key);
MidiRule* GetMidiRule(int i);
protected: protected:
Region** pRegions; ///< Pointer array to the region s
Region* RegionKeyTable[128]; ///< fast lookup for the corresp onding Region of a MIDI key Region* RegionKeyTable[128]; ///< fast lookup for the corresp onding Region of a MIDI key
int RegionIndex;
Instrument(File* pFile, RIFF::List* insList, progress_t* pProgr ess = NULL); Instrument(File* pFile, RIFF::List* insList, progress_t* pProgr ess = NULL);
~Instrument(); ~Instrument();
void UpdateRegionKeyTable();
friend class File; friend class File;
friend class Region; // so Region can call UpdateRegionKeyTable
()
private:
MidiRule** pMidiRules;
};
/** @brief Group of Gigasampler objects
*
* Groups help to organize a huge collection of Gigasampler objects.
* Groups are not concerned at all for the synthesis, but they help
* sound library developers when working on complex instruments with an
* instrument editor (as long as that instrument editor supports it ;-)
.
*
* At the moment, it seems as only samples can be grouped together in
* the Gigasampler format yet. If this is false in the meantime, please
* tell us !
*
* A sample is always assigned to exactly one Group. This also means
* there is always at least one Group in a .gig file, no matter if you
* created one yet or not.
*/
class Group {
public:
String Name; ///< Stores the name of this Group.
Sample* GetFirstSample();
Sample* GetNextSample();
void AddSample(Sample* pSample);
protected:
Group(File* file, RIFF::Chunk* ck3gnm);
virtual ~Group();
virtual void UpdateChunks();
void MoveAll();
friend class File;
private:
File* pFile;
RIFF::Chunk* pNameChunk;
}; };
// TODO: <3gnm> chunk not added yet (just contains the names of the sam ple groups)
/** Parses Gigasampler files and provides abstract access to the data. */ /** Parses Gigasampler files and provides abstract access to the data. */
class File : protected DLS::File { class File : protected DLS::File {
public: public:
static const DLS::version_t VERSION_2;
static const DLS::version_t VERSION_3;
// derived attributes from DLS::Resource // derived attributes from DLS::Resource
DLS::Resource::pInfo; DLS::Resource::pInfo;
DLS::Resource::pDLSID; DLS::Resource::pDLSID;
// derived attributes from DLS::File // derived attributes from DLS::File
DLS::File::pVersion; DLS::File::pVersion;
DLS::File::Instruments; DLS::File::Instruments;
// derived methods from DLS::Resource // derived methods from DLS::Resource
DLS::Resource::GetParent; DLS::Resource::GetParent;
// derived methods from DLS::File
DLS::File::Save;
// overridden methods // overridden methods
File();
File(RIFF::File* pRIFF); File(RIFF::File* pRIFF);
Sample* GetFirstSample(progress_t* pProgress = NULL); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i > otherwise. Sample* GetFirstSample(progress_t* pProgress = NULL); ///< Returns a pointer to the first <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. Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise.
Sample* AddSample();
void DeleteSample(Sample* pSample);
Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <i>Instrument</i> object of the file, <i>NULL</i> otherwise. Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <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. Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise.
Instrument* GetInstrument(uint index, progress_t* pProgress = N ULL); Instrument* GetInstrument(uint index, progress_t* pProgress = N ULL);
~File(); Instrument* AddInstrument();
void DeleteInstrument(Instrument* pInstrument);
Group* GetFirstGroup(); ///< Returns a pointer to the firs
t <i>Group</i> object of the file, <i>NULL</i> otherwise.
Group* GetNextGroup(); ///< Returns a pointer to the next
<i>Group</i> object of the file, <i>NULL</i> otherwise.
Group* GetGroup(uint index);
Group* AddGroup();
void DeleteGroup(Group* pGroup);
void DeleteGroupOnly(Group* pGroup);
void SetAutoLoad(bool b);
bool GetAutoLoad();
virtual ~File();
virtual void UpdateChunks();
protected: protected:
typedef std::list<Sample*> SampleList; // overridden protected methods from DLS::File
typedef std::list<Instrument*> InstrumentList; virtual void LoadSamples();
virtual void LoadInstruments();
SampleList* pSamples; virtual void LoadGroups();
SampleList::iterator SamplesIterator; // own protected methods
InstrumentList* pInstruments; virtual void LoadSamples(progress_t* pProgress);
InstrumentList::iterator InstrumentsIterator; virtual void LoadInstruments(progress_t* pProgress);
void SetSampleChecksum(Sample* pSample, uint32_t crc);
void LoadSamples(progress_t* pProgress = NULL);
void LoadInstruments(progress_t* pProgress = NULL);
friend class Region; friend class Region;
friend class Sample;
friend class Group; // so Group can access protected member pRI
FF
private:
std::list<Group*>* pGroups;
std::list<Group*>::iterator GroupsIterator;
bool bAutoLoad;
}; };
/** Will be thrown whenever a gig specific error occurs while trying to /**
access a Gigasampler File. */ * Will be thrown whenever a gig specific error occurs while trying to
* access a Gigasampler File. Note: In your application you should
* better catch for RIFF::Exception rather than this one, except you
* explicitly want to catch and handle gig::Exception, DLS::Exception
* and RIFF::Exception independently, which usually shouldn't be
* necessary though.
*/
class Exception : public DLS::Exception { class Exception : public DLS::Exception {
public: public:
Exception(String Message); Exception(String Message);
void PrintMessage(); void PrintMessage();
}; };
String libraryName(); String libraryName();
String libraryVersion(); String libraryVersion();
} // namespace gig } // namespace gig
 End of changes. 58 change blocks. 
199 lines changed or deleted 300 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/