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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2100 - (hide annotations) (download) (as text)
Sun May 30 11:39:36 2010 UTC (13 years, 10 months ago) by persson
File MIME type: text/x-c++hdr
File size: 19674 byte(s)
* sf2: changed region lookup API to avoid malloc in RT threads

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

  ViewVC Help
Powered by ViewVC