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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2026 - (show annotations) (download) (as text)
Tue Nov 3 19:08:44 2009 UTC (10 years, 9 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 19935 byte(s)
* sf2: better support for preset regions

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 /** SoundFont specific classes and definitions */
78 namespace sf2 {
79
80 static uint NONE = 0x1ffffff;
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 int modEnvToPitch, modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc, modLfoToVolume, freqModLfo;
370 double delayModLfo;
371 int vibLfoToPitch, freqVibLfo;
372 double delayVibLfo;
373
374 uint exclusiveClass; // exclusive group
375
376 Sample* pSample;
377 bool HasLoop;
378 uint LoopStart; // index (in frames) from the beginning of the sample
379 uint LoopEnd; // index (in frames) from the beginning of the sample
380 Instrument* pInstrument; // used when the region belongs to preset
381
382 Region();
383 Sample* GetSample() { return pSample; }
384 Region* GetParent() { return this; }
385
386 int GetUnityNote();
387
388 /**
389 * @returns The instrument to which this region belongs, or
390 * NULL if it's preset region.
391 */
392 Instrument* GetParentInstrument() { return pParentInstrument; }
393
394 std::vector<ModulatorItem> modulators;
395
396
397 // Instrument can be referenced by more than one presets so we need to calculate values on the fly
398 int GetPan(Region* pPresetRegion = NULL); // -64 - +63
399 int GetFineTune(Region* pPresetRegion = NULL); // -99 - +99
400 int GetCoarseTune(Region* pPresetRegion = NULL); // -120 - +120
401 double GetEG1PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
402 double GetEG1Attack(Region* pPresetRegion = NULL); // in seconds
403 double GetEG1Hold(Region* pPresetRegion = NULL); // in seconds
404 double GetEG1Decay(Region* pPresetRegion = NULL); // in seconds
405 double GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (in permilles)
406 double GetEG1Release(Region* pPresetRegion = NULL); // in seconds
407
408 double GetEG2PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
409 double GetEG2Attack(Region* pPresetRegion = NULL); // in seconds
410 double GetEG2Hold(Region* pPresetRegion = NULL); // in seconds
411 double GetEG2Decay(Region* pPresetRegion = NULL); // in seconds
412 double GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
413 double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
414
415 int GetModEnvToPitch(Region* pPresetRegion = NULL);
416 int GetModLfoToPitch(Region* pPresetRegion = NULL);
417 int GetModEnvToFilterFc(Region* pPresetRegion = NULL);
418 int GetModLfoToFilterFc(Region* pPresetRegion = NULL);
419 double GetModLfoToVolume(Region* pPresetRegion = NULL); // in permilles
420 double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
421 double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
422 int GetVibLfoToPitch(Region* pPresetRegion = NULL);
423 double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
424 double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
425
426 friend class Instrument;
427 friend class Preset;
428
429 private:
430 double EG1PreAttackDelay; // in timecents
431 double EG1Attack; // in timecents
432 double EG1Hold; // in timecents
433 double EG1Decay; // in timecents
434 double EG1Sustain; // Sustain value of the sample amplitude EG (in permilles)
435 double EG1Release; // in timecents
436
437 double EG2PreAttackDelay; // in timecents
438 double EG2Attack; // in timecents
439 double EG2Hold; // in timecents
440 double EG2Decay; // in timecents
441 double EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
442 double EG2Release; // in timecents
443
444 Instrument* pParentInstrument;
445
446 void SetGenerator(sf2::File* pFile, GenList& Gen);
447 void SetModulator(sf2::File* pFile, ModList& Mod);
448 };
449
450 class InstrumentBase {
451 public:
452 String Name;
453 Region* pGlobalRegion;
454
455 InstrumentBase(sf2::File* pFile);
456 virtual ~InstrumentBase();
457
458 sf2::File* GetFile() { return pFile; }
459 String GetName() { return Name; }
460
461 int GetRegionCount();
462 Region* GetRegion(int idx);
463
464 std::vector<Region*> GetRegionsOnKey(int key, uint8_t vel);
465
466 protected:
467 std::vector<Region*> regions;
468 sf2::File* pFile;
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