/[svn]/libgig/trunk/src/SF.h
ViewVC logotype

Annotation of /libgig/trunk/src/SF.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2020 - (hide annotations) (download) (as text)
Fri Oct 30 16:25:27 2009 UTC (14 years, 5 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 17042 byte(s)
* sf2: 24bit support
* sf2: loop support
* sf2: implemented overridingRootKey
* sf2: implemented instrument global region
* sf2: bugfix: some regions were ignored

1 iliev 2016 /***************************************************************************
2     * *
3     * libsf2 - C++ cross-platform SF2 format file access library *
4     * *
5     * Copyright (C) 2009 by Grigor Iliev <grigor@grigoriliev.com> *
6     * *
7     * This library is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This library is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this library; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #ifndef __SF2_SF_H__
24     #define __SF2_SF_H__
25    
26     #include "RIFF.h"
27    
28     #include <vector>
29    
30    
31     #if WORDS_BIGENDIAN
32     #define ENDIAN_SWAP(x) \
33     ( (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24) )
34     #else
35     #define ENDIAN_SWAP(x) (x)
36     #endif
37    
38     #define RIFF_ID(x) ENDIAN_SWAP( (*((uint32_t*) x)) )
39    
40    
41     #define RIFF_TYPE_SF2 RIFF_ID("sfbk")
42    
43     // Level 0
44     #define LIST_TYPE_INFO RIFF_ID("INFO")
45     #define LIST_TYPE_SDTA RIFF_ID("sdta")
46     #define LIST_TYPE_PDTA RIFF_ID("pdta")
47    
48     // Level 1
49     //<INFO-list>
50     #define CHUNK_ID_IFIL RIFF_ID("ifil")
51     #define CHUNK_ID_ISNG RIFF_ID("isng")
52     #define CHUNK_ID_INAM RIFF_ID("INAM")
53     #define CHUNK_ID_IROM RIFF_ID("irom")
54     #define CHUNK_ID_IVER RIFF_ID("iver")
55     #define CHUNK_ID_ICRD RIFF_ID("ICRD")
56     #define CHUNK_ID_IENG RIFF_ID("IENG")
57     #define CHUNK_ID_IPRD RIFF_ID("IPRD")
58     #define CHUNK_ID_ICOP RIFF_ID("ICOP")
59     #define CHUNK_ID_ICMT RIFF_ID("ICMT")
60     #define CHUNK_ID_ISFT RIFF_ID("ISFT")
61    
62     //<sdta-list>
63     #define CHUNK_ID_SMPL RIFF_ID("smpl")
64     #define CHUNK_ID_SM24 RIFF_ID("sm24")
65    
66     //<pdta-list>
67     #define CHUNK_ID_PHDR RIFF_ID("phdr")
68     #define CHUNK_ID_PBAG RIFF_ID("pbag")
69     #define CHUNK_ID_PMOD RIFF_ID("pmod")
70     #define CHUNK_ID_PGEN RIFF_ID("pgen")
71     #define CHUNK_ID_INST RIFF_ID("inst")
72     #define CHUNK_ID_IBAG RIFF_ID("ibag")
73     #define CHUNK_ID_IMOD RIFF_ID("imod")
74     #define CHUNK_ID_IGEN RIFF_ID("igen")
75     #define CHUNK_ID_SHDR RIFF_ID("shdr")
76    
77     #define NONE 0x1ffffff
78    
79     namespace sf2 {
80     typedef struct _PresetBag {
81     uint16_t GenNdx;
82     uint16_t ModNdx;
83     } PresetBag;
84    
85     typedef uint16_t SFModulator;
86     typedef uint16_t SFGenerator;
87     typedef uint16_t SFTransform;
88    
89     typedef struct _ModList {
90     SFModulator ModSrcOper;
91     SFGenerator ModDestOper;
92     uint16_t ModAmount;
93     SFModulator ModAmtSrcOper;
94     SFTransform ModTransOper;
95     } ModList;
96    
97     typedef struct _RangesType {
98     uint8_t byLo;
99     uint8_t byHi;
100     } RangesType;
101    
102     typedef union _GenAmountType {
103     RangesType ranges;
104     short shAmount;
105     uint16_t wAmount;
106     } GenAmountType;
107    
108     typedef struct _GenList {
109     SFGenerator GenOper;
110     GenAmountType GenAmount;
111     } GenList;
112    
113     typedef struct _InstBag {
114     uint16_t InstGenNdx;
115     uint16_t InstModNdx;
116     } InstBag;
117    
118     typedef enum {
119     START_ADDRS_OFFSET = 0,
120     END_ADDRS_OFFSET,
121     STARTLOOP_ADDRS_OFFSET,
122     ENDLOOP_ADDRS_OFFSET ,
123     START_ADDRS_COARSE_OFFSET,
124     MOD_LFO_TO_PITCH,
125     VIB_LFO_TO_PITCH,
126     MOD_ENV_TO_PITCH,
127     INITIAL_FILTER_FC,
128     INITIAL_FILTER_Q,
129     MOD_LFO_TO_FILTER_FC, // 10
130     MOD_ENV_TO_FILTER_FC,
131     END_ADDRS_COARSE_OFFSET,
132     MOD_LFO_TO_VOLUME,
133     UNUSED1,
134     CHORUS_EFFECTS_SEND,
135     REVERB_EFFECTS_SEND,
136     PAN,
137     UNUSED2,
138     UNUSED3,
139     UNUSED4, //20
140     DELAY_MOD_LFO,
141     FREQ_MOD_LFO,
142     DELAY_VIB_LFO,
143     FREQ_VIB_LFO,
144     DELAY_MOD_ENV,
145     ATTACK_MOD_ENV,
146     HOLD_MOD_ENV,
147     DECAY_MOD_ENV,
148     SUSTAIN_MOD_ENV,
149     RELEASEMODENV, // 30
150     KEYNUM_TO_MOD_ENV_HOLD,
151     KEYNUM_TO_MOD_ENV_DECAY,
152     DELAY_VOL_ENV,
153     ATTACK_VOL_ENV,
154     HOLD_VOL_ENV,
155     DECAY_VOL_ENV,
156     SUSTAIN_VOL_ENV,
157     RELEASE_VOL_ENV,
158     KEYNUM_TO_VOL_ENV_HOLD,
159     KEYNUM_TO_VOL_ENV_DECAY, //40
160     INSTRUMENT,
161     RESERVED1,
162     KEY_RANGE,
163     VEL_RANGE,
164     STARTLOOP_ADDRS_COARSE_OFFSET,
165     KEYNUM,
166     VELOCITY,
167     INITIAL_ATTENUATION,
168     RESERVED2,
169     ENDLOOP_ADDRS_COARSE_OFFSET, // 50
170     COARSE_TUNE,
171     FINE_TUNE,
172     SAMPLE_ID,
173     SAMPLE_MODES,
174     RESERVED3,
175     SCALE_TUNING,
176     EXCLUSIVE_CLASS,
177     OVERRIDING_ROOT_KEY,
178     UNUSED5,
179     END_OPER
180     } SFGeneratorType;
181    
182     class Modulator {
183     public:
184    
185     /**
186     * General Controller palette of controllers.
187     * Controller sources.
188     */
189     enum {
190     NO_CONTROLLER = 0,
191     NOTE_ON_VELOCITY = 2,
192     NOTE_ON_KEY_NUMBER = 3,
193     POLY_PRESSURE = 10,
194     CHANNEL_PRESSURE = 13,
195     PITCH_WHEEL = 14,
196     PITCH_WHEEL_SENSITIVITY = 16,
197     LINK = 127
198     };
199    
200     /**
201     * Controller type
202     */
203     enum {
204     LINEAR = 0,
205     CONCAVE,
206     CONVEX,
207     SWITCH
208     };
209    
210     int Type;
211     bool MidiPalete;
212     bool Direction;
213     bool Polarity;
214     int Index;
215    
216     Modulator(SFModulator mod);
217     };
218    
219     class ModulatorItem {
220     public:
221     Modulator ModSrcOper;
222     SFGenerator ModDestOper;
223     uint16_t ModAmount;
224     Modulator ModAmtSrcOper;
225     SFTransform ModTransOper;
226    
227     ModulatorItem(ModList& mod);
228     };
229    
230    
231     typedef std::string String;
232    
233     class Exception : public RIFF::Exception {
234     public: Exception(String Message) : RIFF::Exception(Message) { }
235     };
236    
237     class Version {
238     public:
239     int Major;
240     int Minor;
241    
242     Version(RIFF::Chunk* ck);
243     };
244    
245     class Info {
246     public:
247     Version* pVer; ///< <ifil-ck> ; Refers to the version of the Sound Font RIFF file
248     String SoundEngine; ///< <isng-ck> ; Refers to the target Sound Engine
249     String BankName; ///< <INAM-ck> ; Refers to the Sound Font Bank Name
250     String RomName; ///< [<irom-ck>] ; Refers to the Sound ROM Name
251     Version* pRomVer; ///< [<iver-ck>] ; Refers to the Sound ROM Version
252     String CreationDate; ///< [<ICRD-ck>] ; Refers to the Date of Creation of the Bank
253     String Engineers; ///< [<IENG-ck>] ; Sound Designers and Engineers for the Bank
254     String Product; ///< [<IPRD-ck>] ; Product for which the Bank was intended
255     String Copyright; ///< [<ICOP-ck>] ; Contains any Copyright message
256     String Comments; ///< [<ICMT-ck>] ; Contains any Comments on the Bank
257     String Software; ///< [<ISFT-ck>] ; The SoundFont tools used to create and alter the bank
258    
259     Info(RIFF::List* list);
260     ~Info();
261     private:
262     static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
263     };
264    
265 iliev 2020 class Region;
266    
267 iliev 2016 class Sample {
268     public:
269    
270     typedef enum {
271     MONO_SAMPLE = 1,
272     RIGHT_SAMPLE = 2,
273     LEFT_SAMPLE = 4,
274     LINKED_SAMPLE = 8,
275     ROM_MONO_SAMPLE = 0x8001,
276     ROM_RIGHT_SAMPLE = 0x8002,
277     ROM_LEFT_SAMPLE = 0x8004,
278     ROM_LINKED_SAMPLE = 0x8008
279     } Link;
280    
281     /** Reflects the current playback state for a sample. */
282     class PlaybackState {
283     public:
284     unsigned long position; ///< Current position within the sample.
285     bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
286     unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle.
287     };
288    
289     /** Pointer address and size of a buffer. */
290     struct buffer_t {
291     void* pStart; ///< Points to the beginning of the buffer.
292     unsigned long Size; ///< Size of the actual data in the buffer in bytes.
293     unsigned long NullExtensionSize; ///< The buffer might be bigger than the actual data, if that's the case that unused space at the end of the buffer is filled with NULLs and NullExtensionSize reflects that unused buffer space in bytes. Those NULL extensions are mandatory for differential algorithms that have to take the following data words into account, thus have to access past the buffer's boundary. If you don't know what I'm talking about, just forget this variable. :)
294     buffer_t() {
295     pStart = NULL;
296     Size = 0;
297     NullExtensionSize = 0;
298     }
299     };
300    
301     String Name;
302    
303     Sample(RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24);
304    
305     String GetName() { return Name; }
306     int GetChannelCount();
307     long GetTotalFrameCount();
308     int GetFrameSize();
309     bool HasLoops();
310     bool IsUnpitched() { return OriginalPitch == 255; }
311    
312     buffer_t LoadSampleData();
313     buffer_t LoadSampleData(unsigned long SampleCount);
314     buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
315     buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
316     buffer_t GetCache();
317     void ReleaseSampleData();
318     unsigned long SetPos(unsigned long SampleCount);
319     unsigned long GetPos();
320     unsigned long Read(void* pBuffer, unsigned long SampleCount);
321    
322     unsigned long ReadAndLoop (
323     void* pBuffer,
324     unsigned long FrameCount,
325 iliev 2020 PlaybackState* pPlaybackState,
326     Region* pRegion
327 iliev 2016 );
328    
329     //protected:
330     buffer_t RAMCache; ///< Buffers samples (already uncompressed) in RAM.
331     RIFF::Chunk* pCkSmpl;
332     RIFF::Chunk* pCkSm24;
333    
334     //private:
335     int ChannelCount; // 2 for left and right samples
336    
337 iliev 2020 uint32_t Start; // in sample data points (frames) from the begining of the sample data field
338     uint32_t End; // in sample data points (frames) from the begining of the sample data field
339     uint32_t StartLoop; // in sample data points (frames) from the begining of the sample data field
340     uint32_t EndLoop; // in sample data points (frames) from the begining of the sample data field
341 iliev 2016 uint32_t SampleRate;
342     uint8_t OriginalPitch;
343     uint8_t PitchCorrection;
344     uint16_t SampleLink; /* If sfSampleType indicates a left or right sample, the
345     * sample header index of the associated right or left stereo
346     * sample respectively; zero otherwise. */
347     uint16_t SampleType;
348     };
349    
350     class File;
351     class Instrument;
352    
353     /**
354     * Instrument zone
355     */
356     class Region {
357     public:
358     int loKey, hiKey;
359     int minVel, maxVel;
360     int pan; // -64 - +63
361     int fineTune; // -99 - +99
362 iliev 2020 int coarseTune; // TODO:
363     int overridingRootKey; // represents the MIDI key number at which the sample is to be played back at its original sample rate.
364     int startAddrsOffset, startAddrsCoarseOffset, endAddrsOffset, endAddrsCoarseOffset;
365     int startloopAddrsOffset, startloopAddrsCoarseOffset, endloopAddrsOffset, endloopAddrsCoarseOffset;
366 iliev 2016
367     double EG1PreAttackDelay;
368     double EG1Attack;
369     double EG1Hold;
370     double EG1Decay;
371     double EG1Sustain; // Sustain value of the sample amplitude EG (in permilles)
372     double EG1Release;
373    
374     double EG2PreAttackDelay;
375     double EG2Attack;
376     double EG2Hold;
377     double EG2Decay;
378     double EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
379     double EG2Release;
380    
381     Sample* pSample;
382 iliev 2020 bool HasLoop;
383     uint LoopStart; // index (in frames) from the beginning of the sample
384     uint LoopEnd; // index (in frames) from the beginning of the sample
385 iliev 2016 Instrument* pInstrument; // used when the region belongs to preset
386    
387     Region();
388     Sample* GetSample() { return pSample; }
389     Region* GetParent() { return this; }
390    
391 iliev 2020 int GetUnityNote();
392    
393 iliev 2016 std::vector<ModulatorItem> modulators;
394    
395     friend class Instrument;
396     friend class Preset;
397    
398     private:
399     void SetGenerator(sf2::File* pFile, GenList& Gen);
400     void SetModulator(sf2::File* pFile, ModList& Mod);
401     };
402    
403     class InstrumentBase {
404     public:
405     String Name;
406     Region* pGlobalRegion;
407    
408     InstrumentBase(sf2::File* pFile);
409     virtual ~InstrumentBase();
410    
411     sf2::File* GetFile() { return pFile; }
412     String GetName() { return Name; }
413    
414     int GetRegionCount();
415     Region* GetRegion(int idx);
416    
417     std::vector<Region*> GetRegionsOnKey(int key, uint8_t vel);
418    
419     protected:
420     std::vector<Region*> regions;
421     sf2::File* pFile;
422     };
423    
424     class Instrument : public InstrumentBase {
425     public:
426     Instrument(sf2::File* pFile, RIFF::Chunk* ck);
427     ~Instrument();
428 iliev 2020
429     void DeleteRegion(Region* pRegion);
430 iliev 2016 //private:
431     uint16_t InstBagNdx;
432    
433     /**
434     * Load all regions (zones, bags) in the range idx1 - idx2
435     */
436     void LoadRegions(int idx1, int idx2);
437 iliev 2020
438     Region* CreateRegion();
439 iliev 2016 };
440    
441     class Preset : public InstrumentBase {
442     public:
443     uint16_t PresetNum;
444     uint16_t Bank;
445     uint32_t Library;
446     uint32_t Genre;
447     uint32_t Morphology;
448    
449     Preset(sf2::File* pFile, RIFF::Chunk* ck);
450     ~Preset();
451    
452     //private:
453     sf2::File* pFile;
454     uint16_t PresetBagNdx;
455    
456     /**
457     * Load all regions (zones, bags) in the range idx1 - idx2
458     */
459     void LoadRegions(int idx1, int idx2);
460     };
461    
462     class File {
463     public:
464     Info* pInfo;
465    
466     File(RIFF::File* pRIFF);
467     ~File();
468    
469     int GetPresetCount();
470     Preset* GetPreset(int idx);
471     int GetInstrumentCount();
472     Instrument* GetInstrument(int idx);
473 iliev 2020 void DeleteInstrument(Instrument* pInstrument);
474 iliev 2016 int GetSampleCount();
475     Sample* GetSample(int idx);
476     void DeleteSample(Sample* pSample);
477     bool HasSamples();
478    
479     friend class Region;
480     friend class Instrument;
481     friend class Preset;
482    
483     protected:
484     RIFF::File* pRIFF;
485     std::vector<PresetBag> PresetBags;
486     std::vector<ModList> PresetModLists;
487     std::vector<GenList> PresetGenLists;
488     std::vector<InstBag> InstBags;
489     std::vector<ModList> InstModLists;
490     std::vector<GenList> InstGenLists;
491    
492     private:
493     std::vector<Preset*> Presets;
494     std::vector<Instrument*> Instruments;
495     std::vector<Sample*> Samples;
496     };
497    
498     String libraryName();
499     String libraryVersion();
500    
501     } // namespace sf2
502     #endif // __SF2_SF_H__

  ViewVC Help
Powered by ViewVC