Skip to content

Commit

Permalink
Merge pull request #739 from FluidSynth/parse-cmd3
Browse files Browse the repository at this point in the history
Handle settings-related commands in user command file early
  • Loading branch information
derselbst authored Jan 10, 2021
2 parents 2cada68 + 20ff3f8 commit ca6bcda
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 58 deletions.
3 changes: 3 additions & 0 deletions include/fluidsynth/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ FLUIDSYNTH_API char *fluid_get_sysconf(char *buf, int len);
FLUIDSYNTH_API
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router);

FLUIDSYNTH_API
fluid_cmd_handler_t *new_fluid_cmd_handler2(fluid_settings_t *settings, fluid_synth_t *synth, fluid_midi_router_t *router);

FLUIDSYNTH_API
void delete_fluid_cmd_handler(fluid_cmd_handler_t *handler);
/** @endlifecycle */
Expand Down
136 changes: 99 additions & 37 deletions src/bindings/fluid_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
/* the shell cmd handler struct */
struct _fluid_cmd_handler_t
{
fluid_settings_t *settings;
fluid_synth_t *synth;
fluid_midi_router_t *router;
fluid_cmd_hash_t *commands;
Expand Down Expand Up @@ -539,7 +540,10 @@ fluid_shell_run(void *data)

if(n == 0)
{
FLUID_LOG(FLUID_INFO, "Received EOF while reading commands, exiting the shell.");
if(shell->settings)
{
FLUID_LOG(FLUID_INFO, "Received EOF while reading commands, exiting the shell.");
}
break;
}
}
Expand Down Expand Up @@ -1209,20 +1213,20 @@ fluid_handle_reverb_command(void *data, int ac, char **av, fluid_ostream_t out,
FLUID_ENTRY_COMMAND(data);
fluid_real_t value;

fluid_settings_getnum_range(handler->synth->settings, "synth.reverb.room-size",
fluid_settings_getnum_range(handler->settings, "synth.reverb.room-size",
&values[FLUID_REVERB_ROOMSIZE].min,
&values[FLUID_REVERB_ROOMSIZE].max);

fluid_settings_getnum_range(handler->synth->settings, "synth.reverb.damp",
fluid_settings_getnum_range(handler->settings, "synth.reverb.damp",
&values[FLUID_REVERB_DAMP].min,
&values[FLUID_REVERB_DAMP].max);


fluid_settings_getnum_range(handler->synth->settings, "synth.reverb.width",
fluid_settings_getnum_range(handler->settings, "synth.reverb.width",
&values[FLUID_REVERB_WIDTH].min,
&values[FLUID_REVERB_WIDTH].max);

fluid_settings_getnum_range(handler->synth->settings, "synth.reverb.level",
fluid_settings_getnum_range(handler->settings, "synth.reverb.level",
&values[FLUID_REVERB_LEVEL].min,
&values[FLUID_REVERB_LEVEL].max);

Expand Down Expand Up @@ -1915,7 +1919,9 @@ fluid_handle_set(void *data, int ac, char **av, fluid_ostream_t out)
{
FLUID_ENTRY_COMMAND(data);
int hints;
int ival;
int ival, icur;
double fval, fcur;
char *scur;
int ret = FLUID_FAILED;

if(ac < 2)
Expand All @@ -1924,14 +1930,14 @@ fluid_handle_set(void *data, int ac, char **av, fluid_ostream_t out)
return ret;
}

switch(fluid_settings_get_type(handler->synth->settings, av[0]))
switch(fluid_settings_get_type(handler->settings, av[0]))
{
case FLUID_NO_TYPE:
fluid_ostream_printf(out, "set: Parameter '%s' not found.\n", av[0]);
return ret;

case FLUID_INT_TYPE:
if(fluid_settings_get_hints(handler->synth->settings, av[0], &hints) == FLUID_OK
if(fluid_settings_get_hints(handler->settings, av[0], &hints) == FLUID_OK
&& hints & FLUID_HINT_TOGGLED)
{
if(FLUID_STRCASECMP(av[1], "yes") == 0
Expand All @@ -1950,28 +1956,53 @@ fluid_handle_set(void *data, int ac, char **av, fluid_ostream_t out)
ival = atoi(av[1]);
}

ret = fluid_settings_setint(handler->synth->settings, av[0], ival);
fluid_settings_getint(handler->settings, av[0], &icur);
if (icur == ival)
{
return FLUID_OK;
}

ret = fluid_settings_setint(handler->settings, av[0], ival);
break;

case FLUID_NUM_TYPE:
ret = fluid_settings_setnum(handler->synth->settings, av[0], atof(av[1]));
fval = atof(av[1]);
fluid_settings_getnum(handler->settings, av[0], &fcur);
if (fcur == fval)
{
return FLUID_OK;
}

ret = fluid_settings_setnum(handler->settings, av[0], fval);
break;

case FLUID_STR_TYPE:
ret = fluid_settings_setstr(handler->synth->settings, av[0], av[1]);
fluid_settings_dupstr(handler->settings, av[0], &scur);

if(scur && !FLUID_STRCMP(scur, av[1]))
{
FLUID_FREE(scur);
return FLUID_OK;
}
ret = fluid_settings_setstr(handler->settings, av[0], av[1]);
FLUID_FREE(scur);
break;

case FLUID_SET_TYPE:
fluid_ostream_printf(out, "set: Parameter '%s' is a node.\n", av[0]);
return FLUID_FAILED;

default:
fluid_ostream_printf(out, "Unhandled settings type.");
return FLUID_FAILED;
}

if(ret == FLUID_FAILED)
{
fluid_ostream_printf(out, "set: Value out of range. Try 'info %s' for valid ranges\n", av[0]);
}

if(!fluid_settings_is_realtime(handler->synth->settings, av[0]))
if((handler->synth != NULL || handler->router != NULL) && !fluid_settings_is_realtime(handler->settings, av[0]))
{
fluid_ostream_printf(out, "Warning: '%s' is not a realtime setting, changes won't take effect.\n", av[0]);
}
Expand All @@ -1990,7 +2021,7 @@ fluid_handle_get(void *data, int ac, char **av, fluid_ostream_t out)
return FLUID_FAILED;
}

switch(fluid_settings_get_type(fluid_synth_get_settings(handler->synth), av[0]))
switch(fluid_settings_get_type(handler->settings, av[0]))
{
case FLUID_NO_TYPE:
fluid_ostream_printf(out, "get: no such setting '%s'.\n", av[0]);
Expand All @@ -1999,23 +2030,23 @@ fluid_handle_get(void *data, int ac, char **av, fluid_ostream_t out)
case FLUID_NUM_TYPE:
{
double value;
fluid_settings_getnum(handler->synth->settings, av[0], &value);
fluid_settings_getnum(handler->settings, av[0], &value);
fluid_ostream_printf(out, "%.3f\n", value);
break;
}

case FLUID_INT_TYPE:
{
int value;
fluid_settings_getint(handler->synth->settings, av[0], &value);
fluid_settings_getint(handler->settings, av[0], &value);
fluid_ostream_printf(out, "%d\n", value);
break;
}

case FLUID_STR_TYPE:
{
char *s;
fluid_settings_dupstr(handler->synth->settings, av[0], &s); /* ++ alloc string */
fluid_settings_dupstr(handler->settings, av[0], &s); /* ++ alloc string */
fluid_ostream_printf(out, "%s\n", s ? s : "NULL");

if(s)
Expand All @@ -2037,7 +2068,7 @@ fluid_handle_get(void *data, int ac, char **av, fluid_ostream_t out)
struct _fluid_handle_settings_data_t
{
size_t len;
fluid_synth_t *synth;
fluid_settings_t *settings;
fluid_ostream_t out;
};

Expand Down Expand Up @@ -2067,22 +2098,22 @@ static void fluid_handle_settings_iter2(void *data, const char *name, int type)

fluid_ostream_printf(d->out, " ");

switch(fluid_settings_get_type(fluid_synth_get_settings(d->synth), name))
switch(fluid_settings_get_type(d->settings, name))
{
case FLUID_NUM_TYPE:
{
double value;
fluid_settings_getnum(d->synth->settings, name, &value);
fluid_settings_getnum(d->settings, name, &value);
fluid_ostream_printf(d->out, "%.3f\n", value);
break;
}

case FLUID_INT_TYPE:
{
int value, hints;
fluid_settings_getint(d->synth->settings, name, &value);
fluid_settings_getint(d->settings, name, &value);

if(fluid_settings_get_hints(d->synth->settings, name, &hints) == FLUID_OK)
if(fluid_settings_get_hints(d->settings, name, &hints) == FLUID_OK)
{
if(!(hints & FLUID_HINT_TOGGLED))
{
Expand All @@ -2100,7 +2131,7 @@ static void fluid_handle_settings_iter2(void *data, const char *name, int type)
case FLUID_STR_TYPE:
{
char *s;
fluid_settings_dupstr(d->synth->settings, name, &s); /* ++ alloc string */
fluid_settings_dupstr(d->settings, name, &s); /* ++ alloc string */
fluid_ostream_printf(d->out, "%s\n", s ? s : "NULL");

if(s)
Expand All @@ -2120,11 +2151,11 @@ fluid_handle_settings(void *d, int ac, char **av, fluid_ostream_t out)
struct _fluid_handle_settings_data_t data;

data.len = 0;
data.synth = handler->synth;
data.settings = handler->settings;
data.out = out;

fluid_settings_foreach(fluid_synth_get_settings(handler->synth), &data, fluid_handle_settings_iter1);
fluid_settings_foreach(fluid_synth_get_settings(handler->synth), &data, fluid_handle_settings_iter2);
fluid_settings_foreach(handler->settings, &data, fluid_handle_settings_iter1);
fluid_settings_foreach(handler->settings, &data, fluid_handle_settings_iter2);
return FLUID_OK;
}

Expand Down Expand Up @@ -2154,7 +2185,7 @@ int
fluid_handle_info(void *d, int ac, char **av, fluid_ostream_t out)
{
FLUID_ENTRY_COMMAND(d);
fluid_settings_t *settings = fluid_synth_get_settings(handler->synth);
fluid_settings_t *settings = handler->settings;
struct _fluid_handle_option_data_t data;

if(ac < 1)
Expand Down Expand Up @@ -4253,11 +4284,24 @@ fluid_cmd_handler_destroy_hash_value(void *value)
/**
* Create a new command handler.
*
* See new_fluid_cmd_handler2() for more information.
*/
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router)
{
return new_fluid_cmd_handler2(fluid_synth_get_settings(synth), synth, router);
}

/**
* Create a new command handler.
*
* @param settings If not NULL, all the settings related commands will be added to the new handler. The @p settings
* object must be the same as the one you used for creating the @p synth and @p router. Otherwise the
* behaviour is undefined.
* @param synth If not NULL, all the default synthesizer commands will be added to the new handler.
* @param router If not NULL, all the default midi_router commands will be added to the new handler.
* @return New command handler, or NULL if alloc failed
*/
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router)
fluid_cmd_handler_t *new_fluid_cmd_handler2(fluid_settings_t* settings, fluid_synth_t *synth, fluid_midi_router_t *router)
{
unsigned int i;
fluid_cmd_handler_t *handler;
Expand All @@ -4280,21 +4324,29 @@ fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_rout
return NULL;
}

handler->settings = settings;
handler->synth = synth;
handler->router = router;

for(i = 0; i < FLUID_N_ELEMENTS(fluid_commands); i++)
{
const fluid_cmd_t *cmd = &fluid_commands[i];
int is_router_cmd = FLUID_STRCMP(cmd->topic, "router") == 0;
int is_settings_cmd = FLUID_STRCMP(cmd->topic, "settings") == 0;

if((is_router_cmd && router == NULL) || (!is_router_cmd && synth == NULL))
if((is_router_cmd && router == NULL) ||
(is_settings_cmd && settings == NULL) ||
(!is_router_cmd && !is_settings_cmd && synth == NULL))
{
/* omit registering router and synth commands if they were not requested */
continue;
/* register a no-op command, this avoids an unknown command error later on */
fluid_cmd_t noop = *cmd;
noop.handler = NULL;
fluid_cmd_handler_register(handler, &noop);
}
else
{
fluid_cmd_handler_register(handler, cmd);
}

fluid_cmd_handler_register(handler, &fluid_commands[i]);
}

return handler;
Expand Down Expand Up @@ -4350,13 +4402,23 @@ fluid_cmd_handler_handle(void *data, int ac, char **av, fluid_ostream_t out)

cmd = fluid_hashtable_lookup(handler->commands, av[0]);

if(cmd && cmd->handler)
if(cmd)
{
if(cmd->handler)
{
return (*cmd->handler)(handler, ac - 1, av + 1, out);
}
else
{
/* no-op command */
return 1;
}
}
else
{
return (*cmd->handler)(handler, ac - 1, av + 1, out);
fluid_ostream_printf(out, "unknown command: %s (try help)\n", av[0]);
return FLUID_FAILED;
}

fluid_ostream_printf(out, "unknown command: %s (try help)\n", av[0]);
return FLUID_FAILED;
}


Expand Down
Loading

0 comments on commit ca6bcda

Please sign in to comment.