summaryrefslogtreecommitdiff
path: root/libs/fluidsynth/src/fluid_defsfont.h
blob: 29f3fd9e86b90df50aed52cb03d0af8d6642bdbb (plain)
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
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
/* 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
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 */


#ifndef _FLUID_DEFSFONT_H
#define _FLUID_DEFSFONT_H


#include "fluidsynth.h"
#include "fluidsynth_priv.h"
#include "fluid_list.h"



/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/

/*-----------------------------------sfont.h----------------------------*/

#define SF_SAMPMODES_LOOP	1
#define SF_SAMPMODES_UNROLL	2

#define SF_MIN_SAMPLERATE	400
#define SF_MAX_SAMPLERATE	50000

#define SF_MIN_SAMPLE_LENGTH	32

/* Sound Font structure defines */

typedef struct _SFVersion
{				/* version structure */
  unsigned short major;
  unsigned short minor;
}
SFVersion;

typedef 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 */
}
SFMod;

typedef 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;
}
SFGenAmount;

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

typedef struct _SFZone
{				/* Sample/instrument zone structure */
  fluid_list_t *instsamp;		/* instrument/sample pointer for zone */
  fluid_list_t *gen;			/* list of generators */
  fluid_list_t *mod;			/* list of modulators */
}
SFZone;

typedef struct _SFSample
{				/* Sample structure */
  char name[21];		/* Name of sample */
  unsigned char samfile;		/* Loaded sfont/sample buffer = 0/1 */
  unsigned int start;		/* Offset in sample area to start of sample */
  unsigned int end;			/* Offset from start to end of sample,
				   this is the last point of the
				   sample, the SF spec has this as the
				   1st point after, corrected on
				   load/save */
  unsigned int loopstart;		/* Offset from start to start of loop */
  unsigned int loopend;		/* Offset from start to end of loop,
				   marks the first point after loop,
				   whose sample value is ideally
				   equivalent to loopstart */
  unsigned int samplerate;		/* Sample rate recorded at */
  unsigned char origpitch;		/* root midi key number */
  signed char pitchadj;		/* pitch correction in cents */
  unsigned short sampletype;		/* 1 mono,2 right,4 left,linked 8,0x8000=ROM */
  fluid_sample_t *fluid_sample;	/* Imported sample (fixed up in fluid_defsfont_load) */
}
SFSample;

typedef struct _SFInst
{				/* Instrument structure */
  char name[21];		/* Name of instrument */
  fluid_list_t *zone;			/* list of instrument zones */
}
SFInst;

typedef struct _SFPreset
{				/* Preset structure */
  char name[21];		/* preset name */
  unsigned short prenum;		/* preset number */
  unsigned short bank;			/* bank number */
  unsigned int libr;			/* Not used (preserved) */
  unsigned int genre;		/* Not used (preserved) */
  unsigned int morph;		/* Not used (preserved) */
  fluid_list_t *zone;			/* list of preset zones */
}
SFPreset;

/* NOTE: sffd is also used to determine if sound font is new (NULL) */
typedef struct _SFData
{				/* Sound font data structure */
  SFVersion version;		/* sound font version */
  SFVersion romver;		/* ROM version */
  unsigned int samplepos;		/* position within sffd of the sample chunk */
  unsigned int samplesize;		/* length within sffd of the sample chunk */
  char *fname;			/* file name */
  FILE *sffd;			/* loaded sfont file descriptor */
  fluid_list_t *info;		     /* linked list of info strings (1st byte is ID) */
  fluid_list_t *preset;		/* linked list of preset info */
  fluid_list_t *inst;			/* linked list of instrument info */
  fluid_list_t *sample;		/* linked list of sample info */
}
SFData;

/* 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 */
typedef enum
{ 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
}
Gen_Type;

#define Gen_MaxValid 	Gen_Dummy - 1	/* maximum valid generator */
#define Gen_Count	Gen_Dummy	/* count of generators */
#define GenArrSize sizeof(SFGenAmount)*Gen_Count	/* gen array size */

/* generator unit type */
typedef enum
{
  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 */
}
Gen_Unit;

/* global data */

extern unsigned short badgen[]; 	/* list of bad generators */
extern unsigned short badpgen[]; 	/* list of bad preset generators */

/* functions */
void sfont_init_chunks (void);

void sfont_close (SFData * sf);
void sfont_free_zone (SFZone * zone);
int sfont_preset_compare_func (void* a, void* b);

void sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone);

fluid_list_t *gen_inlist (int gen, fluid_list_t * genlist);
int gen_valid (int gen);
int gen_validp (int gen);


/*-----------------------------------sffile.h----------------------------*/
/*
   File structures and routines (used to be in sffile.h)
*/

#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 */
typedef struct _SFChunk
{				/* RIFF file chunk structure */
  unsigned int id;			/* chunk id */
  unsigned int size;			/* size of the following chunk */
}
SFChunk;

typedef 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 */
}
SFPhdr;

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

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

typedef struct _SFShdr
{				/* Sample header loading struct */
  char name[20];		/* Sample name */
  unsigned int start;		/* Offset to start of sample */
  unsigned int end;			/* Offset to end of sample */
  unsigned int loopstart;		/* Offset to start of loop */
  unsigned int loopend;		/* Offset to end of loop */
  unsigned int samplerate;		/* Sample rate recorded at */
  unsigned char origpitch;		/* root midi key number */
  signed char pitchadj;		/* pitch correction in cents */
  unsigned short samplelink;		/* Not used */
  unsigned short sampletype;		/* 1 mono,2 right,4 left,linked 8,0x8000=ROM */
}
SFShdr;

/* data */
extern char idlist[];

/* functions */
SFData *sfload_file (const char * fname);



/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/

/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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 Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02110-1301, USA.
 */

#include <glib.h>


/*-----------------------------------util.h----------------------------*/
/*
  Utility functions (formerly in util.h)
 */
#define FAIL	0
#define OK	1

enum
{ ErrWarn, ErrFatal, ErrStatus, ErrCorr, ErrEof, ErrMem, Errno,
  ErrRead, ErrWrite
};

#define ErrMax		ErrWrite
#define ErrnoStart	Errno
#define ErrnoEnd	ErrWrite

int gerr (int ev, char * fmt, ...);
int safe_fread (void *buf, int count, FILE * fd);
int safe_fwrite (void *buf, int count, FILE * fd);
int safe_fseek (FILE * fd, long ofs, int whence);


/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/



/***************************************************************
 *
 *       FORWARD DECLARATIONS
 */
typedef struct _fluid_defsfont_t fluid_defsfont_t;
typedef struct _fluid_defpreset_t fluid_defpreset_t;
typedef struct _fluid_preset_zone_t fluid_preset_zone_t;
typedef struct _fluid_inst_t fluid_inst_t;
typedef struct _fluid_inst_zone_t fluid_inst_zone_t;

/*

  Public interface

 */

fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings);
int delete_fluid_defsfloader(fluid_sfloader_t* loader);
fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename);


int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont);
char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont);
fluid_preset_t* fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum);
void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont);
int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset);


int fluid_defpreset_preset_delete(fluid_preset_t* preset);
char* fluid_defpreset_preset_get_name(fluid_preset_t* preset);
int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset);
int fluid_defpreset_preset_get_num(fluid_preset_t* preset);
int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth, int chan, int key, int vel);


/*
 * fluid_defsfont_t
 */
struct _fluid_defsfont_t
{
  char* filename;           /* the filename of this soundfont */
  unsigned int samplepos;   /* the position in the file at which the sample data starts */
  unsigned int samplesize;  /* the size of the sample data */
  short* sampledata;        /* the sample data, loaded in ram */
  fluid_list_t* sample;      /* the samples in this soundfont */
  fluid_defpreset_t* preset; /* the presets of this soundfont */
  int mlock;                 /* Should we try memlock (avoid swapping)? */

  fluid_preset_t iter_preset;        /* preset interface used in the iteration */
  fluid_defpreset_t* iter_cur;       /* the current preset in the iteration */

  fluid_preset_t** preset_stack; /* List of presets that are available to use */
  int preset_stack_capacity;     /* Length of preset_stack array */
  int preset_stack_size;         /* Current number of items in the stack */
};


fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings);
int delete_fluid_defsfont(fluid_defsfont_t* sfont);
int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file);
char* fluid_defsfont_get_name(fluid_defsfont_t* sfont);
fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int prenum);
void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont);
int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset);
int fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont);
int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample);
int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset);


/*
 * fluid_preset_t
 */
struct _fluid_defpreset_t
{
  fluid_defpreset_t* next;
  fluid_defsfont_t* sfont;                  /* the soundfont this preset belongs to */
  char name[21];                        /* the name of the preset */
  unsigned int bank;                    /* the bank number */
  unsigned int num;                     /* the preset number */
  fluid_preset_zone_t* global_zone;        /* the global zone of the preset */
  fluid_preset_zone_t* zone;               /* the chained list of preset zones */
};

fluid_defpreset_t* new_fluid_defpreset(fluid_defsfont_t* sfont);
int delete_fluid_defpreset(fluid_defpreset_t* preset);
fluid_defpreset_t* fluid_defpreset_next(fluid_defpreset_t* preset);
int fluid_defpreset_import_sfont(fluid_defpreset_t* preset, SFPreset* sfpreset, fluid_defsfont_t* sfont);
int fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone);
int fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone);
fluid_preset_zone_t* fluid_defpreset_get_zone(fluid_defpreset_t* preset);
fluid_preset_zone_t* fluid_defpreset_get_global_zone(fluid_defpreset_t* preset);
int fluid_defpreset_get_banknum(fluid_defpreset_t* preset);
int fluid_defpreset_get_num(fluid_defpreset_t* preset);
char* fluid_defpreset_get_name(fluid_defpreset_t* preset);
int fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel);

/*
 * fluid_preset_zone
 */
struct _fluid_preset_zone_t
{
  fluid_preset_zone_t* next;
  char* name;
  fluid_inst_t* inst;
  int keylo;
  int keyhi;
  int vello;
  int velhi;
  fluid_gen_t gen[GEN_LAST];
  fluid_mod_t * mod; /* List of modulators */
};

fluid_preset_zone_t* new_fluid_preset_zone(char* name);
int delete_fluid_preset_zone(fluid_preset_zone_t* zone);
fluid_preset_zone_t* fluid_preset_zone_next(fluid_preset_zone_t* preset);
int fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone* sfzone, fluid_defsfont_t* sfont);
int fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel);
fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone);

/*
 * fluid_inst_t
 */
struct _fluid_inst_t
{
  char name[21];
  fluid_inst_zone_t* global_zone;
  fluid_inst_zone_t* zone;
};

fluid_inst_t* new_fluid_inst(void);
int delete_fluid_inst(fluid_inst_t* inst);
int fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont);
int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone);
fluid_inst_zone_t* fluid_inst_get_zone(fluid_inst_t* inst);
fluid_inst_zone_t* fluid_inst_get_global_zone(fluid_inst_t* inst);

/*
 * fluid_inst_zone_t
 */
struct _fluid_inst_zone_t
{
  fluid_inst_zone_t* next;
  char* name;
  fluid_sample_t* sample;
  int keylo;
  int keyhi;
  int vello;
  int velhi;
  fluid_gen_t gen[GEN_LAST];
  fluid_mod_t * mod; /* List of modulators */
};

fluid_inst_zone_t* new_fluid_inst_zone(char* name);
int delete_fluid_inst_zone(fluid_inst_zone_t* zone);
fluid_inst_zone_t* fluid_inst_zone_next(fluid_inst_zone_t* zone);
int fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont);
int fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel);
fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone);



fluid_sample_t* new_fluid_sample(void);
int delete_fluid_sample(fluid_sample_t* sample);
int fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont);
int fluid_sample_in_rom(fluid_sample_t* sample);


#endif  /* _FLUID_SFONT_H */