libgig  4.1.0
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 
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 
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 
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;
243  String SoundEngine;
244  String BankName;
245  String RomName;
246  Version* pRomVer;
247  String CreationDate;
248  String Engineers;
249  String Product;
250  String Copyright;
251  String Comments;
252  String Software;
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 
278  public:
279  unsigned long position;
280  bool reverse;
281  unsigned long loop_cycles_left;
282  };
283 
285  struct buffer_t {
286  void* pStart;
287  unsigned long Size;
288  unsigned long NullExtensionSize;
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  unsigned long ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer);
317 
318  unsigned long ReadAndLoop (
319  void* pBuffer,
320  unsigned long FrameCount,
321  PlaybackState* pPlaybackState,
322  Region* pRegion
323  );
324 
325  //protected:
326  buffer_t RAMCache;
327  RIFF::Chunk* pCkSmpl;
328  RIFF::Chunk* pCkSm24;
329 
330  //private:
331  int ChannelCount; // 2 for left and right samples
332 
333  uint32_t Start; // in sample data points (frames) from the begining of the sample data field
334  uint32_t End; // in sample data points (frames) from the begining of the sample data field
335  uint32_t StartLoop; // in sample data points (frames) from the begining of the sample data field
336  uint32_t EndLoop; // in sample data points (frames) from the begining of the sample data field
337  uint32_t SampleRate;
338  uint8_t OriginalPitch;
339  uint8_t PitchCorrection;
340  uint16_t SampleLink; /* If sfSampleType indicates a left or right sample, the
341  * sample header index of the associated right or left stereo
342  * sample respectively; zero otherwise. */
343  uint16_t SampleType;
344  };
345 
346  class File;
347  class Instrument;
348 
352  class Region {
353  public:
354  int loKey, hiKey;
355  int minVel, maxVel;
356  int pan; // -64 - +63
357  int fineTune; // -99 - +99
358  int coarseTune; // TODO:
359  int overridingRootKey; // represents the MIDI key number at which the sample is to be played back at its original sample rate.
360  int startAddrsOffset, startAddrsCoarseOffset, endAddrsOffset, endAddrsCoarseOffset;
361  int startloopAddrsOffset, startloopAddrsCoarseOffset, endloopAddrsOffset, endloopAddrsCoarseOffset;
362 
363  int modEnvToPitch , modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc; // in cents
364  int modLfoToVolume /* in centibels */, freqModLfo /* in absolute cents */;
365  int delayModLfo; // in absolute timecents
366  int vibLfoToPitch, freqVibLfo /* in absolute cents */;
367  int delayVibLfo; // in absolute timecents
368  int initialFilterFc /* in absolute cents */, initialFilterQ /* in centibels */;
369 
370  uint exclusiveClass; // exclusive group
371 
372  Sample* pSample;
373  bool HasLoop;
374  uint LoopStart; // index (in frames) from the beginning of the sample
375  uint LoopEnd; // index (in frames) from the beginning of the sample
376  Instrument* pInstrument; // used when the region belongs to preset
377 
378  Region();
379  Sample* GetSample() { return pSample; }
380  Region* GetParent() { return this; }
381 
382  int GetUnityNote();
383 
388  Instrument* GetParentInstrument() { return pParentInstrument; }
389 
390  std::vector<ModulatorItem> modulators;
391 
392 
393  // Instrument can be referenced by more than one presets so we need to calculate values on the fly
394  int GetPan(Region* pPresetRegion = NULL); // -64 - +63
395  int GetFineTune(Region* pPresetRegion = NULL); // -99 - +99
396  int GetCoarseTune(Region* pPresetRegion = NULL); // -120 - +120
397  double GetEG1PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
398  double GetEG1Attack(Region* pPresetRegion = NULL); // in seconds
399  double GetEG1Hold(Region* pPresetRegion = NULL); // in seconds
400  double GetEG1Decay(Region* pPresetRegion = NULL); // in seconds
401  int GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (the decrease in level, expressed in centibels)
402  double GetEG1Release(Region* pPresetRegion = NULL); // in seconds
403 
404  double GetEG2PreAttackDelay(Region* pPresetRegion = NULL); // in seconds
405  double GetEG2Attack(Region* pPresetRegion = NULL); // in seconds
406  double GetEG2Hold(Region* pPresetRegion = NULL); // in seconds
407  double GetEG2Decay(Region* pPresetRegion = NULL); // in seconds
408  int GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
409  double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
410 
411  int GetModEnvToPitch(Region* pPresetRegion = NULL); // in cents
412  int GetModLfoToPitch(Region* pPresetRegion = NULL); // in cents
413  int GetModEnvToFilterFc(Region* pPresetRegion = NULL); // in cents
414  int GetModLfoToFilterFc(Region* pPresetRegion = NULL); // in cents
415  double GetModLfoToVolume(Region* pPresetRegion = NULL); // in centibels
416  double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
417  double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
418  int GetVibLfoToPitch(Region* pPresetRegion = NULL); // in cents
419  double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
420  double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
421  int GetInitialFilterFc(Region* pPresetRegion); // in absolute cents
422  int GetInitialFilterQ(Region* pPresetRegion); // in centibels
423 
424  friend class Instrument;
425  friend class Preset;
426 
427  private:
428  int EG1PreAttackDelay; // in timecents
429  int EG1Attack; // in timecents
430  int EG1Hold; // in timecents
431  int EG1Decay; // in timecents
432  int EG1Sustain; // Sustain value (the decrease in level, expressed in centibels)
433  int EG1Release; // in timecents
434 
435  int EG2PreAttackDelay; // in timecents
436  int EG2Attack; // in timecents
437  int EG2Hold; // in timecents
438  int EG2Decay; // in timecents
439  int EG2Sustain; // Sustain value of the filter cutoff EG (in permilles)
440  int EG2Release; // in timecents
441 
442  Instrument* pParentInstrument;
443 
444  void SetGenerator(sf2::File* pFile, GenList& Gen);
445  void SetModulator(sf2::File* pFile, ModList& Mod);
446  };
447 
448  class InstrumentBase {
449  public:
450  String Name;
451  Region* pGlobalRegion;
452 
453  InstrumentBase(sf2::File* pFile);
454  virtual ~InstrumentBase();
455 
456  sf2::File* GetFile() { return pFile; }
457  String GetName() { return Name; }
458 
459  int GetRegionCount();
460  Region* GetRegion(int idx);
461 
462  protected:
463  std::vector<Region*> regions;
464  sf2::File* pFile;
465  };
466 
467  class Query {
468  public:
469  int key;
470  uint8_t vel;
471 
472  Query(InstrumentBase& instrument);
473  Region* next();
474 
475  private:
476  InstrumentBase& instrument;
477  int i;
478  };
479 
480  class Instrument : public InstrumentBase {
481  public:
482  Instrument(sf2::File* pFile, RIFF::Chunk* ck);
483  ~Instrument();
484 
485  void DeleteRegion(Region* pRegion);
486  //private:
487  uint16_t InstBagNdx;
488 
492  void LoadRegions(int idx1, int idx2);
493 
494  Region* CreateRegion();
495  };
496 
497  class Preset : public InstrumentBase {
498  public:
499  uint16_t PresetNum;
500  uint16_t Bank;
501  uint32_t Library;
502  uint32_t Genre;
503  uint32_t Morphology;
504 
505  Preset(sf2::File* pFile, RIFF::Chunk* ck);
506  ~Preset();
507 
508  //private:
509  sf2::File* pFile;
510  uint16_t PresetBagNdx;
511 
515  void LoadRegions(int idx1, int idx2);
516 
517  Region* CreateRegion();
518  };
519 
520  class File {
521  public:
522  Info* pInfo;
523 
524  File(RIFF::File* pRIFF);
525  ~File();
526 
527  int GetPresetCount();
528  Preset* GetPreset(int idx);
529  int GetInstrumentCount();
530  Instrument* GetInstrument(int idx);
531  void DeleteInstrument(Instrument* pInstrument);
532  int GetSampleCount();
533  Sample* GetSample(int idx);
534  void DeleteSample(Sample* pSample);
535  bool HasSamples();
536 
537  friend class Region;
538  friend class Instrument;
539  friend class Preset;
540 
541  protected:
542  RIFF::File* pRIFF;
543  std::vector<PresetBag> PresetBags;
544  std::vector<ModList> PresetModLists;
545  std::vector<GenList> PresetGenLists;
546  std::vector<InstBag> InstBags;
547  std::vector<ModList> InstModLists;
548  std::vector<GenList> InstGenLists;
549 
550  private:
551  std::vector<Preset*> Presets;
552  std::vector<Instrument*> Instruments;
553  std::vector<Sample*> Samples;
554  };
555 
556  String libraryName();
557  String libraryVersion();
558 
559 } // namespace sf2
560 #endif // __SF2_SF_H__
Instrument zone.
Definition: SF.h:352
String libraryVersion()
Returns version of this C++ library.
Definition: SF.cpp:1561
String libraryName()
Returns the name of this C++ library.
Definition: SF.cpp:1554
unsigned long position
Current position within the sample.
Definition: SF.h:279
SoundFont specific classes and definitions.
Definition: SF.h:62
unsigned long NullExtensionSize
The buffer might be bigger than the actual data, if that&#39;s the case that unused space at the end of t...
Definition: SF.h:288
Reflects the current playback state for a sample.
Definition: SF.h:277
RIFF List Chunk.
Definition: RIFF.h:294
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:281
Ordinary RIFF Chunk.
Definition: RIFF.h:218
void * pStart
Points to the beginning of the buffer.
Definition: SF.h:286
Pointer address and size of a buffer.
Definition: SF.h:285
RIFF File.
Definition: RIFF.h:344
Instrument * GetParentInstrument()
Definition: SF.h:388
Will be thrown whenever an error occurs while handling a RIFF file.
Definition: RIFF.h:404
unsigned long Size
Size of the actual data in the buffer in bytes.
Definition: SF.h:287
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Definition: SF.h:280