mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
Add function API fluid_synth_mixer_set_mapping()
- Add fluid_synth_mixer_set_mapping() in fluid_synth.c. - Add setter function fluid_rvoice_mixer_set_fx_out_mapping() in fluid_rvoice_mixer.c. - Add command sechanmapout in fluid_cmd.c.
This commit is contained in:
parent
ac62a8a41c
commit
0fa451f46b
6 changed files with 254 additions and 0 deletions
|
@ -393,6 +393,10 @@ FLUIDSYNTH_API int fluid_synth_get_breath_mode(fluid_synth_t *synth,
|
|||
FLUIDSYNTH_API int fluid_synth_mixer_get_mapping(fluid_synth_t *synth,
|
||||
int chan, int *out_from_chan, int *fx_from_chan,
|
||||
int *out_from_fx);
|
||||
FLUIDSYNTH_API int fluid_synth_mixer_set_mapping(fluid_synth_t *synth,
|
||||
int chan_to_out, int out_from_chan,
|
||||
int chan_to_fx, int fx_from_chan,
|
||||
int chanfx_to_out, int out_from_fx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -194,6 +194,10 @@ static const fluid_cmd_t fluid_commands[] =
|
|||
"chanmap", "mixer", fluid_handle_chanmap,
|
||||
"chanmap [chan1 chan2..] Print mapping of all or some MIDI channels"
|
||||
},
|
||||
{
|
||||
"setchanmapout", "mixer", fluid_handle_setchanmapout,
|
||||
"setchanmapout chan0 out0 [chan1 out1..] Set mapping MIDI channel to dry output"
|
||||
},
|
||||
/* reverb commands */
|
||||
{
|
||||
"rev_preset", "reverb", fluid_handle_reverbpreset,
|
||||
|
@ -3410,6 +3414,92 @@ int fluid_handle_chanmap(void *data, int ac, char **av,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* type of MIDI channel mapping */
|
||||
enum channel_mapping_type
|
||||
{
|
||||
MAP_CHAN_TO_OUT, /* mapping between MIDI channel and dry output index */
|
||||
MAP_CHAN_TO_FX, /* mappping between MIDI channel and fx input index */
|
||||
MAP_CHANFX_TO_OUT, /* mapping between FX output and dry output index */
|
||||
NBR_MAPPING_TYPE
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Set a mapping to a MIDI channel
|
||||
@param map_type type of mapping to set (see channel_mapping_type enum)
|
||||
(MAP_CHAN_TO_OUT) Any MIDI channels mapped to any audio dry buffers:
|
||||
setchanmapout chan0 out0 [chan1 out1 .. ..]
|
||||
|
||||
(MAP_CHAN_TO_FX) Any MIDI channel mapped to any fx unit input:
|
||||
setchanmapfx chan0 fx0 [chan1 fx1 .. ..]
|
||||
|
||||
(MAP_CHANFX_TO_OUT) Any unit fx output mapped to any audio dry buffers:
|
||||
setchanfxmapout chanfx0 out0 [chanfx1 out1 .. ..]
|
||||
*/
|
||||
static int fluid_setchanmap(void *data, int ac, char **av,
|
||||
fluid_ostream_t out, int map_type)
|
||||
{
|
||||
static const char *name_cde[NBR_MAPPING_TYPE] =
|
||||
{"setchanmapout", "setchanmapfx", "setchanfxmapout"};
|
||||
static const char *too_few_arg_chan_map_msg[NBR_MAPPING_TYPE] =
|
||||
{
|
||||
"too few argument, chan out [chan out]...\n",
|
||||
"too few argument, chan fx [chan fx]...\n",
|
||||
"too few argument, chanfx out [chanfx out]...\n"
|
||||
};
|
||||
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_synth_t *synth = handler->synth;
|
||||
int i, n ;
|
||||
|
||||
/* checks channels arguments by group of 2: chan1 val1 chan2 val1 .. ..*/
|
||||
if(check_channels_group_arguments(ac, av, 2, out, name_cde[map_type],
|
||||
too_few_arg_chan_map_msg[map_type]) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ac / 2; /* number of groups information */
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
struct
|
||||
{
|
||||
int chan;
|
||||
int val;
|
||||
}chan_val[NBR_MAPPING_TYPE] ={-1,0,-1,0,-1,0}; /* set all chan parameter to -1*/
|
||||
int chan, val, result;
|
||||
chan_val[map_type].chan = chan = atoi(av[(i * 2)]);
|
||||
chan_val[map_type].val = val = atoi(av[(i * 2) + 1]);
|
||||
|
||||
/* set mapping */
|
||||
result = fluid_synth_mixer_set_mapping(synth,
|
||||
chan_val[MAP_CHAN_TO_OUT].chan,
|
||||
chan_val[MAP_CHAN_TO_OUT].val,
|
||||
chan_val[MAP_CHAN_TO_FX].chan,
|
||||
chan_val[MAP_CHAN_TO_FX].val,
|
||||
chan_val[MAP_CHANFX_TO_OUT].chan,
|
||||
chan_val[MAP_CHAN_TO_OUT].val);
|
||||
if(result == FLUID_FAILED)
|
||||
{
|
||||
fluid_ostream_printf(out, "%s: channel %3d, map to %3d, %s",
|
||||
name_cde[map_type], chan, val, invalid_arg_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
setchanmapout chan0 out0 [chan1 out1 .. ..]
|
||||
|
||||
Set a mapping between a MIDI channel and a dry output index
|
||||
*/
|
||||
int fluid_handle_setchanmapout(void *data, int ac, char **av,
|
||||
fluid_ostream_t out)
|
||||
{
|
||||
return fluid_setchanmap(data, ac, av, out, MAP_CHAN_TO_OUT);
|
||||
}
|
||||
|
||||
#ifdef LADSPA
|
||||
|
||||
#define CHECK_LADSPA_ENABLED(_fx, _out) \
|
||||
|
|
|
@ -104,6 +104,7 @@ int fluid_handle_setbreathmode(void *data, int ac, char **av, fluid_ostream_t ou
|
|||
int fluid_handle_sleep(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
|
||||
int fluid_handle_chanmap(void *data, int ac, char **av,fluid_ostream_t out);
|
||||
int fluid_handle_setchanmapout(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
|
||||
#ifdef LADSPA
|
||||
int fluid_handle_ladspa_effect(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
|
|
|
@ -828,6 +828,46 @@ fluid_rvoice_mixer_get_fx_out_mapping(fluid_rvoice_mixer_t *mixer, int fxunit_id
|
|||
return mixer->fx[fxunit_idx].to_out;
|
||||
}
|
||||
|
||||
/*
|
||||
Set internal mapping from a fx unit output to a dry buffer index.
|
||||
*/
|
||||
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_fx_set_mapping)
|
||||
{
|
||||
fluid_mixer_fx_t *fx = obj; /* array of fx unit */
|
||||
int fxunit_idx = param[0].i; /* fx unit index */
|
||||
int out_from_fx = param[1].i; /* index of dry output buffer*/
|
||||
fx[fxunit_idx].mapping_to_out = out_from_fx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mapping beetwen fx unit and audio dry output at index out_from_fx.
|
||||
* @param mixer.
|
||||
* @fxunit_idx, index of fx unit to which out_from_fx must be mapped.
|
||||
* @out_from_fx, dry output index to map to fx unit.
|
||||
*/
|
||||
void fluid_rvoice_mixer_set_fx_out_mapping(fluid_rvoice_mixer_t *mixer,
|
||||
int fxunit_idx, int out_from_fx)
|
||||
{
|
||||
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
|
||||
|
||||
/* get fx unit */
|
||||
fluid_mixer_fx_t *fx = mixer->fx;
|
||||
|
||||
/*
|
||||
- First set shadow out_from_fx value here so that it will be returned
|
||||
if queried.
|
||||
- Then set the mapping value through the ring buffer.
|
||||
*/
|
||||
fx[fxunit_idx].to_out = out_from_fx; /* shadow value */
|
||||
|
||||
/* Set the mapping through the ring buffer. */
|
||||
param[0].i = fxunit_idx; /* fx unit index */
|
||||
param[1].i = out_from_fx; /* dry output index */
|
||||
fluid_rvoice_eventhandler_push(mixer->eventhandler,
|
||||
fluid_rvoice_mixer_fx_set_mapping,
|
||||
fx, param);
|
||||
}
|
||||
|
||||
static void
|
||||
fluid_mixer_buffers_free(fluid_mixer_buffers_t *buffers)
|
||||
{
|
||||
|
|
|
@ -42,6 +42,8 @@ fluid_rvoice_mixer_t *new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, in
|
|||
fluid_rvoice_eventhandler_t *, int, int);
|
||||
int
|
||||
fluid_rvoice_mixer_get_fx_out_mapping(fluid_rvoice_mixer_t *mixer, int fxunit_idx);
|
||||
void fluid_rvoice_mixer_set_fx_out_mapping(fluid_rvoice_mixer_t *mixer,
|
||||
int fxunit_idx, int out_from_fx);
|
||||
|
||||
void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t *);
|
||||
|
||||
|
|
|
@ -7481,3 +7481,120 @@ fluid_synth_mixer_get_mapping(fluid_synth_t *synth,
|
|||
|
||||
FLUID_API_RETURN(FLUID_OK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set mixer MIDI channel mapping to audio buffers.
|
||||
* These mapping allows:
|
||||
* (1) Any MIDI channels mapped to any audio dry buffers.
|
||||
* (2) Any MIDI channel mapped to any fx unit input .
|
||||
* (3) Any unit fx output mapped to any audio dry buffers.
|
||||
*
|
||||
* The function allows the setting of mapping (1) or/and(2) or/and (3)
|
||||
* simultaneously or not:
|
||||
* 1)Mapping between MIDI channel chan_to_out and audio dry output at
|
||||
* index out_from_chan. If chan_to_out is -1 this mapping is ignored,
|
||||
* otherwise the mapping is done with the following special case:
|
||||
* if out_from_chan is -1, this disable dry audio for this MIDI channel.
|
||||
* This allows playing only fx (with dry muted temporarily).
|
||||
*
|
||||
* @param synth FluidSynth instance.
|
||||
* @param chan_to_out, MIDI channel to which out_from_chan must be mapped.
|
||||
* Must be in the range (-1 to MIDI channel count-1).
|
||||
* @param out_from_chan, audio output index to map to chan_to_out.
|
||||
* Must be in the range (-1 to synth->audio_groups-1).
|
||||
*
|
||||
* 2)Mapping between MIDI channel chan_to_fx and fx unit input at
|
||||
* index fx_from_chan. If chan_to_fx is -1 this mapping is ignored,
|
||||
* otherwise the mapping is done with the following special case:
|
||||
* if fx_from_chan is -1, this disable fx audio for this MIDI channel.
|
||||
* This allows playing only dry (with fx muted temporarily).
|
||||
*
|
||||
* @param chan_to_fx, MIDI channel to which fx_from_chan must be mapped.
|
||||
* Must be in the range (-1 to MIDI channel count-1).
|
||||
* @param fx_from_chan, fx unit input index to map to chan_to_fx.
|
||||
* Must be in the range (-1 to synth->effects_groups-1).
|
||||
*
|
||||
* 3)Mapping beetwen fx unit output (which is mapped to chanfx_to_out) and
|
||||
* audio dry output at index index out_from_fx. If chanfx_to_out is -1,
|
||||
* this mapping is ignored.
|
||||
*
|
||||
* @param chanfx_to_out, indicates the fx unit (which is actually mapped
|
||||
* to chanfx_to_out) whose output must be mapped with out_from_fx.
|
||||
* Must be in the range (-1 to MIDI channel count-1).
|
||||
* @param out_from_fx, audio output index that must be mapped to fx unit output
|
||||
* (which is actually mapped to chanfx_to_out).
|
||||
* Must be in the range (0 to synth->audio_groups-1).
|
||||
*
|
||||
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
|
||||
*/
|
||||
int
|
||||
fluid_synth_mixer_set_mapping(fluid_synth_t *synth,
|
||||
int chan_to_out, int out_from_chan,
|
||||
int chan_to_fx, int fx_from_chan,
|
||||
int chanfx_to_out, int out_from_fx)
|
||||
{
|
||||
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
|
||||
fluid_synth_api_enter(synth);
|
||||
|
||||
/* Map chan_to_out and audio dry output if queried */
|
||||
if(chan_to_out >= 0)
|
||||
{
|
||||
/* check chan_to_out and out_from_chan */
|
||||
if((chan_to_out >= synth->midi_channels)
|
||||
||(out_from_chan >= synth->audio_groups))
|
||||
{
|
||||
FLUID_API_RETURN(FLUID_FAILED);
|
||||
}
|
||||
|
||||
/* Mapping between MIDI channel chan_to_out and audio dry output
|
||||
at index out_from_chan.
|
||||
*/
|
||||
synth->channel[chan_to_out]->mapping_to_out = out_from_chan;
|
||||
}
|
||||
|
||||
/* Map chan_to_fx and fx input index if queried */
|
||||
if(chan_to_fx >= 0)
|
||||
{
|
||||
/* check chan_to_fx and fx_from_chan */
|
||||
if((chan_to_fx >= synth->midi_channels)
|
||||
||(fx_from_chan >= synth->effects_groups))
|
||||
{
|
||||
FLUID_API_RETURN(FLUID_FAILED);
|
||||
}
|
||||
|
||||
/* Mapping between MIDI channel chan_to_fx and fx input
|
||||
at index fx_from_chan.
|
||||
*/
|
||||
synth->channel[chan_to_fx]->mapping_to_fx = fx_from_chan;
|
||||
}
|
||||
|
||||
/* Map fx unit output and audio dry output if queried */
|
||||
if(chanfx_to_out >= 0)
|
||||
{
|
||||
int fxunit_idx; /* fx input which is actually mapped to chanfx_to_out*/
|
||||
|
||||
/* check chanfx_to_out and out_from_fx */
|
||||
if((chanfx_to_out >= synth->midi_channels)
|
||||
||(out_from_fx >= synth->audio_groups))
|
||||
{
|
||||
FLUID_API_RETURN(FLUID_FAILED);
|
||||
}
|
||||
/* get fx unit actually mapped to chanfx_fx_to out */
|
||||
fxunit_idx = synth->channel[chanfx_to_out]->mapping_to_fx;
|
||||
|
||||
/* check if any fx unit has been mapped to chanfx_to_out */
|
||||
if (fxunit_idx < 0)
|
||||
{
|
||||
FLUID_API_RETURN(FLUID_FAILED);
|
||||
}
|
||||
|
||||
/* Mapping beetwen fx unit output and audio dry output
|
||||
at index index out_from_fx.
|
||||
*/
|
||||
fluid_rvoice_mixer_set_fx_out_mapping(synth->eventhandler->mixer,
|
||||
fxunit_idx, out_from_fx);
|
||||
}
|
||||
|
||||
FLUID_API_RETURN(FLUID_OK);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue