File: sfont.h

package info (click to toggle)
musescore-snapshot 3.2.s20190704+dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 218,116 kB
  • sloc: cpp: 290,563; xml: 200,238; sh: 3,706; ansic: 1,447; python: 393; makefile: 222; perl: 82; pascal: 79
file content (403 lines) | stat: -rw-r--r-- 13,507 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/* FluidSynth - A Software Synthesizer
 *
 * Copyright (C) 2003  Peter Hanappe and others.
 *
 * SoundFont loading code borrowed from Smurf SoundFont Editor by Josh Green
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License
 * as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307, USA
 */

#ifndef _FLUID_DEFSFONT_H
#define _FLUID_DEFSFONT_H

#include "config.h"
#include "fluid.h"

namespace FluidS {

class Preset;
class Sample;
class Instrument;
struct SFGen;
struct SFMod;

struct SFChunk;

//---------------------------------------------------------
//   SFVersion
//---------------------------------------------------------

struct SFVersion {            // version structure
      unsigned short major, minor;
      SFVersion();
      };

//---------------------------------------------------------
//   SFont
//---------------------------------------------------------

class SFont {
      Fluid* synth;
      QFile f;
      unsigned samplepos;           // the position in the file at which the sample data starts
      unsigned samplesize;          // the size of the sample data

      QList<Instrument*> instruments;
      QList<Preset*> presets;
      QList<Sample*> sample;

      int _id;
      int _bankOffset;

      SFVersion _version;		// sound font version
      SFVersion romver;		      // ROM version
      QString _fontName;
      QList<unsigned char*> infos;	// list of info strings (1st byte is ID)

      void read_listchunk(SFChunk* chunk);
      void process_info(int size);
      void process_sdta(unsigned int size);
      void pdtahelper(unsigned int expid, unsigned int reclen, SFChunk* chunk, int* size);

      void process_pdta(int size);
      void load_phdr(int size);
      void load_pbag(int size);
      void load_pmod(int size);
      void load_pgen(int size);
      void load_ihdr(int size);
      void load_ibag(int size);
      void load_imod(int size);
      void load_igen(int size);
      void load_shdr(int size);

      void fixup_pgen();
      void fixup_igen();
      void fixup_sample();

      void readchunk(SFChunk*);
      unsigned short READW();
      void READD(unsigned int& var);
      void FSKIP(int size)    {  return safe_fseek(size); }
      void FSKIPW();
      unsigned char READB();
      char READC();
      void READSTR(char*);

      void safe_fread(void *buf, int count);
      void safe_fseek(long ofs);
      bool load();

   public:
      SFont(Fluid* f);
      virtual ~SFont();

      QString get_name()  const                 { return f.fileName(); }
      Preset* get_preset(int bank, int prenum);

      bool read(const QString& file);

      int load_sampledata();
      unsigned int samplePos() const            { return samplepos;  }
      int id() const                            { return _id; }
      void setId(int i)                         { _id = i;    }
      void setSamplepos(unsigned v)             { samplepos = v; }
      void setSamplesize(unsigned v)            { samplesize = v; }
      unsigned getSamplesize() const            { return samplesize; }
      const QList<Preset*> getPresets() const   { return presets; }
      SFVersion version() const                 { return _version; }
      int bankOffset() const                    { return _bankOffset; }
      void setBankOffset(int val)               { _bankOffset = val; }
      QString fontName() const                  { return _fontName; }

      friend class Preset;
      };

//---------------------------------------------------------
//   Sample
//---------------------------------------------------------

class Sample {
      bool _valid;

   public:
      SFont* sf;
      unsigned int start;
      unsigned int end;
      unsigned int loopstart;
      unsigned int loopend;
      unsigned int samplerate;
      int origpitch;
      int pitchadj;
      int sampletype;

      short* data;

      /** The amplitude, that will lower the level of the sample's loop to
          the noise floor. Needed for note turnoff optimization, will be
          filled out automatically */
      /* Set this to zero, when submitting a new sample. */

      bool amplitude_that_reaches_noise_floor_is_valid;
      double amplitude_that_reaches_noise_floor;

      Sample(SFont*);
      ~Sample();

      bool inRom() const;
      void optimize();
      void load();
      bool valid() const    { return _valid; }
      void setValid(bool v) { _valid = v; }
#ifdef SOUNDFONT3
      bool decompressOggVorbis(char* p, int size);
#endif
      };

//---------------------------------------------------------
//   Zone
//---------------------------------------------------------

class Zone {
   public:
      union {
            Sample* sample;
            int sampIdx;
            Instrument* instrument;
            int instIdx;
            };

      QList<SFGen*> gen;
      QList<SFMod*> mod;

      int keylo, keyhi, vello, velhi;
      Generator   genlist[GEN_LAST];
      QList<Mod*> modlist;        // List of modulators

   public:
      Zone();
      ~Zone();
      bool importZone();
      bool inside_range(int key, int vel) const;
      Instrument* get_inst()     const          { return instrument; }
      Sample* get_sample() const                { return sample; }
      };

//---------------------------------------------------------
//   Instrument
//---------------------------------------------------------

class Instrument {
   public:
      Zone* global_zone;
      QList<Zone*> zones;

   public:
      Instrument();
      ~Instrument();
      Zone* get_global_zone() const     { return global_zone; }
      QList<Zone*> get_zone()           { return zones; }
      bool import_sfont();
      };

//---------------------------------------------------------
//   Preset
//---------------------------------------------------------

class Preset {
   public:
      QString name;                 // the name of the preset
      SFont* sfont;
      int bank;                     // the bank number
      int num;                      // the preset number

      Zone* _global_zone;           // the global zone of the preset
      QList<Zone*> zones;

   public:
      Preset(SFont* sfont);
      ~Preset();

      QString get_name() const                  { return name; }
      int get_banknum() const                   { return bank; }
      int get_num() const                       { return num;  }
      bool noteon(Fluid*, unsigned id, int chan, int key, int vel, double nt);

      void setGlobalZone(Zone* z)               { _global_zone = z;   }
      bool importSfont();

      Zone* global_zone()                       { return _global_zone; }
      void loadSamples();
      QList<Zone*> getZones()                   { return zones; }
      };

//---------------------------------------------------------
//   SFChunk
//---------------------------------------------------------

struct SFChunk {              // RIFF file chunk structure
      unsigned int id;	      // chunk id
      unsigned int size;	// size of the following chunk
      };

struct SFMod {				/* Modulator structure */
      unsigned short src;		/* source modulator */
      unsigned short dest;		/* destination generator */
      signed short amount;		/* signed, degree of modulation */
      unsigned short amtsrc;		/* second source controls amnt of first */
      unsigned short trans;		/* transform applied to source */
      };

union SFGenAmount {			/* Generator amount structure */
      signed short sword;		/* signed 16 bit value */
      unsigned short uword;		/* unsigned 16 bit value */
      struct {
            unsigned char lo;		/* low value for ranges */
            unsigned char hi;		/* high value for ranges */
            } range;
      };

struct SFGen {				/* Generator structure  */
      unsigned short id;		/* generator ID         */
      SFGenAmount amount;		/* generator value      */
      };


/* NOTE: sffd is also used to determine if sound font is new (NULL) */

/* sf file chunk IDs */
enum {
      UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID,
      INFO_ID, SDTA_ID, PDTA_ID,	/* info/sample/preset */

      IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */
      IVER_ID, ICRD_ID, IENG_ID, IPRD_ID,	/* more info ids */
      ICOP_ID, ICMT_ID, ISFT_ID,	/* and yet more info ids */

      SNAM_ID, SMPL_ID,		/* sample ids */
      PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID,	/* preset ids */
      IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID,	/* instrument ids */
      SHDR_ID			/* sample info */
      };

/* generator types */
enum Gen_Type {
      Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
      Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_ModLFO2Pitch,
      Gen_VibLFO2Pitch, Gen_ModEnv2Pitch, Gen_FilterFc, Gen_FilterQ,
      Gen_ModLFO2FilterFc, Gen_ModEnv2FilterFc, Gen_EndAddrCoarseOfs,
      Gen_ModLFO2Vol, Gen_Unused1, Gen_ChorusSend, Gen_ReverbSend, Gen_Pan,
      Gen_Unused2, Gen_Unused3, Gen_Unused4,
      Gen_ModLFODelay, Gen_ModLFOFreq, Gen_VibLFODelay, Gen_VibLFOFreq,
      Gen_ModEnvDelay, Gen_ModEnvAttack, Gen_ModEnvHold, Gen_ModEnvDecay,
      Gen_ModEnvSustain, Gen_ModEnvRelease, Gen_Key2ModEnvHold,
      Gen_Key2ModEnvDecay, Gen_VolEnvDelay, Gen_VolEnvAttack,
      Gen_VolEnvHold, Gen_VolEnvDecay, Gen_VolEnvSustain, Gen_VolEnvRelease,
      Gen_Key2VolEnvHold, Gen_Key2VolEnvDecay, Gen_Instrument,
      Gen_Reserved1, Gen_KeyRange, Gen_VelRange,
      Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity,
      Gen_Attenuation, Gen_Reserved2, Gen_EndLoopAddrCoarseOfs,
      Gen_CoarseTune, Gen_FineTune, Gen_SampleId, Gen_SampleModes,
      Gen_Reserved3, Gen_ScaleTune, Gen_ExclusiveClass, Gen_OverrideRootKey,
      Gen_Dummy
      };

#define Gen_MaxValid 	Gen_Dummy - 1	/* maximum valid generator */

/* generator unit type */
enum Gen_Unit {
      None,				/* No unit type */
      Unit_Smpls,			/* in samples */
      Unit_32kSmpls,		/* in 32k samples */
      Unit_Cent,			/* in cents (1/100th of a semitone) */
      Unit_HzCent,		/* in Hz Cents */
      Unit_TCent,			/* in Time Cents */
      Unit_cB,			/* in centibels (1/100th of a decibel) */
      Unit_Percent,	      /* in percentage */
      Unit_Semitone,		/* in semitones */
      Unit_Range			/* a range of values */
      };

/* global data */

#define CHNKIDSTR(id)           &idlist[(id - 1) * 4]

/* sfont file chunk sizes */
#define SFPHDRSIZE	38
#define SFBAGSIZE	      4
#define SFMODSIZE	      10
#define SFGENSIZE	      4
#define SFIHDRSIZE	22
#define SFSHDRSIZE	46

/* sfont file data structures */

struct SFPhdr {
      unsigned char name[20];		/* preset name */
      unsigned short preset;		/* preset number */
      unsigned short bank;	      /* bank number */
      unsigned short pbagndx;		/* index into preset bag */
      unsigned int library;		/* just for preserving them */
      unsigned int genre;		/* Not used */
      unsigned int morphology;	/* Not used */
      };

struct SFBag {
      unsigned short genndx;		/* index into generator list */
      unsigned short modndx;		/* index into modulator list */
      };

struct SFIhdr {
      char name[20];		      /* Name of instrument */
      unsigned short ibagndx;		/* Instrument bag index */
      };

/* Basic bit swapping functions
 */
#define GUINT16_SWAP_LE_BE_CONSTANT(val)	((unsigned short) ( \
    (((unsigned short) (val) & (unsigned short) 0x00ffU) << 8) | \
    (((unsigned short) (val) & (unsigned short) 0xff00U) >> 8)))
#define GUINT32_SWAP_LE_BE_CONSTANT(val)	((unsigned int) ( \
    (((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \
    (((unsigned int) (val) & (unsigned int) 0x0000ff00U) <<  8) | \
    (((unsigned int) (val) & (unsigned int) 0x00ff0000U) >>  8) | \
    (((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24)))

#define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
#define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))

#define GINT16_TO_LE(val)	((signed short) (val))
#define GUINT16_TO_LE(val)	((unsigned short) (val))
#define GINT16_TO_BE(val)	((signed short) GUINT16_SWAP_LE_BE (val))
#define GUINT16_TO_BE(val)	(GUINT16_SWAP_LE_BE (val))
#define GINT32_TO_LE(val)	((signed int) (val))
#define GUINT32_TO_LE(val)	((unsigned int) (val))
#define GINT32_TO_BE(val)	((signed int) GUINT32_SWAP_LE_BE (val))
#define GUINT32_TO_BE(val)	(GUINT32_SWAP_LE_BE (val))

/* The G*_TO_?E() macros are defined in glibconfig.h.
 * The transformation is symmetric, so the FROM just maps to the TO.
 */
#define GINT16_FROM_LE(val)	(GINT16_TO_LE (val))
#define GUINT16_FROM_LE(val)	(GUINT16_TO_LE (val))
#define GINT16_FROM_BE(val)	(GINT16_TO_BE (val))
#define GUINT16_FROM_BE(val)	(GUINT16_TO_BE (val))
#define GINT32_FROM_LE(val)	(GINT32_TO_LE (val))
#define GUINT32_FROM_LE(val)	(GUINT32_TO_LE (val))
#define GINT32_FROM_BE(val)	(GINT32_TO_BE (val))
#define GUINT32_FROM_BE(val)	(GUINT32_TO_BE (val))
}

#endif  /* _FLUID_SFONT_H */