mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-23 12:21:39 +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);
|
||||
};
|
||||
|
||||
#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.
|
||||
|
|
|
@ -77,6 +77,8 @@ fluid_synth_program_select_by_sfont_name (fluid_synth_t* synth, int chan,
|
|||
FLUIDSYNTH_API
|
||||
int fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id,
|
||||
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_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_sfont_t fluid_sfont_t; /**< SoundFont */
|
||||
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_mod_t fluid_mod_t; /**< SoundFont modulator */
|
||||
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->channum = num;
|
||||
chan->preset = NULL;
|
||||
chan->shadow_preset = NULL;
|
||||
chan->tuning = NULL;
|
||||
|
||||
fluid_channel_init(chan);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
*
|
||||
* Uses atomic operations:
|
||||
* sfont_bank_prog
|
||||
* shadow_preset
|
||||
* key_pressure
|
||||
* channel_pressure
|
||||
* 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) */
|
||||
fluid_preset_t* preset; /**< Selected preset */
|
||||
fluid_preset_t* shadow_preset; /**< Most recently assigned preset */
|
||||
|
||||
int key_pressure; /**< MIDI key 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_event_queue_elem_t *event;
|
||||
fluid_preset_t *preset;
|
||||
fluid_sfont_t *sfont;
|
||||
|
||||
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;
|
||||
case FLUID_EVENT_QUEUE_ELEM_FREE_PRESET: /* Preset free event */
|
||||
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);
|
||||
fluid_rec_mutex_unlock (synth->mutex);
|
||||
|
||||
fluid_synth_sfont_unref (synth, sfont); /* -- unref preset's SoundFont */
|
||||
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_elem_t *event;
|
||||
fluid_channel_t *channel;
|
||||
|
||||
fluid_return_val_if_fail (synth != NULL, 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);
|
||||
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->preset.channel = chan;
|
||||
event->preset.preset = preset;
|
||||
|
@ -2135,7 +2146,9 @@ fluid_synth_set_preset_LOCAL (fluid_synth_t *synth, int chan,
|
|||
{
|
||||
fluid_channel_t *channel;
|
||||
|
||||
/* Set shadow preset again, so it contains the actual latest assigned value */
|
||||
channel = synth->channel[chan];
|
||||
fluid_atomic_pointer_set (&channel->shadow_preset, preset);
|
||||
fluid_channel_set_preset (channel, preset);
|
||||
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 chan MIDI channel number (0 to MIDI channel count - 1)
|
||||
* @return Preset or NULL if no preset active on channel
|
||||
* @deprecated
|
||||
*
|
||||
* 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_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 (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