mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-23 20:31:43 +00:00
Added public fluid_synth_get_channel_preset_info() function and fluid_preset_info_t structure.
Added shadow_preset field to fluid_channel_t which stores the last assigned preset (irrespective of queuing). Presets now deleted under lock for shadow_preset functionality. Marked fluid_synth_get_channel_preset() as deprecated.
This commit is contained in:
parent
50c88d392a
commit
7758f5a630
6 changed files with 100 additions and 3 deletions
|
@ -229,6 +229,20 @@ struct _fluid_preset_t {
|
||||||
int (*notify)(fluid_preset_t* preset, int reason, int chan);
|
int (*notify)(fluid_preset_t* preset, int reason, int chan);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FLUID_PRESET_INFO_NAME_LENGTH 32 /**< Length of preset info name field (including zero terminator) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preset information structure.
|
||||||
|
* @since 1.1.1
|
||||||
|
*/
|
||||||
|
struct _fluid_preset_info_t
|
||||||
|
{
|
||||||
|
int assigned; /**< TRUE if a preset is assigned, FALSE otherwise */
|
||||||
|
int sfont_id; /**< ID of parent SoundFont */
|
||||||
|
int bank; /**< MIDI bank number (0-16383) */
|
||||||
|
int program; /**< MIDI program number (0-127) */
|
||||||
|
char name[FLUID_PRESET_INFO_NAME_LENGTH]; /**< Preset name */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual SoundFont sample.
|
* Virtual SoundFont sample.
|
||||||
|
|
|
@ -77,6 +77,8 @@ fluid_synth_program_select_by_sfont_name (fluid_synth_t* synth, int chan,
|
||||||
FLUIDSYNTH_API
|
FLUIDSYNTH_API
|
||||||
int fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id,
|
int fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id,
|
||||||
unsigned int* bank_num, unsigned int* preset_num);
|
unsigned int* bank_num, unsigned int* preset_num);
|
||||||
|
FLUIDSYNTH_API int fluid_synth_get_channel_preset_info (fluid_synth_t *synth, int chan,
|
||||||
|
fluid_preset_info_t *info);
|
||||||
FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth);
|
FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth);
|
||||||
FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth);
|
FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth);
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis v
|
||||||
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
|
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
|
||||||
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
|
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
|
||||||
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
|
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
|
||||||
|
typedef struct _fluid_preset_info_t fluid_preset_info_t; /**< SoundFont preset info */
|
||||||
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
|
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
|
||||||
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
|
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
|
||||||
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
|
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
|
||||||
|
|
|
@ -53,6 +53,7 @@ new_fluid_channel(fluid_synth_t* synth, int num)
|
||||||
chan->synth = synth;
|
chan->synth = synth;
|
||||||
chan->channum = num;
|
chan->channum = num;
|
||||||
chan->preset = NULL;
|
chan->preset = NULL;
|
||||||
|
chan->shadow_preset = NULL;
|
||||||
chan->tuning = NULL;
|
chan->tuning = NULL;
|
||||||
|
|
||||||
fluid_channel_init(chan);
|
fluid_channel_init(chan);
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
*
|
*
|
||||||
* Uses atomic operations:
|
* Uses atomic operations:
|
||||||
* sfont_bank_prog
|
* sfont_bank_prog
|
||||||
|
* shadow_preset
|
||||||
* key_pressure
|
* key_pressure
|
||||||
* channel_pressure
|
* channel_pressure
|
||||||
* pitch_bend
|
* pitch_bend
|
||||||
|
@ -60,6 +61,7 @@ struct _fluid_channel_t
|
||||||
|
|
||||||
int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */
|
int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */
|
||||||
fluid_preset_t* preset; /**< Selected preset */
|
fluid_preset_t* preset; /**< Selected preset */
|
||||||
|
fluid_preset_t* shadow_preset; /**< Most recently assigned preset */
|
||||||
|
|
||||||
int key_pressure; /**< MIDI key pressure */
|
int key_pressure; /**< MIDI key pressure */
|
||||||
int channel_pressure; /**< MIDI channel pressure */
|
int channel_pressure; /**< MIDI channel pressure */
|
||||||
|
|
|
@ -791,6 +791,7 @@ fluid_synth_return_event_process_callback (void* data, unsigned int msec)
|
||||||
fluid_synth_t *synth = data;
|
fluid_synth_t *synth = data;
|
||||||
fluid_event_queue_elem_t *event;
|
fluid_event_queue_elem_t *event;
|
||||||
fluid_preset_t *preset;
|
fluid_preset_t *preset;
|
||||||
|
fluid_sfont_t *sfont;
|
||||||
|
|
||||||
while ((event = fluid_event_queue_get_outptr (synth->return_queue)))
|
while ((event = fluid_event_queue_get_outptr (synth->return_queue)))
|
||||||
{
|
{
|
||||||
|
@ -827,8 +828,14 @@ fluid_synth_return_event_process_callback (void* data, unsigned int msec)
|
||||||
break;
|
break;
|
||||||
case FLUID_EVENT_QUEUE_ELEM_FREE_PRESET: /* Preset free event */
|
case FLUID_EVENT_QUEUE_ELEM_FREE_PRESET: /* Preset free event */
|
||||||
preset = (fluid_preset_t *)(event->pval);
|
preset = (fluid_preset_t *)(event->pval);
|
||||||
fluid_synth_sfont_unref (synth, preset->sfont); /* -- unref preset's SoundFont */
|
sfont = preset->sfont;
|
||||||
|
|
||||||
|
/* Delete presets under mutex lock, to protect chan->shadow_preset */
|
||||||
|
fluid_rec_mutex_lock (synth->mutex);
|
||||||
delete_fluid_preset (preset);
|
delete_fluid_preset (preset);
|
||||||
|
fluid_rec_mutex_unlock (synth->mutex);
|
||||||
|
|
||||||
|
fluid_synth_sfont_unref (synth, sfont); /* -- unref preset's SoundFont */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2109,6 +2116,7 @@ fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset)
|
||||||
{
|
{
|
||||||
fluid_event_queue_t *queue;
|
fluid_event_queue_t *queue;
|
||||||
fluid_event_queue_elem_t *event;
|
fluid_event_queue_elem_t *event;
|
||||||
|
fluid_channel_t *channel;
|
||||||
|
|
||||||
fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
|
fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
|
||||||
fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
|
fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
|
||||||
|
@ -2118,6 +2126,9 @@ fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset)
|
||||||
event = fluid_synth_get_event_elem (synth, &queue);
|
event = fluid_synth_get_event_elem (synth, &queue);
|
||||||
if (!event) return FLUID_FAILED;
|
if (!event) return FLUID_FAILED;
|
||||||
|
|
||||||
|
channel = synth->channel[chan];
|
||||||
|
fluid_atomic_pointer_set (&channel->shadow_preset, preset);
|
||||||
|
|
||||||
event->type = FLUID_EVENT_QUEUE_ELEM_PRESET;
|
event->type = FLUID_EVENT_QUEUE_ELEM_PRESET;
|
||||||
event->preset.channel = chan;
|
event->preset.channel = chan;
|
||||||
event->preset.preset = preset;
|
event->preset.preset = preset;
|
||||||
|
@ -2135,7 +2146,9 @@ fluid_synth_set_preset_LOCAL (fluid_synth_t *synth, int chan,
|
||||||
{
|
{
|
||||||
fluid_channel_t *channel;
|
fluid_channel_t *channel;
|
||||||
|
|
||||||
|
/* Set shadow preset again, so it contains the actual latest assigned value */
|
||||||
channel = synth->channel[chan];
|
channel = synth->channel[chan];
|
||||||
|
fluid_atomic_pointer_set (&channel->shadow_preset, preset);
|
||||||
fluid_channel_set_preset (channel, preset);
|
fluid_channel_set_preset (channel, preset);
|
||||||
return FLUID_OK;
|
return FLUID_OK;
|
||||||
}
|
}
|
||||||
|
@ -4055,17 +4068,81 @@ fluid_synth_get_sfont_by_name(fluid_synth_t* synth, const char *name)
|
||||||
* @param synth FluidSynth instance
|
* @param synth FluidSynth instance
|
||||||
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
||||||
* @return Preset or NULL if no preset active on channel
|
* @return Preset or NULL if no preset active on channel
|
||||||
|
* @deprecated
|
||||||
*
|
*
|
||||||
* NOTE: Should only be called from within synthesis thread, which includes
|
* NOTE: Should only be called from within synthesis thread, which includes
|
||||||
* SoundFont loader preset noteon methods.
|
* SoundFont loader preset noteon methods. Not thread safe otherwise.
|
||||||
*/
|
*/
|
||||||
fluid_preset_t *
|
fluid_preset_t *
|
||||||
fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan)
|
fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan)
|
||||||
{
|
{
|
||||||
|
fluid_channel_t *channel;
|
||||||
|
|
||||||
fluid_return_val_if_fail (synth != NULL, NULL);
|
fluid_return_val_if_fail (synth != NULL, NULL);
|
||||||
fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, NULL);
|
fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, NULL);
|
||||||
|
|
||||||
return fluid_channel_get_preset(synth->channel[chan]);
|
channel = synth->channel[chan];
|
||||||
|
return fluid_atomic_pointer_get (&channel->shadow_preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get preset information for the currently selected preset on a MIDI channel.
|
||||||
|
* @param synth FluidSynth instance
|
||||||
|
* @param chan MIDI channel number (0 to MIDI channel count - 1)
|
||||||
|
* @param info Caller supplied structure to fill with preset information
|
||||||
|
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||||
|
* @since 1.1.1
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fluid_synth_get_channel_preset_info (fluid_synth_t *synth, int chan,
|
||||||
|
fluid_preset_info_t *info)
|
||||||
|
{
|
||||||
|
fluid_channel_t *channel;
|
||||||
|
fluid_preset_t *preset;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
info->assigned = FALSE;
|
||||||
|
info->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
fluid_return_val_if_fail (synth != NULL, FLUID_FAILED);
|
||||||
|
fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED);
|
||||||
|
fluid_return_val_if_fail (info != NULL, FLUID_FAILED);
|
||||||
|
|
||||||
|
/* Lock mutex to ensure preset doesn't get deleted, while working on it */
|
||||||
|
fluid_rec_mutex_lock (synth->mutex);
|
||||||
|
|
||||||
|
channel = synth->channel[chan];
|
||||||
|
preset = fluid_atomic_pointer_get (&channel->shadow_preset);
|
||||||
|
|
||||||
|
if (preset)
|
||||||
|
{
|
||||||
|
info->assigned = TRUE;
|
||||||
|
name = fluid_preset_get_name (preset);
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
strncpy (info->name, name, FLUID_PRESET_INFO_NAME_LENGTH);
|
||||||
|
info->name[FLUID_PRESET_INFO_NAME_LENGTH - 1] = '\0';
|
||||||
|
}
|
||||||
|
else info->name[0] = '\0';
|
||||||
|
|
||||||
|
info->sfont_id = preset->sfont->id;
|
||||||
|
info->bank = fluid_preset_get_banknum (preset);
|
||||||
|
info->program = fluid_preset_get_num (preset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->assigned = FALSE;
|
||||||
|
fluid_channel_get_sfont_bank_prog (channel, &info->sfont_id, &info->bank, &info->program);
|
||||||
|
info->name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
fluid_rec_mutex_unlock (synth->mutex);
|
||||||
|
|
||||||
|
return FLUID_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue