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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2014 - (show annotations) (download) (as text)
Sun Oct 25 22:11:41 2009 UTC (14 years, 5 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 16172 byte(s)
* implemented EG2

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

  ViewVC Help
Powered by ViewVC