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 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 Info(RIFF::List* list);
00322 virtual ~Info();
00323 virtual void UpdateChunks();
00324 private:
00325 RIFF::List* pResourceListChunk;
00326
00327 static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
00328 static void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault, bool bUseFixedLengthStrings, int size);
00329 };
00330
00332 class Resource {
00333 public:
00334 Info* pInfo;
00335 dlsid_t* pDLSID;
00336
00337 Resource* GetParent() { return pParent; };
00338 virtual void UpdateChunks();
00339 protected:
00340 Resource* pParent;
00341 RIFF::List* pResourceList;
00342
00343 Resource(Resource* Parent, RIFF::List* lstResource);
00344 virtual ~Resource();
00345 };
00346
00348 class Sampler {
00349 public:
00350 uint8_t UnityNote;
00351 int16_t FineTune;
00352 int32_t Gain;
00353 bool NoSampleDepthTruncation;
00354 bool NoSampleCompression;
00355 uint32_t SampleLoops;
00356 sample_loop_t* pSampleLoops;
00357
00358 virtual void UpdateChunks();
00359 protected:
00360 RIFF::List* pParentList;
00361 uint32_t uiHeaderSize;
00362 uint32_t SamplerOptions;
00363 Sampler(RIFF::List* ParentList);
00364 virtual ~Sampler();
00365 };
00366
00375 class Sample : public Resource {
00376 public:
00377 uint16_t FormatTag;
00378 uint16_t Channels;
00379 uint32_t SamplesPerSecond;
00380 uint32_t AverageBytesPerSecond;
00381 uint16_t BlockAlign;
00382 uint16_t BitDepth;
00383 unsigned long SamplesTotal;
00384 uint FrameSize;
00385
00386 void* LoadSampleData();
00387 void ReleaseSampleData();
00388 unsigned long GetSize();
00389 void Resize(int iNewSize);
00390 unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
00391 unsigned long Read(void* pBuffer, unsigned long SampleCount);
00392 unsigned long Write(void* pBuffer, unsigned long SampleCount);
00393 virtual void UpdateChunks();
00394 protected:
00395 RIFF::List* pWaveList;
00396 RIFF::Chunk* pCkData;
00397 RIFF::Chunk* pCkFormat;
00398 unsigned long ulWavePoolOffset;
00399
00400 Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset);
00401 virtual ~Sample();
00402 friend class File;
00403 friend class Region;
00404 };
00405
00407 class Region : public Resource, public Articulator, public Sampler {
00408 public:
00409 range_t KeyRange;
00410 range_t VelocityRange;
00411 uint16_t KeyGroup;
00412 uint16_t Layer;
00413 bool SelfNonExclusive;
00414 bool PhaseMaster;
00415 uint16_t PhaseGroup;
00416 bool MultiChannel;
00417 uint32_t Channel;
00418
00419 Sample* GetSample();
00420 void SetSample(Sample* pSample);
00421 virtual void UpdateChunks();
00422 protected:
00423 RIFF::List* pCkRegion;
00424 uint32_t WavePoolTableIndex;
00425 Sample* pSample;
00426 uint16_t FormatOptionFlags;
00427 uint16_t WaveLinkOptionFlags;
00428
00429 Region(Instrument* pInstrument, RIFF::List* rgnList);
00430 virtual ~Region();
00431 friend class Instrument;
00432 };
00433
00435 class Instrument : public Resource, public Articulator {
00436 public:
00437 bool IsDrum;
00438 uint16_t MIDIBank;
00439 uint8_t MIDIBankCoarse;
00440 uint8_t MIDIBankFine;
00441 uint32_t MIDIProgram;
00442 uint32_t Regions;
00443
00444 Region* GetFirstRegion();
00445 Region* GetNextRegion();
00446 Region* AddRegion();
00447 void DeleteRegion(Region* pRegion);
00448 virtual void UpdateChunks();
00449 protected:
00450 typedef std::list<Region*> RegionList;
00451 struct midi_locale_t {
00452 uint32_t bank;
00453 uint32_t instrument;
00454 };
00455
00456 RIFF::List* pCkInstrument;
00457 RegionList* pRegions;
00458 RegionList::iterator RegionsIterator;
00459
00460 Instrument(File* pFile, RIFF::List* insList);
00461 virtual void LoadRegions();
00462 virtual ~Instrument();
00463 friend class File;
00464 };
00465
00467 class File : public Resource {
00468 public:
00469 version_t* pVersion;
00470 uint32_t Instruments;
00471
00472 File();
00473 File(RIFF::File* pRIFF);
00474 Sample* GetFirstSample();
00475 Sample* GetNextSample();
00476 Sample* AddSample();
00477 void DeleteSample(Sample* pSample);
00478 Instrument* GetFirstInstrument();
00479 Instrument* GetNextInstrument();
00480 Instrument* AddInstrument();
00481 void DeleteInstrument(Instrument* pInstrument);
00482 virtual void UpdateChunks();
00483 virtual void Save(const String& Path);
00484 virtual void Save();
00485 virtual ~File();
00486 protected:
00487 typedef std::list<Sample*> SampleList;
00488 typedef std::list<Instrument*> InstrumentList;
00489
00490 RIFF::File* pRIFF;
00491 std::list<RIFF::File*> ExtensionFiles;
00492 SampleList* pSamples;
00493 SampleList::iterator SamplesIterator;
00494 InstrumentList* pInstruments;
00495 InstrumentList::iterator InstrumentsIterator;
00496 uint32_t WavePoolHeaderSize;
00497 uint32_t WavePoolCount;
00498 uint32_t* pWavePoolTable;
00499 uint32_t* pWavePoolTableHi;
00500 bool b64BitWavePoolOffsets;
00501
00502 virtual void LoadSamples();
00503 virtual void LoadInstruments();
00504 void __ensureMandatoryChunksExist();
00505 friend class Region;
00506 private:
00507 void __UpdateWavePoolTableChunk();
00508 void __UpdateWavePoolTable();
00509 };
00510
00512 class Exception : public RIFF::Exception {
00513 public:
00514 Exception(String Message);
00515 void PrintMessage();
00516 };
00517
00518 String libraryName();
00519 String libraryVersion();
00520
00521 }
00522
00523 #endif // __DLS_H__