00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __DLS_H__
00025 #define __DLS_H__
00026
00027 #include "RIFF.h"
00028
00029 #if WORDS_BIGENDIAN
00030 # define RIFF_TYPE_DLS 0x444C5320
00031 # define LIST_TYPE_INFO 0x494E464F
00032 # define LIST_TYPE_WVPL 0x7776706C
00033 # define LIST_TYPE_DWPL 0x6477706C
00034 # define LIST_TYPE_WAVE 0x77617665
00035 # define LIST_TYPE_LINS 0X6C696E73
00036 # define LIST_TYPE_INS 0X696E7320
00037 # define LIST_TYPE_LRGN 0x6C72676E
00038 # define LIST_TYPE_LART 0x6C617274
00039 # define LIST_TYPE_LAR2 0x6C617232
00040 # define LIST_TYPE_RGN 0x72676E20
00041 # define LIST_TYPE_RGN2 0x72676E32
00042 # define CHUNK_ID_IARL 0x4941524C
00043 # define CHUNK_ID_IART 0x49415254
00044 # define CHUNK_ID_ICMS 0x49434D53
00045 # define CHUNK_ID_ICMT 0x49434D54
00046 # define CHUNK_ID_ICOP 0x49434F50
00047 # define CHUNK_ID_ICRD 0x49435244
00048 # define CHUNK_ID_IENG 0x49454E47
00049 # define CHUNK_ID_IGNR 0x49474E52
00050 # define CHUNK_ID_IKEY 0x494B4559
00051 # define CHUNK_ID_IMED 0x494D4544
00052 # define CHUNK_ID_INAM 0x494E414D
00053 # define CHUNK_ID_IPRD 0x49505244
00054 # define CHUNK_ID_ISBJ 0x4953424A
00055 # define CHUNK_ID_ISFT 0x49534654
00056 # define CHUNK_ID_ISRC 0x49535243
00057 # define CHUNK_ID_ISRF 0x49535246
00058 # define CHUNK_ID_ITCH 0x49544348
00059 # define CHUNK_ID_VERS 0x76657273
00060 # define CHUNK_ID_DLID 0x646C6964
00061 # define CHUNK_ID_FMT 0x666D7420
00062 # define CHUNK_ID_DATA 0x64617461
00063 # define CHUNK_ID_INSH 0x696E7368
00064 # define CHUNK_ID_RGNH 0x72676E68
00065 # define CHUNK_ID_WLNK 0x776C6E6B
00066 # define CHUNK_ID_PTBL 0x7074626C
00067 # define CHUNK_ID_WSMP 0x77736D70
00068 # define CHUNK_ID_COLH 0x636F6C68
00069 # define CHUNK_ID_ARTL 0x6172746C
00070 # define CHUNK_ID_ART2 0x61727432
00071 #else // little endian
00072 # define RIFF_TYPE_DLS 0x20534C44
00073 # define LIST_TYPE_INFO 0x4F464E49
00074 # define LIST_TYPE_WVPL 0x6C707677
00075 # define LIST_TYPE_DWPL 0x6C707764
00076 # define LIST_TYPE_WAVE 0x65766177
00077 # define LIST_TYPE_LINS 0X736E696C
00078 # define LIST_TYPE_INS 0X20736E69
00079 # define LIST_TYPE_LRGN 0x6E67726C
00080 # define LIST_TYPE_LART 0x7472616C
00081 # define LIST_TYPE_LAR2 0x3272616C
00082 # define LIST_TYPE_RGN 0x206E6772
00083 # define LIST_TYPE_RGN2 0x326E6772
00084 # define CHUNK_ID_IARL 0x4C524149
00085 # define CHUNK_ID_IART 0x54524149
00086 # define CHUNK_ID_ICMS 0x534D4349
00087 # define CHUNK_ID_ICMT 0x544D4349
00088 # define CHUNK_ID_ICOP 0x504F4349
00089 # define CHUNK_ID_ICRD 0x44524349
00090 # define CHUNK_ID_IENG 0x474E4549
00091 # define CHUNK_ID_IGNR 0x524E4749
00092 # define CHUNK_ID_IKEY 0x59454B49
00093 # define CHUNK_ID_IMED 0x44454D49
00094 # define CHUNK_ID_INAM 0x4D414E49
00095 # define CHUNK_ID_IPRD 0x44525049
00096 # define CHUNK_ID_ISBJ 0x4A425349
00097 # define CHUNK_ID_ISFT 0x54465349
00098 # define CHUNK_ID_ISRC 0x43525349
00099 # define CHUNK_ID_ISRF 0x46525349
00100 # define CHUNK_ID_ITCH 0x48435449
00101 # define CHUNK_ID_VERS 0x73726576
00102 # define CHUNK_ID_DLID 0x64696C64
00103 # define CHUNK_ID_FMT 0x20746D66
00104 # define CHUNK_ID_DATA 0x61746164
00105 # define CHUNK_ID_INSH 0x68736E69
00106 # define CHUNK_ID_RGNH 0x686E6772
00107 # define CHUNK_ID_WLNK 0x6B6E6C77
00108 # define CHUNK_ID_PTBL 0x6C627470
00109 # define CHUNK_ID_WSMP 0x706D7377
00110 # define CHUNK_ID_COLH 0x686C6F63
00111 # define CHUNK_ID_ARTL 0x6C747261
00112 # define CHUNK_ID_ART2 0x32747261
00113 #endif // WORDS_BIGENDIAN
00114
00115 #define DLS_WAVE_FORMAT_PCM 0x0001
00116
00117
00118
00120 namespace DLS {
00121
00122 typedef std::string String;
00123
00125 struct version_t {
00126 uint16_t minor;
00127 uint16_t major;
00128 uint16_t build;
00129 uint16_t release;
00130 };
00131
00133 struct dlsid_t {
00134 uint32_t ulData1;
00135 uint16_t usData2;
00136 uint16_t usData3;
00137 uint8_t abData[8];
00138 };
00139
00141 typedef enum {
00142
00143 conn_src_none = 0x0000,
00144 conn_src_lfo = 0x0001,
00145 conn_src_keyonvelocity = 0x0002,
00146 conn_src_keynumber = 0x0003,
00147 conn_src_eg1 = 0x0004,
00148 conn_src_eg2 = 0x0005,
00149 conn_src_pitchwheel = 0x0006,
00150 conn_src_polypressure = 0x0007,
00151 conn_src_channelpressure = 0x0008,
00152 conn_src_vibrato = 0x0009,
00153
00154 conn_src_cc1 = 0x0081,
00155 conn_src_cc7 = 0x0087,
00156 conn_src_cc10 = 0x008A,
00157 conn_src_cc11 = 0x008B,
00158 conn_src_cc91 = 0x00DB,
00159 conn_src_cc93 = 0x00DD,
00160
00161 conn_src_rpn0 = 0x0100,
00162 conn_src_rpn1 = 0x0101,
00163 conn_src_rpn2 = 0x0102
00164 } conn_src_t;
00165
00167 typedef enum {
00168
00169 conn_dst_none = 0x0000,
00170 conn_dst_gain = 0x0001,
00171 conn_dst_reserved = 0x0002,
00172 conn_dst_pitch = 0x0003,
00173 conn_dst_pan = 0x0004,
00174 conn_dst_keynumber = 0x0005,
00175
00176 conn_dst_left = 0x0010,
00177 conn_dst_right = 0x0011,
00178 conn_dst_center = 0x0012,
00179 conn_dst_lfe_channel = 0x0013,
00180 conn_dst_leftrear = 0x0014,
00181 conn_dst_rightrear = 0x0015,
00182 conn_dst_chorus = 0x0080,
00183 conn_dst_reverb = 0x0081,
00184
00185 conn_dst_lfo_frequency = 0x0104,
00186 conn_dst_lfo_startdelay = 0x0105,
00187
00188 conn_dst_vib_frequency = 0x0114,
00189 conn_dst_vib_startdelay = 0x0115,
00190
00191 conn_dst_eg1_attacktime = 0x0206,
00192 conn_dst_eg1_decaytime = 0x0207,
00193 conn_dst_eg1_reserved = 0x0208,
00194 conn_dst_eg1_releasetime = 0x0209,
00195 conn_dst_eg1_sustainlevel = 0x020A,
00196 conn_dst_eg1_delaytime = 0x020B,
00197 conn_dst_eg1_holdtime = 0x020C,
00198 conn_dst_eg1_shutdowntime = 0x020D,
00199 conn_dst_eg2_attacktime = 0x030A,
00200 conn_dst_eg2_decaytime = 0x030B,
00201 conn_dst_eg2_reserved = 0x030C,
00202 conn_dst_eg2_releasetime = 0x030D,
00203 conn_dst_eg2_sustainlevel = 0x030E,
00204 conn_dst_eg2_delaytime = 0x030F,
00205 conn_dst_eg2_holdtime = 0x0310,
00206
00207 conn_dst_filter_cutoff = 0x0500,
00208 conn_dst_filter_q = 0x0501
00209 } conn_dst_t;
00210
00212 typedef enum {
00213 conn_trn_none = 0x0000,
00214 conn_trn_concave = 0x0001,
00215 conn_trn_convex = 0x0002,
00216 conn_trn_switch = 0x0003
00217 } conn_trn_t;
00218
00220 struct range_t {
00221 uint16_t low;
00222 uint16_t high;
00223 };
00224
00226 struct sample_loop_t {
00227 uint32_t Size;
00228 uint32_t LoopType;
00229 uint32_t LoopStart;
00230 uint32_t LoopLength;
00231 };
00232
00233
00234 class File;
00235 class Instrument;
00236 class Region;
00237 class Sample;
00238
00240 class Connection {
00241 public:
00242 conn_src_t Source;
00243 conn_trn_t SourceTransform;
00244 bool SourceInvert;
00245 bool SourceBipolar;
00246 conn_src_t Control;
00247 conn_trn_t ControlTransform;
00248 bool ControlInvert;
00249 bool ControlBipolar;
00250 conn_dst_t Destination;
00251 conn_trn_t DestinationTransform;
00252 uint32_t Scale;
00253 protected:
00254 struct conn_block_t {
00255 uint16_t source;
00256 uint16_t control;
00257 uint16_t destination;
00258 uint16_t transform;
00259 uint32_t scale;
00260 };
00261 Connection() {}
00262 void Init(conn_block_t* Header);
00263 conn_block_t ToConnBlock();
00264 virtual ~Connection() {}
00265 friend class Articulation;
00266 };
00267
00269 class Articulation {
00270 public:
00271 Connection* pConnections;
00272 uint32_t Connections;
00273
00274 Articulation(RIFF::Chunk* artl);
00275 virtual ~Articulation();
00276 virtual void UpdateChunks();
00277 protected:
00278 RIFF::Chunk* pArticulationCk;
00279 uint32_t HeaderSize;
00280 };
00281
00283 class Articulator {
00284 public:
00285 Articulator(RIFF::List* ParentList);
00286 Articulation* GetFirstArticulation();
00287 Articulation* GetNextArticulation();
00288 virtual void UpdateChunks();
00289 protected:
00290 typedef std::list<Articulation*> ArticulationList;
00291 RIFF::List* pParentList;
00292 ArticulationList* pArticulations;
00293 ArticulationList::iterator ArticulationsIterator;
00294
00295 void LoadArticulations();
00296 virtual ~Articulator();
00297 };
00298
00300 class Info {
00301 public:
00302 String Name;
00303 String ArchivalLocation;
00304 String CreationDate;
00305 String Comments;
00306 String Product;
00307 String Copyright;
00308 String Artists;
00309 String Genre;
00310 String Keywords;
00311 String Engineer;
00312 String Technician;
00313 String Software;
00314 String Medium;
00315 String Source;
00316 String SourceForm;
00317 String Commissioned;
00318 String Subject;
00319 bool UseFixedLengthStrings;
00320
00321 struct string_length_t {
00322 uint32_t chunkId;
00323 int length;
00324 };
00325
00326 Info(RIFF::List* list);
00327 void SetFixedStringLengths(const string_length_t* lengths);
00328 virtual ~Info();
00329 virtual void UpdateChunks();
00330 private:
00331 RIFF::List* pResourceListChunk;
00332 const string_length_t* pFixedStringLengths;
00333
00334 static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
00335 void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault);
00336 };
00337
00339 class Resource {
00340 public:
00341 Info* pInfo;
00342 dlsid_t* pDLSID;
00343
00344 Resource* GetParent() { return pParent; }
00345 virtual void UpdateChunks();
00346 void GenerateDLSID();
00347 protected:
00348 Resource* pParent;
00349 RIFF::List* pResourceList;
00350
00351 Resource(Resource* Parent, RIFF::List* lstResource);
00352 virtual ~Resource();
00353 };
00354
00356 class Sampler {
00357 public:
00358 uint8_t UnityNote;
00359 int16_t FineTune;
00360 int32_t Gain;
00361 bool NoSampleDepthTruncation;
00362 bool NoSampleCompression;
00363 uint32_t SampleLoops;
00364 sample_loop_t* pSampleLoops;
00365
00366 void AddSampleLoop(sample_loop_t* pLoopDef);
00367 void DeleteSampleLoop(sample_loop_t* pLoopDef);
00368 virtual void SetGain(int32_t gain);
00369 virtual void UpdateChunks();
00370 protected:
00371 RIFF::List* pParentList;
00372 uint32_t uiHeaderSize;
00373 uint32_t SamplerOptions;
00374 Sampler(RIFF::List* ParentList);
00375 virtual ~Sampler();
00376 };
00377
00386 class Sample : public Resource {
00387 public:
00388 uint16_t FormatTag;
00389 uint16_t Channels;
00390 uint32_t SamplesPerSecond;
00391 uint32_t AverageBytesPerSecond;
00392 uint16_t BlockAlign;
00393 uint16_t BitDepth;
00394 unsigned long SamplesTotal;
00395 uint FrameSize;
00396
00397 void* LoadSampleData();
00398 void ReleaseSampleData();
00399 unsigned long GetSize();
00400 void Resize(int iNewSize);
00401 unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
00402 unsigned long Read(void* pBuffer, unsigned long SampleCount);
00403 unsigned long Write(void* pBuffer, unsigned long SampleCount);
00404 virtual void UpdateChunks();
00405 protected:
00406 RIFF::List* pWaveList;
00407 RIFF::Chunk* pCkData;
00408 RIFF::Chunk* pCkFormat;
00409 unsigned long ulWavePoolOffset;
00410
00411 Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset);
00412 virtual ~Sample();
00413 friend class File;
00414 friend class Region;
00415 };
00416
00418 class Region : public Resource, public Articulator, public Sampler {
00419 public:
00420 range_t KeyRange;
00421 range_t VelocityRange;
00422 uint16_t KeyGroup;
00423 uint16_t Layer;
00424 bool SelfNonExclusive;
00425 bool PhaseMaster;
00426 uint16_t PhaseGroup;
00427 bool MultiChannel;
00428 uint32_t Channel;
00429
00430 Sample* GetSample();
00431 void SetSample(Sample* pSample);
00432 virtual void SetKeyRange(uint16_t Low, uint16_t High);
00433 virtual void UpdateChunks();
00434 protected:
00435 RIFF::List* pCkRegion;
00436 uint32_t WavePoolTableIndex;
00437 Sample* pSample;
00438 uint16_t FormatOptionFlags;
00439 uint16_t WaveLinkOptionFlags;
00440
00441 Region(Instrument* pInstrument, RIFF::List* rgnList);
00442 virtual ~Region();
00443 friend class Instrument;
00444 };
00445
00447 class Instrument : public Resource, public Articulator {
00448 public:
00449 bool IsDrum;
00450 uint16_t MIDIBank;
00451 uint8_t MIDIBankCoarse;
00452 uint8_t MIDIBankFine;
00453 uint32_t MIDIProgram;
00454 uint32_t Regions;
00455
00456 Region* GetFirstRegion();
00457 Region* GetNextRegion();
00458 Region* AddRegion();
00459 void DeleteRegion(Region* pRegion);
00460 virtual void UpdateChunks();
00461 protected:
00462 typedef std::list<Region*> RegionList;
00463 struct midi_locale_t {
00464 uint32_t bank;
00465 uint32_t instrument;
00466 };
00467
00468 RIFF::List* pCkInstrument;
00469 RegionList* pRegions;
00470 RegionList::iterator RegionsIterator;
00471
00472 Instrument(File* pFile, RIFF::List* insList);
00473 virtual void LoadRegions();
00474 virtual ~Instrument();
00475 friend class File;
00476 friend class Region;
00477 private:
00478 void MoveRegion(Region* pSrc, Region* pDst);
00479 };
00480
00482 class File : public Resource {
00483 public:
00484 version_t* pVersion;
00485 uint32_t Instruments;
00486
00487 File();
00488 File(RIFF::File* pRIFF);
00489 Sample* GetFirstSample();
00490 Sample* GetNextSample();
00491 Sample* AddSample();
00492 void DeleteSample(Sample* pSample);
00493 Instrument* GetFirstInstrument();
00494 Instrument* GetNextInstrument();
00495 Instrument* AddInstrument();
00496 void DeleteInstrument(Instrument* pInstrument);
00497 virtual void UpdateChunks();
00498 virtual void Save(const String& Path);
00499 virtual void Save();
00500 virtual ~File();
00501 protected:
00502 typedef std::list<Sample*> SampleList;
00503 typedef std::list<Instrument*> InstrumentList;
00504
00505 RIFF::File* pRIFF;
00506 std::list<RIFF::File*> ExtensionFiles;
00507 SampleList* pSamples;
00508 SampleList::iterator SamplesIterator;
00509 InstrumentList* pInstruments;
00510 InstrumentList::iterator InstrumentsIterator;
00511 uint32_t WavePoolHeaderSize;
00512 uint32_t WavePoolCount;
00513 uint32_t* pWavePoolTable;
00514 uint32_t* pWavePoolTableHi;
00515 bool b64BitWavePoolOffsets;
00516
00517 virtual void LoadSamples();
00518 virtual void LoadInstruments();
00519 void __ensureMandatoryChunksExist();
00520 friend class Region;
00521 private:
00522 void __UpdateWavePoolTableChunk();
00523 void __UpdateWavePoolTable();
00524 };
00525
00533 class Exception : public RIFF::Exception {
00534 public:
00535 Exception(String Message);
00536 void PrintMessage();
00537 };
00538
00539 String libraryName();
00540 String libraryVersion();
00541
00542 }
00543
00544 #endif // __DLS_H__