1 /* 2 * libInstPatch 3 * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org> 4 * 5 * This program 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; version 2.1 8 * of the License only. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA or on the web at http://www.gnu.org. 19 */ 20 #ifndef __IPATCH_SF2_VOICE_CACHE_H__ 21 #define __IPATCH_SF2_VOICE_CACHE_H__ 22 23 #include <stdarg.h> 24 #include <glib.h> 25 #include <glib-object.h> 26 27 #include <libinstpatch/IpatchSampleData.h> 28 #include <libinstpatch/IpatchSF2Gen.h> 29 #include <libinstpatch/IpatchSF2Mod.h> 30 #include <libinstpatch/IpatchSample.h> 31 32 /* forward type declarations */ 33 34 typedef struct _IpatchSF2VoiceCache IpatchSF2VoiceCache; 35 typedef struct _IpatchSF2VoiceCacheClass IpatchSF2VoiceCacheClass; 36 typedef struct _IpatchSF2Voice IpatchSF2Voice; 37 typedef struct _IpatchSF2VoiceUpdate IpatchSF2VoiceUpdate; 38 typedef struct _IpatchSF2VoiceSelInfo IpatchSF2VoiceSelInfo; 39 40 #define IPATCH_TYPE_SF2_VOICE_CACHE (ipatch_sf2_voice_cache_get_type ()) 41 #define IPATCH_SF2_VOICE_CACHE(obj) \ 42 (G_TYPE_CHECK_INSTANCE_CAST ((obj), IPATCH_TYPE_SF2_VOICE_CACHE, \ 43 IpatchSF2VoiceCache)) 44 #define IPATCH_SF2_VOICE_CACHE_CLASS(klass) \ 45 (G_TYPE_CHECK_CLASS_CAST ((klass), IPATCH_TYPE_SF2_VOICE_CACHE, \ 46 IpatchSF2VoiceCacheClass)) 47 #define IPATCH_IS_SF2_VOICE_CACHE(obj) \ 48 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IPATCH_TYPE_SF2_VOICE_CACHE)) 49 #define IPATCH_IS_SF2_VOICE_CACHE_CLASS(klass) \ 50 (G_TYPE_CHECK_CLASS_TYPE ((klass), IPATCH_TYPE_SF2_VOICE_CACHE)) 51 52 /** 53 * IpatchSF2VoiceCacheItemFunc: 54 * @cache: Voice cache 55 * @item: Item which voice cache is dependent on 56 * 57 * A callback function type which is called during voice cache population 58 * for each item which the voice cache is dependent on. This can be useful 59 * for determining when a voice cache needs to be updated or for real time 60 * effects. 61 */ 62 typedef void (*IpatchSF2VoiceCacheItemFunc)(IpatchSF2VoiceCache *cache, 63 GObject *item); 64 65 /* SoundFont voice cache object */ 66 struct _IpatchSF2VoiceCache 67 { 68 GObject parent_instance; 69 70 IpatchSF2VoiceSelInfo *sel_info; /* array of selection criteria info */ 71 int sel_count; /* count of selection ranges per voice (integer pairs) */ 72 73 GArray *voices; /* array of IpatchSF2Voice structures */ 74 GArray *ranges; /* array of selection integer pairs for each voice */ 75 76 GSList *default_mods; /* default modulators */ 77 78 /* default loop type which can be used for objects that don't define it */ 79 IpatchSampleLoopType default_loop_type; 80 81 /* dependent item callback function */ 82 IpatchSF2VoiceCacheItemFunc item_func; 83 gpointer item_func_data; /* user defined data used by item_func */ 84 85 /* IpatchSF2VoiceCache user defined */ 86 gpointer user_data; /* Arbitrary data defined by IpatchSF2VoiceCache user */ 87 GDestroyNotify user_data_destroy; /* Optional callback to destroy user_data */ 88 GDestroyNotify voice_user_data_destroy; /* Optional callback to destroy user_data in each voice */ 89 90 /* Added with version 1.1.0 */ 91 GSList *override_mods; /* override modulators (added with libInstPatch version 1.1.0) */ 92 }; 93 94 struct _IpatchSF2VoiceCacheClass 95 { 96 GObjectClass parent_class; 97 }; 98 99 /* a SoundFont voice */ 100 struct _IpatchSF2Voice 101 { 102 /* Set by SF2VoiceCache converter via ipatch_sf2_voice_set_sample_data() */ 103 IpatchSampleData *sample_data; /* sample data for voice */ 104 IpatchSampleStore *sample_store; /* Cached store */ 105 guint32 sample_size; /* size of sample in frames */ 106 107 /* Set by SF2VoiceCache converter */ 108 guint32 loop_start; /* loop start offset (in samples) */ 109 guint32 loop_end; /* loop end offset (in samples, 1st sample after loop) */ 110 guint32 rate; /* sample rate */ 111 guint8 root_note; /* MIDI root note of sample */ 112 gint8 fine_tune; /* fine tune (in cents, -99 - 99) */ 113 guint16 reserved; /* reserved (should be 0) */ 114 115 IpatchSF2GenArray gen_array; /* generator effect values */ 116 GSList *mod_list; /* modulator list */ 117 118 /* IpatchSF2VoiceCache user defined */ 119 gpointer user_data; /* Arbitrary data defined by IpatchSF2VoiceCache user */ 120 121 /* Set internally */ 122 int range_index; /* index in ranges array (int *) to first selection range */ 123 }; 124 125 /* a voice parameter update (used for realtime effects) */ 126 struct _IpatchSF2VoiceUpdate 127 { 128 guint16 voice; /* index of voice with parameter to update */ 129 130 union /* new value for parameter */ 131 { 132 gint16 ival; 133 guint16 uval; 134 }; 135 136 guint8 genid; /* if type == IPATCH_SF2_VOICE_UPDATE_GEN: id of gen */ 137 guint8 reserved[3]; /* padding to 4 bytes */ 138 }; 139 140 /** 141 * IpatchSF2VoiceCacheUpdateHandler: 142 * @cache: Voice cache to get updates for 143 * @select_values: The voice selection criteria to use, should be the same 144 * number of select values as in @cache 145 * @cache_item: Original item @cache was created from 146 * @item: Object for which a property changed 147 * @pspec: Parameter specification of property which changed 148 * @value: The new value of the property 149 * @updates: Output array to store updates to 150 * @max_updates: Size of @updates array (max possible update values). 151 * 152 * Function prototype used to re-calculate SoundFont effect generators for a 153 * single object property change. Useful for real time effect changes. 154 * 155 * Returns: Should return number of updates stored to @updates array. 156 * Will be 0 if no updates required. 157 */ 158 typedef int (*IpatchSF2VoiceCacheUpdateHandler)(IpatchSF2VoiceCache *cache, 159 int *select_values, 160 GObject *cache_item, 161 GObject *item, GParamSpec *pspec, 162 const GValue *value, 163 IpatchSF2VoiceUpdate *updates, 164 guint max_updates); 165 /* voice selection type */ 166 typedef enum 167 { 168 IPATCH_SF2_VOICE_SEL_NOTE, /* MIDI note range */ 169 IPATCH_SF2_VOICE_SEL_VELOCITY, /* MIDI velocity range */ 170 IPATCH_SF2_VOICE_SEL_AFTER_TOUCH, /* MIDI aftertouch range */ 171 IPATCH_SF2_VOICE_SEL_MIDI_CC /* MIDI custom controller (param1: ctrlnum) */ 172 } IpatchSF2VoiceSelType; 173 174 /* selection info structure */ 175 struct _IpatchSF2VoiceSelInfo 176 { 177 IpatchSF2VoiceSelType type; 178 int param1; 179 int param2; /* currently not used */ 180 }; 181 182 /* maximum allowed voice selection criteria (MIDI note, velocity, etc) */ 183 #define IPATCH_SF2_VOICE_CACHE_MAX_SEL_VALUES 32 184 185 /* value used for wildcard selection */ 186 #define IPATCH_SF2_VOICE_SEL_WILDCARD (G_MININT) 187 188 /* For voice cache propagation methods to declare dependent items */ 189 #define ipatch_sf2_voice_cache_declare_item(cache, item) \ 190 if (cache->item_func) cache->item_func (cache, item) 191 192 /* Macro for retrieving a voice pointer from a cache */ 193 #define IPATCH_SF2_VOICE_CACHE_GET_VOICE(cache, index) \ 194 (&g_array_index (cache->voices, IpatchSF2Voice, index)) 195 196 GType ipatch_sf2_voice_cache_get_type(void); 197 IpatchSF2VoiceCache *ipatch_sf2_voice_cache_new(IpatchSF2VoiceSelInfo *info, 198 int sel_count); 199 void ipatch_sf2_voice_cache_set_default_mods(IpatchSF2VoiceCache *cache, 200 GSList *mods); 201 void ipatch_sf2_voice_cache_set_override_mods(IpatchSF2VoiceCache *cache, 202 GSList *mods); 203 204 IpatchSF2Voice *ipatch_sf2_voice_cache_add_voice(IpatchSF2VoiceCache *cache); 205 void ipatch_sf2_voice_cache_set_voice_range(IpatchSF2VoiceCache *cache, 206 IpatchSF2Voice *voice, guint sel_index, int low, int high); 207 void ipatch_sf2_voice_set_sample_data(IpatchSF2Voice *voice, 208 IpatchSampleData *sample_data); 209 gboolean ipatch_sf2_voice_cache_sample_data(IpatchSF2Voice *voice, GError **err); 210 void ipatch_sf2_voice_copy(IpatchSF2Voice *dest, IpatchSF2Voice *src); 211 void ipatch_sf2_voice_cache_optimize(IpatchSF2VoiceCache *cache); 212 int ipatch_sf2_voice_cache_select(IpatchSF2VoiceCache *cache, 213 int *select_values, 214 guint16 *index_array, 215 guint16 max_indexes); 216 int ipatch_sf2_voice_cache_update(IpatchSF2VoiceCache *cache, 217 int *select_values, 218 GObject *cache_item, 219 GObject *item, GParamSpec *pspec, 220 const GValue *value, 221 IpatchSF2VoiceUpdate *updates, 222 guint max_updates); 223 #endif 224