SF.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libsf2 - C++ cross-platform SF2 format file access library            *
00004  *                                                                         *
00005  *   Copyright (C) 2009-2010 by Grigor Iliev  <grigor@grigoriliev.com>     *
00006  *                                                                         *
00007  *   This library is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This library is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this library; if not, write to the Free Software           *
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00020  *   MA  02111-1307  USA                                                   *
00021  ***************************************************************************/
00022 
00023 #ifndef __SF2_SF_H__
00024 #define __SF2_SF_H__
00025 
00026 #include "RIFF.h"
00027 
00028 #include <vector>
00029 
00030 
00031 #define RIFF_ID(x) (*((uint32_t*) x))
00032 
00033 
00034 #define RIFF_TYPE_SF2   RIFF_ID("sfbk")
00035 
00036 // Level 0
00037 #define LIST_TYPE_SDTA  RIFF_ID("sdta")
00038 #define LIST_TYPE_PDTA  RIFF_ID("pdta")
00039 
00040 // Level 1
00041 //<INFO-list>
00042 #define CHUNK_ID_IFIL   RIFF_ID("ifil")
00043 #define CHUNK_ID_ISNG   RIFF_ID("isng")
00044 #define CHUNK_ID_IROM   RIFF_ID("irom")
00045 #define CHUNK_ID_IVER   RIFF_ID("iver")
00046 
00047 //<sdta-list>
00048 #define CHUNK_ID_SM24   RIFF_ID("sm24")
00049 
00050 //<pdta-list>
00051 #define CHUNK_ID_PHDR   RIFF_ID("phdr")
00052 #define CHUNK_ID_PBAG   RIFF_ID("pbag")
00053 #define CHUNK_ID_PMOD   RIFF_ID("pmod")
00054 #define CHUNK_ID_PGEN   RIFF_ID("pgen")
00055 #define CHUNK_ID_INST   RIFF_ID("inst")
00056 #define CHUNK_ID_IBAG   RIFF_ID("ibag")
00057 #define CHUNK_ID_IMOD   RIFF_ID("imod")
00058 #define CHUNK_ID_IGEN   RIFF_ID("igen")
00059 #define CHUNK_ID_SHDR   RIFF_ID("shdr")
00060 
00062 namespace sf2 {
00063 
00064     static uint NONE = 0x1ffffff;
00065 
00066     typedef struct _PresetBag {
00067         uint16_t GenNdx;
00068         uint16_t ModNdx;
00069     } PresetBag;
00070 
00071     typedef uint16_t SFModulator;
00072     typedef uint16_t SFGenerator;
00073     typedef uint16_t SFTransform;
00074 
00075     typedef struct _ModList {
00076         SFModulator  ModSrcOper;
00077         SFGenerator  ModDestOper;
00078         uint16_t     ModAmount;
00079         SFModulator  ModAmtSrcOper;
00080         SFTransform  ModTransOper;
00081     } ModList;
00082 
00083     typedef struct _RangesType {
00084         #if WORDS_BIGENDIAN
00085         uint8_t byHi;
00086         uint8_t byLo;
00087         #else
00088         uint8_t byLo;
00089         uint8_t byHi;
00090         #endif
00091     } RangesType;
00092 
00093     typedef union _GenAmountType {
00094         RangesType  ranges;
00095         short       shAmount;
00096         uint16_t    wAmount;
00097     } GenAmountType;
00098 
00099     typedef struct _GenList {
00100         SFGenerator    GenOper;
00101         GenAmountType  GenAmount;
00102     } GenList;
00103 
00104     typedef struct _InstBag {
00105         uint16_t InstGenNdx;
00106         uint16_t InstModNdx;
00107     } InstBag;
00108 
00109     typedef enum {
00110         START_ADDRS_OFFSET = 0,
00111         END_ADDRS_OFFSET,
00112         STARTLOOP_ADDRS_OFFSET,
00113         ENDLOOP_ADDRS_OFFSET ,
00114         START_ADDRS_COARSE_OFFSET,
00115         MOD_LFO_TO_PITCH,
00116         VIB_LFO_TO_PITCH,
00117         MOD_ENV_TO_PITCH,
00118         INITIAL_FILTER_FC,
00119         INITIAL_FILTER_Q,
00120         MOD_LFO_TO_FILTER_FC, // 10
00121         MOD_ENV_TO_FILTER_FC,
00122         END_ADDRS_COARSE_OFFSET,
00123         MOD_LFO_TO_VOLUME,
00124         UNUSED1,
00125         CHORUS_EFFECTS_SEND,
00126         REVERB_EFFECTS_SEND,
00127         PAN,
00128         UNUSED2,
00129         UNUSED3,
00130         UNUSED4, //20
00131         DELAY_MOD_LFO,
00132         FREQ_MOD_LFO,
00133         DELAY_VIB_LFO,
00134         FREQ_VIB_LFO,
00135         DELAY_MOD_ENV,
00136         ATTACK_MOD_ENV,
00137         HOLD_MOD_ENV,
00138         DECAY_MOD_ENV,
00139         SUSTAIN_MOD_ENV,
00140         RELEASEMODENV, // 30
00141         KEYNUM_TO_MOD_ENV_HOLD,
00142         KEYNUM_TO_MOD_ENV_DECAY,
00143         DELAY_VOL_ENV,
00144         ATTACK_VOL_ENV,
00145         HOLD_VOL_ENV,
00146         DECAY_VOL_ENV,
00147         SUSTAIN_VOL_ENV,
00148         RELEASE_VOL_ENV,
00149         KEYNUM_TO_VOL_ENV_HOLD,
00150         KEYNUM_TO_VOL_ENV_DECAY, //40
00151         INSTRUMENT,
00152         RESERVED1,
00153         KEY_RANGE,
00154         VEL_RANGE,
00155         STARTLOOP_ADDRS_COARSE_OFFSET,
00156         KEYNUM,
00157         VELOCITY,
00158         INITIAL_ATTENUATION,
00159         RESERVED2,
00160         ENDLOOP_ADDRS_COARSE_OFFSET, // 50
00161         COARSE_TUNE,
00162         FINE_TUNE,
00163         SAMPLE_ID,
00164         SAMPLE_MODES,
00165         RESERVED3,
00166         SCALE_TUNING,
00167         EXCLUSIVE_CLASS,
00168         OVERRIDING_ROOT_KEY,
00169         UNUSED5,
00170         END_OPER
00171     } SFGeneratorType;
00172 
00173     class Modulator {
00174         public:
00175 
00180             enum {
00181                 NO_CONTROLLER = 0,
00182                 NOTE_ON_VELOCITY = 2,
00183                 NOTE_ON_KEY_NUMBER = 3,
00184                 POLY_PRESSURE = 10,
00185                 CHANNEL_PRESSURE = 13,
00186                 PITCH_WHEEL = 14,
00187                 PITCH_WHEEL_SENSITIVITY = 16,
00188                 LINK = 127
00189             };
00190 
00194             enum {
00195                 LINEAR = 0,
00196                 CONCAVE,
00197                 CONVEX,
00198                 SWITCH
00199             };
00200 
00201             int  Type;
00202             bool MidiPalete;
00203             bool Direction;
00204             bool Polarity;
00205             int  Index;
00206 
00207             Modulator(SFModulator mod);
00208     };
00209 
00210     class ModulatorItem {
00211         public:
00212             Modulator    ModSrcOper;
00213             SFGenerator  ModDestOper;
00214             uint16_t     ModAmount;
00215             Modulator    ModAmtSrcOper;
00216             SFTransform  ModTransOper;
00217 
00218             ModulatorItem(ModList& mod);
00219     };
00220 
00221 
00222     typedef std::string String;
00223 
00224     class Exception : public RIFF::Exception {
00225         public: Exception(String Message) : RIFF::Exception(Message) { }
00226     };
00227 
00228     class Version {
00229         public:
00230             int Major;
00231             int Minor;
00232 
00233             Version(RIFF::Chunk* ck);
00234     };
00235 
00236     class Info {
00237         public:
00238             Version*  pVer;          
00239             String    SoundEngine;   
00240             String    BankName;      
00241             String    RomName;       
00242             Version*  pRomVer;       
00243             String    CreationDate;  
00244             String    Engineers;     
00245             String    Product;       
00246             String    Copyright;     
00247             String    Comments;      
00248             String    Software;      
00249 
00250             Info(RIFF::List* list);
00251             ~Info();
00252         private:
00253             static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
00254     };
00255 
00256     class Region;
00257 
00258     class Sample {
00259         public:
00260 
00261             typedef enum {
00262                 MONO_SAMPLE       = 1,
00263                 RIGHT_SAMPLE      = 2,
00264                 LEFT_SAMPLE       = 4,
00265                 LINKED_SAMPLE     = 8,
00266                 ROM_MONO_SAMPLE   = 0x8001,
00267                 ROM_RIGHT_SAMPLE  = 0x8002,
00268                 ROM_LEFT_SAMPLE   = 0x8004,
00269                 ROM_LINKED_SAMPLE = 0x8008
00270             } Link;
00271 
00273             class PlaybackState {
00274                 public:
00275                     unsigned long position;          
00276                     bool          reverse;           
00277                     unsigned long loop_cycles_left;  
00278             };
00279 
00281             struct buffer_t {
00282                 void*         pStart;            
00283                 unsigned long Size;              
00284                 unsigned long NullExtensionSize; 
00285                 buffer_t() {
00286                     pStart            = NULL;
00287                     Size              = 0;
00288                     NullExtensionSize = 0;
00289                 }
00290             };
00291 
00292             String Name;
00293 
00294             Sample(RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24);
00295 
00296             String  GetName() { return Name; }
00297             int     GetChannelCount();
00298             long    GetTotalFrameCount();
00299             int     GetFrameSize();
00300             bool    HasLoops();
00301             bool    IsUnpitched() { return OriginalPitch == 255; }
00302 
00303             buffer_t  LoadSampleData();
00304             buffer_t  LoadSampleData(unsigned long SampleCount);
00305             buffer_t  LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
00306             buffer_t  LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
00307             buffer_t  GetCache();
00308             void      ReleaseSampleData();
00309             unsigned long SetPos(unsigned long SampleCount);
00310             unsigned long GetPos();
00311             unsigned long Read(void* pBuffer, unsigned long SampleCount);
00312 
00313             unsigned long ReadAndLoop (
00314                 void*           pBuffer,
00315                 unsigned long   FrameCount,
00316                 PlaybackState*  pPlaybackState,
00317                 Region*         pRegion
00318             );
00319 
00320         //protected:
00321             buffer_t      RAMCache;   
00322             RIFF::Chunk*  pCkSmpl;
00323             RIFF::Chunk*  pCkSm24;
00324 
00325         //private:
00326             int ChannelCount; // 2 for left and right samples
00327 
00328             uint32_t Start;     // in sample data points (frames) from the begining of the sample data field
00329             uint32_t End;       // in sample data points (frames) from the begining of the sample data field
00330             uint32_t StartLoop; // in sample data points (frames) from the begining of the sample data field
00331             uint32_t EndLoop;   // in sample data points (frames) from the begining of the sample data field
00332             uint32_t SampleRate;
00333             uint8_t  OriginalPitch;
00334             uint8_t  PitchCorrection;
00335             uint16_t SampleLink; /* If sfSampleType indicates a left or right sample, the
00336                                   * sample header index of the associated right or left stereo
00337                                   * sample respectively; zero otherwise. */
00338             uint16_t SampleType;
00339     };
00340 
00341     class File;
00342     class Instrument;
00343 
00347     class Region {
00348         public:
00349             int loKey, hiKey;
00350             int minVel, maxVel;
00351             int pan; // -64 - +63
00352             int fineTune; // -99 - +99
00353             int coarseTune; // TODO:
00354             int overridingRootKey; // represents the MIDI key number at which the sample is to be played back at its original sample rate.
00355             int startAddrsOffset, startAddrsCoarseOffset, endAddrsOffset, endAddrsCoarseOffset;
00356             int startloopAddrsOffset, startloopAddrsCoarseOffset, endloopAddrsOffset, endloopAddrsCoarseOffset;
00357 
00358             int modEnvToPitch, modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume, freqModLfo;
00359             int delayModLfo;
00360             int vibLfoToPitch, freqVibLfo;
00361             int delayVibLfo;
00362 
00363             uint exclusiveClass; // exclusive group
00364 
00365             Sample* pSample;
00366             bool    HasLoop;
00367             uint    LoopStart; // index (in frames) from the beginning of the sample
00368             uint    LoopEnd;   // index (in frames) from the beginning of the sample
00369             Instrument* pInstrument; // used when the region belongs to preset
00370 
00371             Region();
00372             Sample* GetSample() { return pSample; }
00373             Region* GetParent() { return this; }
00374 
00375             int GetUnityNote();
00376 
00381             Instrument* GetParentInstrument() { return pParentInstrument; }
00382 
00383             std::vector<ModulatorItem> modulators;
00384 
00385 
00386             // Instrument can be referenced by more than one presets so we need to calculate values on the fly
00387             int    GetPan(Region* pPresetRegion = NULL); // -64 - +63
00388             int    GetFineTune(Region* pPresetRegion = NULL); // -99 - +99
00389             int    GetCoarseTune(Region* pPresetRegion = NULL); // -120 - +120
00390             double GetEG1PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
00391             double GetEG1Attack(Region* pPresetRegion = NULL); // in seconds
00392             double GetEG1Hold(Region* pPresetRegion = NULL); // in seconds
00393             double GetEG1Decay(Region* pPresetRegion = NULL); // in seconds
00394             double GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (in permilles)
00395             double GetEG1Release(Region* pPresetRegion = NULL); // in seconds
00396 
00397             double GetEG2PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
00398             double GetEG2Attack(Region* pPresetRegion = NULL); // in seconds
00399             double GetEG2Hold(Region* pPresetRegion = NULL); // in seconds
00400             double GetEG2Decay(Region* pPresetRegion = NULL); // in seconds
00401             double GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
00402             double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
00403 
00404             int    GetModEnvToPitch(Region* pPresetRegion = NULL);
00405             int    GetModLfoToPitch(Region* pPresetRegion = NULL);
00406             int    GetModEnvToFilterFc(Region* pPresetRegion = NULL);
00407             int    GetModLfoToFilterFc(Region* pPresetRegion = NULL);
00408             double GetModLfoToVolume(Region* pPresetRegion = NULL); // in permilles
00409             double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
00410             double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
00411             int    GetVibLfoToPitch(Region* pPresetRegion = NULL);
00412             double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
00413             double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
00414 
00415             friend class Instrument;
00416             friend class Preset;
00417 
00418         private:
00419             int EG1PreAttackDelay; // in timecents
00420             int EG1Attack; // in timecents
00421             int EG1Hold; // in timecents
00422             int EG1Decay; // in timecents
00423             int EG1Sustain; // Sustain value of the sample amplitude EG (in permilles)
00424             int EG1Release; // in timecents
00425 
00426             int EG2PreAttackDelay; // in timecents
00427             int EG2Attack; // in timecents
00428             int EG2Hold; // in timecents
00429             int EG2Decay; // in timecents
00430             int EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
00431             int EG2Release; // in timecents
00432 
00433             Instrument* pParentInstrument;
00434 
00435             void SetGenerator(sf2::File* pFile, GenList& Gen);
00436             void SetModulator(sf2::File* pFile, ModList& Mod);
00437     };
00438 
00439     class InstrumentBase {
00440         public:
00441             String   Name;
00442             Region*  pGlobalRegion;
00443 
00444             InstrumentBase(sf2::File* pFile);
00445             virtual ~InstrumentBase();
00446 
00447             sf2::File* GetFile() { return pFile; }
00448             String     GetName() { return Name; }
00449 
00450             int      GetRegionCount();
00451             Region*  GetRegion(int idx);
00452 
00453         protected:
00454             std::vector<Region*> regions;
00455             sf2::File* pFile;
00456     };
00457 
00458     class Query {
00459         public:
00460             int key;
00461             uint8_t vel;
00462 
00463             Query(InstrumentBase& instrument);
00464             Region* next();
00465 
00466         private:
00467             InstrumentBase& instrument;
00468             int i;
00469     };
00470 
00471     class Instrument : public InstrumentBase {
00472         public:
00473             Instrument(sf2::File* pFile, RIFF::Chunk* ck);
00474             ~Instrument();
00475 
00476             void DeleteRegion(Region* pRegion);
00477         //private:
00478             uint16_t InstBagNdx;
00479 
00483             void LoadRegions(int idx1, int idx2);
00484 
00485             Region* CreateRegion();
00486     };
00487 
00488     class Preset : public InstrumentBase {
00489         public:
00490             uint16_t  PresetNum;
00491             uint16_t  Bank;
00492             uint32_t  Library;
00493             uint32_t  Genre;
00494             uint32_t  Morphology;
00495 
00496             Preset(sf2::File* pFile, RIFF::Chunk* ck);
00497             ~Preset();
00498 
00499         //private:
00500             sf2::File*  pFile;
00501             uint16_t    PresetBagNdx;
00502 
00506             void LoadRegions(int idx1, int idx2);
00507 
00508             Region* CreateRegion();
00509     };
00510 
00511     class File {
00512         public:
00513             Info* pInfo;
00514 
00515             File(RIFF::File* pRIFF);
00516             ~File();
00517 
00518             int          GetPresetCount();
00519             Preset*      GetPreset(int idx);
00520             int          GetInstrumentCount();
00521             Instrument*  GetInstrument(int idx);
00522             void         DeleteInstrument(Instrument* pInstrument);
00523             int          GetSampleCount();
00524             Sample*      GetSample(int idx);
00525             void         DeleteSample(Sample* pSample);
00526             bool         HasSamples();
00527 
00528             friend class Region;
00529             friend class Instrument;
00530             friend class Preset;
00531 
00532         protected:
00533             RIFF::File*             pRIFF;
00534             std::vector<PresetBag>  PresetBags;
00535             std::vector<ModList>    PresetModLists;
00536             std::vector<GenList>    PresetGenLists;
00537             std::vector<InstBag>    InstBags;
00538             std::vector<ModList>    InstModLists;
00539             std::vector<GenList>    InstGenLists;
00540 
00541         private:
00542             std::vector<Preset*> Presets;
00543             std::vector<Instrument*> Instruments;
00544             std::vector<Sample*> Samples;
00545     };
00546 
00547     String libraryName();
00548     String libraryVersion();
00549 
00550 } // namespace sf2
00551 #endif // __SF2_SF_H__

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