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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3481 - (hide 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 iliev 2016 /***************************************************************************
2     * *
3     * libsf2 - C++ cross-platform SF2 format file access library *
4     * *
5 persson 2044 * Copyright (C) 2009-2010 by Grigor Iliev <grigor@grigoriliev.com> *
6 iliev 2016 * *
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 persson 2044 #define RIFF_ID(x) (*((uint32_t*) x))
32 iliev 2016
33    
34 persson 2044 #define RIFF_TYPE_SF2 RIFF_ID("sfbk")
35 iliev 2016
36     // Level 0
37 persson 2044 #define LIST_TYPE_SDTA RIFF_ID("sdta")
38     #define LIST_TYPE_PDTA RIFF_ID("pdta")
39 iliev 2016
40     // Level 1
41     //<INFO-list>
42 persson 2044 #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 iliev 2016
47     //<sdta-list>
48 persson 2044 #define CHUNK_ID_SM24 RIFF_ID("sm24")
49 iliev 2016
50     //<pdta-list>
51 persson 2044 #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 iliev 2016
61 schoenebeck 2022 /** SoundFont specific classes and definitions */
62 iliev 2016 namespace sf2 {
63 persson 2044
64 iliev 2026 static uint NONE = 0x1ffffff;
65    
66 iliev 2204 double ToSeconds(int Timecents);
67 iliev 2206 double ToRatio(int Centibels);
68 iliev 2204 double ToHz(int cents);
69    
70 iliev 2016 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 persson 2044 #if WORDS_BIGENDIAN
89     uint8_t byHi;
90 iliev 2016 uint8_t byLo;
91 persson 2044 #else
92     uint8_t byLo;
93 iliev 2016 uint8_t byHi;
94 persson 2044 #endif
95 iliev 2016 } 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 iliev 2206 RELEASE_MOD_ENV, // 30
145 iliev 2016 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 schoenebeck 3481 class File;
178     class Instrument;
179    
180 iliev 2016 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 persson 2044 SFGenerator ModDestOper;
221     uint16_t ModAmount;
222     Modulator ModAmtSrcOper;
223     SFTransform ModTransOper;
224 iliev 2016
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 iliev 2020 class Region;
264    
265 iliev 2016 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 schoenebeck 3481 Sample(File* file, RIFF::Chunk* ck, RIFF::Chunk* pCkSmpl, RIFF::Chunk* pCkSm24);
302 iliev 2016
303     String GetName() { return Name; }
304     int GetChannelCount();
305     long GetTotalFrameCount();
306     int GetFrameSize();
307     bool HasLoops();
308     bool IsUnpitched() { return OriginalPitch == 255; }
309 schoenebeck 3481 File* GetFile() { return pFile; }
310 iliev 2016
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 schoenebeck 2780 unsigned long ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer);
321 iliev 2016
322     unsigned long ReadAndLoop (
323     void* pBuffer,
324     unsigned long FrameCount,
325 iliev 2020 PlaybackState* pPlaybackState,
326     Region* pRegion
327 iliev 2016 );
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 iliev 2020 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 iliev 2016 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 schoenebeck 3481
349     File* pFile;
350 iliev 2016 };
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 iliev 2020 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 iliev 2016
366 iliev 2204 int modEnvToPitch , modLfoToPitch, modEnvToFilterFc, modLfoToFilterFc; // in cents
367 iliev 2206 int modLfoToVolume /* in centibels */, freqModLfo /* in absolute cents */;
368 iliev 2204 int delayModLfo; // in absolute timecents
369 iliev 2206 int vibLfoToPitch, freqVibLfo /* in absolute cents */;
370 iliev 2204 int delayVibLfo; // in absolute timecents
371 iliev 2206 int initialFilterFc /* in absolute cents */, initialFilterQ /* in centibels */;
372 iliev 2016
373 iliev 2026 uint exclusiveClass; // exclusive group
374 iliev 2016
375     Sample* pSample;
376 iliev 2020 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 iliev 2016 Instrument* pInstrument; // used when the region belongs to preset
380    
381     Region();
382     Sample* GetSample() { return pSample; }
383     Region* GetParent() { return this; }
384    
385 iliev 2020 int GetUnityNote();
386    
387 iliev 2026 /**
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 iliev 2016 std::vector<ModulatorItem> modulators;
394    
395 iliev 2026
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 iliev 2206 int GetEG1Sustain(Region* pPresetRegion = NULL); // Sustain value of the sample amplitude EG (the decrease in level, expressed in centibels)
405 iliev 2026 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 iliev 2206 int GetEG2Sustain(Region* pPresetRegion = NULL); // Sustain value of the filter cutoff EG (in permilles)
412 iliev 2026 double GetEG2Release(Region* pPresetRegion = NULL); // in seconds
413    
414 iliev 2206 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 iliev 2026 double GetFreqModLfo(Region* pPresetRegion = NULL); // in Hz
420     double GetDelayModLfo(Region* pPresetRegion = NULL); // in seconds
421 iliev 2204 int GetVibLfoToPitch(Region* pPresetRegion = NULL); // in cents
422 iliev 2026 double GetFreqVibLfo(Region* pPresetRegion = NULL); // in Hz
423     double GetDelayVibLfo(Region* pPresetRegion = NULL); // in seconds
424 iliev 2206 int GetInitialFilterFc(Region* pPresetRegion); // in absolute cents
425     int GetInitialFilterQ(Region* pPresetRegion); // in centibels
426 iliev 2026
427 iliev 2016 friend class Instrument;
428     friend class Preset;
429    
430     private:
431 persson 2044 int EG1PreAttackDelay; // in timecents
432     int EG1Attack; // in timecents
433     int EG1Hold; // in timecents
434     int EG1Decay; // in timecents
435 iliev 2206 int EG1Sustain; // Sustain value (the decrease in level, expressed in centibels)
436 persson 2044 int EG1Release; // in timecents
437 iliev 2026
438 persson 2044 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 iliev 2026
445     Instrument* pParentInstrument;
446    
447 iliev 2016 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 persson 2044
462 iliev 2016 int GetRegionCount();
463     Region* GetRegion(int idx);
464    
465     protected:
466     std::vector<Region*> regions;
467     sf2::File* pFile;
468     };
469    
470 persson 2100 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 iliev 2016 class Instrument : public InstrumentBase {
484     public:
485     Instrument(sf2::File* pFile, RIFF::Chunk* ck);
486     ~Instrument();
487 iliev 2020
488     void DeleteRegion(Region* pRegion);
489 iliev 2016 //private:
490     uint16_t InstBagNdx;
491 persson 2044
492 iliev 2016 /**
493     * Load all regions (zones, bags) in the range idx1 - idx2
494     */
495     void LoadRegions(int idx1, int idx2);
496 iliev 2020
497     Region* CreateRegion();
498 iliev 2016 };
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 iliev 2026
520     Region* CreateRegion();
521 iliev 2016 };
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 iliev 2020 void DeleteInstrument(Instrument* pInstrument);
535 iliev 2016 int GetSampleCount();
536     Sample* GetSample(int idx);
537     void DeleteSample(Sample* pSample);
538     bool HasSamples();
539 schoenebeck 3481 RIFF::File* GetRiffFile();
540 iliev 2016
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