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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2022 - (show annotations) (download) (as text)
Sun Nov 1 10:46:00 2009 UTC (14 years, 5 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 17095 byte(s)
- generate API docs of SF classes as well

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

  ViewVC Help
Powered by ViewVC