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_GEN_H__
21 #define __IPATCH_SF2_GEN_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <libinstpatch/IpatchItem.h>
27 
28 /* total number of generators */
29 #define IPATCH_SF2_GEN_COUNT 59
30 
31 /* forward type declarations */
32 typedef union _IpatchSF2GenAmount IpatchSF2GenAmount;
33 typedef struct _IpatchSF2GenArray IpatchSF2GenArray;
34 typedef struct _IpatchSF2GenInfo IpatchSF2GenInfo;
35 
36 /* IpatchSF2GenArray has a glib boxed type */
37 #define IPATCH_TYPE_SF2_GEN_ARRAY   (ipatch_sf2_gen_array_get_type ())
38 
39 /**
40  * IpatchSF2GenPropsType:
41  *
42  * Generator property type (defines which gens are valid and their ranges).
43  * Note that TRUE/FALSE can be used to designate PRESET/INST (backwards
44  * compatible with previous function).  Also note that global properties can
45  * be treated as a flag: #IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG.
46  */
47 typedef enum
48 {
49     IPATCH_SF2_GEN_PROPS_INST = 0,	/* instrument "absolute" properties */
50     IPATCH_SF2_GEN_PROPS_PRESET = 1,	/* preset "offset" properties */
51     IPATCH_SF2_GEN_PROPS_INST_GLOBAL = 2,	/* inst properties with no sample link */
52     IPATCH_SF2_GEN_PROPS_PRESET_GLOBAL = 3  /* preset props with no inst link */
53 } IpatchSF2GenPropsType;
54 
55 /* can treat GLOBAL enums from IpatchSF2GenPropsType as a flag */
56 #define IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG	0x02
57 
58 /* mask of props type without global flag */
59 #define IPATCH_SF2_GEN_PROPS_MASK		0x01
60 
61 /* Generator amount (effect parameter amount) */
62 union _IpatchSF2GenAmount
63 {
64     /*< public >*/
65     gint16 sword;			/* signed 16 bit value */
66     guint16 uword;		/* unsigned 16 bit value */
67     struct
68     {
69         guint8 low;			/* low value of range */
70         guint8 high;		/* high value of range */
71     } range;			/* range values, low - high */
72 };
73 
74 /* Generator (effect parameter) */
75 struct _IpatchSF2Gen
76 {
77     /*< public >*/
78     guint16 id;			/* generator #IPGenType ID */
79     IpatchSF2GenAmount amount;	/* generator value */
80 };
81 
82 /* generator array */
83 struct _IpatchSF2GenArray
84 {
85     /*< public >*/
86     guint64 flags; /* 1 bit for each generator indicating if it is set */
87     IpatchSF2GenAmount values[IPATCH_SF2_GEN_COUNT]; /* gen values */
88 };
89 
90 
91 /* calculate the set bit value for a given generator ID */
92 #define IPATCH_SF2_GENID_SET(genid) ((guint64)0x1 << (genid))
93 
94 /* macros for manipulating individual set flag bits in a generator array
95    Note: These macros don't take into account multi-thread locking. */
96 #define IPATCH_SF2_GEN_ARRAY_TEST_FLAG(array, genid) \
97   (((array)->flags & ((guint64)0x1 << (genid))) != 0)
98 #define IPATCH_SF2_GEN_ARRAY_SET_FLAG(array, genid) \
99   ((array)->flags |= ((guint64)0x1 << (genid)))
100 #define IPATCH_SF2_GEN_ARRAY_CLEAR_FLAG(array, genid) \
101   ((array)->flags &= ~((guint64)0x1 << (genid)))
102 
103 /* generator (effect parameter) types */
104 typedef enum
105 {
106     IPATCH_SF2_GEN_SAMPLE_START = 0, /* sample start offset */
107     IPATCH_SF2_GEN_SAMPLE_END = 1,	/* sample end offset */
108     IPATCH_SF2_GEN_SAMPLE_LOOP_START = 2,/* sample loop start offset */
109     IPATCH_SF2_GEN_SAMPLE_LOOP_END = 3, /* sample loop end offset */
110     IPATCH_SF2_GEN_SAMPLE_COARSE_START = 4, /* sample start coarse offset */
111     IPATCH_SF2_GEN_MOD_LFO_TO_PITCH = 5, /* modulation LFO to pitch */
112     IPATCH_SF2_GEN_VIB_LFO_TO_PITCH = 6, /* vibrato LFO to pitch */
113     IPATCH_SF2_GEN_MOD_ENV_TO_PITCH = 7, /* modulation envelope to pitch */
114     IPATCH_SF2_GEN_FILTER_CUTOFF = 8,	/* initial filter cutoff */
115     IPATCH_SF2_GEN_FILTER_Q = 9,	/* filter Q */
116     IPATCH_SF2_GEN_MOD_LFO_TO_FILTER_CUTOFF = 10, /* mod LFO to filter cutoff */
117     IPATCH_SF2_GEN_MOD_ENV_TO_FILTER_CUTOFF = 11, /* mod envelope to filter cutoff */
118     IPATCH_SF2_GEN_SAMPLE_COARSE_END = 12, /* sample end course offset */
119     IPATCH_SF2_GEN_MOD_LFO_TO_VOLUME = 13, /* modulation LFO to volume */
120     IPATCH_SF2_GEN_UNUSED1 = 14,
121     IPATCH_SF2_GEN_CHORUS = 15, /* chorus */
122     IPATCH_SF2_GEN_REVERB = 16, /* reverb */
123     IPATCH_SF2_GEN_PAN = 17,	/* panning */
124     IPATCH_SF2_GEN_UNUSED2 = 18,
125     IPATCH_SF2_GEN_UNUSED3 = 19,
126     IPATCH_SF2_GEN_UNUSED4 = 20,
127     IPATCH_SF2_GEN_MOD_LFO_DELAY = 21, /* modulation LFO delay */
128     IPATCH_SF2_GEN_MOD_LFO_FREQ = 22, /* modulation LFO frequency */
129     IPATCH_SF2_GEN_VIB_LFO_DELAY = 23, /* vibrato LFO delay */
130     IPATCH_SF2_GEN_VIB_LFO_FREQ = 24, /* vibrato LFO frequency */
131     IPATCH_SF2_GEN_MOD_ENV_DELAY = 25, /* modulation envelope delay */
132     IPATCH_SF2_GEN_MOD_ENV_ATTACK = 26, /* modulation envelope attack */
133     IPATCH_SF2_GEN_MOD_ENV_HOLD = 27, /* modulation envelope hold */
134     IPATCH_SF2_GEN_MOD_ENV_DECAY = 28, /* modulation envelope decay */
135     IPATCH_SF2_GEN_MOD_ENV_SUSTAIN = 29, /* modulation envelope sustain */
136     IPATCH_SF2_GEN_MOD_ENV_RELEASE = 30, /* modulation envelope release */
137     IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_HOLD = 31, /* MIDI note to mod envelope hold */
138     IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_DECAY = 32, /* MIDI note to mod env decay */
139     IPATCH_SF2_GEN_VOL_ENV_DELAY = 33, /* volume envelope delay */
140     IPATCH_SF2_GEN_VOL_ENV_ATTACK = 34, /* volume envelope attack */
141     IPATCH_SF2_GEN_VOL_ENV_HOLD = 35, /* volume envelope hold */
142     IPATCH_SF2_GEN_VOL_ENV_DECAY = 36, /* volume envelope decay */
143     IPATCH_SF2_GEN_VOL_ENV_SUSTAIN = 37, /* volume envelope sustain */
144     IPATCH_SF2_GEN_VOL_ENV_RELEASE = 38, /* volume envelope release */
145     IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_HOLD = 39, /* MIDI note to vol envelope hold */
146     IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_DECAY = 40, /* MIDI note to volume env decay */
147     IPATCH_SF2_GEN_INSTRUMENT_ID = 41, /* instrument ID */
148     IPATCH_SF2_GEN_RESERVED1 = 42,
149     IPATCH_SF2_GEN_NOTE_RANGE = 43,	/* note range */
150     IPATCH_SF2_GEN_VELOCITY_RANGE = 44, /* note on velocity range */
151     IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_START = 45, /* sample coarse loop start */
152     IPATCH_SF2_GEN_FIXED_NOTE = 46, /* MIDI fixed note */
153     IPATCH_SF2_GEN_FIXED_VELOCITY = 47, /* MIDI fixed velocity */
154     IPATCH_SF2_GEN_ATTENUATION = 48, /* initial volume attenuation */
155     IPATCH_SF2_GEN_RESERVED2 = 49,
156     IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_END = 50, /* sample end loop course ofs */
157     IPATCH_SF2_GEN_COARSE_TUNE = 51, /* course tuning */
158     IPATCH_SF2_GEN_FINE_TUNE_OVERRIDE = 52,	/* fine tune override */
159     IPATCH_SF2_GEN_SAMPLE_ID = 53,	/* sample ID */
160     IPATCH_SF2_GEN_SAMPLE_MODES = 54, /* sample flags (IpatchSF2GenSampleModes)*/
161     IPATCH_SF2_GEN_RESERVED3 = 55,
162     IPATCH_SF2_GEN_SCALE_TUNE = 56, /* scale tuning (tuning per MIDI note) */
163     IPATCH_SF2_GEN_EXCLUSIVE_CLASS = 57, /* exclusive class (only 1 at a time) */
164     IPATCH_SF2_GEN_ROOT_NOTE_OVERRIDE = 58	/* root note override */
165 } IpatchSF2GenType;
166 
167 /* Flags for IPATCH_SF2_GEN_SAMPLE_MODES generator
168    sfspec24.pdf - p 36 - generator sampleModes (54)
169 */
170 typedef enum
171 {
172   IPATCH_SF2_GEN_SAMPLE_MODE_NOLOOP, /* no loop */
173   IPATCH_SF2_GEN_SAMPLE_MODE_LOOP,   /* standard loop */
174   /* not used. Should be interpreted as "no loop" */
175   IPATCH_SF2_GEN_SAMPLE_MODE_UNUSED,
176   /* loop during the depression of the key, then plays the remainder
177      of the sample.
178   */
179   IPATCH_SF2_GEN_SAMPLE_MODE_LOOP_RELEASE
180 } IpatchSF2GenSampleModes;
181 
182 /* generator info and constraints structure */
183 struct _IpatchSF2GenInfo
184 {
185     /*< public >*/
186     IpatchSF2GenAmount min;	/* minimum value allowed */
187     IpatchSF2GenAmount max;	/* maximum value allowed */
188     IpatchSF2GenAmount def;	/* default value */
189     gint16 unit;			/* #IpatchUnitType type */
190     char *label;			/* short descriptive label */
191     char *descr;			/* more complete description */
192 };
193 
194 extern IpatchSF2GenArray *ipatch_sf2_gen_ofs_array;
195 extern IpatchSF2GenArray *ipatch_sf2_gen_abs_array;
196 extern guint64 ipatch_sf2_gen_ofs_valid_mask;
197 extern guint64 ipatch_sf2_gen_abs_valid_mask;
198 extern guint64 ipatch_sf2_gen_add_mask;
199 
200 /* Useful when libinstpatch library is used as a static library. */
201 extern const IpatchSF2GenInfo ipatch_sf2_gen_info[]; /* IpatchSF2Gen_tables.c */
202 /*
203  Getter function returning ipatch_sf2_gen_info table.
204  Useful when libinstpatch library is used as a shared library linked at load time.
205 */
206 const IpatchSF2GenInfo *ipatch_sf2_get_gen_info(void);
207 
208 
209 gboolean ipatch_sf2_gen_is_valid(guint genid, IpatchSF2GenPropsType propstype);
210 
211 GType ipatch_sf2_gen_array_get_type(void);
212 IpatchSF2GenArray *ipatch_sf2_gen_array_new(gboolean clear);
213 void ipatch_sf2_gen_array_free(IpatchSF2GenArray *genarray);
214 IpatchSF2GenArray *
215 ipatch_sf2_gen_array_duplicate(const IpatchSF2GenArray *array);
216 
217 void ipatch_sf2_gen_array_init(IpatchSF2GenArray *array, gboolean offset,
218                                gboolean set);
219 gboolean ipatch_sf2_gen_array_offset(IpatchSF2GenArray *abs_array,
220                                      const IpatchSF2GenArray *ofs_array);
221 gboolean ipatch_sf2_gen_array_intersect_test(const IpatchSF2GenArray *array1,
222         const IpatchSF2GenArray *array2);
223 guint ipatch_sf2_gen_array_count_set(IpatchSF2GenArray *array);
224 
225 void ipatch_sf2_gen_amount_to_value(guint genid, const IpatchSF2GenAmount *amt,
226                                     GValue *value);
227 
228 void ipatch_sf2_gen_default_value(guint genid, gboolean ispreset,
229                                   IpatchSF2GenAmount *out_amt);
230 gboolean ipatch_sf2_gen_offset(guint genid, IpatchSF2GenAmount *dst,
231                                const IpatchSF2GenAmount *ofs);
232 
233 void ipatch_sf2_gen_clamp(guint genid, int *sfval, gboolean ispreset);
234 gboolean ipatch_sf2_gen_range_intersect(IpatchSF2GenAmount *dst,
235                                         const IpatchSF2GenAmount *src);
236 gboolean ipatch_sf2_gen_range_intersect_test(const IpatchSF2GenAmount *amt1,
237         const IpatchSF2GenAmount *amt2);
238 
239 G_CONST_RETURN char *ipatch_sf2_gen_get_prop_name(guint genid);
240 
241 #endif
242