libgig 4.4.1
SF.h
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
62namespace 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 File;
178 class Instrument;
179
180 class Modulator {
181 public:
182
187 enum {
188 NO_CONTROLLER = 0,
189 NOTE_ON_VELOCITY = 2,
190 NOTE_ON_KEY_NUMBER = 3,
191 POLY_PRESSURE = 10,
192 CHANNEL_PRESSURE = 13,
193 PITCH_WHEEL = 14,
194 PITCH_WHEEL_SENSITIVITY = 16,
195 LINK = 127
196 };
197
201 enum {
202 LINEAR = 0,
203 CONCAVE,
204 CONVEX,
205 SWITCH
206 };
207
208 int Type;
209 bool MidiPalete;
210 bool Direction;
211 bool Polarity;
212 int Index;
213
214 Modulator(SFModulator mod);
215 };
216
217 class ModulatorItem {
218 public:
219 Modulator ModSrcOper;
220 SFGenerator ModDestOper;
221 uint16_t ModAmount;
222 Modulator ModAmtSrcOper;
223 SFTransform ModTransOper;
224
225 ModulatorItem(ModList& mod);
226 };
227
228
229 typedef std::string String;
230
231 class Exception : public RIFF::Exception {
232 public: Exception(String Message) : RIFF::Exception(Message) { }
233 };
234
235 class Version {
236 public:
237 int Major;
238 int Minor;
239
240 Version(RIFF::Chunk* ck);
241 };
242
243 class Info {
244 public:
245 Version* pVer;
246 String SoundEngine;
247 String BankName;
248 String RomName;
249 Version* pRomVer;
250 String CreationDate;
251 String Engineers;
252 String Product;
253 String Copyright;
254 String Comments;
255 String Software;
256
257 Info(RIFF::List* list);
258 ~Info();
259 private:
260 static void LoadString(uint32_t ChunkID, RIFF::List* lstINFO, String& s);
261 };
262
263 class Region;
264
265 class Sample {
266 public:
267
268 typedef enum {
269 MONO_SAMPLE = 1,
270 RIGHT_SAMPLE = 2,
271 LEFT_SAMPLE = 4,
272 LINKED_SAMPLE = 8,
273 ROM_MONO_SAMPLE = 0x8001,
274 ROM_RIGHT_SAMPLE = 0x8002,
275 ROM_LEFT_SAMPLE = 0x8004,
276 ROM_LINKED_SAMPLE = 0x8008
277 } Link;
278
281 public:
282 unsigned long position;
283 bool reverse;
284 unsigned long loop_cycles_left;
285 };
286
288 struct buffer_t {
289 void* pStart;
290 unsigned long Size;
291 unsigned long NullExtensionSize;
292 buffer_t() {
293 pStart = NULL;
294 Size = 0;
296 }
297 };
298
299 String Name;
300
301 Sample(File* file, RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24);
302
303 String GetName() { return Name; }
304 int GetChannelCount();
305 long GetTotalFrameCount();
306 int GetFrameSize();
307 bool HasLoops();
308 bool IsUnpitched() { return OriginalPitch == 255; }
309 File* GetFile() { return pFile; }
310
311 buffer_t LoadSampleData();
312 buffer_t LoadSampleData(unsigned long SampleCount);
313 buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
314 buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
315 buffer_t GetCache();
316 void ReleaseSampleData();
317 unsigned long SetPos(unsigned long SampleCount);
318 unsigned long GetPos();
319 unsigned long Read(void* pBuffer, unsigned long SampleCount);
320 unsigned long ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer);
321
322 unsigned long ReadAndLoop (
323 void* pBuffer,
324 unsigned long FrameCount,
325 PlaybackState* pPlaybackState,
326 Region* pRegion
327 );
328
329 //protected:
330 buffer_t RAMCache;
331 RIFF::Chunk* pCkSmpl;
332 RIFF::Chunk* pCkSm24;
333
334 //private:
335 int ChannelCount; // 2 for left and right samples
336
337 uint32_t Start; // in sample data points (frames) from the begining of the sample data field
338 uint32_t End; // in sample data points (frames) from the begining of the sample data field
339 uint32_t StartLoop; // in sample data points (frames) from the begining of the sample data field
340 uint32_t EndLoop; // in sample data points (frames) from the begining of the sample data field
341 uint32_t SampleRate;
342 uint8_t OriginalPitch;
343 uint8_t PitchCorrection;
344 uint16_t SampleLink; /* If sfSampleType indicates a left or right sample, the
345 * sample header index of the associated right or left stereo
346 * sample respectively; zero otherwise. */
347 uint16_t SampleType;
348
349 File* pFile;
350 };
351
355 class Region {
356 public:
357 int loKey, hiKey;
358 int minVel, maxVel;
359 int pan; // -64 - +63
360 int fineTune; // -99 - +99
361 int coarseTune; // TODO:
362 int overridingRootKey; // represents the MIDI key number at which the sample is to be played back at its original sample rate.
363 int startAddrsOffset, startAddrsCoarseOffset, endAddrsOffset, endAddrsCoarseOffset;
364 int startloopAddrsOffset, startloopAddrsCoarseOffset, endloopAddrsOffset, endloopAddrsCoarseOffset;
365
366 int modEnvToPitch , modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc; // in cents
367 int modLfoToVolume /* in centibels */, freqModLfo /* in absolute cents */;
368 int delayModLfo; // in absolute timecents
369 int vibLfoToPitch, freqVibLfo /* in absolute cents */;
370 int delayVibLfo; // in absolute timecents
371 int initialFilterFc /* in absolute cents */, initialFilterQ /* in centibels */;
372
373 uint exclusiveClass; // exclusive group
374
375 Sample* pSample;
376 bool HasLoop;
377 uint LoopStart; // index (in frames) from the beginning of the sample
378 uint LoopEnd; // index (in frames) from the beginning of the sample
379 Instrument* pInstrument; // used when the region belongs to preset
380
381 Region();
382 Sample* GetSample() { return pSample; }
383 Region* GetParent() { return this; }
384
385 int GetUnityNote();
386
391 Instrument* GetParentInstrument() { return pParentInstrument; }
392
393 std::vector<ModulatorItem> modulators;
394
395
396 // Instrument can be referenced by more than one presets so we need to calculate values on the fly
397 int GetPan(Region* pPresetRegion = NULL); // -64 - +63
398 int GetFineTune(Region* pPresetRegion = NULL); // -99 - +99
399 int GetCoarseTune(Region* pPresetRegion = NULL); // -120 - +120
400 double GetEG1PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
401 double GetEG1Attack(Region* pPresetRegion = NULL); // in seconds
402 double GetEG1Hold(Region* pPresetRegion = NULL); // in seconds
403 double GetEG1Decay(Region* pPresetRegion = NULL); // in seconds
404 int GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (the decrease in level, expressed in centibels)
405 double GetEG1Release(Region* pPresetRegion = NULL); // in seconds
406
407 double GetEG2PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
408 double GetEG2Attack(Region* pPresetRegion = NULL); // in seconds
409 double GetEG2Hold(Region* pPresetRegion = NULL); // in seconds
410 double GetEG2Decay(Region* pPresetRegion = NULL); // in seconds
411 int GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
412 double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
413
414 int GetModEnvToPitch(Region* pPresetRegion = NULL); // in cents
415 int GetModLfoToPitch(Region* pPresetRegion = NULL); // in cents
416 int GetModEnvToFilterFc(Region* pPresetRegion = NULL); // in cents
417 int GetModLfoToFilterFc(Region* pPresetRegion = NULL); // in cents
418 double GetModLfoToVolume(Region* pPresetRegion = NULL); // in centibels
419 double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
420 double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
421 int GetVibLfoToPitch(Region* pPresetRegion = NULL); // in cents
422 double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
423 double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
424 int GetInitialFilterFc(Region* pPresetRegion); // in absolute cents
425 int GetInitialFilterQ(Region* pPresetRegion); // in centibels
426
427 friend class Instrument;
428 friend class Preset;
429
430 private:
431 int EG1PreAttackDelay; // in timecents
432 int EG1Attack; // in timecents
433 int EG1Hold; // in timecents
434 int EG1Decay; // in timecents
435 int EG1Sustain; // Sustain value (the decrease in level, expressed in centibels)
436 int EG1Release; // in timecents
437
438 int EG2PreAttackDelay; // in timecents
439 int EG2Attack; // in timecents
440 int EG2Hold; // in timecents
441 int EG2Decay; // in timecents
442 int EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
443 int EG2Release; // in timecents
444
445 Instrument* pParentInstrument;
446
447 void SetGenerator(sf2::File* pFile, GenList& Gen);
448 void SetModulator(sf2::File* pFile, ModList& Mod);
449 };
450
451 class InstrumentBase {
452 public:
453 String Name;
454 Region* pGlobalRegion;
455
456 InstrumentBase(sf2::File* pFile);
457 virtual ~InstrumentBase();
458
459 sf2::File* GetFile() { return pFile; }
460 String GetName() { return Name; }
461
462 int GetRegionCount();
463 Region* GetRegion(int idx);
464
465 protected:
466 std::vector<Region*> regions;
467 sf2::File* pFile;
468 };
469
470 class Query {
471 public:
472 int key;
473 uint8_t vel;
474
475 Query(InstrumentBase& instrument);
476 Region* next();
477
478 private:
479 InstrumentBase& instrument;
480 int i;
481 };
482
483 class Instrument : public InstrumentBase {
484 public:
485 Instrument(sf2::File* pFile, RIFF::Chunk* ck);
486 ~Instrument();
487
488 void DeleteRegion(Region* pRegion);
489 //private:
490 uint16_t InstBagNdx;
491
495 void LoadRegions(int idx1, int idx2);
496
497 Region* CreateRegion();
498 };
499
500 class Preset : public InstrumentBase {
501 public:
502 uint16_t PresetNum;
503 uint16_t Bank;
504 uint32_t Library;
505 uint32_t Genre;
506 uint32_t Morphology;
507
508 Preset(sf2::File* pFile, RIFF::Chunk* ck);
509 ~Preset();
510
511 //private:
512 sf2::File* pFile;
513 uint16_t PresetBagNdx;
514
518 void LoadRegions(int idx1, int idx2);
519
520 Region* CreateRegion();
521 };
522
523 class File {
524 public:
525 Info* pInfo;
526
527 File(RIFF::File* pRIFF);
528 ~File();
529
530 int GetPresetCount();
531 Preset* GetPreset(int idx);
532 int GetInstrumentCount();
533 Instrument* GetInstrument(int idx);
534 void DeleteInstrument(Instrument* pInstrument);
535 int GetSampleCount();
536 Sample* GetSample(int idx);
537 void DeleteSample(Sample* pSample);
538 bool HasSamples();
539 RIFF::File* GetRiffFile();
540
541 friend class Region;
542 friend class Instrument;
543 friend class Preset;
544
545 protected:
546 RIFF::File* pRIFF;
547 std::vector<PresetBag> PresetBags;
548 std::vector<ModList> PresetModLists;
549 std::vector<GenList> PresetGenLists;
550 std::vector<InstBag> InstBags;
551 std::vector<ModList> InstModLists;
552 std::vector<GenList> InstGenLists;
553
554 private:
555 std::vector<Preset*> Presets;
556 std::vector<Instrument*> Instruments;
557 std::vector<Sample*> Samples;
558 };
559
560 String libraryName();
561 String libraryVersion();
562
563} // namespace sf2
564#endif // __SF2_SF_H__
Ordinary RIFF Chunk.
Definition RIFF.h:179
Will be thrown whenever an error occurs while handling a RIFF file.
Definition RIFF.h:391
RIFF File.
Definition RIFF.h:313
RIFF List Chunk.
Definition RIFF.h:261
Instrument zone.
Definition SF.h:355
Instrument * GetParentInstrument()
Definition SF.h:391
Reflects the current playback state for a sample.
Definition SF.h:280
unsigned long loop_cycles_left
How many times the loop has still to be passed, this value will be decremented with each loop cycle.
Definition SF.h:284
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
Definition SF.h:283
unsigned long position
Current position within the sample.
Definition SF.h:282
SoundFont specific classes and definitions.
Definition SF.h:62
String libraryVersion()
Returns version of this C++ library.
Definition SF.cpp:1572
String libraryName()
Returns the name of this C++ library.
Definition SF.cpp:1565
Pointer address and size of a buffer.
Definition SF.h:288
unsigned long Size
Size of the actual data in the buffer in bytes.
Definition SF.h:290
void * pStart
Points to the beginning of the buffer.
Definition SF.h:289
unsigned long NullExtensionSize
The buffer might be bigger than the actual data, if that's the case that unused space at the end of t...
Definition SF.h:291