1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20 
21 
22 #ifndef _PRIV_FLUID_SFONT_H
23 #define _PRIV_FLUID_SFONT_H
24 
25 #include "fluidsynth.h"
26 
27 int fluid_sample_validate(fluid_sample_t *sample, unsigned int max_end);
28 int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end);
29 
30 /*
31  * Utility macros to access soundfonts, presets, and samples
32  */
33 
34 #define fluid_sfloader_delete(_loader) { if ((_loader) && (_loader)->free) (*(_loader)->free)(_loader); }
35 #define fluid_sfloader_load(_loader, _filename) (*(_loader)->load)(_loader, _filename)
36 
37 
38 #define fluid_sfont_delete_internal(_sf)   ( ((_sf) && (_sf)->free)? (*(_sf)->free)(_sf) : 0)
39 
40 
41 #define fluid_preset_delete_internal(_preset) \
42   { if ((_preset) && (_preset)->free) { (*(_preset)->free)(_preset); }}
43 
44 #define fluid_preset_noteon(_preset,_synth,_ch,_key,_vel) \
45   (*(_preset)->noteon)(_preset,_synth,_ch,_key,_vel)
46 
47 #define fluid_preset_notify(_preset,_reason,_chan) \
48   { if ((_preset) && (_preset)->notify) { (*(_preset)->notify)(_preset,_reason,_chan); }}
49 
50 
51 #define fluid_sample_incr_ref(_sample) { (_sample)->refcount++; }
52 
53 #define fluid_sample_decr_ref(_sample) \
54   (_sample)->refcount--; \
55   if (((_sample)->refcount == 0) && ((_sample)->notify)) \
56     (*(_sample)->notify)(_sample, FLUID_SAMPLE_DONE);
57 
58 
59 
60 /**
61  * File callback structure to enable custom soundfont loading (e.g. from memory).
62  */
63 struct _fluid_file_callbacks_t
64 {
65     fluid_sfloader_callback_open_t  fopen;
66     fluid_sfloader_callback_read_t  fread;
67     fluid_sfloader_callback_seek_t  fseek;
68     fluid_sfloader_callback_close_t fclose;
69     fluid_sfloader_callback_tell_t  ftell;
70 };
71 
72 /**
73  * SoundFont loader structure.
74  */
75 struct _fluid_sfloader_t
76 {
77     void *data;           /**< User defined data pointer used by _fluid_sfloader_t::load() */
78 
79     /** Callback structure specifying file operations used during soundfont loading to allow custom loading, such as from memory */
80     fluid_file_callbacks_t file_callbacks;
81 
82     fluid_sfloader_free_t free;
83 
84     fluid_sfloader_load_t load;
85 };
86 
87 /**
88  * Virtual SoundFont instance structure.
89  */
90 struct _fluid_sfont_t
91 {
92     void *data;           /**< User defined data */
93     int id;               /**< SoundFont ID */
94     int refcount;         /**< SoundFont reference count (1 if no presets referencing it) */
95     int bankofs;          /**< Bank offset */
96 
97     fluid_sfont_free_t free;
98 
99     fluid_sfont_get_name_t get_name;
100 
101     fluid_sfont_get_preset_t get_preset;
102 
103     fluid_sfont_iteration_start_t iteration_start;
104 
105     fluid_sfont_iteration_next_t iteration_next;
106 };
107 
108 /**
109  * Virtual SoundFont preset.
110  */
111 struct _fluid_preset_t
112 {
113     void *data;                                   /**< User supplied data */
114     fluid_sfont_t *sfont;                         /**< Parent virtual SoundFont */
115 
116     fluid_preset_free_t free;
117 
118     fluid_preset_get_name_t get_name;
119 
120     fluid_preset_get_banknum_t get_banknum;
121 
122     fluid_preset_get_num_t get_num;
123 
124     fluid_preset_noteon_t noteon;
125 
126     /**
127      * Virtual SoundFont preset notify method.
128      * @param preset Virtual SoundFont preset
129      * @param reason #FLUID_PRESET_SELECTED or #FLUID_PRESET_UNSELECTED
130      * @param chan MIDI channel number
131      * @return Should return #FLUID_OK
132      *
133      * Implement this optional method if the preset needs to be notified about
134      * preset select and unselect events.
135      *
136      * This method may be called from within synthesis context and therefore
137      * should be as efficient as possible and not perform any operations considered
138      * bad for realtime audio output (memory allocations and other OS calls).
139      */
140     int (*notify)(fluid_preset_t *preset, int reason, int chan);
141 };
142 
143 /**
144  * Virtual SoundFont sample.
145  */
146 struct _fluid_sample_t
147 {
148     char name[21];                /**< Sample name */
149 
150     /* The following for sample pointers store the original pointers from the Soundfont
151      * file. They are never changed after loading and are used to re-create the
152      * actual sample pointers after a sample has been unloaded and loaded again. The
153      * actual sample pointers get modified during loading for SF3 (compressed) samples
154      * and individually loaded SF2 samples. */
155     unsigned int source_start;
156     unsigned int source_end;
157     unsigned int source_loopstart;
158     unsigned int source_loopend;
159 
160     unsigned int start;           /**< Start index */
161     unsigned int end;	        /**< End index, index of last valid sample point (contrary to SF spec) */
162     unsigned int loopstart;       /**< Loop start index */
163     unsigned int loopend;         /**< Loop end index, first point following the loop (superimposed on loopstart) */
164 
165     unsigned int samplerate;      /**< Sample rate */
166     int origpitch;                /**< Original pitch (MIDI note number, 0-127) */
167     int pitchadj;                 /**< Fine pitch adjustment (+/- 99 cents) */
168     int sampletype;               /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */
169     int auto_free;                /**< TRUE if _fluid_sample_t::data and _fluid_sample_t::data24 should be freed upon sample destruction */
170     short *data;                  /**< Pointer to the sample's 16 bit PCM data */
171     char *data24;                 /**< If not NULL, pointer to the least significant byte counterparts of each sample data point in order to create 24 bit audio samples */
172 
173     int amplitude_that_reaches_noise_floor_is_valid;      /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */
174     double amplitude_that_reaches_noise_floor;            /**< The amplitude at which the sample's loop will be below the noise floor.  For voice off optimization, calculated automatically. */
175 
176     unsigned int refcount;        /**< Count of voices using this sample */
177     int preset_count;             /**< Count of selected presets using this sample (used for dynamic sample loading) */
178 
179     /**
180      * Implement this function to receive notification when sample is no longer used.
181      * @param sample Virtual SoundFont sample
182      * @param reason #FLUID_SAMPLE_DONE only currently
183      * @return Should return #FLUID_OK
184      */
185     int (*notify)(fluid_sample_t *sample, int reason);
186 };
187 
188 
189 #endif /* _PRIV_FLUID_SFONT_H */
190