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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2204 - (show annotations) (download) (as text)
Mon Jul 11 17:23:54 2011 UTC (9 years, 3 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 19935 byte(s)
* sf2: some fixes to sf2dump
* sf2: ToSeconds(), ToPermilles(), ToHz() are now exposed to the C++ API

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 ToPermilles(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 RELEASEMODENV, // 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
368 uint exclusiveClass; // exclusive group
369
370 Sample* pSample;
371 bool HasLoop;
372 uint LoopStart; // index (in frames) from the beginning of the sample
373 uint LoopEnd; // index (in frames) from the beginning of the sample
374 Instrument* pInstrument; // used when the region belongs to preset
375
376 Region();
377 Sample* GetSample() { return pSample; }
378 Region* GetParent() { return this; }
379
380 int GetUnityNote();
381
382 /**
383 * @returns The instrument to which this region belongs, or
384 * NULL if it's preset region.
385 */
386 Instrument* GetParentInstrument() { return pParentInstrument; }
387
388 std::vector<ModulatorItem> modulators;
389
390
391 // Instrument can be referenced by more than one presets so we need to calculate values on the fly
392 int GetPan(Region* pPresetRegion = NULL); // -64 - +63
393 int GetFineTune(Region* pPresetRegion = NULL); // -99 - +99
394 int GetCoarseTune(Region* pPresetRegion = NULL); // -120 - +120
395 double GetEG1PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
396 double GetEG1Attack(Region* pPresetRegion = NULL); // in seconds
397 double GetEG1Hold(Region* pPresetRegion = NULL); // in seconds
398 double GetEG1Decay(Region* pPresetRegion = NULL); // in seconds
399 double GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (in permilles)
400 double GetEG1Release(Region* pPresetRegion = NULL); // in seconds
401
402 double GetEG2PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
403 double GetEG2Attack(Region* pPresetRegion = NULL); // in seconds
404 double GetEG2Hold(Region* pPresetRegion = NULL); // in seconds
405 double GetEG2Decay(Region* pPresetRegion = NULL); // in seconds
406 double GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
407 double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
408
409 int GetModEnvToPitch(Region* pPresetRegion = NULL);
410 int GetModLfoToPitch(Region* pPresetRegion = NULL);
411 int GetModEnvToFilterFc(Region* pPresetRegion = NULL);
412 int GetModLfoToFilterFc(Region* pPresetRegion = NULL);
413 double GetModLfoToVolume(Region* pPresetRegion = NULL); // in permilles
414 double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
415 double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
416 int GetVibLfoToPitch(Region* pPresetRegion = NULL); // in cents
417 double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
418 double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
419
420 friend class Instrument;
421 friend class Preset;
422
423 private:
424 int EG1PreAttackDelay; // in timecents
425 int EG1Attack; // in timecents
426 int EG1Hold; // in timecents
427 int EG1Decay; // in timecents
428 int EG1Sustain; // Sustain value of the sample amplitude EG (in permilles)
429 int EG1Release; // in timecents
430
431 int EG2PreAttackDelay; // in timecents
432 int EG2Attack; // in timecents
433 int EG2Hold; // in timecents
434 int EG2Decay; // in timecents
435 int EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
436 int EG2Release; // in timecents
437
438 Instrument* pParentInstrument;
439
440 void SetGenerator(sf2::File* pFile, GenList& Gen);
441 void SetModulator(sf2::File* pFile, ModList& Mod);
442 };
443
444 class InstrumentBase {
445 public:
446 String Name;
447 Region* pGlobalRegion;
448
449 InstrumentBase(sf2::File* pFile);
450 virtual ~InstrumentBase();
451
452 sf2::File* GetFile() { return pFile; }
453 String GetName() { return Name; }
454
455 int GetRegionCount();
456 Region* GetRegion(int idx);
457
458 protected:
459 std::vector<Region*> regions;
460 sf2::File* pFile;
461 };
462
463 class Query {
464 public:
465 int key;
466 uint8_t vel;
467
468 Query(InstrumentBase& instrument);
469 Region* next();
470
471 private:
472 InstrumentBase& instrument;
473 int i;
474 };
475
476 class Instrument : public InstrumentBase {
477 public:
478 Instrument(sf2::File* pFile, RIFF::Chunk* ck);
479 ~Instrument();
480
481 void DeleteRegion(Region* pRegion);
482 //private:
483 uint16_t InstBagNdx;
484
485 /**
486 * Load all regions (zones, bags) in the range idx1 - idx2
487 */
488 void LoadRegions(int idx1, int idx2);
489
490 Region* CreateRegion();
491 };
492
493 class Preset : public InstrumentBase {
494 public:
495 uint16_t PresetNum;
496 uint16_t Bank;
497 uint32_t Library;
498 uint32_t Genre;
499 uint32_t Morphology;
500
501 Preset(sf2::File* pFile, RIFF::Chunk* ck);
502 ~Preset();
503
504 //private:
505 sf2::File* pFile;
506 uint16_t PresetBagNdx;
507
508 /**
509 * Load all regions (zones, bags) in the range idx1 - idx2
510 */
511 void LoadRegions(int idx1, int idx2);
512
513 Region* CreateRegion();
514 };
515
516 class File {
517 public:
518 Info* pInfo;
519
520 File(RIFF::File* pRIFF);
521 ~File();
522
523 int GetPresetCount();
524 Preset* GetPreset(int idx);
525 int GetInstrumentCount();
526 Instrument* GetInstrument(int idx);
527 void DeleteInstrument(Instrument* pInstrument);
528 int GetSampleCount();
529 Sample* GetSample(int idx);
530 void DeleteSample(Sample* pSample);
531 bool HasSamples();
532
533 friend class Region;
534 friend class Instrument;
535 friend class Preset;
536
537 protected:
538 RIFF::File* pRIFF;
539 std::vector<PresetBag> PresetBags;
540 std::vector<ModList> PresetModLists;
541 std::vector<GenList> PresetGenLists;
542 std::vector<InstBag> InstBags;
543 std::vector<ModList> InstModLists;
544 std::vector<GenList> InstGenLists;
545
546 private:
547 std::vector<Preset*> Presets;
548 std::vector<Instrument*> Instruments;
549 std::vector<Sample*> Samples;
550 };
551
552 String libraryName();
553 String libraryVersion();
554
555 } // namespace sf2
556 #endif // __SF2_SF_H__

  ViewVC Help
Powered by ViewVC