mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-27 06:22:06 +00:00
Merge pull request #739 from FluidSynth/parse-cmd3
Handle settings-related commands in user command file early
This commit is contained in:
commit
ca6bcda7d9
3 changed files with 140 additions and 58 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -1950,20 +1956,45 @@ 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)
|
||||
|
@ -1971,7 +2002,7 @@ fluid_handle_set(void *data, int ac, char **av, fluid_ostream_t out)
|
|||
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]);
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -1999,7 +2030,7 @@ 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;
|
||||
}
|
||||
|
@ -2007,7 +2038,7 @@ fluid_handle_get(void *data, int ac, char **av, fluid_ostream_t out)
|
|||
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;
|
||||
}
|
||||
|
@ -2015,7 +2046,7 @@ fluid_handle_get(void *data, int ac, char **av, fluid_ostream_t out)
|
|||
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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -2067,12 +2098,12 @@ 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;
|
||||
}
|
||||
|
@ -2080,9 +2111,9 @@ static void fluid_handle_settings_iter2(void *data, const char *name, int type)
|
|||
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))
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -4280,6 +4324,7 @@ 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;
|
||||
|
||||
|
@ -4287,14 +4332,21 @@ fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_rout
|
|||
{
|
||||
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;
|
||||
|
@ -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)
|
||||
{
|
||||
return (*cmd->handler)(handler, ac - 1, av + 1, out);
|
||||
if(cmd->handler)
|
||||
{
|
||||
return (*cmd->handler)(handler, ac - 1, av + 1, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no-op command */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ void print_configure(void);
|
|||
/*
|
||||
* the globals
|
||||
*/
|
||||
fluid_cmd_handler_t *cmd_handler = NULL;
|
||||
int option_help = 0; /* set to 1 if "-o help" is specified */
|
||||
|
||||
|
||||
|
@ -308,6 +307,7 @@ fast_render_loop(fluid_settings_t *settings, fluid_synth_t *synth, fluid_player_
|
|||
|
||||
1)creating the settings.
|
||||
2)reading/setting all options in command line.
|
||||
2.5)read configuration file the first time and execute all "set" commands
|
||||
3)creating the synth.
|
||||
4)loading the soundfonts specified in command line
|
||||
(multiple soundfonts loading is possible).
|
||||
|
@ -318,7 +318,7 @@ fast_render_loop(fluid_settings_t *settings, fluid_synth_t *synth, fluid_player_
|
|||
(multiple midifiles loading is possible).
|
||||
9)loading a default soundfont if needed before starting the player.
|
||||
10)create a command handler.
|
||||
11)reading the configuration file and submit it to the command handler.
|
||||
11)reading the entire configuration file for the second time and submit it to the command handler.
|
||||
12)create a tcp shell if any requested.
|
||||
13)create a synchronous user shell if interactive.
|
||||
14)entering fast rendering loop if requested.
|
||||
|
@ -338,6 +338,7 @@ int main(int argc, char **argv)
|
|||
fluid_midi_driver_t *mdriver = NULL;
|
||||
fluid_audio_driver_t *adriver = NULL;
|
||||
fluid_synth_t *synth = NULL;
|
||||
fluid_cmd_handler_t *cmd_handler = NULL;
|
||||
#ifdef NETWORK_SUPPORT
|
||||
fluid_server_t *server = NULL;
|
||||
int with_server = 0;
|
||||
|
@ -369,7 +370,6 @@ int main(int argc, char **argv)
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
/* create the settings */
|
||||
settings = new_fluid_settings();
|
||||
|
||||
|
@ -773,7 +773,8 @@ int main(int argc, char **argv)
|
|||
arg1 = i;
|
||||
#endif
|
||||
|
||||
if (!quiet) {
|
||||
if (!quiet)
|
||||
{
|
||||
print_welcome();
|
||||
}
|
||||
|
||||
|
@ -830,6 +831,36 @@ int main(int argc, char **argv)
|
|||
fluid_settings_setint(settings, "synth.lock-memory", 0);
|
||||
}
|
||||
|
||||
if(config_file == NULL)
|
||||
{
|
||||
config_file = fluid_get_userconf(buf, sizeof(buf));
|
||||
if(config_file == NULL)
|
||||
{
|
||||
config_file = fluid_get_sysconf(buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle set commands before creating the synth */
|
||||
if(config_file != NULL)
|
||||
{
|
||||
cmd_handler = new_fluid_cmd_handler2(settings, NULL, NULL);
|
||||
if(cmd_handler == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create the early command handler\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(fluid_source(cmd_handler, config_file) < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to early-execute command configuration file '%s'\n", config_file);
|
||||
/* the command file seems broken, don't read it again */
|
||||
config_file = NULL;
|
||||
}
|
||||
|
||||
delete_fluid_cmd_handler(cmd_handler);
|
||||
cmd_handler = NULL;
|
||||
}
|
||||
|
||||
/* create the synthesizer */
|
||||
synth = new_fluid_synth(settings);
|
||||
|
||||
|
@ -950,20 +981,9 @@ int main(int argc, char **argv)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if(config_file != NULL)
|
||||
if(config_file != NULL && fluid_source(cmd_handler, config_file) < 0)
|
||||
{
|
||||
if(fluid_source(cmd_handler, config_file) < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to execute user provided command configuration file '%s'\n", config_file);
|
||||
}
|
||||
}
|
||||
else if(fluid_get_userconf(buf, sizeof(buf)) != NULL)
|
||||
{
|
||||
fluid_source(cmd_handler, buf);
|
||||
}
|
||||
else if(fluid_get_sysconf(buf, sizeof(buf)) != NULL)
|
||||
{
|
||||
fluid_source(cmd_handler, buf);
|
||||
fprintf(stderr, "Failed to execute command configuration file '%s'\n", config_file);
|
||||
}
|
||||
|
||||
/* run the server, if requested */
|
||||
|
@ -1071,10 +1091,7 @@ cleanup:
|
|||
|
||||
#endif /* NETWORK_SUPPORT */
|
||||
|
||||
if(cmd_handler != NULL)
|
||||
{
|
||||
delete_fluid_cmd_handler(cmd_handler);
|
||||
}
|
||||
delete_fluid_cmd_handler(cmd_handler);
|
||||
|
||||
if(player != NULL)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue