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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2206 - (show annotations) (download) (as text)
Fri Jul 15 14:48:40 2011 UTC (8 years, 4 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 20275 byte(s)
* sf2: generators' values are now ensured to be in the allowed range
* sf2: GetEG2Sustain() now returns the decrease in the level
* sf2: removed ToPermilles() and added ToRatio() function
* sf2: added GetInitialFilterFc() and GetInitialFilterQ()

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

  ViewVC Help
Powered by ViewVC