Removed fluid_file_renderer_get_(type_names/format_names/endian_names) from API, now just using settings subsystem.

Removed explicity enable of AUFILE_SUPPORT in fluid_adriver.c.
Warning about failure to set high priority scheduling, now only printed if actually attempted high priority scheduling.
Removed unused fluid_alsa2.c.
Moved fluid_file_audio_driver_settings() from fluid_aufile.c to fluid_filerenderer.c and renamed to fluid_file_renderer_settings().
Added fluid_file_renderer_find_valid_format() to search for valid audio formats for a given file type (to fix Ogg/Vorbis output).
Added audio.jack.server and midi.jack.server settings.
Now using jack_client_open() instead of deprecated jack_client_new().
Fixed declaration of new_fluid_midishare_midi_driver() in fluid_mdriver.c.
Added support for realtime settings to fluid_oss.c and fluid_pulse.c.
Added call to Pa_Terminate() in fluid_portaudio_driver_settings() to free unused resources (such as Jack connections).
Removed synth.midi-mode and preset note-off ignore code for now, until its properly supported.
Added/improved command line "help" output for -a, -E, -m, -O and -T.
Welcome message and "Rendering audio to file .." message now displayed on fast render (-F).
This commit is contained in:
Josh Green 2009-10-19 05:41:07 +00:00
parent 420ba8198f
commit c7a865ff24
16 changed files with 231 additions and 689 deletions

View File

@ -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
}

View File

@ -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 }
};

View File

@ -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 {

View File

@ -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;
}

View File

@ -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)

View File

@ -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 */
};
/**

View File

@ -26,6 +26,7 @@
#include "fluidsynth_priv.h"
#include "fluid_synth.h"
#include "fluid_sys.h"
#include "fluid_settings.h"
#if LIBSNDFILE_SUPPORT
#include <sndfile.h>
@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -34,9 +34,6 @@
#include <pulse/simple.h>
#include <pulse/error.h>
/* 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 {

View File

@ -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);
}

View File

@ -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);

View File

@ -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) */

View File

@ -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);
}