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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3481 - (show annotations) (download) (as text)
Fri Feb 22 12:12:50 2019 UTC (5 years, 1 month ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 20507 byte(s)
* gig.h, gig.cpp: Added File::GetRiffFile() method.
* DLS.h, DLS.cpp: Added File::GetRiffFile() method.
* sf2.h, sf2.cpp: Added Sample::GetFile() and
  File::GetRiffFile() methods.
* RIFF.h, RIFF.cpp: Added a 2nd (overridden)
  progress_t::subdivide() method which allows a more
  fine graded control into which portions the subtasks
  are divided to.
* RIFF Fix: API doc comment for Chunk::GetFilePos() was
  completely wrong.
* Bumped version (4.1.0.svn14).

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
61 /** SoundFont specific classes and definitions */
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
183 /**
184 * General Controller palette of controllers.
185 * Controller sources.
186 */
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
198 /**
199 * Controller type
200 */
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; ///< <ifil-ck> ; Refers to the version of the Sound Font RIFF file
246 String SoundEngine; ///< <isng-ck> ; Refers to the target Sound Engine
247 String BankName; ///< <INAM-ck> ; Refers to the Sound Font Bank Name
248 String RomName; ///< [<irom-ck>] ; Refers to the Sound ROM Name
249 Version* pRomVer; ///< [<iver-ck>] ; Refers to the Sound ROM Version
250 String CreationDate; ///< [<ICRD-ck>] ; Refers to the Date of Creation of the Bank
251 String Engineers; ///< [<IENG-ck>] ; Sound Designers and Engineers for the Bank
252 String Product; ///< [<IPRD-ck>] ; Product for which the Bank was intended
253 String Copyright; ///< [<ICOP-ck>] ; Contains any Copyright message
254 String Comments; ///< [<ICMT-ck>] ; Contains any Comments on the Bank
255 String Software; ///< [<ISFT-ck>] ; The SoundFont tools used to create and alter the bank
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
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(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; ///< Buffers samples (already uncompressed) in RAM.
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
352 /**
353 * Instrument zone
354 */
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
387 /**
388 * @returns The instrument to which this region belongs, or
389 * NULL if it's preset region.
390 */
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
492 /**
493 * Load all regions (zones, bags) in the range idx1 - idx2
494 */
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
515 /**
516 * Load all regions (zones, bags) in the range idx1 - idx2
517 */
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__

  ViewVC Help
Powered by ViewVC