summaryrefslogtreecommitdiff
path: root/libs/fluidsynth/fluidsynth/sfont.h
blob: 0df4d6d4a81060095234f479fb821daaadd7ef7e (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
/* FluidSynth - A Software Synthesizer
 *
 * Copyright (C) 2003  Peter Hanappe and others.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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 _FLUIDSYNTH_SFONT_H
#define _FLUIDSYNTH_SFONT_H

#ifdef __cplusplus
extern "C" {
#endif


/**
 * @file sfont.h
 * @brief SoundFont plugins
 *
 * It is possible to add new SoundFont loaders to the
 * synthesizer. This API allows for virtual SoundFont files to be loaded
 * and synthesized, which may not actually be SoundFont files, as long as they
 * can be represented by the SoundFont synthesis model.
 *
 * To add a new SoundFont loader to the synthesizer, call
 * fluid_synth_add_sfloader() and pass a pointer to an
 * #fluid_sfloader_t instance created by new_fluid_sfloader().
 * On creation, you must specify a callback function \p load
 * that will be called for every file attempting to load it and
 * if successful returns a #fluid_sfont_t instance, or NULL if it fails.
 *
 * The #fluid_sfont_t structure contains a callback to obtain the
 * name of the SoundFont. It contains two functions to iterate
 * though the contained presets, and one function to obtain a
 * preset corresponding to a bank and preset number. This
 * function should return a #fluid_preset_t instance.
 *
 * The #fluid_preset_t instance contains some functions to obtain
 * information from the preset (name, bank, number). The most
 * important callback is the noteon function. The noteon function
 * is called by fluidsynth internally and
 * should call fluid_synth_alloc_voice() for every sample that has
 * to be played. fluid_synth_alloc_voice() expects a pointer to a
 * #fluid_sample_t instance and returns a pointer to the opaque
 * #fluid_voice_t structure. To set or increment the values of a
 * generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
 * finished initializing the voice call fluid_voice_start() to
 * start playing the synthesis voice.
 */

/**
 * Some notification enums for presets and samples.
 */
enum
{
    FLUID_PRESET_SELECTED,                /**< Preset selected notify */
    FLUID_PRESET_UNSELECTED,              /**< Preset unselected notify */
    FLUID_SAMPLE_DONE                     /**< Sample no longer needed notify */
};

/**
 * Indicates the type of a sample used by the _fluid_sample_t::sampletype field.
 */
enum fluid_sample_type
{
    FLUID_SAMPLETYPE_MONO = 0x1, /**< Used for mono samples */
    FLUID_SAMPLETYPE_RIGHT = 0x2, /**< Used for right samples of a stereo pair */
    FLUID_SAMPLETYPE_LEFT = 0x4, /**< Used for left samples of a stereo pair */
    FLUID_SAMPLETYPE_LINKED = 0x8, /**< Currently not used */
    FLUID_SAMPLETYPE_OGG_VORBIS = 0x10, /**< Used for Ogg Vorbis compressed samples @since 1.1.7 */
    FLUID_SAMPLETYPE_ROM = 0x8000 /**< Indicates ROM samples, causes sample to be ignored */
};


/**
 * Method to load an instrument file (does not actually need to be a real file name,
 * could be another type of string identifier that the \a loader understands).
 * @param loader SoundFont loader
 * @param filename File name or other string identifier
 * @return The loaded instrument file (SoundFont) or NULL if an error occured.
 */
typedef fluid_sfont_t *(*fluid_sfloader_load_t)(fluid_sfloader_t *loader, const char *filename);

/**
 * The free method should free the memory allocated for a fluid_sfloader_t instance in
 * addition to any private data. Any custom user provided cleanup function must ultimately call
 * delete_fluid_sfloader() to ensure proper cleanup of the #fluid_sfloader_t struct. If no private data
 * needs to be freed, setting this to delete_fluid_sfloader() is sufficient.
 * @param loader SoundFont loader
 */
typedef void (*fluid_sfloader_free_t)(fluid_sfloader_t *loader);


FLUIDSYNTH_API fluid_sfloader_t *new_fluid_sfloader(fluid_sfloader_load_t load, fluid_sfloader_free_t free);
FLUIDSYNTH_API void delete_fluid_sfloader(fluid_sfloader_t *loader);

FLUIDSYNTH_API fluid_sfloader_t *new_fluid_defsfloader(fluid_settings_t *settings);

/**
 * Opens the file or memory indicated by \c filename in binary read mode.
 * \c filename matches the string provided during the fluid_synth_sfload() call.
 *
 * @return returns a file handle on success, NULL otherwise
 */
typedef void *(* fluid_sfloader_callback_open_t)(const char *filename);

/**
 * Reads \c count bytes to the specified buffer \c buf.
 *
 * @return returns #FLUID_OK if exactly \c count bytes were successfully read, else returns #FLUID_FAILED and leaves \a buf unmodified.
 */
typedef int (* fluid_sfloader_callback_read_t)(void *buf, int count, void *handle);

/**
 * Same purpose and behaviour as fseek.
 *
 * @param origin either \c SEEK_SET, \c SEEK_CUR or \c SEEK_END
 *
 * @return returns #FLUID_OK if the seek was successfully performed while not seeking beyond a buffer or file, #FLUID_FAILED otherwise
 */
typedef int (* fluid_sfloader_callback_seek_t)(void *handle, long offset, int origin);

/**
 * Closes the handle returned by #fluid_sfloader_callback_open_t and frees used ressources.
 *
 * @return returns #FLUID_OK on success, #FLUID_FAILED on error
 */
typedef int (* fluid_sfloader_callback_close_t)(void *handle);

/** @return returns current file offset or #FLUID_FAILED on error */
typedef long (* fluid_sfloader_callback_tell_t)(void *handle);


FLUIDSYNTH_API int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader,
        fluid_sfloader_callback_open_t open,
        fluid_sfloader_callback_read_t read,
        fluid_sfloader_callback_seek_t seek,
        fluid_sfloader_callback_tell_t tell,
        fluid_sfloader_callback_close_t close);

FLUIDSYNTH_API int fluid_sfloader_set_data(fluid_sfloader_t *loader, void *data);
FLUIDSYNTH_API void *fluid_sfloader_get_data(fluid_sfloader_t *loader);



/**
 * Method to return the name of a virtual SoundFont.
 * @param sfont Virtual SoundFont
 * @return The name of the virtual SoundFont.
 */
typedef const char *(*fluid_sfont_get_name_t)(fluid_sfont_t *sfont);

/**
 * Get a virtual SoundFont preset by bank and program numbers.
 * @param sfont Virtual SoundFont
 * @param bank MIDI bank number (0-16383)
 * @param prenum MIDI preset number (0-127)
 * @return Should return an allocated virtual preset or NULL if it could not
 *   be found.
 */
typedef fluid_preset_t *(*fluid_sfont_get_preset_t)(fluid_sfont_t *sfont, int bank, int prenum);

/**
 * Start virtual SoundFont preset iteration method.
 * @param sfont Virtual SoundFont
 *
 * Starts/re-starts virtual preset iteration in a SoundFont.
 */
typedef void (*fluid_sfont_iteration_start_t)(fluid_sfont_t *sfont);

/**
 * Virtual SoundFont preset iteration function.
 * @param sfont Virtual SoundFont
 * @return NULL when no more presets are available, otherwise the a pointer to the current preset
 *
 * Returns preset information to the caller. The returned buffer is only valid until a subsequent
 * call to this function.
 */
typedef fluid_preset_t *(*fluid_sfont_iteration_next_t)(fluid_sfont_t *sfont);

/**
 * Method to free a virtual SoundFont bank. Any custom user provided cleanup function must ultimately call
 * delete_fluid_sfont() to ensure proper cleanup of the #fluid_sfont_t struct. If no private data
 * needs to be freed, setting this to delete_fluid_sfont() is sufficient.
 * @param sfont Virtual SoundFont to free.
 * @return Should return 0 when it was able to free all resources or non-zero
 *   if some of the samples could not be freed because they are still in use,
 *   in which case the free will be tried again later, until success.
 */
typedef int (*fluid_sfont_free_t)(fluid_sfont_t *sfont);


FLUIDSYNTH_API fluid_sfont_t *new_fluid_sfont(fluid_sfont_get_name_t get_name,
        fluid_sfont_get_preset_t get_preset,
        fluid_sfont_iteration_start_t iter_start,
        fluid_sfont_iteration_next_t iter_next,
        fluid_sfont_free_t free);

FLUIDSYNTH_API int delete_fluid_sfont(fluid_sfont_t *sfont);

FLUIDSYNTH_API int fluid_sfont_set_data(fluid_sfont_t *sfont, void *data);
FLUIDSYNTH_API void *fluid_sfont_get_data(fluid_sfont_t *sfont);

FLUIDSYNTH_API int fluid_sfont_get_id(fluid_sfont_t *sfont);
FLUIDSYNTH_API const char *fluid_sfont_get_name(fluid_sfont_t *sfont);
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_get_preset(fluid_sfont_t *sfont, int bank, int prenum);
FLUIDSYNTH_API void fluid_sfont_iteration_start(fluid_sfont_t *sfont);
FLUIDSYNTH_API fluid_preset_t *fluid_sfont_iteration_next(fluid_sfont_t *sfont);

/**
 * Method to get a virtual SoundFont preset name.
 * @param preset Virtual SoundFont preset
 * @return Should return the name of the preset.  The returned string must be
 *   valid for the duration of the virtual preset (or the duration of the
 *   SoundFont, in the case of preset iteration).
 */
typedef const char *(*fluid_preset_get_name_t)(fluid_preset_t *preset);

/**
 * Method to get a virtual SoundFont preset MIDI bank number.
 * @param preset Virtual SoundFont preset
 * @param return The bank number of the preset
 */
typedef int (*fluid_preset_get_banknum_t)(fluid_preset_t *preset);

/**
 * Method to get a virtual SoundFont preset MIDI program number.
 * @param preset Virtual SoundFont preset
 * @param return The program number of the preset
 */
typedef int (*fluid_preset_get_num_t)(fluid_preset_t *preset);

/**
 * Method to handle a noteon event (synthesize the instrument).
 * @param preset Virtual SoundFont preset
 * @param synth Synthesizer instance
 * @param chan MIDI channel number of the note on event
 * @param key MIDI note number (0-127)
 * @param vel MIDI velocity (0-127)
 * @return #FLUID_OK on success (0) or #FLUID_FAILED (-1) otherwise
 *
 * This method may be called from within synthesis context and therefore
 * should be as efficient as possible and not perform any operations considered
 * bad for realtime audio output (memory allocations and other OS calls).
 *
 * Call fluid_synth_alloc_voice() for every sample that has
 * to be played. fluid_synth_alloc_voice() expects a pointer to a
 * #fluid_sample_t structure and returns a pointer to the opaque
 * #fluid_voice_t structure. To set or increment the values of a
 * generator, use fluid_voice_gen_set() or fluid_voice_gen_incr(). When you are
 * finished initializing the voice call fluid_voice_start() to
 * start playing the synthesis voice.  Starting with FluidSynth 1.1.0 all voices
 * created will be started at the same time.
 */
typedef int (*fluid_preset_noteon_t)(fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel);

/**
 * Method to free a virtual SoundFont preset. Any custom user provided cleanup function must ultimately call
 * delete_fluid_preset() to ensure proper cleanup of the #fluid_preset_t struct. If no private data
 * needs to be freed, setting this to delete_fluid_preset() is sufficient.
 * @param preset Virtual SoundFont preset
 * @return Should return 0
 */
typedef void (*fluid_preset_free_t)(fluid_preset_t *preset);

FLUIDSYNTH_API fluid_preset_t *new_fluid_preset(fluid_sfont_t *parent_sfont,
        fluid_preset_get_name_t get_name,
        fluid_preset_get_banknum_t get_bank,
        fluid_preset_get_num_t get_num,
        fluid_preset_noteon_t noteon,
        fluid_preset_free_t free);
FLUIDSYNTH_API void delete_fluid_preset(fluid_preset_t *preset);

FLUIDSYNTH_API int fluid_preset_set_data(fluid_preset_t *preset, void *data);
FLUIDSYNTH_API void *fluid_preset_get_data(fluid_preset_t *preset);

FLUIDSYNTH_API const char *fluid_preset_get_name(fluid_preset_t *preset);
FLUIDSYNTH_API int fluid_preset_get_banknum(fluid_preset_t *preset);
FLUIDSYNTH_API int fluid_preset_get_num(fluid_preset_t *preset);
FLUIDSYNTH_API fluid_sfont_t *fluid_preset_get_sfont(fluid_preset_t *preset);

FLUIDSYNTH_API fluid_sample_t *new_fluid_sample(void);
FLUIDSYNTH_API void delete_fluid_sample(fluid_sample_t *sample);
FLUIDSYNTH_API size_t fluid_sample_sizeof(void);

FLUIDSYNTH_API int fluid_sample_set_name(fluid_sample_t *sample, const char *name);
FLUIDSYNTH_API int fluid_sample_set_sound_data(fluid_sample_t *sample,
        short *data,
        char *data24,
        unsigned int nbframes,
        unsigned int sample_rate,
        short copy_data);

FLUIDSYNTH_API int fluid_sample_set_loop(fluid_sample_t *sample, unsigned int loop_start, unsigned int loop_end);
FLUIDSYNTH_API int fluid_sample_set_pitch(fluid_sample_t *sample, int root_key, int fine_tune);

#ifdef __cplusplus
}
#endif

#endif /* _FLUIDSYNTH_SFONT_H */