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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2100 - (show 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 /***************************************************************************
2 * *
3 * libsf2 - C++ cross-platform SF2 format file access library *
4 * *
5 * Copyright (C) 2009-2010 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 #define RIFF_ID(x) (*((uint32_t*) x))
32
33
34 #define RIFF_TYPE_SF2 RIFF_ID("sfbk")
35
36 // Level 0
37 #define LIST_TYPE_SDTA RIFF_ID("sdta")
38 #define LIST_TYPE_PDTA RIFF_ID("pdta")
39
40 // Level 1
41 //<INFO-list>
42 #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
47 //<sdta-list>
48 #define CHUNK_ID_SM24 RIFF_ID("sm24")
49
50 //<pdta-list>
51 #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
61 /** SoundFont specific classes and definitions */
62 namespace sf2 {
63
64 static uint NONE = 0x1ffffff;
65
66 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 #if WORDS_BIGENDIAN
85 uint8_t byHi;
86 uint8_t byLo;
87 #else
88 uint8_t byLo;
89 uint8_t byHi;
90 #endif
91 } 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 SFGenerator ModDestOper;
214 uint16_t ModAmount;
215 Modulator ModAmtSrcOper;
216 SFTransform ModTransOper;
217
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 class Region;
257
258 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 PlaybackState* pPlaybackState,
317 Region* pRegion
318 );
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 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 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 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
358 int modEnvToPitch, modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume, freqModLfo;
359 int delayModLfo;
360 int vibLfoToPitch, freqVibLfo;
361 int delayVibLfo;
362
363 uint exclusiveClass; // exclusive group
364
365 Sample* pSample;
366 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 Instrument* pInstrument; // used when the region belongs to preset
370
371 Region();
372 Sample* GetSample() { return pSample; }
373 Region* GetParent() { return this; }
374
375 int GetUnityNote();
376
377 /**
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 std::vector<ModulatorItem> modulators;
384
385
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 friend class Instrument;
416 friend class Preset;
417
418 private:
419 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
426 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
433 Instrument* pParentInstrument;
434
435 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
450 int GetRegionCount();
451 Region* GetRegion(int idx);
452
453 protected:
454 std::vector<Region*> regions;
455 sf2::File* pFile;
456 };
457
458 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 class Instrument : public InstrumentBase {
472 public:
473 Instrument(sf2::File* pFile, RIFF::Chunk* ck);
474 ~Instrument();
475
476 void DeleteRegion(Region* pRegion);
477 //private:
478 uint16_t InstBagNdx;
479
480 /**
481 * Load all regions (zones, bags) in the range idx1 - idx2
482 */
483 void LoadRegions(int idx1, int idx2);
484
485 Region* CreateRegion();
486 };
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
508 Region* CreateRegion();
509 };
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 void DeleteInstrument(Instrument* pInstrument);
523 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