This commit is contained in:
derselbst 2017-12-27 17:24:44 +01:00
commit be9caa1953

View file

@ -120,149 +120,96 @@ void delete_fluid_file_audio_driver(fluid_audio_driver_t* p);
/* Available audio drivers, listed in order of preference */ /* Available audio drivers, listed in order of preference */
static const fluid_audriver_definition_t fluid_audio_drivers[] =
{
#if JACK_SUPPORT #if JACK_SUPPORT
#define JACK_DEF_INIT \
{ "jack", \ { "jack", \
new_fluid_jack_audio_driver, \ new_fluid_jack_audio_driver, \
new_fluid_jack_audio_driver2, \ new_fluid_jack_audio_driver2, \
delete_fluid_jack_audio_driver, \ delete_fluid_jack_audio_driver, \
fluid_jack_audio_driver_settings }, fluid_jack_audio_driver_settings },
#else
#define JACK_DEF_INIT
#endif #endif
#if ALSA_SUPPORT #if ALSA_SUPPORT
#define ALSA_DEF_INIT \
{ "alsa", \ { "alsa", \
new_fluid_alsa_audio_driver, \ new_fluid_alsa_audio_driver, \
new_fluid_alsa_audio_driver2, \ new_fluid_alsa_audio_driver2, \
delete_fluid_alsa_audio_driver, \ delete_fluid_alsa_audio_driver, \
fluid_alsa_audio_driver_settings }, fluid_alsa_audio_driver_settings },
#else
#define ALSA_DEF_INIT
#endif #endif
#if OSS_SUPPORT #if OSS_SUPPORT
#define OSS_DEF_INIT \
{ "oss", \ { "oss", \
new_fluid_oss_audio_driver, \ new_fluid_oss_audio_driver, \
new_fluid_oss_audio_driver2, \ new_fluid_oss_audio_driver2, \
delete_fluid_oss_audio_driver, \ delete_fluid_oss_audio_driver, \
fluid_oss_audio_driver_settings }, fluid_oss_audio_driver_settings },
#else
#define OSS_DEF_INIT
#endif #endif
#if PULSE_SUPPORT #if PULSE_SUPPORT
#define PULSE_DEF_INIT \
{ "pulseaudio", \ { "pulseaudio", \
new_fluid_pulse_audio_driver, \ new_fluid_pulse_audio_driver, \
new_fluid_pulse_audio_driver2, \ new_fluid_pulse_audio_driver2, \
delete_fluid_pulse_audio_driver, \ delete_fluid_pulse_audio_driver, \
fluid_pulse_audio_driver_settings }, fluid_pulse_audio_driver_settings },
#else
#define PULSE_DEF_INIT
#endif #endif
#if COREAUDIO_SUPPORT #if COREAUDIO_SUPPORT
#define COREAUDIO_DEF_INIT \
{ "coreaudio", \ { "coreaudio", \
new_fluid_core_audio_driver, \ new_fluid_core_audio_driver, \
new_fluid_core_audio_driver2, \ new_fluid_core_audio_driver2, \
delete_fluid_core_audio_driver, \ delete_fluid_core_audio_driver, \
fluid_core_audio_driver_settings }, fluid_core_audio_driver_settings },
#else
#define COREAUDIO_DEF_INIT
#endif #endif
#if DSOUND_SUPPORT #if DSOUND_SUPPORT
#define DSOUND_DEF_INIT \
{ "dsound", \ { "dsound", \
new_fluid_dsound_audio_driver, \ new_fluid_dsound_audio_driver, \
NULL, \ NULL, \
delete_fluid_dsound_audio_driver, \ delete_fluid_dsound_audio_driver, \
fluid_dsound_audio_driver_settings }, fluid_dsound_audio_driver_settings },
#else
#define DSOUND_DEF_INIT
#endif #endif
#if PORTAUDIO_SUPPORT #if PORTAUDIO_SUPPORT
#define PORTAUDIO_DEF_INIT \
{ "portaudio", \ { "portaudio", \
new_fluid_portaudio_driver, \ new_fluid_portaudio_driver, \
NULL, \ NULL, \
delete_fluid_portaudio_driver, \ delete_fluid_portaudio_driver, \
fluid_portaudio_driver_settings }, fluid_portaudio_driver_settings },
#else
#define PORTAUDIO_DEF_INIT
#endif #endif
#if SNDMAN_SUPPORT #if SNDMAN_SUPPORT
#define SNDMAN_DEF_INIT \
{ "sndman", \ { "sndman", \
new_fluid_sndmgr_audio_driver, \ new_fluid_sndmgr_audio_driver, \
new_fluid_sndmgr_audio_driver2, \ new_fluid_sndmgr_audio_driver2, \
delete_fluid_sndmgr_audio_driver, \ delete_fluid_sndmgr_audio_driver, \
NULL }, NULL },
#else
#define SNDMAN_DEF_INIT
#endif #endif
#if DART_SUPPORT #if DART_SUPPORT
#define DART_DEF_INIT \
{ "dart", \ { "dart", \
new_fluid_dart_audio_driver, \ new_fluid_dart_audio_driver, \
NULL, \ NULL, \
delete_fluid_dart_audio_driver, \ delete_fluid_dart_audio_driver, \
fluid_dart_audio_driver_settings }, fluid_dart_audio_driver_settings },
#else
#define DART_DEF_INIT
#endif #endif
#if AUFILE_SUPPORT #if AUFILE_SUPPORT
#define AUFILE_DEF_INIT \
{ "file", \ { "file", \
new_fluid_file_audio_driver, \ new_fluid_file_audio_driver, \
NULL, \ NULL, \
delete_fluid_file_audio_driver, \ delete_fluid_file_audio_driver, \
NULL }, NULL },
#else
#define AUFILE_DEF_INIT
#endif #endif
#define AVAILABLE_AUDRIVERS \
JACK_DEF_INIT \
ALSA_DEF_INIT \
OSS_DEF_INIT \
PULSE_DEF_INIT \
COREAUDIO_DEF_INIT \
DSOUND_DEF_INIT \
PORTAUDIO_DEF_INIT \
SNDMAN_DEF_INIT \
DART_DEF_INIT \
AUFILE_DEF_INIT
/* fluid_audio_drivers_template is a compile-constant template containing all audio drivers
* fluidsynth has been built with
*
* fluid_audio_drivers contains all the drivers registered for usage with
* fluid_audio_driver_register()
*
* To maintain backwards compatibility, all available drivers are initially registered, so
* this must be the same as fluid_audio_drivers_template. But arrays are unassignable in C
* and copying them at runtime with memcpy in fluid_audio_driver_settings() wouldnt be
* threadsafe. So use this ugly macro hack to initialize both equally at compiletime.
*/
static const fluid_audriver_definition_t fluid_audio_drivers_template[] =
{
AVAILABLE_AUDRIVERS
}; };
static fluid_audriver_definition_t fluid_audio_drivers[] = #define ENABLE_AUDIO_DRIVER(_drv, _idx) \
{ _drv[(_idx) / (sizeof(*(_drv))*8)] &= ~(1 << ((_idx) % (sizeof((*_drv))*8)))
AVAILABLE_AUDRIVERS
};
#define IS_AUDIO_DRIVER_ENABLED(_drv, _idx) \
(!(_drv[(_idx) / (sizeof(*(_drv))*8)] & (1 << ((_idx) % (sizeof((*_drv))*8)))))
static uint8_t fluid_adriver_disable_mask[(FLUID_N_ELEMENTS(fluid_audio_drivers)+7)/8] = {0};
void fluid_audio_driver_settings(fluid_settings_t* settings) void fluid_audio_driver_settings(fluid_settings_t* settings)
{ {
@ -343,13 +290,42 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
fluid_settings_add_option(settings, "audio.driver", "file"); fluid_settings_add_option(settings, "audio.driver", "file");
#endif #endif
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers) && fluid_audio_drivers[i].name != NULL; i++) { for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_audio_drivers[i].settings != NULL) { if (fluid_audio_drivers[i].settings != NULL &&
IS_AUDIO_DRIVER_ENABLED(fluid_adriver_disable_mask, i)) {
fluid_audio_drivers[i].settings(settings); fluid_audio_drivers[i].settings(settings);
} }
} }
} }
static const fluid_audriver_definition_t*
find_fluid_audio_driver(fluid_settings_t* settings)
{
unsigned int i;
char* name;
char *allnames;
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
/* If this driver is de-activated, just ignore it */
if (!IS_AUDIO_DRIVER_ENABLED(fluid_adriver_disable_mask, i))
continue;
if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name)) {
FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name);
return &fluid_audio_drivers[i];
}
}
allnames = fluid_settings_option_concat (settings, "audio.driver", NULL);
fluid_settings_dupstr (settings, "audio.driver", &name); /* ++ alloc name */
FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver %s. Valid drivers are: %s.",
name ? name : "NULL", allnames ? allnames : "ERROR");
if (name) FLUID_FREE (name);
if (allnames) FLUID_FREE (allnames);
return NULL;
}
/** /**
* Create a new audio driver. * Create a new audio driver.
* @param settings Configuration settings used to select and create the audio * @param settings Configuration settings used to select and create the audio
@ -363,28 +339,17 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
fluid_audio_driver_t* fluid_audio_driver_t*
new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
{ {
unsigned int i; const fluid_audriver_definition_t *def = find_fluid_audio_driver(settings);
fluid_audio_driver_t* driver = NULL;
char* name;
char *allnames;
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers) && fluid_audio_drivers[i].name != NULL; i++) { if (def) {
if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name)) { fluid_audio_driver_t *driver = (*def->new)(settings, synth);
FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name);
driver = (*fluid_audio_drivers[i].new)(settings, synth); if (driver)
if (driver) { driver->name = def->name;
driver->name = fluid_audio_drivers[i].name;
} return driver;
return driver;
}
} }
allnames = fluid_settings_option_concat (settings, "audio.driver", NULL);
fluid_settings_dupstr (settings, "audio.driver", &name); /* ++ alloc name */
FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver %s. Valid drivers are: %s.",
name ? name : "NULL", allnames ? allnames : "ERROR");
if (name) FLUID_FREE (name);
if (allnames) FLUID_FREE (allnames);
return NULL; return NULL;
} }
@ -405,26 +370,22 @@ new_fluid_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
fluid_audio_driver_t* fluid_audio_driver_t*
new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) new_fluid_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data)
{ {
unsigned int i; const fluid_audriver_definition_t *def = find_fluid_audio_driver(settings);
fluid_audio_driver_t* driver = NULL;
char* name;
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers) && fluid_audio_drivers[i].name != NULL; i++) { if (def) {
if (fluid_settings_str_equal(settings, "audio.driver", fluid_audio_drivers[i].name) && fluid_audio_driver_t *driver = NULL;
(fluid_audio_drivers[i].new2 != NULL)) {
FLUID_LOG(FLUID_DBG, "Using '%s' audio driver", fluid_audio_drivers[i].name); if (def->new2 == NULL)
driver = (*fluid_audio_drivers[i].new2)(settings, func, data); FLUID_LOG(FLUID_DBG, "Callback mode unsupported on '%s' audio driver", def->name);
if (driver) { else {
driver->name = fluid_audio_drivers[i].name; driver = (*def->new2)(settings, func, data);
} if (driver)
return driver; driver->name = def->name;
} }
return driver;
} }
fluid_settings_dupstr(settings, "audio.driver", &name); /* ++ alloc name */
FLUID_LOG(FLUID_ERR, "Couldn't find the requested audio driver: %s",
name ? name : "NULL");
if (name) FLUID_FREE (name);
return NULL; return NULL;
} }
@ -441,9 +402,9 @@ delete_fluid_audio_driver(fluid_audio_driver_t* driver)
fluid_return_if_fail(driver != NULL); fluid_return_if_fail(driver != NULL);
/* iterate over fluid_audio_drivers_template to ensure deleting even drivers currently not registered */ /* iterate over fluid_audio_drivers_template to ensure deleting even drivers currently not registered */
for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers_template); i++) { for (i = 0; i < FLUID_N_ELEMENTS(fluid_audio_drivers); i++) {
if (fluid_audio_drivers_template[i].name == driver->name) { if (fluid_audio_drivers[i].name == driver->name) {
fluid_audio_drivers_template[i].free(driver); fluid_audio_drivers[i].free(driver);
return; return;
} }
} }
@ -476,49 +437,46 @@ delete_fluid_audio_driver(fluid_audio_driver_t* driver)
*/ */
int fluid_audio_driver_register(const char** adrivers) int fluid_audio_driver_register(const char** adrivers)
{ {
unsigned int i=0, add=0; unsigned int i;
int res = FLUID_FAILED; uint8_t disable_mask[FLUID_N_ELEMENTS(fluid_adriver_disable_mask)];
if(adrivers == NULL) if (adrivers == NULL) {
{ /* Pass NULL to register all available drivers. */
res = FLUID_OK; FLUID_MEMSET(fluid_adriver_disable_mask, 0, sizeof(fluid_adriver_disable_mask));
goto cleanup;
return FLUID_OK;
} }
else
{
FLUID_MEMSET(fluid_audio_drivers, 0, sizeof(fluid_audio_drivers));
for(i=0; adrivers[i] != NULL; i++)
{
unsigned int j;
/* search the requested audio driver in the template and copy it over if found */
for (j = 0; j < FLUID_N_ELEMENTS(fluid_audio_drivers_template); j++)
{
if (FLUID_STRCMP(adrivers[i], fluid_audio_drivers_template[j].name) == 0)
{
FLUID_MEMCPY(&fluid_audio_drivers[add], &fluid_audio_drivers_template[j], sizeof(fluid_audio_drivers[add]));
add++;
break;
}
}
if(j >= FLUID_N_ELEMENTS(fluid_audio_drivers_template)) FLUID_MEMSET(disable_mask, 0xFF, sizeof(disable_mask));
for(i=0; adrivers[i] != NULL; i++)
{
unsigned int j;
/* search the requested audio driver in the template and copy it over if found */
for (j = 0; j < FLUID_N_ELEMENTS(fluid_audio_drivers); j++)
{
if (FLUID_STRCMP(adrivers[i], fluid_audio_drivers[j].name) == 0)
{ {
/* requested driver not found, failure */ ENABLE_AUDIO_DRIVER(disable_mask, j);
goto cleanup; break;
} }
} }
if(j >= FLUID_N_ELEMENTS(fluid_audio_drivers))
{
/* requested driver not found, failure */
return FLUID_FAILED;
}
} }
if(i >= FLUID_N_ELEMENTS(fluid_audio_drivers_template)) if(i >= FLUID_N_ELEMENTS(fluid_audio_drivers))
{ {
/* user requested more drivers than this build of fluidsynth supports, failure */ /* user requested more drivers than this build of fluidsynth supports, failure */
goto cleanup; return FLUID_FAILED;
} }
res = FLUID_OK; /* Update list of activated drivers */
return res; FLUID_MEMCPY(fluid_adriver_disable_mask, disable_mask, sizeof(disable_mask));
cleanup: return FLUID_OK;
FLUID_MEMCPY(fluid_audio_drivers, fluid_audio_drivers_template, sizeof(fluid_audio_drivers));
return res;
} }