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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2022 - (hide annotations) (download) (as text)
Sun Nov 1 10:46:00 2009 UTC (14 years, 5 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 17095 byte(s)
- generate API docs of SF classes as well

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 schoenebeck 2022 /** SoundFont specific classes and definitions */
80 iliev 2016 namespace sf2 {
81 schoenebeck 2022
82 iliev 2016 typedef struct _PresetBag {
83     uint16_t GenNdx;
84     uint16_t ModNdx;
85     } PresetBag;
86    
87     typedef uint16_t SFModulator;
88     typedef uint16_t SFGenerator;
89     typedef uint16_t SFTransform;
90    
91     typedef struct _ModList {
92     SFModulator ModSrcOper;
93     SFGenerator ModDestOper;
94     uint16_t ModAmount;
95     SFModulator ModAmtSrcOper;
96     SFTransform ModTransOper;
97     } ModList;
98    
99     typedef struct _RangesType {
100     uint8_t byLo;
101     uint8_t byHi;
102     } RangesType;
103    
104     typedef union _GenAmountType {
105     RangesType ranges;
106     short shAmount;
107     uint16_t wAmount;
108     } GenAmountType;
109    
110     typedef struct _GenList {
111     SFGenerator GenOper;
112     GenAmountType GenAmount;
113     } GenList;
114    
115     typedef struct _InstBag {
116     uint16_t InstGenNdx;
117     uint16_t InstModNdx;
118     } InstBag;
119    
120     typedef enum {
121     START_ADDRS_OFFSET = 0,
122     END_ADDRS_OFFSET,
123     STARTLOOP_ADDRS_OFFSET,
124     ENDLOOP_ADDRS_OFFSET ,
125     START_ADDRS_COARSE_OFFSET,
126     MOD_LFO_TO_PITCH,
127     VIB_LFO_TO_PITCH,
128     MOD_ENV_TO_PITCH,
129     INITIAL_FILTER_FC,
130     INITIAL_FILTER_Q,
131     MOD_LFO_TO_FILTER_FC, // 10
132     MOD_ENV_TO_FILTER_FC,
133     END_ADDRS_COARSE_OFFSET,
134     MOD_LFO_TO_VOLUME,
135     UNUSED1,
136     CHORUS_EFFECTS_SEND,
137     REVERB_EFFECTS_SEND,
138     PAN,
139     UNUSED2,
140     UNUSED3,
141     UNUSED4, //20
142     DELAY_MOD_LFO,
143     FREQ_MOD_LFO,
144     DELAY_VIB_LFO,
145     FREQ_VIB_LFO,
146     DELAY_MOD_ENV,
147     ATTACK_MOD_ENV,
148     HOLD_MOD_ENV,
149     DECAY_MOD_ENV,
150     SUSTAIN_MOD_ENV,
151     RELEASEMODENV, // 30
152     KEYNUM_TO_MOD_ENV_HOLD,
153     KEYNUM_TO_MOD_ENV_DECAY,
154     DELAY_VOL_ENV,
155     ATTACK_VOL_ENV,
156     HOLD_VOL_ENV,
157     DECAY_VOL_ENV,
158     SUSTAIN_VOL_ENV,
159     RELEASE_VOL_ENV,
160     KEYNUM_TO_VOL_ENV_HOLD,
161     KEYNUM_TO_VOL_ENV_DECAY, //40
162     INSTRUMENT,
163     RESERVED1,
164     KEY_RANGE,
165     VEL_RANGE,
166     STARTLOOP_ADDRS_COARSE_OFFSET,
167     KEYNUM,
168     VELOCITY,
169     INITIAL_ATTENUATION,
170     RESERVED2,
171     ENDLOOP_ADDRS_COARSE_OFFSET, // 50
172     COARSE_TUNE,
173     FINE_TUNE,
174     SAMPLE_ID,
175     SAMPLE_MODES,
176     RESERVED3,
177     SCALE_TUNING,
178     EXCLUSIVE_CLASS,
179     OVERRIDING_ROOT_KEY,
180     UNUSED5,
181     END_OPER
182     } SFGeneratorType;
183    
184     class Modulator {
185     public:
186    
187     /**
188     * General Controller palette of controllers.
189     * Controller sources.
190     */
191     enum {
192     NO_CONTROLLER = 0,
193     NOTE_ON_VELOCITY = 2,
194     NOTE_ON_KEY_NUMBER = 3,
195     POLY_PRESSURE = 10,
196     CHANNEL_PRESSURE = 13,
197     PITCH_WHEEL = 14,
198     PITCH_WHEEL_SENSITIVITY = 16,
199     LINK = 127
200     };
201    
202     /**
203     * Controller type
204     */
205     enum {
206     LINEAR = 0,
207     CONCAVE,
208     CONVEX,
209     SWITCH
210     };
211    
212     int Type;
213     bool MidiPalete;
214     bool Direction;
215     bool Polarity;
216     int Index;
217    
218     Modulator(SFModulator mod);
219     };
220    
221     class ModulatorItem {
222     public:
223     Modulator ModSrcOper;
224     SFGenerator ModDestOper;
225     uint16_t ModAmount;
226     Modulator ModAmtSrcOper;
227     SFTransform ModTransOper;
228    
229     ModulatorItem(ModList& mod);
230     };
231    
232    
233     typedef std::string String;
234    
235     class Exception : public RIFF::Exception {
236     public: Exception(String Message) : RIFF::Exception(Message) { }
237     };
238    
239     class Version {
240     public:
241     int Major;
242     int Minor;
243    
244     Version(RIFF::Chunk* ck);
245     };
246    
247     class Info {
248     public:
249     Version* pVer; ///< <ifil-ck> ; Refers to the version of the Sound Font RIFF file
250     String SoundEngine; ///< <isng-ck> ; Refers to the target Sound Engine
251     String BankName; ///< <INAM-ck> ; Refers to the Sound Font Bank Name
252     String RomName; ///< [<irom-ck>] ; Refers to the Sound ROM Name
253     Version* pRomVer; ///< [<iver-ck>] ; Refers to the Sound ROM Version
254     String CreationDate; ///< [<ICRD-ck>] ; Refers to the Date of Creation of the Bank
255     String Engineers; ///< [<IENG-ck>] ; Sound Designers and Engineers for the Bank
256     String Product; ///< [<IPRD-ck>] ; Product for which the Bank was intended
257     String Copyright; ///< [<ICOP-ck>] ; Contains any Copyright message
258     String Comments; ///< [<ICMT-ck>] ; Contains any Comments on the Bank
259     String Software; ///< [<ISFT-ck>] ; The SoundFont tools used to create and alter the bank
260    
261     Info(RIFF::List* list);
262     ~Info();
263     private:
264     static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
265     };
266    
267 iliev 2020 class Region;
268    
269 iliev 2016 class Sample {
270     public:
271    
272     typedef enum {
273     MONO_SAMPLE = 1,
274     RIGHT_SAMPLE = 2,
275     LEFT_SAMPLE = 4,
276     LINKED_SAMPLE = 8,
277     ROM_MONO_SAMPLE = 0x8001,
278     ROM_RIGHT_SAMPLE = 0x8002,
279     ROM_LEFT_SAMPLE = 0x8004,
280     ROM_LINKED_SAMPLE = 0x8008
281     } Link;
282    
283     /** Reflects the current playback state for a sample. */
284     class PlaybackState {
285     public:
286     unsigned long position; ///< Current position within the sample.
287     bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
288     unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle.
289     };
290    
291     /** Pointer address and size of a buffer. */
292     struct buffer_t {
293     void* pStart; ///< Points to the beginning of the buffer.
294     unsigned long Size; ///< Size of the actual data in the buffer in bytes.
295     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. :)
296     buffer_t() {
297     pStart = NULL;
298     Size = 0;
299     NullExtensionSize = 0;
300     }
301     };
302    
303     String Name;
304    
305     Sample(RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24);
306    
307     String GetName() { return Name; }
308     int GetChannelCount();
309     long GetTotalFrameCount();
310     int GetFrameSize();
311     bool HasLoops();
312     bool IsUnpitched() { return OriginalPitch == 255; }
313    
314     buffer_t LoadSampleData();
315     buffer_t LoadSampleData(unsigned long SampleCount);
316     buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
317     buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
318     buffer_t GetCache();
319     void ReleaseSampleData();
320     unsigned long SetPos(unsigned long SampleCount);
321     unsigned long GetPos();
322     unsigned long Read(void* pBuffer, unsigned long SampleCount);
323    
324     unsigned long ReadAndLoop (
325     void* pBuffer,
326     unsigned long FrameCount,
327 iliev 2020 PlaybackState* pPlaybackState,
328     Region* pRegion
329 iliev 2016 );
330    
331     //protected:
332     buffer_t RAMCache; ///< Buffers samples (already uncompressed) in RAM.
333     RIFF::Chunk* pCkSmpl;
334     RIFF::Chunk* pCkSm24;
335    
336     //private:
337     int ChannelCount; // 2 for left and right samples
338    
339 iliev 2020 uint32_t Start; // in sample data points (frames) from the begining of the sample data field
340     uint32_t End; // in sample data points (frames) from the begining of the sample data field
341     uint32_t StartLoop; // in sample data points (frames) from the begining of the sample data field
342     uint32_t EndLoop; // in sample data points (frames) from the begining of the sample data field
343 iliev 2016 uint32_t SampleRate;
344     uint8_t OriginalPitch;
345     uint8_t PitchCorrection;
346     uint16_t SampleLink; /* If sfSampleType indicates a left or right sample, the
347     * sample header index of the associated right or left stereo
348     * sample respectively; zero otherwise. */
349     uint16_t SampleType;
350     };
351    
352     class File;
353     class Instrument;
354    
355     /**
356     * Instrument zone
357     */
358     class Region {
359     public:
360     int loKey, hiKey;
361     int minVel, maxVel;
362     int pan; // -64 - +63
363     int fineTune; // -99 - +99
364 iliev 2020 int coarseTune; // TODO:
365     int overridingRootKey; // represents the MIDI key number at which the sample is to be played back at its original sample rate.
366     int startAddrsOffset, startAddrsCoarseOffset, endAddrsOffset, endAddrsCoarseOffset;
367     int startloopAddrsOffset, startloopAddrsCoarseOffset, endloopAddrsOffset, endloopAddrsCoarseOffset;
368 iliev 2016
369     double EG1PreAttackDelay;
370     double EG1Attack;
371     double EG1Hold;
372     double EG1Decay;
373     double EG1Sustain; // Sustain value of the sample amplitude EG (in permilles)
374     double EG1Release;
375    
376     double EG2PreAttackDelay;
377     double EG2Attack;
378     double EG2Hold;
379     double EG2Decay;
380     double EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
381     double EG2Release;
382    
383     Sample* pSample;
384 iliev 2020 bool HasLoop;
385     uint LoopStart; // index (in frames) from the beginning of the sample
386     uint LoopEnd; // index (in frames) from the beginning of the sample
387 iliev 2016 Instrument* pInstrument; // used when the region belongs to preset
388    
389     Region();
390     Sample* GetSample() { return pSample; }
391     Region* GetParent() { return this; }
392    
393 iliev 2020 int GetUnityNote();
394    
395 iliev 2016 std::vector<ModulatorItem> modulators;
396    
397     friend class Instrument;
398     friend class Preset;
399    
400     private:
401     void SetGenerator(sf2::File* pFile, GenList& Gen);
402     void SetModulator(sf2::File* pFile, ModList& Mod);
403     };
404    
405     class InstrumentBase {
406     public:
407     String Name;
408     Region* pGlobalRegion;
409    
410     InstrumentBase(sf2::File* pFile);
411     virtual ~InstrumentBase();
412    
413     sf2::File* GetFile() { return pFile; }
414     String GetName() { return Name; }
415    
416     int GetRegionCount();
417     Region* GetRegion(int idx);
418    
419     std::vector<Region*> GetRegionsOnKey(int key, uint8_t vel);
420    
421     protected:
422     std::vector<Region*> regions;
423     sf2::File* pFile;
424     };
425    
426     class Instrument : public InstrumentBase {
427     public:
428     Instrument(sf2::File* pFile, RIFF::Chunk* ck);
429     ~Instrument();
430 iliev 2020
431     void DeleteRegion(Region* pRegion);
432 iliev 2016 //private:
433     uint16_t InstBagNdx;
434    
435     /**
436     * Load all regions (zones, bags) in the range idx1 - idx2
437     */
438     void LoadRegions(int idx1, int idx2);
439 iliev 2020
440     Region* CreateRegion();
441 iliev 2016 };
442    
443     class Preset : public InstrumentBase {
444     public:
445     uint16_t PresetNum;
446     uint16_t Bank;
447     uint32_t Library;
448     uint32_t Genre;
449     uint32_t Morphology;
450    
451     Preset(sf2::File* pFile, RIFF::Chunk* ck);
452     ~Preset();
453    
454     //private:
455     sf2::File* pFile;
456     uint16_t PresetBagNdx;
457    
458     /**
459     * Load all regions (zones, bags) in the range idx1 - idx2
460     */
461     void LoadRegions(int idx1, int idx2);
462     };
463    
464     class File {
465     public:
466     Info* pInfo;
467    
468     File(RIFF::File* pRIFF);
469     ~File();
470    
471     int GetPresetCount();
472     Preset* GetPreset(int idx);
473     int GetInstrumentCount();
474     Instrument* GetInstrument(int idx);
475 iliev 2020 void DeleteInstrument(Instrument* pInstrument);
476 iliev 2016 int GetSampleCount();
477     Sample* GetSample(int idx);
478     void DeleteSample(Sample* pSample);
479     bool HasSamples();
480    
481     friend class Region;
482     friend class Instrument;
483     friend class Preset;
484    
485     protected:
486     RIFF::File* pRIFF;
487     std::vector<PresetBag> PresetBags;
488     std::vector<ModList> PresetModLists;
489     std::vector<GenList> PresetGenLists;
490     std::vector<InstBag> InstBags;
491     std::vector<ModList> InstModLists;
492     std::vector<GenList> InstGenLists;
493    
494     private:
495     std::vector<Preset*> Presets;
496     std::vector<Instrument*> Instruments;
497     std::vector<Sample*> Samples;
498     };
499    
500     String libraryName();
501     String libraryVersion();
502    
503     } // namespace sf2
504     #endif // __SF2_SF_H__

  ViewVC Help
Powered by ViewVC