## IpatchSF2Gen IpatchSF2Gen — SoundFont generator functions and definitions |

## Stability Level

Stable, unless otherwise indicated

## Synopsis

    #define             IPATCH_SF2_GEN_COUNT
                        IpatchSF2GenArray;
                        IpatchSF2GenInfo;
    #define             IPATCH_TYPE_SF2_GEN_ARRAY
    enum                IpatchSF2GenPropsType;
    #define             IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG
    #define             IPATCH_SF2_GEN_PROPS_MASK
    union               IpatchSF2GenAmount;
    struct              IpatchSF2Gen;
    #define             IPATCH_SF2_GENID_SET                (genid)
    #define             IPATCH_SF2_GEN_ARRAY_TEST_FLAG      (array, genid)
    #define             IPATCH_SF2_GEN_ARRAY_SET_FLAG       (array, genid)
    #define             IPATCH_SF2_GEN_ARRAY_CLEAR_FLAG     (array, genid)
    enum                IpatchSF2GenType;
    enum                IpatchSF2GenSampleModes;
    extern              IpatchSF2GenArray *ipatch_sf2_gen_ofs_array;
    extern              IpatchSF2GenArray *ipatch_sf2_gen_abs_array;
    extern              guint64 ipatch_sf2_gen_ofs_valid_mask;
    extern              guint64 ipatch_sf2_gen_abs_valid_mask;
    extern              guint64 ipatch_sf2_gen_add_mask;
    gboolean            ipatch_sf2_gen_is_valid             (guint genid,
                                                             IpatchSF2GenPropsType propstype);
    GType               ipatch_sf2_gen_array_get_type       (void);
    IpatchSF2GenArray * ipatch_sf2_gen_array_new            (gboolean clear);
    void                ipatch_sf2_gen_array_free           (IpatchSF2GenArray *genarray);
    IpatchSF2GenArray * ipatch_sf2_gen_array_duplicate      (const IpatchSF2GenArray *array);
    void                ipatch_sf2_gen_array_init           (IpatchSF2GenArray *array,
                                                             gboolean offset,
                                                             gboolean set);
    gboolean            ipatch_sf2_gen_array_offset         (IpatchSF2GenArray *abs_array,
                                                             const IpatchSF2GenArray *ofs_array);
    gboolean            ipatch_sf2_gen_array_intersect_test (const IpatchSF2GenArray *array1,
                                                             const IpatchSF2GenArray *array2);
    guint               ipatch_sf2_gen_array_count_set      (IpatchSF2GenArray *array);
    void                ipatch_sf2_gen_amount_to_value      (guint genid,
                                                             const IpatchSF2GenAmount *amt,
                                                             GValue *value);
    void                ipatch_sf2_gen_default_value        (guint genid,
                                                             gboolean ispreset,
                                                             IpatchSF2GenAmount *out_amt);
    gboolean            ipatch_sf2_gen_offset               (guint genid,
                                                             IpatchSF2GenAmount *dst,
                                                             const IpatchSF2GenAmount *ofs);
    void                ipatch_sf2_gen_clamp                (guint genid,
                                                             int *sfval,
                                                             gboolean ispreset);
    gboolean            ipatch_sf2_gen_range_intersect      (IpatchSF2GenAmount *dst,
                                                             const IpatchSF2GenAmount *src);
    gboolean            ipatch_sf2_gen_range_intersect_test (const IpatchSF2GenAmount *amt1,
                                                             const IpatchSF2GenAmount *amt2);
    const char *        ipatch_sf2_gen_get_prop_name        (guint genid);

## Description

SoundFont generators are synthesis parameters used by IpatchSF2Preset, IpatchSF2Inst, IpatchSF2PZone and IpatchSF2IZone objects.

## Details

### IPATCH_SF2_GEN_COUNT

    #define IPATCH_SF2_GEN_COUNT 59

### IpatchSF2GenArray

    typedef struct {
      guint64 flags; /* 1 bit for each generator indicating if it is set */
      IpatchSF2GenAmount values[IPATCH_SF2_GEN_COUNT]; /* gen values */
    } IpatchSF2GenArray;

### IpatchSF2GenInfo

    typedef struct {
      IpatchSF2GenAmount min;	/* minimum value allowed */
      IpatchSF2GenAmount max;	/* maximum value allowed */
      IpatchSF2GenAmount def;	/* default value */
      gint16 unit;			/* #IpatchUnitType type */
      char *label;			/* short descriptive label */
      char *descr;			/* more complete description */
    } IpatchSF2GenInfo;

### IPATCH_TYPE_SF2_GEN_ARRAY

    #define IPATCH_TYPE_SF2_GEN_ARRAY   (ipatch_sf2_gen_array_get_type ())

### enum IpatchSF2GenPropsType

    typedef enum
    {
      IPATCH_SF2_GEN_PROPS_INST = 0,	/* instrument "absolute" properties */
      IPATCH_SF2_GEN_PROPS_PRESET = 1,	/* preset "offset" properties */
      IPATCH_SF2_GEN_PROPS_INST_GLOBAL = 2,	/* inst properties with no sample link */
      IPATCH_SF2_GEN_PROPS_PRESET_GLOBAL = 3  /* preset props with no inst link */
    } IpatchSF2GenPropsType;

Generator property type (defines which gens are valid and their ranges). Note that TRUE/FALSE can be used to designate PRESET/INST (backwards compatible with previous function). Also note that global properties can be treated as a flag: IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG.

### IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG

    #define IPATCH_SF2_GEN_PROPS_GLOBAL_FLAG	0x02

### IPATCH_SF2_GEN_PROPS_MASK

    #define IPATCH_SF2_GEN_PROPS_MASK		0x01

### union IpatchSF2GenAmount

    union IpatchSF2GenAmount
    {
      /*< public >*/
      gint16 sword;			/* signed 16 bit value */
      guint16 uword;		/* unsigned 16 bit value */
      struct
      {
        guint8 low;			/* low value of range */
        guint8 high;		/* high value of range */
      } range;			/* range values, low - high */
    };

### struct IpatchSF2Gen

    struct IpatchSF2Gen {
      guint16 id;			/* generator #IPGenType ID */
      IpatchSF2GenAmount amount;	/* generator value */
    };

### IPATCH_SF2_GENID_SET()

    #define IPATCH_SF2_GENID_SET(genid) ((guint64)0x1 << (genid))

### IPATCH_SF2_GEN_ARRAY_TEST_FLAG()

    #define             IPATCH_SF2_GEN_ARRAY_TEST_FLAG(array, genid)

### IPATCH_SF2_GEN_ARRAY_SET_FLAG()

    #define             IPATCH_SF2_GEN_ARRAY_SET_FLAG(array, genid)

### IPATCH_SF2_GEN_ARRAY_CLEAR_FLAG()

    #define             IPATCH_SF2_GEN_ARRAY_CLEAR_FLAG(array, genid)

### enum IpatchSF2GenType

    typedef enum
    {
      IPATCH_SF2_GEN_SAMPLE_START = 0, /* sample start offset */
      IPATCH_SF2_GEN_SAMPLE_END = 1,	/* sample end offset */
      IPATCH_SF2_GEN_SAMPLE_LOOP_START = 2,/* sample loop start offset */
      IPATCH_SF2_GEN_SAMPLE_LOOP_END = 3, /* sample loop end offset */
      IPATCH_SF2_GEN_SAMPLE_COARSE_START = 4, /* sample start coarse offset */
      IPATCH_SF2_GEN_MOD_LFO_TO_PITCH = 5, /* modulation LFO to pitch */
      IPATCH_SF2_GEN_VIB_LFO_TO_PITCH = 6, /* vibrato LFO to pitch */
      IPATCH_SF2_GEN_MOD_ENV_TO_PITCH = 7, /* modulation envelope to pitch */
      IPATCH_SF2_GEN_FILTER_CUTOFF = 8,	/* initial filter cutoff */
      IPATCH_SF2_GEN_FILTER_Q = 9,	/* filter Q */
      IPATCH_SF2_GEN_MOD_LFO_TO_FILTER_CUTOFF = 10, /* mod LFO to filter cutoff */
      IPATCH_SF2_GEN_MOD_ENV_TO_FILTER_CUTOFF = 11, /* mod envelope to filter cutoff */
      IPATCH_SF2_GEN_SAMPLE_COARSE_END = 12, /* sample end course offset */
      IPATCH_SF2_GEN_MOD_LFO_TO_VOLUME = 13, /* modulation LFO to volume */
      IPATCH_SF2_GEN_UNUSED1 = 14,
      IPATCH_SF2_GEN_CHORUS = 15, /* chorus */
      IPATCH_SF2_GEN_REVERB = 16, /* reverb */
      IPATCH_SF2_GEN_PAN = 17,	/* panning */
      IPATCH_SF2_GEN_UNUSED2 = 18,
      IPATCH_SF2_GEN_UNUSED3 = 19,
      IPATCH_SF2_GEN_UNUSED4 = 20,
      IPATCH_SF2_GEN_MOD_LFO_DELAY = 21, /* modulation LFO delay */
      IPATCH_SF2_GEN_MOD_LFO_FREQ = 22, /* modulation LFO frequency */
      IPATCH_SF2_GEN_VIB_LFO_DELAY = 23, /* vibrato LFO delay */
      IPATCH_SF2_GEN_VIB_LFO_FREQ = 24, /* vibrato LFO frequency */
      IPATCH_SF2_GEN_MOD_ENV_DELAY = 25, /* modulation envelope delay */
      IPATCH_SF2_GEN_MOD_ENV_ATTACK = 26, /* modulation envelope attack */
      IPATCH_SF2_GEN_MOD_ENV_HOLD = 27, /* modulation envelope hold */
      IPATCH_SF2_GEN_MOD_ENV_DECAY = 28, /* modulation envelope decay */
      IPATCH_SF2_GEN_MOD_ENV_SUSTAIN = 29, /* modulation envelope sustain */
      IPATCH_SF2_GEN_MOD_ENV_RELEASE = 30, /* modulation envelope release */
      IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_HOLD = 31, /* MIDI note to mod envelope hold */
      IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_DECAY = 32, /* MIDI note to mod env decay */
      IPATCH_SF2_GEN_VOL_ENV_DELAY = 33, /* volume envelope delay */
      IPATCH_SF2_GEN_VOL_ENV_ATTACK = 34, /* volume envelope attack */
      IPATCH_SF2_GEN_VOL_ENV_HOLD = 35, /* volume envelope hold */
      IPATCH_SF2_GEN_VOL_ENV_DECAY = 36, /* volume envelope decay */
      IPATCH_SF2_GEN_VOL_ENV_SUSTAIN = 37, /* volume envelope sustain */
      IPATCH_SF2_GEN_VOL_ENV_RELEASE = 38, /* volume envelope release */
      IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_HOLD = 39, /* MIDI note to vol envelope hold */
      IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_DECAY = 40, /* MIDI note to volume env decay */
      IPATCH_SF2_GEN_INSTRUMENT_ID = 41, /* instrument ID */
      IPATCH_SF2_GEN_RESERVED1 = 42,
      IPATCH_SF2_GEN_NOTE_RANGE = 43,	/* note range */
      IPATCH_SF2_GEN_VELOCITY_RANGE = 44, /* note on velocity range */
      IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_START = 45, /* sample coarse loop start */
      IPATCH_SF2_GEN_FIXED_NOTE = 46, /* MIDI fixed note */
      IPATCH_SF2_GEN_FIXED_VELOCITY = 47, /* MIDI fixed velocity */
      IPATCH_SF2_GEN_ATTENUATION = 48, /* initial volume attenuation */
      IPATCH_SF2_GEN_RESERVED2 = 49,
      IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_END = 50, /* sample end loop course ofs */
      IPATCH_SF2_GEN_COARSE_TUNE = 51, /* course tuning */
      IPATCH_SF2_GEN_FINE_TUNE_OVERRIDE = 52,	/* fine tune override */
      IPATCH_SF2_GEN_SAMPLE_ID = 53,	/* sample ID */
      IPATCH_SF2_GEN_SAMPLE_MODES = 54, /* sample flags (IpatchSF2GenSampleModes)*/
      IPATCH_SF2_GEN_RESERVED3 = 55,
      IPATCH_SF2_GEN_SCALE_TUNE = 56, /* scale tuning (tuning per MIDI note) */
      IPATCH_SF2_GEN_EXCLUSIVE_CLASS = 57, /* exclusive class (only 1 at a time) */
      IPATCH_SF2_GEN_ROOT_NOTE_OVERRIDE = 58	/* root note override */
    } IpatchSF2GenType;

### enum IpatchSF2GenSampleModes

    typedef enum
    {
      IPATCH_SF2_GEN_SAMPLE_MODE_NOLOOP = 0,
      IPATCH_SF2_GEN_SAMPLE_MODE_LOOP   = 1 << 0,
      IPATCH_SF2_GEN_SAMPLE_MODE_LOOP_RELEASE = 1 << 1
    } IpatchSF2GenSampleModes;

### ipatch_sf2_gen_ofs_array

    extern IpatchSF2GenArray *ipatch_sf2_gen_ofs_array;

### ipatch_sf2_gen_abs_array

    extern IpatchSF2GenArray *ipatch_sf2_gen_abs_array;

### ipatch_sf2_gen_ofs_valid_mask

    extern guint64 ipatch_sf2_gen_ofs_valid_mask;

### ipatch_sf2_gen_abs_valid_mask

    extern guint64 ipatch_sf2_gen_abs_valid_mask;

### ipatch_sf2_gen_add_mask

    extern guint64 ipatch_sf2_gen_add_mask;

### ipatch_sf2_gen_is_valid ()

    gboolean            ipatch_sf2_gen_is_valid             (guint genid,
                                                             IpatchSF2GenPropsType propstype);

Checks if a generator is valid for the given `propstype`.

`genid` : | Generator ID to check
`propstype` : | Generator property type (instrument/preset + global)
Returns : | `TRUE` if valid, `FALSE` otherwise

### ipatch_sf2_gen_array_get_type ()

    GType               ipatch_sf2_gen_array_get_type       (void);

### ipatch_sf2_gen_array_new ()

    IpatchSF2GenArray * ipatch_sf2_gen_array_new            (gboolean clear);

Create a new generator array object. A convenience function really, because one could just allocate an IpatchSF2GenArray structure instead.

`clear` : | If `TRUE` then array will be cleared, `FALSE` will not initalize it and it is up to the caller to do so.
Returns : | New generator

### ipatch_sf2_gen_array_free ()

    void                ipatch_sf2_gen_array_free           (IpatchSF2GenArray *genarray);

### ipatch_sf2_gen_array_duplicate ()

    IpatchSF2GenArray * ipatch_sf2_gen_array_duplicate      (const IpatchSF2GenArray *array);

Duplicates a generator array structure.

`array` : | Generator array to duplicate
Returns : | A newly allocated generator array structure which is a duplicate of `array`.

### ipatch_sf2_gen_array_init ()

    void                ipatch_sf2_gen_array_init           (IpatchSF2GenArray *array,
                                                             gboolean offset,
                                                             gboolean set);

Initialize a generator array to default values.

`array` : | Generator array
`offset` : | `TRUE` = initialize to Preset offset (zero) values, `FALSE` = initialize to instrument default values
`set` : | `TRUE` to set flags indicating generator values are set, `FALSE` to clear all flag "set" bits

### ipatch_sf2_gen_array_offset ()

    gboolean            ipatch_sf2_gen_array_offset         (IpatchSF2GenArray *abs_array,
                                                             const IpatchSF2GenArray *ofs_array);

Offsets the generators amount array in `abs_array` by adding the values in `ofs_array` to it. Values are clamped to their valid ranges.

`abs_array` : | Destination generator amount array that contains absolute (Instrument) generator values
`ofs_array` : | Source generator amount array that contains offset (Preset) generator values
Returns : | `FALSE` if note or velocity range does not intersect (in which case the non-intersecting ranges are left unassigned), `TRUE` otherwise

### ipatch_sf2_gen_array_intersect_test ()

    gboolean            ipatch_sf2_gen_array_intersect_test (const IpatchSF2GenArray *array1,
                                                             const IpatchSF2GenArray *array2);

Checks if the note and velocity ranges in two generator arrays intersect.

`array1` : | First generator amount array
`array2` : | Second generator amount array
Returns : | `TRUE` if both ranges intersect, `FALSE` if one or both do not.

### ipatch_sf2_gen_array_count_set ()

    guint               ipatch_sf2_gen_array_count_set      (IpatchSF2GenArray *array);

Get count of "set" generators in a generator array.

`array` : | Generator array
Returns : | Count of "set" generators.

### ipatch_sf2_gen_amount_to_value ()

    void                ipatch_sf2_gen_amount_to_value      (guint genid,
                                                             const IpatchSF2GenAmount *amt,
                                                             GValue *value);

Converts a generator amount to a GValue. Value will be initialized to one of two types: G_TYPE_INT for signed/unsigned integers or IPATCH_TYPE_RANGE for velocity or note split ranges.

`genid` : | Generator ID
`amt` : | Generator amount for given `genid`
`value` : | Uninitialized GValue to set to `amt`

### ipatch_sf2_gen_default_value ()

    void                ipatch_sf2_gen_default_value        (guint genid,
                                                             gboolean ispreset,
                                                             IpatchSF2GenAmount *out_amt);

Get default value for a generator ID for the specified (`ispreset`) zone type.

`genid` : | Generator ID
`ispreset` : | TRUE for preset generators, FALSE for instrument
`out_amt` : | A pointer to store the default amount into

### ipatch_sf2_gen_offset ()

    gboolean            ipatch_sf2_gen_offset               (guint genid,
                                                             IpatchSF2GenAmount *dst,
                                                             const IpatchSF2GenAmount *ofs);

Offsets a generator amount. Result of offset is clamped to maximum and minimum values for the given generator ID. In the case of note or velocity ranges a return value of `TRUE` (clamped) means that the ranges don't intersect (contrary return value to other range related functions).

`genid` : | ID of Generator to offset. Must be a valid preset generator.
`dst` : | Pointer to the initial amount to offset, result is stored back into this parameter.
`ofs` : | Pointer to offset amount.
Returns : | `TRUE` if value was clamped, `FALSE` otherwise.

### ipatch_sf2_gen_clamp ()

    void                ipatch_sf2_gen_clamp                (guint genid,
                                                             int *sfval,
                                                             gboolean ispreset);

Clamp a generators value to its valid range.

`genid` : | Generator ID (IpatchSF2GenType)
`sfval` : | Generator value to clamp (changed in place)
`ispreset` : | TRUE if its a Preset generator, FALSE if Instrument

### ipatch_sf2_gen_range_intersect ()

    gboolean            ipatch_sf2_gen_range_intersect      (IpatchSF2GenAmount *dst,
                                                             const IpatchSF2GenAmount *src);

Find intersection of two generator ranges (common shared range). If ranges don't share anything in common `dst` is not assigned.

`dst` : | First generator amount range, result is also stored here
`src` : | Second generator amount range
Returns : | `FALSE` if ranges don't share any range in common.

### ipatch_sf2_gen_range_intersect_test ()

    gboolean            ipatch_sf2_gen_range_intersect_test (const IpatchSF2GenAmount *amt1,
                                                             const IpatchSF2GenAmount *amt2);

Test if two ranges intersect.

`amt1` : | First generator amount range
`amt2` : | Second generator amount range
Returns : | `FALSE` if ranges don't share any range in common, `TRUE` otherwise

### ipatch_sf2_gen_get_prop_name ()

    const char *        ipatch_sf2_gen_get_prop_name        (guint genid);

Get the GObject property name for a given generator ID.

`genid` : | Generator ID
Returns : | Property name or `NULL` if no property name for `genid`. The returned string is internal and should not be modified or freed.