DLS.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libgig - C++ cross-platform Gigasampler format file access library    *
00004  *                                                                         *
00005  *   Copyright (C) 2003-2010 by Christian Schoenebeck                      *
00006  *                              <cuse@users.sourceforge.net>               *
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this library; if not, write to the Free Software           *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
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_WVPL 0x7776706C
00032 # define LIST_TYPE_DWPL 0x6477706C  
00033 # define LIST_TYPE_WAVE 0x77617665
00034 # define LIST_TYPE_LINS 0X6C696E73
00035 # define LIST_TYPE_INS  0X696E7320
00036 # define LIST_TYPE_LRGN 0x6C72676E
00037 # define LIST_TYPE_LART 0x6C617274
00038 # define LIST_TYPE_LAR2 0x6C617232
00039 # define LIST_TYPE_RGN  0x72676E20
00040 # define LIST_TYPE_RGN2 0x72676E32
00041 # define CHUNK_ID_IARL  0x4941524C
00042 # define CHUNK_ID_IART  0x49415254
00043 # define CHUNK_ID_ICMS  0x49434D53
00044 # define CHUNK_ID_IGNR  0x49474E52
00045 # define CHUNK_ID_IKEY  0x494B4559
00046 # define CHUNK_ID_IMED  0x494D4544
00047 # define CHUNK_ID_ISBJ  0x4953424A
00048 # define CHUNK_ID_ISRC  0x49535243
00049 # define CHUNK_ID_ISRF  0x49535246
00050 # define CHUNK_ID_ITCH  0x49544348
00051 # define CHUNK_ID_VERS  0x76657273
00052 # define CHUNK_ID_DLID  0x646C6964
00053 # define CHUNK_ID_FMT   0x666D7420
00054 # define CHUNK_ID_DATA  0x64617461
00055 # define CHUNK_ID_INSH  0x696E7368
00056 # define CHUNK_ID_RGNH  0x72676E68
00057 # define CHUNK_ID_WLNK  0x776C6E6B
00058 # define CHUNK_ID_PTBL  0x7074626C
00059 # define CHUNK_ID_WSMP  0x77736D70
00060 # define CHUNK_ID_COLH  0x636F6C68
00061 # define CHUNK_ID_ARTL  0x6172746C
00062 # define CHUNK_ID_ART2  0x61727432
00063 #else  // little endian
00064 # define RIFF_TYPE_DLS  0x20534C44
00065 # define LIST_TYPE_WVPL 0x6C707677
00066 # define LIST_TYPE_DWPL 0x6C707764  
00067 # define LIST_TYPE_WAVE 0x65766177
00068 # define LIST_TYPE_LINS 0X736E696C
00069 # define LIST_TYPE_INS  0X20736E69
00070 # define LIST_TYPE_LRGN 0x6E67726C
00071 # define LIST_TYPE_LART 0x7472616C
00072 # define LIST_TYPE_LAR2 0x3272616C
00073 # define LIST_TYPE_RGN  0x206E6772
00074 # define LIST_TYPE_RGN2 0x326E6772
00075 # define CHUNK_ID_IARL  0x4C524149
00076 # define CHUNK_ID_IART  0x54524149
00077 # define CHUNK_ID_ICMS  0x534D4349
00078 # define CHUNK_ID_IGNR  0x524E4749
00079 # define CHUNK_ID_IKEY  0x59454B49
00080 # define CHUNK_ID_IMED  0x44454D49
00081 # define CHUNK_ID_ISBJ  0x4A425349
00082 # define CHUNK_ID_ISRC  0x43525349
00083 # define CHUNK_ID_ISRF  0x46525349
00084 # define CHUNK_ID_ITCH  0x48435449
00085 # define CHUNK_ID_VERS  0x73726576
00086 # define CHUNK_ID_DLID  0x64696C64
00087 # define CHUNK_ID_FMT   0x20746D66
00088 # define CHUNK_ID_DATA  0x61746164
00089 # define CHUNK_ID_INSH  0x68736E69
00090 # define CHUNK_ID_RGNH  0x686E6772
00091 # define CHUNK_ID_WLNK  0x6B6E6C77
00092 # define CHUNK_ID_PTBL  0x6C627470
00093 # define CHUNK_ID_WSMP  0x706D7377
00094 # define CHUNK_ID_COLH  0x686C6F63
00095 # define CHUNK_ID_ARTL  0x6C747261
00096 # define CHUNK_ID_ART2  0x32747261
00097 #endif // WORDS_BIGENDIAN
00098 
00099 #define DLS_WAVE_FORMAT_PCM                     0x0001
00100 
00101 //TODO: no support for conditional chunks <cdl> yet
00102 
00104 namespace DLS {
00105 
00106     typedef std::string String;
00107 
00109     struct version_t {
00110         uint16_t minor;
00111         uint16_t major;
00112         uint16_t build;
00113         uint16_t release;
00114     };
00115 
00117     struct dlsid_t {
00118         uint32_t ulData1;
00119         uint16_t usData2;
00120         uint16_t usData3;
00121         uint8_t  abData[8];
00122     };
00123 
00125     typedef enum {
00126         // Modulator Sources
00127         conn_src_none            = 0x0000,
00128         conn_src_lfo             = 0x0001,
00129         conn_src_keyonvelocity   = 0x0002,
00130         conn_src_keynumber       = 0x0003,
00131         conn_src_eg1             = 0x0004,
00132         conn_src_eg2             = 0x0005,
00133         conn_src_pitchwheel      = 0x0006,
00134         conn_src_polypressure    = 0x0007,
00135         conn_src_channelpressure = 0x0008,
00136         conn_src_vibrato         = 0x0009,
00137         // MIDI Controller Sources
00138         conn_src_cc1             = 0x0081,
00139         conn_src_cc7             = 0x0087,
00140         conn_src_cc10            = 0x008A,
00141         conn_src_cc11            = 0x008B,
00142         conn_src_cc91            = 0x00DB,
00143         conn_src_cc93            = 0x00DD,
00144         // Registered Parameter Numbers
00145         conn_src_rpn0            = 0x0100,
00146         conn_src_rpn1            = 0x0101,
00147         conn_src_rpn2            = 0x0102
00148     } conn_src_t;
00149 
00151     typedef enum {
00152         // Generic Destinations
00153         conn_dst_none             = 0x0000,
00154         conn_dst_gain             = 0x0001,
00155         conn_dst_reserved         = 0x0002,
00156         conn_dst_pitch            = 0x0003,
00157         conn_dst_pan              = 0x0004,
00158         conn_dst_keynumber        = 0x0005,
00159         // Channel Output Destinations
00160         conn_dst_left             = 0x0010,
00161         conn_dst_right            = 0x0011,
00162         conn_dst_center           = 0x0012,
00163         conn_dst_lfe_channel      = 0x0013,
00164         conn_dst_leftrear         = 0x0014,
00165         conn_dst_rightrear        = 0x0015,
00166         conn_dst_chorus           = 0x0080,
00167         conn_dst_reverb           = 0x0081,
00168         // Modulator LFO Destinations
00169         conn_dst_lfo_frequency    = 0x0104,
00170         conn_dst_lfo_startdelay   = 0x0105,
00171         // Vibrato LFO Destinations
00172         conn_dst_vib_frequency    = 0x0114,
00173         conn_dst_vib_startdelay   = 0x0115,
00174         // EG Destinations
00175         conn_dst_eg1_attacktime   = 0x0206,
00176         conn_dst_eg1_decaytime    = 0x0207,
00177         conn_dst_eg1_reserved     = 0x0208,
00178         conn_dst_eg1_releasetime  = 0x0209,
00179         conn_dst_eg1_sustainlevel = 0x020A,
00180         conn_dst_eg1_delaytime    = 0x020B,
00181         conn_dst_eg1_holdtime     = 0x020C,
00182         conn_dst_eg1_shutdowntime = 0x020D,
00183         conn_dst_eg2_attacktime   = 0x030A,
00184         conn_dst_eg2_decaytime    = 0x030B,
00185         conn_dst_eg2_reserved     = 0x030C,
00186         conn_dst_eg2_releasetime  = 0x030D,
00187         conn_dst_eg2_sustainlevel = 0x030E,
00188         conn_dst_eg2_delaytime    = 0x030F,
00189         conn_dst_eg2_holdtime     = 0x0310,
00190         // Filter Destinations
00191         conn_dst_filter_cutoff    = 0x0500,
00192         conn_dst_filter_q         = 0x0501
00193     } conn_dst_t;
00194 
00196     typedef enum {
00197         conn_trn_none    = 0x0000,
00198         conn_trn_concave = 0x0001,
00199         conn_trn_convex  = 0x0002,
00200         conn_trn_switch  = 0x0003
00201     } conn_trn_t;
00202 
00204     struct range_t {
00205         uint16_t low;  
00206         uint16_t high; 
00207     };
00208 
00210     struct sample_loop_t {
00211         uint32_t Size;       
00212         uint32_t LoopType;   
00213         uint32_t LoopStart;  
00214         uint32_t LoopLength; 
00215     };
00216 
00217     // just symbol prototyping
00218     class File;
00219     class Instrument;
00220     class Region;
00221     class Sample;
00222 
00224     class Connection {
00225         public:
00226             conn_src_t Source;
00227             conn_trn_t SourceTransform;
00228             bool       SourceInvert;
00229             bool       SourceBipolar;
00230             conn_src_t Control;
00231             conn_trn_t ControlTransform;
00232             bool       ControlInvert;
00233             bool       ControlBipolar;
00234             conn_dst_t Destination;
00235             conn_trn_t DestinationTransform;
00236             uint32_t   Scale;
00237         protected:
00238             struct conn_block_t {
00239                 uint16_t source;
00240                 uint16_t control;
00241                 uint16_t destination;
00242                 uint16_t transform;
00243                 uint32_t scale;
00244             };
00245             Connection() {}
00246             void Init(conn_block_t* Header);
00247             conn_block_t ToConnBlock();
00248             virtual ~Connection() {}
00249             friend class Articulation;
00250     };
00251 
00253     class Articulation {
00254         public:
00255             Connection*  pConnections; 
00256             uint32_t     Connections;  
00257 
00258             Articulation(RIFF::Chunk* artl);
00259             virtual ~Articulation();
00260             virtual void UpdateChunks();
00261         protected:
00262             RIFF::Chunk* pArticulationCk;
00263             uint32_t     HeaderSize;
00264     };
00265 
00267     class Articulator {
00268         public:
00269             Articulator(RIFF::List* ParentList);
00270             Articulation* GetFirstArticulation();
00271             Articulation* GetNextArticulation();
00272             virtual void  UpdateChunks();
00273         protected:
00274             typedef std::list<Articulation*> ArticulationList;
00275             RIFF::List*                 pParentList;
00276             ArticulationList*           pArticulations;
00277             ArticulationList::iterator  ArticulationsIterator;
00278 
00279             void LoadArticulations();
00280             virtual ~Articulator();
00281     };
00282 
00284     class Info {
00285         public:
00286             String Name;             
00287             String ArchivalLocation; 
00288             String CreationDate;     
00289             String Comments;         
00290             String Product;          
00291             String Copyright;        
00292             String Artists;          
00293             String Genre;            
00294             String Keywords;         
00295             String Engineer;         
00296             String Technician;       
00297             String Software;         
00298             String Medium;           
00299             String Source;           
00300             String SourceForm;       
00301             String Commissioned;     
00302             String Subject;          
00303             bool UseFixedLengthStrings; 
00304 
00305             struct string_length_t {
00306                 uint32_t chunkId;
00307                 int      length;
00308             };
00309 
00310             Info(RIFF::List* list);
00311             void SetFixedStringLengths(const string_length_t* lengths);
00312             virtual ~Info();
00313             virtual void UpdateChunks();
00314         private:
00315             RIFF::List*            pResourceListChunk;
00316             const string_length_t* pFixedStringLengths; 
00317 
00318             static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
00319             void SaveString(uint32_t ChunkID, RIFF::List* lstINFO, const String& s, const String& sDefault);
00320     };
00321 
00323     class Resource {
00324         public:
00325             Info*    pInfo;  
00326             dlsid_t* pDLSID; 
00327 
00328             Resource* GetParent() { return pParent; }
00329             virtual void UpdateChunks();
00330             void GenerateDLSID();
00331         protected:
00332             Resource* pParent;
00333             RIFF::List* pResourceList;
00334 
00335             Resource(Resource* Parent, RIFF::List* lstResource);
00336             virtual ~Resource();
00337     };
00338 
00340     class Sampler {
00341         public:
00342             uint8_t        UnityNote;
00343             int16_t        FineTune;
00344             int32_t        Gain; 
00345             bool           NoSampleDepthTruncation;
00346             bool           NoSampleCompression;
00347             uint32_t       SampleLoops;  
00348             sample_loop_t* pSampleLoops; 
00349 
00350             void AddSampleLoop(sample_loop_t* pLoopDef);
00351             void DeleteSampleLoop(sample_loop_t* pLoopDef);
00352             virtual void SetGain(int32_t gain);
00353             virtual void UpdateChunks();
00354         protected:
00355             RIFF::List*    pParentList;
00356             uint32_t       uiHeaderSize;
00357             uint32_t       SamplerOptions;
00358             Sampler(RIFF::List* ParentList);
00359             virtual ~Sampler();
00360     };
00361 
00370     class Sample : public Resource {
00371         public:
00372             uint16_t      FormatTag;             
00373             uint16_t      Channels;              
00374             uint32_t      SamplesPerSecond;      
00375             uint32_t      AverageBytesPerSecond; 
00376             uint16_t      BlockAlign;            
00377             uint16_t      BitDepth;              
00378             unsigned long SamplesTotal;          
00379             uint          FrameSize;             
00380 
00381             void*         LoadSampleData();
00382             void          ReleaseSampleData();
00383             unsigned long GetSize();
00384             void          Resize(int iNewSize);
00385             unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
00386             unsigned long Read(void* pBuffer, unsigned long SampleCount);
00387             unsigned long Write(void* pBuffer, unsigned long SampleCount);
00388             virtual void  UpdateChunks();
00389         protected:
00390             RIFF::List*   pWaveList;
00391             RIFF::Chunk*  pCkData;
00392             RIFF::Chunk*  pCkFormat;
00393             unsigned long ulWavePoolOffset;  // needed for comparison with the wave pool link table, thus the link to instruments
00394 
00395             Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset);
00396             virtual ~Sample();
00397             friend class File;
00398             friend class Region; // Region has to compare the wave pool offset to get its sample
00399     };
00400 
00402     class Region : public Resource, public Articulator, public Sampler {
00403         public:
00404             range_t     KeyRange; 
00405             range_t     VelocityRange;
00406             uint16_t    KeyGroup;
00407             uint16_t    Layer;
00408             bool        SelfNonExclusive;
00409             bool        PhaseMaster;
00410             uint16_t    PhaseGroup;
00411             bool        MultiChannel;
00412             uint32_t    Channel;
00413 
00414             Sample*     GetSample();
00415             void        SetSample(Sample* pSample);
00416             virtual void SetKeyRange(uint16_t Low, uint16_t High);
00417             virtual void UpdateChunks();
00418         protected:
00419             RIFF::List* pCkRegion;
00420             uint32_t    WavePoolTableIndex; // index in the wave pool table to the sample wave this region is linked to
00421             Sample*     pSample;            // every region refers to exactly one sample
00422             uint16_t    FormatOptionFlags;
00423             uint16_t    WaveLinkOptionFlags;
00424 
00425             Region(Instrument* pInstrument, RIFF::List* rgnList);
00426             virtual ~Region();
00427             friend class Instrument;
00428     };
00429 
00431     class Instrument : public Resource, public Articulator {
00432         public:
00433             bool     IsDrum;         
00434             uint16_t MIDIBank;       
00435             uint8_t  MIDIBankCoarse; 
00436             uint8_t  MIDIBankFine;   
00437             uint32_t MIDIProgram;    
00438             uint32_t Regions;        
00439 
00440             Region*  GetFirstRegion();
00441             Region*  GetNextRegion();
00442             Region*  AddRegion();
00443             void     DeleteRegion(Region* pRegion);
00444             virtual void UpdateChunks();
00445         protected:
00446             typedef std::list<Region*> RegionList;
00447             struct midi_locale_t {
00448                 uint32_t bank;
00449                 uint32_t instrument;
00450             };
00451 
00452             RIFF::List*          pCkInstrument;
00453             RegionList*          pRegions;
00454             RegionList::iterator RegionsIterator;
00455 
00456             Instrument(File* pFile, RIFF::List* insList);
00457             virtual void LoadRegions();
00458             virtual ~Instrument();
00459             friend class File;
00460             friend class Region;
00461         private:
00462             void MoveRegion(Region* pSrc, Region* pDst);
00463     };
00464 
00466     class File : public Resource {
00467         public:
00468             version_t* pVersion;              
00469             uint32_t   Instruments;           
00470 
00471             File();
00472             File(RIFF::File* pRIFF);
00473             Sample*     GetFirstSample();     
00474             Sample*     GetNextSample();      
00475             Sample*     AddSample();
00476             void        DeleteSample(Sample* pSample);
00477             Instrument* GetFirstInstrument(); 
00478             Instrument* GetNextInstrument();  
00479             Instrument* AddInstrument();
00480             void        DeleteInstrument(Instrument* pInstrument);
00481             virtual void UpdateChunks();
00482             virtual void Save(const String& Path);
00483             virtual void Save();
00484             virtual ~File();
00485         protected:
00486             typedef std::list<Sample*>     SampleList;
00487             typedef std::list<Instrument*> InstrumentList;
00488 
00489             RIFF::File*              pRIFF;
00490             std::list<RIFF::File*>   ExtensionFiles;
00491             SampleList*              pSamples;
00492             SampleList::iterator     SamplesIterator;
00493             InstrumentList*          pInstruments;
00494             InstrumentList::iterator InstrumentsIterator;
00495             uint32_t                 WavePoolHeaderSize;
00496             uint32_t                 WavePoolCount;
00497             uint32_t*                pWavePoolTable;
00498             uint32_t*                pWavePoolTableHi;
00499             bool                     b64BitWavePoolOffsets;
00500 
00501             virtual void LoadSamples();
00502             virtual void LoadInstruments();
00503             void __ensureMandatoryChunksExist();
00504             friend class Region; // Region has to look in the wave pool table to get its sample
00505         private:
00506             void __UpdateWavePoolTableChunk();
00507             void __UpdateWavePoolTable();
00508     };
00509 
00517     class Exception : public RIFF::Exception {
00518         public:
00519             Exception(String Message);
00520             void PrintMessage();
00521     };
00522 
00523     String libraryName();
00524     String libraryVersion();
00525 
00526 } // namespace DLS
00527 
00528 #endif // __DLS_H__

Generated on Sun May 1 03:22:45 2011 for libgig by  doxygen 1.5.2