libgig  4.3.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 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;
295  NullExtensionSize = 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:232
Will be thrown whenever an error occurs while handling a RIFF file.
Definition: RIFF.h:418
RIFF File.
Definition: RIFF.h:358
RIFF List Chunk.
Definition: RIFF.h:308
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:1566
String libraryName()
Returns the name of this C++ library.
Definition: SF.cpp:1559
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