diff --git a/fluidsynth/include/fluidsynth/audio.h b/fluidsynth/include/fluidsynth/audio.h index c71c9ead..57005a5a 100644 --- a/fluidsynth/include/fluidsynth/audio.h +++ b/fluidsynth/include/fluidsynth/audio.h @@ -69,9 +69,6 @@ FLUIDSYNTH_API void fluid_audio_driver_get_names(char* buf, size_t buflen, const FLUIDSYNTH_API fluid_file_renderer_t *new_fluid_file_renderer(fluid_synth_t* synth); FLUIDSYNTH_API int fluid_file_renderer_process_block(fluid_file_renderer_t* dev); FLUIDSYNTH_API void delete_fluid_file_renderer(fluid_file_renderer_t* dev); -FLUIDSYNTH_API const char **fluid_file_renderer_get_type_names (void); -FLUIDSYNTH_API const char **fluid_file_renderer_get_format_names (void); -FLUIDSYNTH_API const char **fluid_file_renderer_get_endian_names (void); #ifdef __cplusplus } diff --git a/fluidsynth/src/fluid_adriver.c b/fluidsynth/src/fluid_adriver.c index 5e251c65..97120436 100644 --- a/fluidsynth/src/fluid_adriver.c +++ b/fluidsynth/src/fluid_adriver.c @@ -112,12 +112,10 @@ int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p); void fluid_dart_audio_driver_settings(fluid_settings_t* settings); #endif -#define AUFILE_SUPPORT 1 #if AUFILE_SUPPORT fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth); int delete_fluid_file_audio_driver(fluid_audio_driver_t* p); -void fluid_file_audio_driver_settings(fluid_settings_t* settings); #endif /* Available audio drivers, listed in order of preference */ @@ -190,7 +188,7 @@ fluid_audriver_definition_t fluid_audio_drivers[] = { new_fluid_file_audio_driver, NULL, delete_fluid_file_audio_driver, - fluid_file_audio_driver_settings }, + NULL }, #endif { NULL, NULL, NULL, NULL, NULL } }; diff --git a/fluidsynth/src/fluid_alsa.c b/fluidsynth/src/fluid_alsa.c index fea85a86..24c42482 100644 --- a/fluidsynth/src/fluid_alsa.c +++ b/fluidsynth/src/fluid_alsa.c @@ -322,8 +322,8 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings, while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -338,8 +338,8 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings, err = pthread_create(&dev->thread, &attr, fluid_alsa_formats[i].run, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -714,8 +714,8 @@ new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings, while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); sched = SCHED_OTHER; continue; } else { @@ -730,8 +730,8 @@ new_fluid_alsa_rawmidi_driver(fluid_settings_t* settings, err = pthread_create(&dev->thread, &attr, fluid_alsa_midi_run, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); sched = SCHED_OTHER; continue; } else { @@ -1042,8 +1042,8 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings, while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); sched = SCHED_OTHER; continue; } else { @@ -1058,8 +1058,8 @@ new_fluid_alsa_seq_driver(fluid_settings_t* settings, err = pthread_create(&dev->thread, &attr, fluid_alsa_seq_run, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the MIDI input"); sched = SCHED_OTHER; continue; } else { diff --git a/fluidsynth/src/fluid_alsa2.c b/fluidsynth/src/fluid_alsa2.c deleted file mode 100644 index d6d18371..00000000 --- a/fluidsynth/src/fluid_alsa2.c +++ /dev/null @@ -1,367 +0,0 @@ -/* FluidSynth - A Software Synthesizer - * - * Copyright (C) 2003 Peter Hanappe and others. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ - - -typedef struct { - fluid_audio_driver_t driver; - snd_pcm_t *handle; - fluid_audio_func_t callback; - void* data; - pthread_t thread; - int cont; - int period_size; - float* buffers[2]; -} fluid_alsa_audio_driver_t; - -fluid_audio_driver_t* new_fluid_alsa_audio_driver(fluid_settings_t* settings, - fluid_synth_t* synth); - -fluid_audio_driver_t* new_fluid_alsa_audio_driver2(fluid_settings_t* settings, - fluid_audio_func_t func, - void* data) - -void fluid_alsa_audio_driver_settings(fluid_settings_t* settings); -int delete_fluid_alsa_audio_driver(fluid_audio_driver_t* p); -static void* fluid_alsa_audio_run(void* d); - -static int fluid_alsa_audio_set_hwparams(snd_pcm_t *handle, - snd_pcm_hw_params_t *params, - snd_pcm_access_t access); - -static int fluid_alsa_audio_set_swparams(snd_pcm_t *handle, - snd_pcm_sw_params_t *swparams); - -static int fluid_alsa_xrun_recovery(fluid_alsa_audio_driver_t *dev, int err) - - -void -fluid_alsa_audio_driver_settings(fluid_settings_t* settings) -{ - fluid_settings_register_str(settings, "audio.alsa.device", "default", 0, NULL, NULL); -} - -fluid_audio_driver_t* -new_fluid_alsa_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) -{ - return new_fluid_alsa_audio_driver2(settings, - (fluid_audio_func_t) fluid_synth_process, - (void*) synth); -} - - -fluid_audio_driver_t* -new_fluid_alsa_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) -{ - fluid_alsa_audio_driver_t* dev = NULL; - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - char* device; - int i, periods; - double sample_rate; - - dev = FLUID_NEW(fluid_alsa_audio_driver_t); - if (dev == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return NULL; - } - FLUID_MEMSET(dev, 0, sizeof(fluid_alsa_audio_driver_t)); - - dev->callback = func; - dev->data = data; - dev->cont = 1; - - fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); - fluid_settings_getint(settings, "audio.periods", &periods); - fluid_settings_getint(settings, "audio.period-size", &dev->period_size); - - if (!fluid_settings_getstr(settings, "audio.alsa.device", &devname)) { - device = "plughw:0,0"; - } - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - - if ((err = snd_pcm_open(&dev->handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { - FLUID_LOG(FLUID_ERR, "Playback open error: %s", snd_strerror(err)); - goto error_recovery; - } - if ((err = set_hwparams(dev->handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { - FLUID_LOG(FLUID_ERR, "Setting of hwparams failed: %s", snd_strerror(err)); - goto error_recovery; - } - if ((err = set_swparams(dev->handle, swparams)) < 0) { - FLUID_LOG(FLUID_ERR, "Setting of swparams failed: %s", snd_strerror(err)); - goto error_recovery; - } - - for (i = 0; i < 2; i++) { - dev->buffers[i] = FLUID_ARRAY(float, dev->period_size); - if (dev->buffers[i] == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - } - - error_recovery: - - delete_fluid_alsa_audio_driver((fluid_audio_driver_t*) dev); - return NULL; -} - - - -static int set_hwparams(snd_pcm_t *handle, - snd_pcm_hw_params_t *params, - snd_pcm_access_t access, - int channels, - int sample_rate, - snd_pcm_format_t format) -{ - int err, dir; - - /* choose all parameters */ - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - printf("Broken configuration for playback: no configurations available: %s", - snd_strerror(err)); - return err; - } - - /* set the interleaved read/write format */ - err = snd_pcm_hw_params_set_access(handle, params, access); - if (err < 0) { - printf("Access type not available for playback: %s", snd_strerror(err)); - return err; - } - - /* set the sample format */ - err = snd_pcm_hw_params_set_format(handle, params, format); - if (err < 0) { - printf("Sample format not available for playback: %s", snd_strerror(err)); - return err; - } - - /* set the count of channels */ - err = snd_pcm_hw_params_set_channels(handle, params, channels); - if (err < 0) { - printf("Channels count (%i) not available for playbacks: %s", - channels, snd_strerror(err)); - return err; - } - - /* set the stream rate */ - err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0); - if (err < 0) { - printf("Rate %iHz not available for playback: %s", - rate, snd_strerror(err)); - return err; - } - if (err != rate) { - printf("Rate doesn't match (requested %iHz, get %iHz)", rate, err); - return -EINVAL; - } - - /* set the buffer time */ - err = snd_pcm_hw_params_set_buffer_time_near(handle, params, buffer_time, &dir); - if (err < 0) { - printf("Unable to set buffer time %i for playback: %s", - buffer_time, snd_strerror(err)); - return err; - } - buffer_size = snd_pcm_hw_params_get_buffer_size(params); - - /* set the period time */ - err = snd_pcm_hw_params_set_period_time_near(handle, params, period_time, &dir); - if (err < 0) { - printf("Unable to set period time %i for playback: %s", - period_time, snd_strerror(err)); - return err; - } - period_size = snd_pcm_hw_params_get_period_size(params, &dir); - - /* write the parameters to device */ - err = snd_pcm_hw_params(handle, params); - if (err < 0) { - printf("Unable to set hw params for playback: %s", snd_strerror(err)); - return err; - } - return 0; -} - -static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams) -{ - int err; - - /* get the current swparams */ - err = snd_pcm_sw_params_current(handle, swparams); - if (err < 0) { - printf("Unable to determine current swparams for playback: %s", - snd_strerror(err)); - return err; - } - - /* start the transfer when the buffer is full */ - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, buffer_size); - if (err < 0) { - printf("Unable to set start threshold mode for playback: %s", - snd_strerror(err)); - return err; - } - - /* allow the transfer when at least period_size samples can be processed */ - err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size); - if (err < 0) { - printf("Unable to set avail min for playback: %s", snd_strerror(err)); - return err; - } - - /* align all transfers to 1 sample */ - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); - if (err < 0) { - printf("Unable to set transfer align for playback: %s", snd_strerror(err)); - return err; - } - - /* write the parameters to the playback device */ - err = snd_pcm_sw_params(handle, swparams); - if (err < 0) { - printf("Unable to set sw params for playback: %s", snd_strerror(err)); - return err; - } - return 0; -} - - -static void* fluid_alsa_audio_run(void* d) -{ - fluid_alsa_audio_driver_t* dev = (fluid_alsa_audio_driver_t*) d; - double phase = 0; - const snd_pcm_channel_area_t *my_areas; - snd_pcm_uframes_t offset, frames, size; - snd_pcm_sframes_t avail, commitres; - snd_pcm_state_t state; - int err, first = 1; - - while (dev->cont) { - - state = snd_pcm_state(dev->handle); - if (state == SND_PCM_STATE_XRUN) { - err = fluid_alsa_xrun_recovery(dev->handle, -EPIPE); - if (err < 0) { - printf("XRUN recovery failed: %s", snd_strerror(err)); - return err; - } - first = 1; - } else if (state == SND_PCM_STATE_SUSPENDED) { - err = fluid_alsa_xrun_recovery(dev->handle, -ESTRPIPE); - if (err < 0) { - printf("SUSPEND recovery failed: %s", snd_strerror(err)); - return err; - } - } - avail = snd_pcm_avail_update(dev->handle); - if (avail < 0) { - err = fluid_alsa_xrun_recovery(dev->handle, avail); - if (err < 0) { - printf("avail update failed: %s", snd_strerror(err)); - return err; - } - first = 1; - continue; - } - if (avail < period_size) { - if (first) { - first = 0; - err = snd_pcm_start(dev->handle); - if (err < 0) { - printf("Start error: %s", snd_strerror(err)); - exit(EXIT_FAILURE); - } - } else { - err = snd_pcm_wait(dev->handle, -1); - if (err < 0) { - if ((err = fluid_alsa_xrun_recovery(dev->handle, err)) < 0) { - printf("snd_pcm_wait error: %s", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - } - continue; - } - - size = dev->period_size; - - while (size > 0) { - - frames = size; - err = snd_pcm_mmap_begin(dev->handle, &my_areas, &offset, &frames); - if (err < 0) { - if ((err = fluid_alsa_xrun_recovery(dev->handle, err)) < 0) { - printf("MMAP begin avail error: %s", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - - generate_sine(my_areas, offset, frames, &phase); - commitres = snd_pcm_mmap_commit(dev->handle, offset, frames); - - if (commitres < 0 || commitres != frames) { - err = fluid_alsa_xrun_recovery(dev->handle, commitres >= 0 ? -EPIPE : commitres); - if (err < 0) { - printf("MMAP commit error: %s", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - size -= frames; - } - } -} - - -/* fluid_alsa_xrun_recovery - * - * Underrun and suspend recovery - */ -static int fluid_alsa_xrun_recovery(fluid_alsa_audio_driver_t *dev, int err) -{ - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(dev->handle); - if (err < 0) { - printf("Can't recovery from underrun, prepare failed: %s", snd_strerror(err)); - } - return 0; - - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(dev->handle)) == -EAGAIN) { - sleep(1); /* wait until the suspend flag is released */ - } - if (err < 0) { - err = snd_pcm_prepare(dev->handle); - if (err < 0) { - printf("Can't recovery from suspend, prepare failed: %s", snd_strerror(err)); - } - } - return 0; - } - return err; -} diff --git a/fluidsynth/src/fluid_aufile.c b/fluidsynth/src/fluid_aufile.c index 05ba73cc..bcbc2bf0 100644 --- a/fluidsynth/src/fluid_aufile.c +++ b/fluidsynth/src/fluid_aufile.c @@ -52,7 +52,6 @@ fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth); int delete_fluid_file_audio_driver(fluid_audio_driver_t* p); -void fluid_file_audio_driver_settings(fluid_settings_t* settings); static int fluid_file_audio_run_s16(void* d, unsigned int msec); /************************************************************** @@ -61,40 +60,6 @@ static int fluid_file_audio_run_s16(void* d, unsigned int msec); * */ -void fluid_file_audio_driver_settings(fluid_settings_t* settings) -{ -#if LIBSNDFILE_SUPPORT - const char **names, **np; -#endif - -#if LIBSNDFILE_SUPPORT - fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.wav", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.type", "auto", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.endian", "auto", 0, NULL, NULL); - - fluid_settings_add_option (settings, "audio.file.type", "auto"); - - names = fluid_file_renderer_get_type_names (); - for (np = names; *np; np++) - fluid_settings_add_option(settings, "audio.file.type", *np); - - names = fluid_file_renderer_get_format_names (); - for (np = names; *np; np++) - fluid_settings_add_option(settings, "audio.file.format", *np); - - names = fluid_file_renderer_get_endian_names (); - for (np = names; *np; np++) - fluid_settings_add_option(settings, "audio.file.endian", *np); -#else - fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.type", "raw", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL); - fluid_settings_register_str(settings, "audio.file.endian", "cpu", 0, NULL, NULL); -#endif -} - - fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) diff --git a/fluidsynth/src/fluid_event_queue.h b/fluidsynth/src/fluid_event_queue.h index 029abaf3..f05215ec 100644 --- a/fluidsynth/src/fluid_event_queue.h +++ b/fluidsynth/src/fluid_event_queue.h @@ -40,8 +40,7 @@ enum fluid_event_queue_elem FLUID_EVENT_QUEUE_ELEM_FREE_PRESET, /**< Free preset return event. Uses pval field of event value */ FLUID_EVENT_QUEUE_ELEM_SET_TUNING, /**< Set tuning event. Uses set_tuning field of event value */ FLUID_EVENT_QUEUE_ELEM_REPL_TUNING, /**< Replace tuning event. Uses repl_tuning field of event value */ - FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING, /**< Unref tuning return event. Uses unref_tuning field of event value */ - FLUID_EVENT_QUEUE_ELEM_MIDI_MODE /**< Set MIDI mode event. Uses ival field of event value */ + FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING /**< Unref tuning return event. Uses unref_tuning field of event value */ }; /** diff --git a/fluidsynth/src/fluid_filerenderer.c b/fluidsynth/src/fluid_filerenderer.c index a2fee8b8..b5f2bb25 100644 --- a/fluidsynth/src/fluid_filerenderer.c +++ b/fluidsynth/src/fluid_filerenderer.c @@ -26,6 +26,7 @@ #include "fluidsynth_priv.h" #include "fluid_synth.h" #include "fluid_sys.h" +#include "fluid_settings.h" #if LIBSNDFILE_SUPPORT #include @@ -99,6 +100,7 @@ const int endian_ids[] = { static int fluid_file_renderer_parse_options (char *filetype, char *format, char *endian, char *filename, SF_INFO *info); static int fluid_file_renderer_find_file_type (char *extension, int *type); +static int fluid_file_renderer_find_valid_format (SF_INFO *info); #else /* No libsndfile support */ @@ -125,6 +127,61 @@ const char *endian_names[] = { #endif +void +fluid_file_renderer_settings (fluid_settings_t* settings) +{ +#if LIBSNDFILE_SUPPORT + SF_FORMAT_INFO finfo, cmpinfo; + int major_count; + int i, i2; + const char **np; + + fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.wav", 0, NULL, NULL); + fluid_settings_register_str(settings, "audio.file.type", "auto", 0, NULL, NULL); + fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL); + fluid_settings_register_str(settings, "audio.file.endian", "auto", 0, NULL, NULL); + + fluid_settings_add_option (settings, "audio.file.type", "auto"); + + sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)); + + for (i = 0; i < major_count; i++) + { + finfo.format = i; + sf_command (NULL, SFC_GET_FORMAT_MAJOR, &finfo, sizeof (finfo)); + + /* Check for duplicates */ + for (i2 = 0; i2 < i; i2++) + { + cmpinfo.format = i2; + sf_command (NULL, SFC_GET_FORMAT_MAJOR, &cmpinfo, sizeof (cmpinfo)); + + if (FLUID_STRCMP (cmpinfo.extension, finfo.extension) == 0) + break; + } + + if (i2 == i) + fluid_settings_add_option (settings, "audio.file.type", finfo.extension); + } + + for (np = format_names; *np; np++) + fluid_settings_add_option (settings, "audio.file.format", *np); + + for (np = endian_names; *np; np++) + fluid_settings_add_option (settings, "audio.file.endian", *np); + +#else + + fluid_settings_register_str(settings, "audio.file.name", "fluidsynth.raw", 0, NULL, NULL); + fluid_settings_register_str(settings, "audio.file.type", "raw", 0, NULL, NULL); + fluid_settings_add_option (settings "audio.file.type", "raw"); + fluid_settings_register_str(settings, "audio.file.format", "s16", 0, NULL, NULL); + fluid_settings_add_option (settings "audio.file.format", "s16"); + fluid_settings_register_str(settings, "audio.file.endian", "cpu", 0, NULL, NULL); + fluid_settings_add_option (settings "audio.file.endian", "cpu"); +#endif +} + /** * Create a new file renderer and open the file. * @param synth The synth that creates audio data. @@ -209,7 +266,13 @@ new_fluid_file_renderer(fluid_synth_t* synth) info.samplerate = samplerate + 0.5; info.channels = 2; - if (!sf_format_check (&info)) + /* Search for valid format for given file type, if invalid and no format was specified. + * To handle Ogg/Vorbis and possibly future file types with new formats. + * Checking if format is SF_FORMAT_PCM_16 isn't a fool proof way to check if + * format was specified or not (if user specifies "s16" itself), but should suffice. */ + if (!sf_format_check (&info) + && ((info.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM_16 + || !fluid_file_renderer_find_valid_format (&info))) { FLUID_LOG(FLUID_ERR, "Invalid or unsupported audio file format settings"); goto error_recovery; @@ -319,77 +382,6 @@ fluid_file_renderer_process_block(fluid_file_renderer_t* dev) #endif -#if LIBSNDFILE_SUPPORT -/** - * Get NULL terminated list of supported audio file type names. - * @return NULL terminated list of strings which is internal and should not be - * modified or freed. NOTE: May return NULL if memory allocation fails. - */ -const char ** -fluid_file_renderer_get_type_names (void) -{ - static fluid_mutex_t mutex = FLUID_MUTEX_INIT; - static const char **type_names = NULL; - SF_FORMAT_INFO finfo; - int major_count; - int i, i2, index; - - fluid_mutex_lock (mutex); - - if (!type_names) - { - sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)); - - type_names = FLUID_ARRAY (const char *, major_count + 1); - - if (type_names) - { - for (i = 0, index = 0; i < major_count; i++) - { - finfo.format = i; - sf_command (NULL, SFC_GET_FORMAT_MAJOR, &finfo, sizeof (finfo)); - - /* Check for duplicates */ - for (i2 = 0; i2 < index; i2++) - if (strcmp (type_names[i2], finfo.extension) == 0) - break; - - if (i2 < index) continue; - - type_names[index++] = finfo.extension; /* Add name to array */ - } - - type_names[index] = NULL; - } - else FLUID_LOG (FLUID_ERR, "Out of memory"); - } - - fluid_mutex_unlock (mutex); - - return (const char **)type_names; -} -#else -const char ** -fluid_file_renderer_get_type_names (void) -{ - return type_names; -} -#endif - - -const char ** -fluid_file_renderer_get_format_names (void) -{ - return format_names; -} - -const char ** -fluid_file_renderer_get_endian_names (void) -{ - return endian_names; -} - - #if LIBSNDFILE_SUPPORT /** @@ -508,4 +500,27 @@ fluid_file_renderer_find_file_type (char *extension, int *type) return FALSE; } +/* Search for a valid audio format for a given file type */ +static int +fluid_file_renderer_find_valid_format (SF_INFO *info) +{ + SF_FORMAT_INFO format_info; + int count, i; + + sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)); + + for (i = 0; i < count; i++) + { + format_info.format = i; + + sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &format_info, sizeof (format_info)); + + info->format = (info->format & ~SF_FORMAT_SUBMASK) | format_info.format; + + if (sf_format_check (info)) return TRUE; + } + + return FALSE; +} + #endif diff --git a/fluidsynth/src/fluid_jack.c b/fluidsynth/src/fluid_jack.c index d0e94ed6..b1f25c2f 100644 --- a/fluidsynth/src/fluid_jack.c +++ b/fluidsynth/src/fluid_jack.c @@ -93,6 +93,7 @@ fluid_jack_audio_driver_settings(fluid_settings_t* settings) fluid_settings_add_option(settings, "audio.jack.multi", "no"); fluid_settings_add_option(settings, "audio.jack.multi", "yes"); fluid_settings_register_int(settings, "audio.jack.autoconnect", 0, 0, 1, FLUID_HINT_TOGGLED, NULL, NULL); + fluid_settings_register_str(settings, "audio.jack.server", "", 0, NULL, NULL); } @@ -108,14 +109,14 @@ new_fluid_jack_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) fluid_audio_driver_t* new_fluid_jack_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, void* data) { fluid_jack_audio_driver_t* dev = NULL; - char name[64]; - int i; - /* for looking up ports */ - const char ** jack_ports; + const char ** jack_ports; /* for looking up ports */ char* client_name; int autoconnect = 0; int jack_srate; double sample_rate; + char name[64]; + char *server; + int i; dev = FLUID_NEW(fluid_jack_audio_driver_t); if (dev == NULL) { @@ -141,7 +142,15 @@ new_fluid_jack_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func if (client_name) FLUID_FREE (client_name); /* -- free client name */ - if ((dev->client = jack_client_new(name)) == 0) { + fluid_settings_dupstr (settings, "audio.jack.server", &server); + + if (server && server[0] != '\0') + dev->client = jack_client_open (name, JackServerName, NULL, server); + else dev->client = jack_client_open (name, JackNullOption, NULL); + + if (server) FLUID_FREE (server); + + if (dev->client == NULL) { FLUID_LOG(FLUID_ERR, "Jack server not running?"); goto error_recovery; } @@ -371,6 +380,7 @@ fluid_jack_audio_driver_shutdown(void *arg) void fluid_jack_midi_driver_settings (fluid_settings_t *settings) { fluid_settings_register_str (settings, "midi.jack.id", "fluidsynth-midi", 0, NULL, NULL); + fluid_settings_register_str (settings, "midi.jack.server", "", 0, NULL, NULL); } /* @@ -383,6 +393,7 @@ new_fluid_jack_midi_driver (fluid_settings_t *settings, fluid_jack_midi_driver_t* dev; char *client_name; char name[64]; + char *server; /* not much use doing anything */ if (handler == NULL) @@ -426,9 +437,16 @@ new_fluid_jack_midi_driver (fluid_settings_t *settings, if (client_name) FLUID_FREE (client_name); /* -- free client name */ - if ((dev->client = jack_client_new (name)) == 0) - { - FLUID_LOG (FLUID_ERR, "Jack server not running?"); + fluid_settings_dupstr (settings, "audio.jack.server", &server); + + if (server && server[0] != '\0') + dev->client = jack_client_open (name, JackServerName, NULL, server); + else dev->client = jack_client_open (name, JackNullOption, NULL); + + if (server) FLUID_FREE (server); + + if (dev->client == NULL) { + FLUID_LOG(FLUID_ERR, "Jack server not running?"); goto error_recovery; } diff --git a/fluidsynth/src/fluid_mdriver.c b/fluidsynth/src/fluid_mdriver.c index a3e4d68a..3d6cb78d 100644 --- a/fluidsynth/src/fluid_mdriver.c +++ b/fluidsynth/src/fluid_mdriver.c @@ -67,8 +67,8 @@ void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings); /* definitions for the MidiShare driver */ #if MIDISHARE_SUPPORT fluid_midi_driver_t* new_fluid_midishare_midi_driver(fluid_settings_t* settings, - void* event_handler_data, - handle_midi_event_func_t handler); + handle_midi_event_func_t handler, + void* event_handler_data); int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p); #endif diff --git a/fluidsynth/src/fluid_oss.c b/fluidsynth/src/fluid_oss.c index a64a55d3..c812a757 100644 --- a/fluidsynth/src/fluid_oss.c +++ b/fluidsynth/src/fluid_oss.c @@ -45,9 +45,6 @@ #define BUFFER_LENGTH 512 -/* SCHED_FIFO priorities for OSS threads (see pthread_attr_setschedparam) */ -#define OSS_PCM_SCHED_PRIORITY 90 -#define OSS_MIDI_SCHED_PRIORITY 90 /** fluid_oss_audio_driver_t * @@ -120,8 +117,9 @@ new_fluid_oss_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) int format; pthread_attr_t attr; int err; - int sched = SCHED_FIFO; + int sched; struct sched_param priority; + int realtime_prio = 0; dev = FLUID_NEW(fluid_oss_audio_driver_t); if (dev == NULL) { @@ -133,6 +131,11 @@ new_fluid_oss_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); + fluid_settings_getint (settings, "audio.realtime-prio", &realtime_prio); + + if (fluid_settings_str_equal (settings, "audio.realtime", "yes")) + sched = SCHED_FIFO; + else sched = SCHED_OTHER; dev->dspfd = -1; dev->synth = synth; @@ -240,8 +243,8 @@ new_fluid_oss_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -251,13 +254,13 @@ new_fluid_oss_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) } /* SCHED_FIFO will not be active without setting the priority */ - priority.sched_priority = (sched == SCHED_FIFO) ? OSS_PCM_SCHED_PRIORITY : 0; + priority.sched_priority = (sched == SCHED_FIFO) ? realtime_prio : 0; pthread_attr_setschedparam (&attr, &priority); err = pthread_create(&dev->thread, &attr, fluid_oss_audio_run, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -291,8 +294,9 @@ new_fluid_oss_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, int format; pthread_attr_t attr; int err; - int sched = SCHED_FIFO; + int sched; struct sched_param priority; + int realtime_prio = 0; dev = FLUID_NEW(fluid_oss_audio_driver_t); if (dev == NULL) { @@ -304,6 +308,11 @@ new_fluid_oss_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, fluid_settings_getint(settings, "audio.periods", &periods); fluid_settings_getint(settings, "audio.period-size", &period_size); fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); + fluid_settings_getint (settings, "audio.realtime-prio", &realtime_prio); + + if (fluid_settings_str_equal (settings, "audio.realtime", "yes")) + sched = SCHED_FIFO; + else sched = SCHED_OTHER; dev->dspfd = -1; dev->synth = NULL; @@ -401,8 +410,8 @@ new_fluid_oss_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -412,13 +421,13 @@ new_fluid_oss_audio_driver2(fluid_settings_t* settings, fluid_audio_func_t func, } /* SCHED_FIFO will not be active without setting the priority */ - priority.sched_priority = (sched == SCHED_FIFO) ? OSS_PCM_SCHED_PRIORITY : 0; + priority.sched_priority = (sched == SCHED_FIFO) ? realtime_prio : 0; pthread_attr_setschedparam (&attr, &priority); err = pthread_create(&dev->thread, &attr, fluid_oss_audio_run2, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -599,8 +608,9 @@ new_fluid_oss_midi_driver(fluid_settings_t* settings, int err; fluid_oss_midi_driver_t* dev; pthread_attr_t attr; - int sched = SCHED_FIFO; + int sched; struct sched_param priority; + int realtime_prio; char* device = NULL; /* not much use doing anything */ @@ -641,6 +651,12 @@ new_fluid_oss_midi_driver(fluid_settings_t* settings, } } + fluid_settings_getint (settings, "midi.realtime-prio", &realtime_prio); + + if (fluid_settings_str_equal (settings, "midi.realtime", "yes")) + sched = SCHED_FIFO; + else sched = SCHED_OTHER; + /* open the default hardware device. only use midi in. */ dev->fd = open(device, O_RDONLY, 0); if (dev->fd < 0) { @@ -670,7 +686,7 @@ new_fluid_oss_midi_driver(fluid_settings_t* settings, } /* SCHED_FIFO will not be active without setting the priority */ - priority.sched_priority = (sched == SCHED_FIFO) ? OSS_MIDI_SCHED_PRIORITY : 0; + priority.sched_priority = (sched == SCHED_FIFO) ? realtime_prio : 0; pthread_attr_setschedparam (&attr, &priority); err = pthread_create(&dev->thread, &attr, fluid_oss_midi_run, (void*) dev); diff --git a/fluidsynth/src/fluid_portaudio.c b/fluidsynth/src/fluid_portaudio.c index 0875f380..38237858 100644 --- a/fluidsynth/src/fluid_portaudio.c +++ b/fluidsynth/src/fluid_portaudio.c @@ -97,8 +97,14 @@ fluid_portaudio_driver_settings (fluid_settings_t *settings) deviceInfo = Pa_GetDeviceInfo (i); if ( deviceInfo->maxOutputChannels >= 2 ) fluid_settings_add_option (settings, "audio.portaudio.device", - (char *)(deviceInfo->name)); + deviceInfo->name); } + + /* done with PortAudio for now, may get reopened later */ + err = Pa_Terminate(); + + if (err != paNoError) + printf ("PortAudio termination error: %s\n", Pa_GetErrorText (err) ); } fluid_audio_driver_t * @@ -119,6 +125,16 @@ new_fluid_portaudio_driver (fluid_settings_t *settings, fluid_synth_t *synth) return NULL; } + err = Pa_Initialize (); + + if (err != paNoError) + { + FLUID_LOG (FLUID_ERR, "Error initializing PortAudio driver: %s", + Pa_GetErrorText (err)); + FLUID_FREE (dev); + return NULL; + } + FLUID_MEMSET (dev, 0, sizeof (fluid_portaudio_driver_t)); dev->synth = synth; diff --git a/fluidsynth/src/fluid_pulse.c b/fluidsynth/src/fluid_pulse.c index a2b75a12..742b128b 100644 --- a/fluidsynth/src/fluid_pulse.c +++ b/fluidsynth/src/fluid_pulse.c @@ -34,9 +34,6 @@ #include #include -/* SCHED_FIFO priorities for threads (see pthread_attr_setschedparam) */ -#define PULSE_PCM_SCHED_PRIORITY 90 - /** fluid_pulse_audio_driver_t * * This structure should not be accessed directly. Use audio port @@ -89,8 +86,9 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings, char *server = NULL; char *device = NULL; pthread_attr_t attr; - int sched = SCHED_FIFO; struct sched_param priority; + int realtime_prio; + int sched; int err; dev = FLUID_NEW(fluid_pulse_audio_driver_t); @@ -106,6 +104,11 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings, fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate); fluid_settings_dupstr(settings, "audio.pulseaudio.server", &server); /* ++ alloc server string */ fluid_settings_dupstr(settings, "audio.pulseaudio.device", &device); /* ++ alloc device string */ + fluid_settings_getint (settings, "audio.realtime-prio", &realtime_prio); + + if (fluid_settings_str_equal (settings, "audio.realtime", "yes")) + sched = SCHED_FIFO; + else sched = SCHED_OTHER; if (server && strcmp (server, "default") == 0) { @@ -164,8 +167,8 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings, while (1) { err = pthread_attr_setschedpolicy(&attr, sched); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { @@ -175,14 +178,14 @@ new_fluid_pulse_audio_driver2(fluid_settings_t* settings, } /* SCHED_FIFO will not be active without setting the priority */ - priority.sched_priority = (sched == SCHED_FIFO) ? PULSE_PCM_SCHED_PRIORITY : 0; + priority.sched_priority = (sched == SCHED_FIFO) ? realtime_prio : 0; pthread_attr_setschedparam(&attr, &priority); err = pthread_create(&dev->thread, &attr, func ? fluid_pulse_audio_run2 : fluid_pulse_audio_run, (void*) dev); if (err) { - FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); if (sched == SCHED_FIFO) { + FLUID_LOG(FLUID_WARN, "Couldn't set high priority scheduling for the audio output"); sched = SCHED_OTHER; continue; } else { diff --git a/fluidsynth/src/fluid_settings.c b/fluidsynth/src/fluid_settings.c index 9de405dc..33139a2f 100644 --- a/fluidsynth/src/fluid_settings.c +++ b/fluidsynth/src/fluid_settings.c @@ -28,6 +28,9 @@ #include "fluid_settings.h" #include "fluid_midi.h" +/* Defined in fluid_filerenderer.c */ +extern void fluid_file_renderer_settings (fluid_settings_t* settings); + /* maximum allowed components of a settings variable (separated by '.') */ #define MAX_SETTINGS_TOKENS 8 /* currently only a max of 3 are used */ #define MAX_SETTINGS_LABEL 256 /* max length of a settings variable label */ @@ -293,6 +296,7 @@ fluid_settings_init(fluid_settings_t* settings) fluid_synth_settings(settings); fluid_shell_settings(settings); fluid_player_settings(settings); + fluid_file_renderer_settings(settings); fluid_audio_driver_settings(settings); fluid_midi_driver_settings(settings); } diff --git a/fluidsynth/src/fluid_synth.c b/fluidsynth/src/fluid_synth.c index 0d591c03..47a83c8f 100644 --- a/fluidsynth/src/fluid_synth.c +++ b/fluidsynth/src/fluid_synth.c @@ -61,12 +61,6 @@ static int fluid_synth_cc_real(fluid_synth_t* synth, int channum, int num, int value, int noqueue); static int fluid_synth_update_device_id (fluid_synth_t *synth, char *name, int value); -static int fluid_synth_update_midi_mode (fluid_synth_t *synth, char *name, - char *value); -static int fluid_synth_update_midi_mode_lock (fluid_synth_t *synth, char *name, - char *value); -static void fluid_synth_set_midi_mode_LOCAL (fluid_synth_t *synth, - fluid_synth_midi_mode_t mode); static int fluid_synth_sysex_midi_tuning (fluid_synth_t *synth, char *data, int len, char *response, int *response_len, int avail_response, @@ -245,15 +239,6 @@ void fluid_synth_settings(fluid_settings_t* settings) 0, 0, 126, 0, NULL, NULL); fluid_settings_register_int(settings, "synth.cpu-cores", 1, 1, 256, 0, NULL, NULL); - fluid_settings_register_str(settings, "synth.midi-mode", "normal", 0, NULL, NULL); - fluid_settings_add_option(settings, "synth.midi-mode", "normal"); - fluid_settings_add_option(settings, "synth.midi-mode", "gm"); - fluid_settings_add_option(settings, "synth.midi-mode", "gs"); - - fluid_settings_register_str(settings, "synth.midi-mode-lock", "no", 0, NULL, NULL); - fluid_settings_add_option(settings, "synth.midi-mode-lock", "no"); - fluid_settings_add_option(settings, "synth.midi-mode-lock", "yes"); - fluid_settings_register_int(settings, "synth.min-note-length", 10, 0, 65535, 0, NULL, NULL); } @@ -566,7 +551,6 @@ new_fluid_synth(fluid_settings_t *settings) synth->with_chorus = fluid_settings_str_equal(settings, "synth.chorus.active", "yes"); synth->verbose = fluid_settings_str_equal(settings, "synth.verbose", "yes"); synth->dump = fluid_settings_str_equal(settings, "synth.dump", "yes"); - synth->midi_mode_lock = fluid_settings_str_equal(settings, "synth.midi-mode-lock", "yes"); fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony); fluid_settings_getnum(settings, "synth.sample-rate", &synth->sample_rate); @@ -592,10 +576,6 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_register_int(settings, "synth.device-id", synth->device_id, 126, 0, 0, (fluid_int_update_t) fluid_synth_update_device_id, synth); - fluid_settings_register_str(settings, "synth.midi-mode", "normal", 0, - (fluid_str_update_t) fluid_synth_update_midi_mode, synth); - fluid_settings_register_str(settings, "synth.midi-mode-lock", "no", 0, - (fluid_str_update_t) fluid_synth_update_midi_mode_lock, synth); /* do some basic sanity checking on the settings */ @@ -1378,20 +1358,8 @@ fluid_synth_noteoff_LOCAL(fluid_synth_t* synth, int chan, int key) { fluid_voice_t* voice; int status = FLUID_FAILED; - int midi_mode; int i; - /* We ignore percussion note offs in GM/GS for everything except - * Long Guiro and Long Whistle, as per GM revision 2 spec - JG */ - if (chan == 9) - { - midi_mode = fluid_atomic_int_get (&synth->midi_mode); - - if ((midi_mode == FLUID_SYNTH_MIDI_MODE_GM || midi_mode == FLUID_SYNTH_MIDI_MODE_GS) - && key != 72 && key != 74) - return FLUID_OK; - } - for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; if (_ON(voice) && (voice->chan == chan) && (voice->key == key)) { @@ -1625,60 +1593,6 @@ fluid_synth_update_device_id (fluid_synth_t *synth, char *name, int value) return 0; } -/* Handler for synth.midi-mode setting. */ -static int -fluid_synth_update_midi_mode (fluid_synth_t *synth, char *name, char *value) -{ - int mode = FLUID_SYNTH_MIDI_MODE_NORMAL; - - if (FLUID_STRCMP (value, "gm") == 0) - mode = FLUID_SYNTH_MIDI_MODE_GM; - else if (FLUID_STRCMP (value, "gs") == 0) - mode = FLUID_SYNTH_MIDI_MODE_GS; - - if (fluid_synth_should_queue (synth)) - fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_MIDI_MODE, mode); - else fluid_synth_set_midi_mode_LOCAL (synth, mode); - - return 0; -} - -/* Local synthesis context version of set MIDI mode */ -static void -fluid_synth_set_midi_mode_LOCAL (fluid_synth_t *synth, fluid_synth_midi_mode_t mode) -{ - char *modestr; - - if (synth->verbose) - { - switch (mode) - { - case FLUID_SYNTH_MIDI_MODE_GM: - modestr = "gm"; - break; - case FLUID_SYNTH_MIDI_MODE_GS: - modestr = "gs"; - break; - default: - modestr = "default"; - break; - } - - FLUID_LOG (FLUID_INFO, "midimode\t%s", modestr); - } - - fluid_atomic_int_set (&synth->midi_mode, mode); -} - -/* Handler for synth.midi-mode-lock setting. */ -static int -fluid_synth_update_midi_mode_lock (fluid_synth_t *synth, char *name, char *value) -{ - fluid_atomic_int_set (&synth->midi_mode_lock, - value && FLUID_STRCMP (value, "yes") == 0); - return 0; -} - /** * Process a MIDI SYSEX (system exclusive) message. * @param synth FluidSynth instance @@ -1727,44 +1641,6 @@ fluid_synth_sysex(fluid_synth_t *synth, char *data, int len, && data[2] == MIDI_SYSEX_MIDI_TUNING_ID) return fluid_synth_sysex_midi_tuning (synth, data, len, response, response_len, avail_response, handled, dryrun); - - /* General MIDI message? */ - if (data[0] == MIDI_SYSEX_UNIV_NON_REALTIME - && (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL) - && data[2] == MIDI_SYSEX_GM_ID) - { - switch (data[3]) - { - case MIDI_SYSEX_GM_ON: - if (!fluid_atomic_int_get (&synth->midi_mode_lock)) - fluid_synth_setstr (synth, "synth.midi-mode", "gm"); - - if (handled) *handled = FALSE; - break; - case MIDI_SYSEX_GM_OFF: - if (!fluid_atomic_int_get (&synth->midi_mode_lock)) - fluid_synth_setstr (synth, "synth.midi-mode", "normal"); - - if (handled) *handled = FALSE; - break; - } - - return FLUID_OK; - } - - /* GS reset message? */ - if (len == 9 && data[0] == MIDI_SYSEX_MANUF_ROLAND - && data[1] == 0x10 && data[2] == 0x42 && data[3] == 0x12 && data[4] == 0x40 - && data[5] == 0x00 && data[6] == 0x7F && data[7] == 0x00 && data[8] == 0x41) - { - if (!fluid_atomic_int_get (&synth->midi_mode_lock)) - fluid_synth_setstr (synth, "synth.midi-mode", "gs"); - - if (handled) *handled = FALSE; - - return FLUID_OK; - } - return FLUID_OK; } @@ -3538,9 +3414,6 @@ fluid_synth_process_event_queue_LOCAL (fluid_synth_t *synth, event->repl_tuning.new_tuning, event->repl_tuning.apply, TRUE); break; - case FLUID_EVENT_QUEUE_ELEM_MIDI_MODE: - fluid_synth_set_midi_mode_LOCAL (synth, event->ival); - break; } fluid_event_queue_next_outptr (queue); diff --git a/fluidsynth/src/fluid_synth.h b/fluidsynth/src/fluid_synth.h index 148f415b..7b6dd0ec 100644 --- a/fluidsynth/src/fluid_synth.h +++ b/fluidsynth/src/fluid_synth.h @@ -77,16 +77,6 @@ enum fluid_synth_status #define SYNTH_REVERB_CHANNEL 0 #define SYNTH_CHORUS_CHANNEL 1 -/** - * Defines the current MIDI mode. - */ -typedef enum -{ - FLUID_SYNTH_MIDI_MODE_NORMAL, /**< Normal MIDI mode (percussion channel not special) */ - FLUID_SYNTH_MIDI_MODE_GM, /**< GM MIDI mode, no note-offs on percussion channel (except for long guiro and whistle) */ - FLUID_SYNTH_MIDI_MODE_GS /**< GS MIDI mode, identical to #FLUID_SYNTH_MIDI_MODE_GM at the moment */ -} fluid_synth_midi_mode_t; - /** * Structure used for sfont_info field in #fluid_synth_t for each loaded * SoundFont with the SoundFont instance and additional fields. @@ -142,8 +132,6 @@ typedef struct _fluid_sfont_info_t { * with_reverb * with_chorus * state - * midi_mode - * midi_mode_lock * cpu_load * noteid * storeid @@ -188,8 +176,6 @@ struct _fluid_synth_t int state; /**< the synthesizer state */ unsigned int ticks; /**< the number of audio samples since the start */ unsigned int start; /**< the start in msec, as returned by system clock */ - int midi_mode; /**< Current MIDI mode (#fluid_synth_midi_mode_t) */ - int midi_mode_lock; /**< TRUE if MIDI mode cannot be changed by SYSEX messages */ fluid_list_t *loaders; /**< the SoundFont loaders */ fluid_list_t *sfont_info; /**< List of fluid_sfont_info_t for each loaded SoundFont (remains until SoundFont is unloaded) */ diff --git a/fluidsynth/src/fluidsynth.c b/fluidsynth/src/fluidsynth.c index 4099ceb8..3d6972da 100644 --- a/fluidsynth/src/fluidsynth.c +++ b/fluidsynth/src/fluidsynth.c @@ -208,6 +208,19 @@ settings_foreach_func (void *data, char *name, int type) } } +/* Output options for a setting string to stdout */ +static void +show_settings_str_options (fluid_settings_t *settings, char *name) +{ + OptionBag bag; + + bag.count = fluid_settings_option_count (settings, name); + bag.curindex = 0; + fluid_settings_foreach_option_alpha (settings, name, &bag, + settings_option_foreach_func); + printf ("\n"); +} + static void fast_render_loop(fluid_settings_t* settings, fluid_synth_t* synth, fluid_player_t* player) { @@ -353,7 +366,14 @@ int main(int argc, char** argv) break; #endif case 'a': - fluid_settings_setstr(settings, "audio.driver", optarg); + if (FLUID_STRCMP (optarg, "help") == 0) + { + print_welcome (); + printf ("-a options (audio driver):\n "); + show_settings_str_options (settings, "audio.driver"); + exit (0); + } + else fluid_settings_setstr(settings, "audio.driver", optarg); break; case 'C': if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) { @@ -372,20 +392,15 @@ int main(int argc, char** argv) case 'E': if (FLUID_STRCMP (optarg, "help") == 0) { - const char **names = fluid_file_renderer_get_endian_names (); - const char **sp; - print_welcome (); printf ("-E options (audio file byte order):\n "); - - for (sp = names; *sp; sp++) - printf (" %s", *sp); + show_settings_str_options (settings, "audio.file.endian"); #if LIBSNDFILE_SUPPORT - printf ("\n\nauto: Use audio file format's default endian byte order\n" + printf ("\nauto: Use audio file format's default endian byte order\n" "cpu: Use CPU native byte order\n"); #else - printf ("\n\nNOTE: No libsndfile support!\n" + printf ("\nNOTE: No libsndfile support!\n" "cpu: Use CPU native byte order\n"); #endif exit (0); @@ -425,7 +440,14 @@ int main(int argc, char** argv) connect_lash = 0; break; case 'm': - fluid_settings_setstr(settings, "midi.driver", optarg); + if (FLUID_STRCMP (optarg, "help") == 0) + { + print_welcome (); + printf ("-m options (MIDI driver):\n "); + show_settings_str_options (settings, "midi.driver"); + exit (0); + } + else fluid_settings_setstr(settings, "midi.driver", optarg); break; case 'n': midi_in = 0; @@ -433,19 +455,16 @@ int main(int argc, char** argv) case 'O': if (FLUID_STRCMP (optarg, "help") == 0) { - const char **names = fluid_file_renderer_get_format_names (); - const char **sp; - print_welcome (); - printf ("-O options (file audio format):\n "); - - for (sp = names; *sp; sp++) - printf (" %s", *sp); + printf ("-O options (audio file format):\n "); + show_settings_str_options (settings, "audio.file.format"); #if LIBSNDFILE_SUPPORT - printf ("\n"); + printf ("\ns8, s16, s24, s32: Signed PCM audio of the given number of bits\n"); + printf ("float, double: 32 bit and 64 bit floating point audio\n"); + printf ("u8: Unsigned 8 bit audio\n"); #else - printf ("\n\nNOTE: No libsndfile support!\n"); + printf ("\nNOTE: No libsndfile support!\n"); #endif exit (0); } @@ -473,21 +492,14 @@ int main(int argc, char** argv) case 'T': if (FLUID_STRCMP (optarg, "help") == 0) { - const char **names = fluid_file_renderer_get_type_names (); - const char **sp; - - if (!names) exit (1); /* Can happen if out of memory */ - print_welcome (); printf ("-T options (audio file type):\n "); - - for (sp = names; *sp; sp++) - printf (" %s", *sp); + show_settings_str_options (settings, "audio.file.type"); #if LIBSNDFILE_SUPPORT - printf ("\n\nauto: Determine type from file name extension, defaults to \"wav\"\n"); + printf ("\nauto: Determine type from file name extension, defaults to \"wav\"\n"); #else - printf ("\n\nNOTE: No libsndfile support!\n"); + printf ("\nNOTE: No libsndfile support!\n"); #endif exit (0); } @@ -706,6 +718,13 @@ int main(int argc, char** argv) } if (fast_render) { + char *filename; + + print_welcome (); + fluid_settings_dupstr (settings, "audio.file.name", &filename); + printf ("Rendering audio to file '%s'..\n", filename); + if (filename) FLUID_FREE (filename); + fast_render_loop(settings, synth, player); }