updated fluidsynth to 1.0.9
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -26,10 +26,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FLUIDSYNTH_VERSION "1.0.8"
|
#define FLUIDSYNTH_VERSION "1.0.9"
|
||||||
#define FLUIDSYNTH_VERSION_MAJOR 1
|
#define FLUIDSYNTH_VERSION_MAJOR 1
|
||||||
#define FLUIDSYNTH_VERSION_MINOR 0
|
#define FLUIDSYNTH_VERSION_MINOR 0
|
||||||
#define FLUIDSYNTH_VERSION_MICRO 8
|
#define FLUIDSYNTH_VERSION_MICRO 9
|
||||||
|
|
||||||
|
|
||||||
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
|
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
[:Team:]
|
||||||
|
Current development team
|
||||||
|
|
||||||
|
Josh Green
|
||||||
|
Bernat Arlandis i Mañó
|
||||||
|
Pedro Lopez-Cabanillas
|
||||||
|
|
||||||
|
|
||||||
[:Idea:]
|
[:Idea:]
|
||||||
|
|
||||||
@@ -12,25 +19,24 @@ author. Josh Green is the current maintainer. Below you'll find a
|
|||||||
summary of contributions.
|
summary of contributions.
|
||||||
|
|
||||||
|
|
||||||
* Peter Hanappe. Initiated the project. files: sticked his nose in all
|
* Peter Hanappe. Initiated the project. files: stuck his nose in all
|
||||||
files.
|
files.
|
||||||
|
|
||||||
* Josh Green is the current maintainer and contributed a lot of code
|
* Josh Green is the current maintainer and contributed a lot of code
|
||||||
directly or indirectly through the Swami and Smurf code base.
|
directly or indirectly through the Swami and Smurf code base.
|
||||||
The SoundFont loader is completely based on his code. He also wrote
|
The SoundFont loader is completely based on his code. He also wrote
|
||||||
the alsa sequencer driver. He made many changes and bug fixes,
|
the alsa sequencer driver. He made many changes and bug fixes,
|
||||||
but above all, he's one of the driver forces behind the synthesizer.
|
but above all, he's one of the driving forces behind the synthesizer.
|
||||||
He also created the current FluidSynth graphic logo with Blender
|
He also created the current FluidSynth graphic logo with Blender
|
||||||
(the blue waves with FluidSynth letters partially submerged).
|
(the blue waves with FluidSynth letters partially submerged).
|
||||||
files: iiwu_defsfont.{c,h}, iiwu_alsa{c,h} and others.
|
|
||||||
|
|
||||||
* Markus Nentwig (re-)designed the resonant filter, the chorus, the
|
* Markus Nentwig (re-)designed the resonant filter, the chorus, the
|
||||||
LADSPA subsystem, the MIDI router, optimized for SSE, made many
|
LADSPA subsystem, the MIDI router, optimized for SSE, made many
|
||||||
changes and bug fixes and got the synthesizer to actually work. Most
|
changes and bug fixes and got the synthesizer to actually work. Most
|
||||||
importantly, he used it on stage to make music. files:
|
importantly, he used it on stage to make music.
|
||||||
iiwu_ladspa.{c,h}, iiwu_cmd.{c,h}, iiwu_voice.{c,h}, iiwu_synth.c,
|
|
||||||
iiwu_sse.h, iiwu_dsp_core.h, iiwu_rev.{c,h}, and basically all the
|
* S. Christian Collins did much testing of FluidSynth in regards to
|
||||||
other files.
|
EMU10K1 compatibility and provided many synthesis fixes in that regard.
|
||||||
|
|
||||||
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
|
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
|
||||||
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many
|
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many
|
||||||
@@ -98,7 +104,11 @@ summary of contributions.
|
|||||||
signed integer type). Mozilla NSPR library, www.mozilla.org. file:
|
signed integer type). Mozilla NSPR library, www.mozilla.org. file:
|
||||||
iiwu_phase.h
|
iiwu_phase.h
|
||||||
|
|
||||||
* Growing list of individuals who contributed bug fixes and corrections:
|
* KO Myung-Hun for OS/2 support with Dart audio driver.
|
||||||
|
|
||||||
|
* Growing list of individuals who contributed bug fixes, corrections and minor features:
|
||||||
|
Pedro Lopez-Cabanillas for midi.winmidi.device setting.
|
||||||
|
Nicolas Boulicault for ALSA sequencer midi.portname setting.
|
||||||
Werner Schweer
|
Werner Schweer
|
||||||
Dave Philips
|
Dave Philips
|
||||||
Anthony Green
|
Anthony Green
|
||||||
|
|||||||
@@ -160,11 +160,8 @@
|
|||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#define STDC_HEADERS 1
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
/* Define to use long long type, where appropriate */
|
|
||||||
/* #undef USE_LONGLONG */
|
|
||||||
|
|
||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#define VERSION "1.0.7"
|
#define VERSION "1.0.9"
|
||||||
|
|
||||||
/* Define to do all DSP in single floating point precision */
|
/* Define to do all DSP in single floating point precision */
|
||||||
#define WITH_FLOAT 1
|
#define WITH_FLOAT 1
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ typedef struct _fluid_audriver_definition_t
|
|||||||
} fluid_audriver_definition_t;
|
} fluid_audriver_definition_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if PULSE_SUPPORT
|
||||||
|
fluid_audio_driver_t* new_fluid_pulse_audio_driver(fluid_settings_t* settings,
|
||||||
|
fluid_synth_t* synth);
|
||||||
|
fluid_audio_driver_t* new_fluid_pulse_audio_driver2(fluid_settings_t* settings,
|
||||||
|
fluid_audio_func_t func, void* data);
|
||||||
|
int delete_fluid_pulse_audio_driver(fluid_audio_driver_t* p);
|
||||||
|
void fluid_pulse_audio_driver_settings(fluid_settings_t* settings);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ALSA_SUPPORT
|
#if ALSA_SUPPORT
|
||||||
fluid_audio_driver_t* new_fluid_alsa_audio_driver(fluid_settings_t* settings,
|
fluid_audio_driver_t* new_fluid_alsa_audio_driver(fluid_settings_t* settings,
|
||||||
@@ -74,6 +82,7 @@ void fluid_dsound_audio_driver_settings(fluid_settings_t* settings);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PORTAUDIO_SUPPORT
|
#if PORTAUDIO_SUPPORT
|
||||||
|
void fluid_portaudio_driver_settings (fluid_settings_t *settings);
|
||||||
fluid_audio_driver_t* new_fluid_portaudio_driver(fluid_settings_t* settings,
|
fluid_audio_driver_t* new_fluid_portaudio_driver(fluid_settings_t* settings,
|
||||||
fluid_synth_t* synth);
|
fluid_synth_t* synth);
|
||||||
int delete_fluid_portaudio_driver(fluid_audio_driver_t* p);
|
int delete_fluid_portaudio_driver(fluid_audio_driver_t* p);
|
||||||
@@ -96,6 +105,13 @@ fluid_audio_driver_t* new_fluid_sndmgr_audio_driver2(fluid_settings_t* settings,
|
|||||||
int delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p);
|
int delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DART_SUPPORT
|
||||||
|
fluid_audio_driver_t* new_fluid_dart_audio_driver(fluid_settings_t* settings,
|
||||||
|
fluid_synth_t* synth);
|
||||||
|
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
|
#define AUFILE_SUPPORT 1
|
||||||
#if AUFILE_SUPPORT
|
#if AUFILE_SUPPORT
|
||||||
fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings,
|
fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings,
|
||||||
@@ -104,13 +120,14 @@ int delete_fluid_file_audio_driver(fluid_audio_driver_t* p);
|
|||||||
void fluid_file_audio_driver_settings(fluid_settings_t* settings);
|
void fluid_file_audio_driver_settings(fluid_settings_t* settings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Available audio drivers, listed in order of preference */
|
||||||
fluid_audriver_definition_t fluid_audio_drivers[] = {
|
fluid_audriver_definition_t fluid_audio_drivers[] = {
|
||||||
#if OSS_SUPPORT
|
#if JACK_SUPPORT
|
||||||
{ "oss",
|
{ "jack",
|
||||||
new_fluid_oss_audio_driver,
|
new_fluid_jack_audio_driver,
|
||||||
new_fluid_oss_audio_driver2,
|
new_fluid_jack_audio_driver2,
|
||||||
delete_fluid_oss_audio_driver,
|
delete_fluid_jack_audio_driver,
|
||||||
fluid_oss_audio_driver_settings },
|
fluid_jack_audio_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
#if ALSA_SUPPORT
|
#if ALSA_SUPPORT
|
||||||
{ "alsa",
|
{ "alsa",
|
||||||
@@ -119,6 +136,20 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
|
|||||||
delete_fluid_alsa_audio_driver,
|
delete_fluid_alsa_audio_driver,
|
||||||
fluid_alsa_audio_driver_settings },
|
fluid_alsa_audio_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
|
#if OSS_SUPPORT
|
||||||
|
{ "oss",
|
||||||
|
new_fluid_oss_audio_driver,
|
||||||
|
new_fluid_oss_audio_driver2,
|
||||||
|
delete_fluid_oss_audio_driver,
|
||||||
|
fluid_oss_audio_driver_settings },
|
||||||
|
#endif
|
||||||
|
#if PULSE_SUPPORT
|
||||||
|
{ "pulseaudio",
|
||||||
|
new_fluid_pulse_audio_driver,
|
||||||
|
new_fluid_pulse_audio_driver2,
|
||||||
|
delete_fluid_pulse_audio_driver,
|
||||||
|
fluid_pulse_audio_driver_settings },
|
||||||
|
#endif
|
||||||
#if COREAUDIO_SUPPORT
|
#if COREAUDIO_SUPPORT
|
||||||
{ "coreaudio",
|
{ "coreaudio",
|
||||||
new_fluid_core_audio_driver,
|
new_fluid_core_audio_driver,
|
||||||
@@ -138,7 +169,7 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
|
|||||||
new_fluid_portaudio_driver,
|
new_fluid_portaudio_driver,
|
||||||
NULL,
|
NULL,
|
||||||
delete_fluid_portaudio_driver,
|
delete_fluid_portaudio_driver,
|
||||||
NULL },
|
fluid_portaudio_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
#if SNDMAN_SUPPORT
|
#if SNDMAN_SUPPORT
|
||||||
{ "sndman",
|
{ "sndman",
|
||||||
@@ -147,12 +178,12 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
|
|||||||
delete_fluid_sndmgr_audio_driver,
|
delete_fluid_sndmgr_audio_driver,
|
||||||
NULL },
|
NULL },
|
||||||
#endif
|
#endif
|
||||||
#if JACK_SUPPORT
|
#if DART_SUPPORT
|
||||||
{ "jack",
|
{ "dart",
|
||||||
new_fluid_jack_audio_driver,
|
new_fluid_dart_audio_driver,
|
||||||
new_fluid_jack_audio_driver2,
|
NULL,
|
||||||
delete_fluid_jack_audio_driver,
|
delete_fluid_dart_audio_driver,
|
||||||
fluid_jack_audio_driver_settings },
|
fluid_dart_audio_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
#if AUFILE_SUPPORT
|
#if AUFILE_SUPPORT
|
||||||
{ "file",
|
{ "file",
|
||||||
@@ -191,8 +222,12 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the default driver */
|
/* Set the default driver */
|
||||||
#if ALSA_SUPPORT
|
#if JACK_SUPPORT
|
||||||
|
fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL);
|
||||||
|
#elif ALSA_SUPPORT
|
||||||
fluid_settings_register_str(settings, "audio.driver", "alsa", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "alsa", 0, NULL, NULL);
|
||||||
|
#elif PULSE_SUPPORT
|
||||||
|
fluid_settings_register_str(settings, "audio.driver", "pulseaudio", 0, NULL, NULL);
|
||||||
#elif OSS_SUPPORT
|
#elif OSS_SUPPORT
|
||||||
fluid_settings_register_str(settings, "audio.driver", "oss", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "oss", 0, NULL, NULL);
|
||||||
#elif COREAUDIO_SUPPORT
|
#elif COREAUDIO_SUPPORT
|
||||||
@@ -203,8 +238,8 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||||||
fluid_settings_register_str(settings, "audio.driver", "sndman", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "sndman", 0, NULL, NULL);
|
||||||
#elif PORTAUDIO_SUPPORT
|
#elif PORTAUDIO_SUPPORT
|
||||||
fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL);
|
||||||
#elif JACK_SUPPORT
|
#elif DART_SUPPORT
|
||||||
fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "dart", 0, NULL, NULL);
|
||||||
#elif AUFILE_SUPPORT
|
#elif AUFILE_SUPPORT
|
||||||
fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
@@ -212,6 +247,9 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add all drivers to the list of options */
|
/* Add all drivers to the list of options */
|
||||||
|
#if PULSE_SUPPORT
|
||||||
|
fluid_settings_add_option(settings, "audio.driver", "pulseaudio");
|
||||||
|
#endif
|
||||||
#if ALSA_SUPPORT
|
#if ALSA_SUPPORT
|
||||||
fluid_settings_add_option(settings, "audio.driver", "alsa");
|
fluid_settings_add_option(settings, "audio.driver", "alsa");
|
||||||
#endif
|
#endif
|
||||||
@@ -233,6 +271,9 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||||||
#if JACK_SUPPORT
|
#if JACK_SUPPORT
|
||||||
fluid_settings_add_option(settings, "audio.driver", "jack");
|
fluid_settings_add_option(settings, "audio.driver", "jack");
|
||||||
#endif
|
#endif
|
||||||
|
#if DART_SUPPORT
|
||||||
|
fluid_settings_add_option(settings, "audio.driver", "dart");
|
||||||
|
#endif
|
||||||
#if AUFILE_SUPPORT
|
#if AUFILE_SUPPORT
|
||||||
fluid_settings_add_option(settings, "audio.driver", "file");
|
fluid_settings_add_option(settings, "audio.driver", "file");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ fluid_channel_init(fluid_channel_t* chan)
|
|||||||
chan->interp_method = FLUID_INTERP_DEFAULT;
|
chan->interp_method = FLUID_INTERP_DEFAULT;
|
||||||
chan->tuning = NULL;
|
chan->tuning = NULL;
|
||||||
chan->nrpn_select = 0;
|
chan->nrpn_select = 0;
|
||||||
|
chan->nrpn_active = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -85,16 +86,20 @@ fluid_channel_init_ctrl(fluid_channel_t* chan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Volume / initial attenuation (MSB & LSB) */
|
/* Volume / initial attenuation (MSB & LSB) */
|
||||||
SETCC(chan, 7, 127);
|
SETCC(chan, VOLUME_MSB, 127);
|
||||||
SETCC(chan, 39, 0);
|
SETCC(chan, VOLUME_LSB, 0);
|
||||||
|
|
||||||
/* Pan (MSB & LSB) */
|
/* Pan (MSB & LSB) */
|
||||||
SETCC(chan, 10, 64);
|
SETCC(chan, PAN_MSB, 64);
|
||||||
SETCC(chan, 10, 64);
|
SETCC(chan, PAN_LSB, 0);
|
||||||
|
|
||||||
/* Expression (MSB & LSB) */
|
/* Expression (MSB & LSB) */
|
||||||
SETCC(chan, 11, 127);
|
SETCC(chan, EXPRESSION_MSB, 127);
|
||||||
SETCC(chan, 43, 127);
|
SETCC(chan, EXPRESSION_LSB, 127);
|
||||||
|
|
||||||
|
/* Set RPN controllers to NULL state */
|
||||||
|
SETCC(chan, RPN_LSB, 127);
|
||||||
|
SETCC(chan, RPN_MSB, 127);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -241,18 +246,52 @@ fluid_channel_cc(fluid_channel_t* chan, int num, int value)
|
|||||||
{
|
{
|
||||||
int data = (value << 7) + chan->cc[DATA_ENTRY_LSB];
|
int data = (value << 7) + chan->cc[DATA_ENTRY_LSB];
|
||||||
|
|
||||||
/* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */
|
if (chan->nrpn_active) /* NRPN is active? */
|
||||||
if ((chan->cc[NRPN_MSB] == 120) && (chan->cc[NRPN_LSB] < 100)) {
|
{
|
||||||
float val = fluid_gen_scale_nrpn(chan->nrpn_select, data);
|
/* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */
|
||||||
FLUID_LOG(FLUID_WARN, "%s: %d: Data = %d, value = %f", __FILE__, __LINE__, data, val);
|
if ((chan->cc[NRPN_MSB] == 120) && (chan->cc[NRPN_LSB] < 100))
|
||||||
fluid_synth_set_gen(chan->synth, chan->channum, chan->nrpn_select, val);
|
{
|
||||||
|
if (chan->nrpn_select < GEN_LAST)
|
||||||
|
{
|
||||||
|
float val = fluid_gen_scale_nrpn(chan->nrpn_select, data);
|
||||||
|
fluid_synth_set_gen(chan->synth, chan->channum, chan->nrpn_select, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
chan->nrpn_select = 0; /* Reset to 0 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (chan->cc[RPN_MSB] == 0) /* RPN is active: MSB = 0? */
|
||||||
|
{
|
||||||
|
switch (chan->cc[RPN_LSB])
|
||||||
|
{
|
||||||
|
case RPN_PITCH_BEND_RANGE:
|
||||||
|
fluid_channel_pitch_wheel_sens (chan, value); /* Set bend range in semitones */
|
||||||
|
/* FIXME - Handle LSB? (Fine bend range in cents) */
|
||||||
|
break;
|
||||||
|
case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over 1 semitone (+/- 50 cents, 8192 = center) */
|
||||||
|
fluid_synth_set_gen(chan->synth, chan->channum, GEN_FINETUNE,
|
||||||
|
(data - 8192) / 8192.0 * 50.0);
|
||||||
|
break;
|
||||||
|
case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */
|
||||||
|
fluid_synth_set_gen(chan->synth, chan->channum, GEN_COARSETUNE,
|
||||||
|
value - 64);
|
||||||
|
break;
|
||||||
|
case RPN_TUNING_PROGRAM_CHANGE:
|
||||||
|
break;
|
||||||
|
case RPN_TUNING_BANK_SELECT:
|
||||||
|
break;
|
||||||
|
case RPN_MODULATION_DEPTH_RANGE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NRPN_MSB:
|
case NRPN_MSB:
|
||||||
chan->cc[NRPN_LSB] = 0;
|
chan->cc[NRPN_LSB] = 0;
|
||||||
chan->nrpn_select = 0;
|
chan->nrpn_select = 0;
|
||||||
|
chan->nrpn_active = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NRPN_LSB:
|
case NRPN_LSB:
|
||||||
@@ -266,19 +305,15 @@ fluid_channel_cc(fluid_channel_t* chan, int num, int value)
|
|||||||
chan->nrpn_select += 10000;
|
chan->nrpn_select += 10000;
|
||||||
} else if (value < 100) {
|
} else if (value < 100) {
|
||||||
chan->nrpn_select += value;
|
chan->nrpn_select += value;
|
||||||
FLUID_LOG(FLUID_WARN, "%s: %d: NRPN Select = %d", __FILE__, __LINE__, chan->nrpn_select);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chan->nrpn_active = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RPN_MSB:
|
case RPN_MSB:
|
||||||
break;
|
|
||||||
|
|
||||||
case RPN_LSB:
|
case RPN_LSB:
|
||||||
/* erase any previously received NRPN message */
|
chan->nrpn_active = 0;
|
||||||
chan->cc[NRPN_MSB] = 0;
|
|
||||||
chan->cc[NRPN_LSB] = 0;
|
|
||||||
chan->nrpn_select = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -297,6 +332,17 @@ fluid_channel_get_cc(fluid_channel_t* chan, int num)
|
|||||||
return ((num >= 0) && (num < 128))? chan->cc[num] : 0;
|
return ((num >= 0) && (num < 128))? chan->cc[num] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fluid_channel_pressure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fluid_channel_pressure(fluid_channel_t* chan, int val)
|
||||||
|
{
|
||||||
|
chan->channel_pressure = val;
|
||||||
|
fluid_synth_modulate_voices(chan->synth, chan->channum, 0, FLUID_MOD_CHANNELPRESSURE);
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fluid_channel_pitch_bend
|
* fluid_channel_pitch_bend
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ struct _fluid_channel_t
|
|||||||
|
|
||||||
/* NRPN system */
|
/* NRPN system */
|
||||||
short nrpn_select;
|
short nrpn_select;
|
||||||
|
short nrpn_active; /* 1 if data entry CCs are for NRPN, 0 if RPN */
|
||||||
|
|
||||||
/* The values of the generators, set by NRPN messages, or by
|
/* The values of the generators, set by NRPN messages, or by
|
||||||
* fluid_synth_set_gen(), are cached in the channel so they can be
|
* fluid_synth_set_gen(), are cached in the channel so they can be
|
||||||
@@ -87,6 +88,7 @@ int fluid_channel_set_banknum(fluid_channel_t* chan, unsigned int bank);
|
|||||||
int fluid_channel_set_prognum(fluid_channel_t* chan, int prognum);
|
int fluid_channel_set_prognum(fluid_channel_t* chan, int prognum);
|
||||||
int fluid_channel_get_prognum(fluid_channel_t* chan);
|
int fluid_channel_get_prognum(fluid_channel_t* chan);
|
||||||
int fluid_channel_cc(fluid_channel_t* chan, int ctrl, int val);
|
int fluid_channel_cc(fluid_channel_t* chan, int ctrl, int val);
|
||||||
|
int fluid_channel_pressure(fluid_channel_t* chan, int val);
|
||||||
int fluid_channel_pitch_bend(fluid_channel_t* chan, int val);
|
int fluid_channel_pitch_bend(fluid_channel_t* chan, int val);
|
||||||
int fluid_channel_pitch_wheel_sens(fluid_channel_t* chan, int val);
|
int fluid_channel_pitch_wheel_sens(fluid_channel_t* chan, int val);
|
||||||
int fluid_channel_get_cc(fluid_channel_t* chan, int num);
|
int fluid_channel_get_cc(fluid_channel_t* chan, int num);
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
/* EMU 8k/10k don't follow spec in regards to volume attenuation.
|
/* EMU 8k/10k don't follow spec in regards to volume attenuation.
|
||||||
* This factor is used in the equation pow (10.0, cb / FLUID_ATTEN_POWER_FACTOR).
|
* This factor is used in the equation pow (10.0, cb / FLUID_ATTEN_POWER_FACTOR).
|
||||||
* By the standard this should be -200.0. */
|
* By the standard this should be -200.0. */
|
||||||
#define FLUID_ATTEN_POWER_FACTOR (-531.509)
|
/* 07/11/2008 modified by S. Christian Collins for increased velocity sensitivity. Now it equals the response of EMU10K1 programming.*/
|
||||||
|
#define FLUID_ATTEN_POWER_FACTOR (-200.0) /* was (-531.509)*/
|
||||||
|
|
||||||
void fluid_conversion_config(void);
|
void fluid_conversion_config(void);
|
||||||
|
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan
|
|||||||
* page 69, 'bullet' 3 defines 'identical'. */
|
* page 69, 'bullet' 3 defines 'identical'. */
|
||||||
|
|
||||||
for (i = 0; i < mod_list_count; i++){
|
for (i = 0; i < mod_list_count; i++){
|
||||||
if (fluid_mod_test_identity(mod,mod_list[i])){
|
if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
|
||||||
mod_list[i] = NULL;
|
mod_list[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -768,7 +768,7 @@ fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan
|
|||||||
mod = preset_zone->mod;
|
mod = preset_zone->mod;
|
||||||
while (mod){
|
while (mod){
|
||||||
for (i = 0; i < mod_list_count; i++){
|
for (i = 0; i < mod_list_count; i++){
|
||||||
if (fluid_mod_test_identity(mod,mod_list[i])){
|
if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
|
||||||
mod_list[i] = NULL;
|
mod_list[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,15 @@ int delete_fluid_alsa_seq_driver(fluid_midi_driver_t* p);
|
|||||||
void fluid_alsa_seq_driver_settings(fluid_settings_t* settings);
|
void fluid_alsa_seq_driver_settings(fluid_settings_t* settings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* JACK */
|
||||||
|
#if JACK_SUPPORT
|
||||||
|
void fluid_jack_midi_driver_settings (fluid_settings_t *settings);
|
||||||
|
fluid_midi_driver_t *new_fluid_jack_midi_driver (fluid_settings_t *settings,
|
||||||
|
handle_midi_event_func_t handler,
|
||||||
|
void *data);
|
||||||
|
int delete_fluid_jack_midi_driver(fluid_midi_driver_t *p);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* OSS */
|
/* OSS */
|
||||||
#if OSS_SUPPORT
|
#if OSS_SUPPORT
|
||||||
fluid_midi_driver_t* new_fluid_oss_midi_driver(fluid_settings_t* settings,
|
fluid_midi_driver_t* new_fluid_oss_midi_driver(fluid_settings_t* settings,
|
||||||
@@ -52,6 +61,7 @@ fluid_midi_driver_t* new_fluid_winmidi_driver(fluid_settings_t* settings,
|
|||||||
handle_midi_event_func_t handler,
|
handle_midi_event_func_t handler,
|
||||||
void* event_handler_data);
|
void* event_handler_data);
|
||||||
int delete_fluid_winmidi_driver(fluid_midi_driver_t* p);
|
int delete_fluid_winmidi_driver(fluid_midi_driver_t* p);
|
||||||
|
void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* definitions for the MidiShare driver */
|
/* definitions for the MidiShare driver */
|
||||||
@@ -62,6 +72,14 @@ fluid_midi_driver_t* new_fluid_midishare_midi_driver(fluid_settings_t* settings,
|
|||||||
int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p);
|
int delete_fluid_midishare_midi_driver(fluid_midi_driver_t* p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* definitions for the CoreMidi driver */
|
||||||
|
#if COREMIDI_SUPPORT
|
||||||
|
fluid_midi_driver_t* new_fluid_coremidi_driver(fluid_settings_t* settings,
|
||||||
|
void* event_handler_data,
|
||||||
|
handle_midi_event_func_t handler);
|
||||||
|
int delete_fluid_coremidi_driver(fluid_midi_driver_t* p);
|
||||||
|
void fluid_coremidi_driver_settings(fluid_settings_t* settings);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -78,6 +96,12 @@ struct fluid_mdriver_definition_t {
|
|||||||
|
|
||||||
|
|
||||||
struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
|
struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
|
||||||
|
#if JACK_SUPPORT
|
||||||
|
{ "jack",
|
||||||
|
new_fluid_jack_midi_driver,
|
||||||
|
delete_fluid_jack_midi_driver,
|
||||||
|
fluid_jack_midi_driver_settings },
|
||||||
|
#endif
|
||||||
#if OSS_SUPPORT
|
#if OSS_SUPPORT
|
||||||
{ "oss",
|
{ "oss",
|
||||||
new_fluid_oss_midi_driver,
|
new_fluid_oss_midi_driver,
|
||||||
@@ -98,13 +122,19 @@ struct fluid_mdriver_definition_t fluid_midi_drivers[] = {
|
|||||||
{ "winmidi",
|
{ "winmidi",
|
||||||
new_fluid_winmidi_driver,
|
new_fluid_winmidi_driver,
|
||||||
delete_fluid_winmidi_driver,
|
delete_fluid_winmidi_driver,
|
||||||
NULL },
|
fluid_winmidi_midi_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
#if MIDISHARE_SUPPORT
|
#if MIDISHARE_SUPPORT
|
||||||
{ "midishare",
|
{ "midishare",
|
||||||
new_fluid_midishare_midi_driver,
|
new_fluid_midishare_midi_driver,
|
||||||
delete_fluid_midishare_midi_driver,
|
delete_fluid_midishare_midi_driver,
|
||||||
NULL },
|
NULL },
|
||||||
|
#endif
|
||||||
|
#if COREMIDI_SUPPORT
|
||||||
|
{ "coremidi",
|
||||||
|
new_fluid_coremidi_driver,
|
||||||
|
delete_fluid_coremidi_driver,
|
||||||
|
fluid_coremidi_driver_settings },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
@@ -118,12 +148,16 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
|
|||||||
/* Set the default driver */
|
/* Set the default driver */
|
||||||
#if ALSA_SUPPORT
|
#if ALSA_SUPPORT
|
||||||
fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "midi.driver", "alsa_seq", 0, NULL, NULL);
|
||||||
|
#elif JACK_SUPPORT
|
||||||
|
fluid_settings_register_str(settings, "midi.driver", "jack", 0, NULL, NULL);
|
||||||
#elif OSS_SUPPORT
|
#elif OSS_SUPPORT
|
||||||
fluid_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "midi.driver", "oss", 0, NULL, NULL);
|
||||||
#elif WINMIDI_SUPPORT
|
#elif WINMIDI_SUPPORT
|
||||||
fluid_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "midi.driver", "winmidi", 0, NULL, NULL);
|
||||||
#elif MIDISHARE_SUPPORT
|
#elif MIDISHARE_SUPPORT
|
||||||
fluid_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "midi.driver", "midishare", 0, NULL, NULL);
|
||||||
|
#elif COREMIDI_SUPPORT
|
||||||
|
fluid_settings_register_str(settings, "midi.driver", "coremidi", 0, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
fluid_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "midi.driver", "", 0, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
@@ -133,6 +167,9 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
|
|||||||
fluid_settings_add_option(settings, "midi.driver", "alsa_seq");
|
fluid_settings_add_option(settings, "midi.driver", "alsa_seq");
|
||||||
fluid_settings_add_option(settings, "midi.driver", "alsa_raw");
|
fluid_settings_add_option(settings, "midi.driver", "alsa_raw");
|
||||||
#endif
|
#endif
|
||||||
|
#if JACK_SUPPORT
|
||||||
|
fluid_settings_add_option(settings, "midi.driver", "jack");
|
||||||
|
#endif
|
||||||
#if OSS_SUPPORT
|
#if OSS_SUPPORT
|
||||||
fluid_settings_add_option(settings, "midi.driver", "oss");
|
fluid_settings_add_option(settings, "midi.driver", "oss");
|
||||||
#endif
|
#endif
|
||||||
@@ -142,6 +179,9 @@ void fluid_midi_driver_settings(fluid_settings_t* settings)
|
|||||||
#if MIDISHARE_SUPPORT
|
#if MIDISHARE_SUPPORT
|
||||||
fluid_settings_add_option(settings, "midi.driver", "midishare");
|
fluid_settings_add_option(settings, "midi.driver", "midishare");
|
||||||
#endif
|
#endif
|
||||||
|
#if COREMIDI_SUPPORT
|
||||||
|
fluid_settings_add_option(settings, "midi.driver", "coremidi");
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
|
for (i = 0; fluid_midi_drivers[i].name != NULL; i++) {
|
||||||
if (fluid_midi_drivers[i].settings != NULL) {
|
if (fluid_midi_drivers[i].settings != NULL) {
|
||||||
@@ -168,7 +208,7 @@ fluid_midi_driver_t* new_fluid_midi_driver(fluid_settings_t* settings, handle_mi
|
|||||||
FLUID_LOG(FLUID_DBG, "Using '%s' midi driver", fluid_midi_drivers[i].name);
|
FLUID_LOG(FLUID_DBG, "Using '%s' midi driver", fluid_midi_drivers[i].name);
|
||||||
driver = fluid_midi_drivers[i].new(settings, handler, event_handler_data);
|
driver = fluid_midi_drivers[i].new(settings, handler, event_handler_data);
|
||||||
if (driver) {
|
if (driver) {
|
||||||
driver->name = fluid_midi_drivers[i].name;
|
driver->name = fluid_midi_drivers[i].name;
|
||||||
}
|
}
|
||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int
|
|||||||
return FLUID_FAILED;
|
return FLUID_FAILED;
|
||||||
}
|
}
|
||||||
id[4]='\0';
|
id[4]='\0';
|
||||||
|
mf->dtime = 0;
|
||||||
|
|
||||||
while (!found_track){
|
while (!found_track){
|
||||||
|
|
||||||
@@ -354,7 +355,6 @@ int fluid_midi_file_read_varlen(fluid_midi_file* mf)
|
|||||||
*/
|
*/
|
||||||
int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
|
int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
|
||||||
{
|
{
|
||||||
int dtime;
|
|
||||||
int status;
|
int status;
|
||||||
int type;
|
int type;
|
||||||
int tempo;
|
int tempo;
|
||||||
@@ -371,7 +371,7 @@ int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
|
|||||||
if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
|
if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
|
||||||
return FLUID_FAILED;
|
return FLUID_FAILED;
|
||||||
}
|
}
|
||||||
dtime = mf->varlen;
|
mf->dtime += mf->varlen;
|
||||||
|
|
||||||
/* read the status byte */
|
/* read the status byte */
|
||||||
status = fluid_midi_file_getc(mf);
|
status = fluid_midi_file_getc(mf);
|
||||||
@@ -519,12 +519,13 @@ int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
|
|||||||
result = FLUID_FAILED;
|
result = FLUID_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
evt->dtime = dtime;
|
evt->dtime = mf->dtime;
|
||||||
evt->type = MIDI_SET_TEMPO;
|
evt->type = MIDI_SET_TEMPO;
|
||||||
evt->channel = 0;
|
evt->channel = 0;
|
||||||
evt->param1 = tempo;
|
evt->param1 = tempo;
|
||||||
evt->param2 = 0;
|
evt->param2 = 0;
|
||||||
fluid_track_add_event(track, evt);
|
fluid_track_add_event(track, evt);
|
||||||
|
mf->dtime = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIDI_SMPTE_OFFSET:
|
case MIDI_SMPTE_OFFSET:
|
||||||
@@ -642,12 +643,13 @@ int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
|
|||||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
return FLUID_FAILED;
|
return FLUID_FAILED;
|
||||||
}
|
}
|
||||||
evt->dtime = dtime;
|
evt->dtime = mf->dtime;
|
||||||
evt->type = type;
|
evt->type = type;
|
||||||
evt->channel = channel;
|
evt->channel = channel;
|
||||||
evt->param1 = param1;
|
evt->param1 = param1;
|
||||||
evt->param2 = param2;
|
evt->param2 = param2;
|
||||||
fluid_track_add_event(track, evt);
|
fluid_track_add_event(track, evt);
|
||||||
|
mf->dtime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FLUID_OK;
|
return FLUID_OK;
|
||||||
|
|||||||
@@ -146,6 +146,16 @@ enum fluid_midi_control_change {
|
|||||||
POLY_ON = 0x7F
|
POLY_ON = 0x7F
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* General MIDI RPN event numbers (LSB, MSB = 0) */
|
||||||
|
enum midi_rpn_event {
|
||||||
|
RPN_PITCH_BEND_RANGE = 0x00,
|
||||||
|
RPN_CHANNEL_FINE_TUNE = 0x01,
|
||||||
|
RPN_CHANNEL_COARSE_TUNE = 0x02,
|
||||||
|
RPN_TUNING_PROGRAM_CHANGE = 0x03,
|
||||||
|
RPN_TUNING_BANK_SELECT = 0x04,
|
||||||
|
RPN_MODULATION_DEPTH_RANGE = 0x05
|
||||||
|
};
|
||||||
|
|
||||||
enum midi_meta_event {
|
enum midi_meta_event {
|
||||||
MIDI_COPYRIGHT = 0x02,
|
MIDI_COPYRIGHT = 0x02,
|
||||||
MIDI_TRACK_NAME = 0x03,
|
MIDI_TRACK_NAME = 0x03,
|
||||||
@@ -280,6 +290,7 @@ typedef struct {
|
|||||||
int trackpos;
|
int trackpos;
|
||||||
int eot;
|
int eot;
|
||||||
int varlen;
|
int varlen;
|
||||||
|
int dtime;
|
||||||
} fluid_midi_file;
|
} fluid_midi_file;
|
||||||
|
|
||||||
fluid_midi_file* new_fluid_midi_file(char* filename);
|
fluid_midi_file* new_fluid_midi_file(char* filename);
|
||||||
|
|||||||
@@ -146,12 +146,17 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||||||
(mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
|
(mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
|
||||||
| FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
|
| FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
|
||||||
(mod->dest == GEN_FILTERFC)) {
|
(mod->dest == GEN_FILTERFC)) {
|
||||||
|
// S. Christian Collins' mod, to stop forcing velocity based filtering
|
||||||
|
/*
|
||||||
if (voice->vel < 64){
|
if (voice->vel < 64){
|
||||||
return (fluid_real_t) mod->amount / 2.0;
|
return (fluid_real_t) mod->amount / 2.0;
|
||||||
} else {
|
} else {
|
||||||
return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
|
return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
return 0; // (fluid_real_t) mod->amount / 2.0;
|
||||||
}
|
}
|
||||||
|
// end S. Christian Collins' mod
|
||||||
|
|
||||||
/* get the initial value of the first source */
|
/* get the initial value of the first source */
|
||||||
if (mod->src1 > 0) {
|
if (mod->src1 > 0) {
|
||||||
@@ -198,7 +203,7 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||||||
v1 = -1.0f + 2.0f * v1 / range1;
|
v1 = -1.0f + 2.0f * v1 / range1;
|
||||||
break;
|
break;
|
||||||
case 3: /* linear, bipolar, negative */
|
case 3: /* linear, bipolar, negative */
|
||||||
v1 = -1.0f + 2.0f * v1 / range1;
|
v1 = 1.0f - 2.0f * v1 / range1;
|
||||||
break;
|
break;
|
||||||
case 4: /* concave, unipolar, positive */
|
case 4: /* concave, unipolar, positive */
|
||||||
v1 = fluid_concave(v1);
|
v1 = fluid_concave(v1);
|
||||||
@@ -219,7 +224,7 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||||||
v1 = fluid_convex(127 - v1);
|
v1 = fluid_convex(127 - v1);
|
||||||
break;
|
break;
|
||||||
case 10: /* convex, bipolar, positive */
|
case 10: /* convex, bipolar, positive */
|
||||||
v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
|
v1 = (v1 > 64)? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1));
|
||||||
break;
|
break;
|
||||||
case 11: /* convex, bipolar, negative */
|
case 11: /* convex, bipolar, negative */
|
||||||
v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
|
v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void fluid_synth_settings(fluid_settings_t* settings)
|
|||||||
fluid_settings_register_str(settings, "synth.reverb.active", "yes", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "synth.reverb.active", "yes", 0, NULL, NULL);
|
||||||
fluid_settings_register_str(settings, "synth.chorus.active", "yes", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "synth.chorus.active", "yes", 0, NULL, NULL);
|
||||||
fluid_settings_register_str(settings, "synth.ladspa.active", "no", 0, NULL, NULL);
|
fluid_settings_register_str(settings, "synth.ladspa.active", "no", 0, NULL, NULL);
|
||||||
|
fluid_settings_register_str(settings, "midi.portname", "", 0, NULL, NULL);
|
||||||
|
|
||||||
fluid_settings_register_int(settings, "synth.polyphony",
|
fluid_settings_register_int(settings, "synth.polyphony",
|
||||||
256, 16, 4096, 0, NULL, NULL);
|
256, 16, 4096, 0, NULL, NULL);
|
||||||
@@ -996,8 +997,48 @@ fluid_synth_modulate_voices_all(fluid_synth_t* synth, int chan)
|
|||||||
return FLUID_OK;
|
return FLUID_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* fluid_synth_pitch_bend
|
* Set the MIDI channel pressure controller value.
|
||||||
|
* @param synth FluidSynth instance
|
||||||
|
* @param chan MIDI channel number
|
||||||
|
* @param val MIDI channel pressure value (7 bit, 0-127)
|
||||||
|
* @return FLUID_OK on success
|
||||||
|
*
|
||||||
|
* Assign to the MIDI channel pressure controller value on a specific MIDI channel
|
||||||
|
* in real time.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
|
||||||
|
/* fluid_mutex_unlock(synth->busy); */
|
||||||
|
|
||||||
|
/* check the ranges of the arguments */
|
||||||
|
if ((chan < 0) || (chan >= synth->midi_channels)) {
|
||||||
|
FLUID_LOG(FLUID_WARN, "Channel out of range");
|
||||||
|
return FLUID_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (synth->verbose) {
|
||||||
|
FLUID_LOG(FLUID_INFO, "channelpressure\t%d\t%d", chan, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the channel pressure value in the channel */
|
||||||
|
fluid_channel_pressure(synth->channel[chan], val);
|
||||||
|
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the MIDI pitch bend controller value.
|
||||||
|
* @param synth FluidSynth instance
|
||||||
|
* @param chan MIDI channel number
|
||||||
|
* @param val MIDI pitch bend value (14 bit, 0-16383 with 8192 being center)
|
||||||
|
* @return FLUID_OK on success
|
||||||
|
*
|
||||||
|
* Assign to the MIDI pitch bend controller value on a specific MIDI channel
|
||||||
|
* in real time.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val)
|
fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val)
|
||||||
@@ -1169,48 +1210,72 @@ fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum)
|
|||||||
fluid_channel_t* channel;
|
fluid_channel_t* channel;
|
||||||
unsigned int banknum;
|
unsigned int banknum;
|
||||||
unsigned int sfont_id;
|
unsigned int sfont_id;
|
||||||
|
int subst_bank, subst_prog;
|
||||||
|
|
||||||
/* fluid_mutex_lock(synth->busy); /\* Don't interfere with the audio thread *\/ */
|
if ((prognum < 0) || (prognum >= FLUID_NUM_PROGRAMS) ||
|
||||||
/* fluid_mutex_unlock(synth->busy); */
|
(chan < 0) || (chan >= synth->midi_channels))
|
||||||
|
{
|
||||||
if ((prognum >= 0) && (prognum < FLUID_NUM_PROGRAMS) &&
|
FLUID_LOG(FLUID_ERR, "Index out of range (chan=%d, prog=%d)", chan, prognum);
|
||||||
(chan >= 0) && (chan < synth->midi_channels)) {
|
return FLUID_FAILED;
|
||||||
|
|
||||||
channel = synth->channel[chan];
|
|
||||||
banknum = fluid_channel_get_banknum(channel);
|
|
||||||
|
|
||||||
/* inform the channel of the new program number */
|
|
||||||
fluid_channel_set_prognum(channel, prognum);
|
|
||||||
|
|
||||||
if (synth->verbose) {
|
|
||||||
FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* special handling of channel 10 (or 9 counting from 0). channel
|
|
||||||
10 is the percussion channel. */
|
|
||||||
if (channel->channum == 9) {
|
|
||||||
|
|
||||||
/* try to search the drum instrument first */
|
|
||||||
preset = fluid_synth_find_preset(synth, banknum | DRUM_INST_MASK, prognum);
|
|
||||||
|
|
||||||
/* if that fails try to search the melodic instrument */
|
|
||||||
if (preset == NULL) {
|
|
||||||
preset = fluid_synth_find_preset(synth, banknum, prognum);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
preset = fluid_synth_find_preset(synth, banknum, prognum);
|
|
||||||
}
|
|
||||||
|
|
||||||
sfont_id = preset? fluid_sfont_get_id(preset->sfont) : 0;
|
|
||||||
fluid_channel_set_sfontnum(channel, sfont_id);
|
|
||||||
fluid_channel_set_preset(channel, preset);
|
|
||||||
|
|
||||||
return FLUID_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FLUID_LOG(FLUID_ERR, "Index out of range (chan=%d, prog=%d)", chan, prognum);
|
channel = synth->channel[chan];
|
||||||
return FLUID_FAILED;
|
banknum = fluid_channel_get_banknum(channel);
|
||||||
|
|
||||||
|
/* inform the channel of the new program number */
|
||||||
|
fluid_channel_set_prognum(channel, prognum);
|
||||||
|
|
||||||
|
if (synth->verbose)
|
||||||
|
FLUID_LOG(FLUID_INFO, "prog\t%d\t%d\t%d", chan, banknum, prognum);
|
||||||
|
|
||||||
|
/* Special handling of channel 10 (or 9 counting from 0). channel
|
||||||
|
* 10 is the percussion channel.
|
||||||
|
*
|
||||||
|
* FIXME - Shouldn't hard code bank selection for channel 10. I think this
|
||||||
|
* is a hack for MIDI files that do bank changes in GM mode. Proper way to
|
||||||
|
* handle this would probably be to ignore bank changes when in GM mode.
|
||||||
|
*/
|
||||||
|
if (channel->channum == 9)
|
||||||
|
preset = fluid_synth_find_preset(synth, DRUM_INST_BANK, prognum);
|
||||||
|
else preset = fluid_synth_find_preset(synth, banknum, prognum);
|
||||||
|
|
||||||
|
/* Fallback to another preset if not found */
|
||||||
|
if (!preset)
|
||||||
|
{
|
||||||
|
subst_bank = banknum;
|
||||||
|
subst_prog = prognum;
|
||||||
|
|
||||||
|
/* Melodic instrument? */
|
||||||
|
if (channel->channum != 9 && banknum != DRUM_INST_BANK)
|
||||||
|
{
|
||||||
|
subst_bank = 0;
|
||||||
|
|
||||||
|
/* Fallback first to bank 0:prognum */
|
||||||
|
preset = fluid_synth_find_preset(synth, 0, prognum);
|
||||||
|
|
||||||
|
/* Fallback to first preset in bank 0 */
|
||||||
|
if (!preset && prognum != 0)
|
||||||
|
{
|
||||||
|
preset = fluid_synth_find_preset(synth, 0, 0);
|
||||||
|
subst_prog = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Percussion: Fallback to preset 0 in percussion bank */
|
||||||
|
{
|
||||||
|
preset = fluid_synth_find_preset(synth, DRUM_INST_BANK, 0);
|
||||||
|
subst_prog = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preset)
|
||||||
|
FLUID_LOG(FLUID_WARN, "Instrument not found on channel %d [bank=%d prog=%d], substituted [bank=%d prog=%d]",
|
||||||
|
chan, banknum, prognum, subst_bank, subst_prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
sfont_id = preset? fluid_sfont_get_id(preset->sfont) : 0;
|
||||||
|
fluid_channel_set_sfontnum(channel, sfont_id);
|
||||||
|
fluid_channel_set_preset(channel, preset);
|
||||||
|
|
||||||
|
return FLUID_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1562,13 +1627,11 @@ void fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level,
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
||||||
float** left, float** right,
|
float** left, float** right,
|
||||||
float** fx_left, float** fx_right)
|
float** fx_left, float** fx_right)
|
||||||
{
|
{
|
||||||
fluid_real_t** left_in = synth->left_buf;
|
fluid_real_t** left_in = synth->left_buf;
|
||||||
fluid_real_t** right_in = synth->right_buf;
|
fluid_real_t** right_in = synth->right_buf;
|
||||||
fluid_real_t** fx_left_in = synth->fx_left_buf;
|
|
||||||
fluid_real_t** fx_right_in = synth->fx_right_buf;
|
|
||||||
double time = fluid_utime();
|
double time = fluid_utime();
|
||||||
int i, num, available, count, bytes;
|
int i, num, available, count, bytes;
|
||||||
|
|
||||||
@@ -1590,10 +1653,6 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||||||
FLUID_MEMCPY(left[i], left_in[i] + synth->cur, bytes);
|
FLUID_MEMCPY(left[i], left_in[i] + synth->cur, bytes);
|
||||||
FLUID_MEMCPY(right[i], right_in[i] + synth->cur, bytes);
|
FLUID_MEMCPY(right[i], right_in[i] + synth->cur, bytes);
|
||||||
}
|
}
|
||||||
for (i = 0; i < synth->effects_channels; i++) {
|
|
||||||
FLUID_MEMCPY(fx_left[i], fx_left_in[i] + synth->cur, bytes);
|
|
||||||
FLUID_MEMCPY(fx_right[i], fx_right_in[i] + synth->cur, bytes);
|
|
||||||
}
|
|
||||||
count += num;
|
count += num;
|
||||||
num += synth->cur; /* if we're now done, num becomes the new synth->cur below */
|
num += synth->cur; /* if we're now done, num becomes the new synth->cur below */
|
||||||
}
|
}
|
||||||
@@ -1609,10 +1668,6 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||||||
FLUID_MEMCPY(left[i] + count, left_in[i], bytes);
|
FLUID_MEMCPY(left[i] + count, left_in[i], bytes);
|
||||||
FLUID_MEMCPY(right[i] + count, right_in[i], bytes);
|
FLUID_MEMCPY(right[i] + count, right_in[i], bytes);
|
||||||
}
|
}
|
||||||
for (i = 0; i < synth->effects_channels; i++) {
|
|
||||||
FLUID_MEMCPY(fx_left[i] + count, fx_left_in[i], bytes);
|
|
||||||
FLUID_MEMCPY(fx_right[i] + count, fx_right_in[i], bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
count += num;
|
count += num;
|
||||||
}
|
}
|
||||||
@@ -1628,11 +1683,28 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int fluid_synth_process(fluid_synth_t* synth, int len,
|
int fluid_synth_process(fluid_synth_t* synth, int len,
|
||||||
int nin, float** in,
|
int nin, float** in,
|
||||||
int nout, float** out)
|
int nout, float** out)
|
||||||
{
|
{
|
||||||
return fluid_synth_write_float(synth, len, out[0], 0, 1, out[1], 0, 1);
|
if (nout==2) {
|
||||||
|
return fluid_synth_write_float(synth, len, out[0], 0, 1, out[1], 0, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float **left, **right;
|
||||||
|
int i;
|
||||||
|
left = FLUID_ARRAY(float*, nout/2);
|
||||||
|
right = FLUID_ARRAY(float*, nout/2);
|
||||||
|
for(i=0; i<nout/2; i++) {
|
||||||
|
left[i] = out[2*i];
|
||||||
|
right[i] = out[2*i+1];
|
||||||
|
}
|
||||||
|
fluid_synth_nwrite_float(synth, len, left, right, NULL, NULL);
|
||||||
|
FLUID_FREE(left);
|
||||||
|
FLUID_FREE(right);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3028,6 +3100,9 @@ int fluid_synth_handle_midi_event(void* data, fluid_midi_event_t* event)
|
|||||||
case PROGRAM_CHANGE:
|
case PROGRAM_CHANGE:
|
||||||
return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event));
|
return fluid_synth_program_change(synth, chan, fluid_midi_event_get_program(event));
|
||||||
|
|
||||||
|
case CHANNEL_PRESSURE:
|
||||||
|
return fluid_synth_channel_pressure(synth, chan, fluid_midi_event_get_program(event));
|
||||||
|
|
||||||
case PITCH_BEND:
|
case PITCH_BEND:
|
||||||
return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));
|
return fluid_synth_pitch_bend(synth, chan, fluid_midi_event_get_pitch(event));
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@
|
|||||||
*
|
*
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*/
|
*/
|
||||||
#define FLUID_NUM_PROGRAMS 129
|
#define FLUID_NUM_PROGRAMS 128
|
||||||
#define DRUM_INST_MASK ((unsigned int)0x80000000)
|
#define DRUM_INST_BANK 128
|
||||||
|
|
||||||
#if defined(WITH_FLOAT)
|
#if defined(WITH_FLOAT)
|
||||||
#define FLUID_SAMPLE_FORMAT FLUID_SAMPLE_FLOAT
|
#define FLUID_SAMPLE_FORMAT FLUID_SAMPLE_FLOAT
|
||||||
|
|||||||
@@ -635,6 +635,185 @@ unsigned int fluid_curtime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
/*=============================================================*/
|
||||||
|
/* */
|
||||||
|
/* OS2 */
|
||||||
|
/* */
|
||||||
|
/*=============================================================*/
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Timer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _fluid_timer_t
|
||||||
|
{
|
||||||
|
long msec;
|
||||||
|
fluid_timer_callback_t callback;
|
||||||
|
void* data;
|
||||||
|
int thread_id;
|
||||||
|
int cont;
|
||||||
|
int auto_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int fluid_timer_count = 0;
|
||||||
|
void fluid_timer_run(void *data);
|
||||||
|
|
||||||
|
fluid_timer_t*
|
||||||
|
new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
|
||||||
|
int new_thread, int auto_destroy)
|
||||||
|
{
|
||||||
|
fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
|
||||||
|
if (timer == NULL) {
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer->cont = 1;
|
||||||
|
timer->msec = msec;
|
||||||
|
timer->callback = callback;
|
||||||
|
timer->data = data;
|
||||||
|
timer->thread_id =-1;
|
||||||
|
timer->auto_destroy = auto_destroy;
|
||||||
|
|
||||||
|
if (new_thread) {
|
||||||
|
timer->thread_id = _beginthread( fluid_timer_run, NULL, 256 * 1024, ( void * )timer );
|
||||||
|
if (timer->thread_id == -1) {
|
||||||
|
FLUID_LOG(FLUID_ERR, "Couldn't create timer thread");
|
||||||
|
FLUID_FREE(timer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, timer->thread_id);
|
||||||
|
} else {
|
||||||
|
fluid_timer_run(( void * )timer);
|
||||||
|
}
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fluid_timer_run(void *data)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int cont = 1;
|
||||||
|
long start;
|
||||||
|
long delay;
|
||||||
|
fluid_timer_t* timer;
|
||||||
|
timer = (fluid_timer_t*) data;
|
||||||
|
|
||||||
|
if ((timer == NULL) || (timer->callback == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 );
|
||||||
|
|
||||||
|
/* keep track of the start time for absolute positioning */
|
||||||
|
start = fluid_curtime();
|
||||||
|
|
||||||
|
while (cont) {
|
||||||
|
|
||||||
|
/* do whatever we have to do */
|
||||||
|
cont = (*timer->callback)(timer->data, fluid_curtime() - start);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* to avoid incremental time errors, I calculate the delay between
|
||||||
|
two callbacks bringing in the "absolute" time (count *
|
||||||
|
timer->msec) */
|
||||||
|
delay = (count * timer->msec) - (fluid_curtime() - start);
|
||||||
|
if (delay > 0) {
|
||||||
|
DosSleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
cont &= timer->cont;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUID_LOG(FLUID_DBG, "Timer thread finished");
|
||||||
|
|
||||||
|
if (timer->auto_destroy) {
|
||||||
|
FLUID_FREE(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
delete_fluid_timer(fluid_timer_t* timer)
|
||||||
|
{
|
||||||
|
timer->cont = 0;
|
||||||
|
fluid_timer_join(timer);
|
||||||
|
FLUID_FREE(timer);
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fluid_timer_join(fluid_timer_t* timer)
|
||||||
|
{
|
||||||
|
ULONG wait_result;
|
||||||
|
if (timer->thread_id == -1) {
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
wait_result = DosWaitThread(&timer->thread_id, DCWW_WAIT);
|
||||||
|
return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Time
|
||||||
|
*/
|
||||||
|
|
||||||
|
double rdtsc(void);
|
||||||
|
double fluid_estimate_cpu_frequency(void);
|
||||||
|
|
||||||
|
static double fluid_cpu_frequency = -1.0;
|
||||||
|
|
||||||
|
void fluid_time_config(void)
|
||||||
|
{
|
||||||
|
if (fluid_cpu_frequency < 0.0) {
|
||||||
|
fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int fluid_curtime(void)
|
||||||
|
{
|
||||||
|
ULONG ulMS;
|
||||||
|
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulMS, sizeof( ULONG ));
|
||||||
|
return ulMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
double fluid_utime(void)
|
||||||
|
{
|
||||||
|
return (rdtsc() / fluid_cpu_frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Q2ULL( q ) (*(unsigned long long *)&q)
|
||||||
|
|
||||||
|
double rdtsc(void)
|
||||||
|
{
|
||||||
|
QWORD t;
|
||||||
|
DosTmrQueryTime(&t);
|
||||||
|
return (double)Q2ULL(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
double fluid_estimate_cpu_frequency(void)
|
||||||
|
{
|
||||||
|
unsigned int before, after;
|
||||||
|
QWORD start, stop;
|
||||||
|
|
||||||
|
before = fluid_curtime();
|
||||||
|
DosTmrQueryTime(&start);
|
||||||
|
|
||||||
|
DosSleep(1000);
|
||||||
|
|
||||||
|
after = fluid_curtime();
|
||||||
|
DosTmrQueryTime(&stop);
|
||||||
|
|
||||||
|
return (double) 1000 * (Q2ULL(stop) - Q2ULL(start)) / (after - before);
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(__BEOS__) || defined(__HAIKU__)
|
#elif defined(__BEOS__) || defined(__HAIKU__)
|
||||||
|
|
||||||
struct _fluid_timer_t
|
struct _fluid_timer_t
|
||||||
@@ -1153,6 +1332,75 @@ int fluid_thread_join(fluid_thread_t* thread)
|
|||||||
return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
|
return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
|
||||||
|
struct _fluid_thread_t {
|
||||||
|
int thread_id;
|
||||||
|
fluid_thread_func_t func;
|
||||||
|
void* data;
|
||||||
|
int detached;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void fluid_thread_start(void *data)
|
||||||
|
{
|
||||||
|
fluid_thread_t* thread = (fluid_thread_t*) data;
|
||||||
|
|
||||||
|
thread->func(thread->data);
|
||||||
|
|
||||||
|
if (thread->detached) {
|
||||||
|
FLUID_FREE(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
|
||||||
|
{
|
||||||
|
fluid_thread_t* thread;
|
||||||
|
|
||||||
|
if (func == NULL) {
|
||||||
|
FLUID_LOG(FLUID_ERR, "Invalid thread function");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread = FLUID_NEW(fluid_thread_t);
|
||||||
|
if (thread == NULL) {
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread->data = data;
|
||||||
|
thread->func = func;
|
||||||
|
thread->detached = detach;
|
||||||
|
|
||||||
|
thread->thread_id = _beginthread(fluid_thread_start, NULL, 256 * 1024, (void *) thread);
|
||||||
|
if (thread->thread_id == -1) {
|
||||||
|
FLUID_LOG(FLUID_ERR, "Couldn't create the thread");
|
||||||
|
FLUID_FREE(thread);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delete_fluid_thread(fluid_thread_t* thread)
|
||||||
|
{
|
||||||
|
FLUID_FREE(thread);
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int fluid_thread_join(fluid_thread_t* thread)
|
||||||
|
{
|
||||||
|
ULONG wait_result;
|
||||||
|
if (thread->thread_id == -1) {
|
||||||
|
return FLUID_OK;
|
||||||
|
}
|
||||||
|
wait_result = DosWaitThread(&thread->thread_id, DCWW_WAIT);
|
||||||
|
return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(__BEOS__) || defined(__HAIKU__)
|
#elif defined(__BEOS__) || defined(__HAIKU__)
|
||||||
/* Not implemented */
|
/* Not implemented */
|
||||||
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; }
|
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach) { return NULL; }
|
||||||
|
|||||||
@@ -90,6 +90,15 @@ double fluid_utime(void);
|
|||||||
unsigned int fluid_curtime();
|
unsigned int fluid_curtime();
|
||||||
#define fluid_utime() 0.0
|
#define fluid_utime() 0.0
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
#define INCL_DOS
|
||||||
|
#include <os2.h>
|
||||||
|
|
||||||
|
typedef int socklen_t;
|
||||||
|
|
||||||
|
unsigned int fluid_curtime(void);
|
||||||
|
double fluid_utime(void);
|
||||||
|
|
||||||
#elif (defined(__BEOS__) || defined(__HAIKU__))
|
#elif (defined(__BEOS__) || defined(__HAIKU__))
|
||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
@@ -143,13 +152,12 @@ typedef HANDLE fluid_mutex_t;
|
|||||||
#define fluid_mutex_lock(_m) WaitForSingleObject(_m, INFINITE)
|
#define fluid_mutex_lock(_m) WaitForSingleObject(_m, INFINITE)
|
||||||
#define fluid_mutex_unlock(_m) ReleaseMutex(_m)
|
#define fluid_mutex_unlock(_m) ReleaseMutex(_m)
|
||||||
|
|
||||||
#else
|
#elif defined(__OS2__)
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
typedef HMTX fluid_mutex_t;
|
||||||
typedef sem_id fluid_mutex_t;
|
#define fluid_mutex_init(_m) { (_m) = 0; DosCreateMutexSem( NULL, &(_m), 0, FALSE ); }
|
||||||
#define fluid_mutex_init(_m) { (_m) = create_sem(1, "fs_sem"); }
|
#define fluid_mutex_destroy(_m) if (_m) { DosCloseMutexSem(_m); }
|
||||||
#define fluid_mutex_destroy(_m) delete_sem(_m);
|
#define fluid_mutex_lock(_m) DosRequestMutexSem(_m, -1L)
|
||||||
#define fluid_mutex_lock(_m) acquire_sem(_m);
|
#define fluid_mutex_unlock(_m) DosReleaseMutexSem(_m)
|
||||||
#define fluid_mutex_unlock(_m) release_sem(_m);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
typedef pthread_mutex_t fluid_mutex_t;
|
typedef pthread_mutex_t fluid_mutex_t;
|
||||||
@@ -158,7 +166,6 @@ typedef pthread_mutex_t fluid_mutex_t;
|
|||||||
#define fluid_mutex_lock(_m) pthread_mutex_lock(&(_m))
|
#define fluid_mutex_lock(_m) pthread_mutex_lock(&(_m))
|
||||||
#define fluid_mutex_unlock(_m) pthread_mutex_unlock(&(_m))
|
#define fluid_mutex_unlock(_m) pthread_mutex_unlock(&(_m))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,7 +290,7 @@ extern fluid_profile_data_t fluid_profile_data[];
|
|||||||
sample data.
|
sample data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if HAVE_SYS_MMAN_H
|
#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__)
|
||||||
#define fluid_mlock(_p,_n) mlock(_p, _n)
|
#define fluid_mlock(_p,_n) mlock(_p, _n)
|
||||||
#define fluid_munlock(_p,_n) munlock(_p,_n)
|
#define fluid_munlock(_p,_n) munlock(_p,_n)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -283,6 +283,10 @@ fluid_voice_write(fluid_voice_t* voice,
|
|||||||
/* skip to the next section of the envelope if necessary */
|
/* skip to the next section of the envelope if necessary */
|
||||||
while (voice->volenv_count >= env_data->count)
|
while (voice->volenv_count >= env_data->count)
|
||||||
{
|
{
|
||||||
|
// If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
|
||||||
|
if (env_data && voice->volenv_section == FLUID_VOICE_ENVDECAY)
|
||||||
|
voice->volenv_val = env_data->min * env_data->coeff;
|
||||||
|
|
||||||
env_data = &voice->volenv_data[++voice->volenv_section];
|
env_data = &voice->volenv_data[++voice->volenv_section];
|
||||||
voice->volenv_count = 0;
|
voice->volenv_count = 0;
|
||||||
}
|
}
|
||||||
@@ -515,7 +519,7 @@ fluid_voice_write(fluid_voice_t* voice,
|
|||||||
* into account for both significant frequency relocation and for
|
* into account for both significant frequency relocation and for
|
||||||
* bandwidth readjustment'. */
|
* bandwidth readjustment'. */
|
||||||
|
|
||||||
fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / 44100.0f));
|
fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / ((float) voice->output_rate)));
|
||||||
fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
|
fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
|
||||||
fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
|
fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
|
||||||
fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin);
|
fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin);
|
||||||
@@ -1031,6 +1035,8 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||||||
fluid_real_t x;
|
fluid_real_t x;
|
||||||
fluid_real_t y;
|
fluid_real_t y;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
// Alternate attenuation scale used by EMU10K1 cards when setting the attenuation at the preset or instrument level within the SoundFont bank.
|
||||||
|
static const float ALT_ATTENUATION_SCALE = 0.4;
|
||||||
|
|
||||||
switch (gen) {
|
switch (gen) {
|
||||||
|
|
||||||
@@ -1042,7 +1048,8 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GEN_ATTENUATION:
|
case GEN_ATTENUATION:
|
||||||
voice->attenuation = _GEN(voice, GEN_ATTENUATION);
|
voice->attenuation = ((fluid_real_t)(voice)->gen[GEN_ATTENUATION].val*ALT_ATTENUATION_SCALE) +
|
||||||
|
(fluid_real_t)(voice)->gen[GEN_ATTENUATION].mod + (fluid_real_t)(voice)->gen[GEN_ATTENUATION].nrpn;
|
||||||
|
|
||||||
/* Range: SF2.01 section 8.1.3 # 48
|
/* Range: SF2.01 section 8.1.3 # 48
|
||||||
* Motivation for range checking:
|
* Motivation for range checking:
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ int main(int argc, char** argv)
|
|||||||
int with_server = 0;
|
int with_server = 0;
|
||||||
int dump = 0;
|
int dump = 0;
|
||||||
int connect_lash = 1;
|
int connect_lash = 1;
|
||||||
char *optchars = "a:C:c:df:G:g:hijK:L:lm:no:R:r:sVvz:";
|
char *optchars = "a:C:c:df:G:g:hijK:L:lm:no:p:R:r:sVvz:";
|
||||||
#ifdef LASH_ENABLED
|
#ifdef LASH_ENABLED
|
||||||
int enabled_lash = 0; /* set to TRUE if lash gets enabled */
|
int enabled_lash = 0; /* set to TRUE if lash gets enabled */
|
||||||
fluid_lash_args_t *lash_args;
|
fluid_lash_args_t *lash_args;
|
||||||
@@ -247,6 +247,7 @@ int main(int argc, char** argv)
|
|||||||
{"no-midi-in", 0, 0, 'n'},
|
{"no-midi-in", 0, 0, 'n'},
|
||||||
{"no-shell", 0, 0, 'i'},
|
{"no-shell", 0, 0, 'i'},
|
||||||
{"option", 1, 0, 'o'},
|
{"option", 1, 0, 'o'},
|
||||||
|
{"portname", 1, 0, 'p'},
|
||||||
{"reverb", 1, 0, 'R'},
|
{"reverb", 1, 0, 'R'},
|
||||||
{"sample-rate", 1, 0, 'r'},
|
{"sample-rate", 1, 0, 'r'},
|
||||||
{"server", 0, 0, 's'},
|
{"server", 0, 0, 's'},
|
||||||
@@ -264,7 +265,7 @@ int main(int argc, char** argv)
|
|||||||
char *optarg;
|
char *optarg;
|
||||||
|
|
||||||
/* Skip non switch arguments (assume they are file names) */
|
/* Skip non switch arguments (assume they are file names) */
|
||||||
if ((argv[i][0] != '-') || (argv[i][1] == '\0')) continue;
|
if ((argv[i][0] != '-') || (argv[i][1] == '\0')) break;
|
||||||
|
|
||||||
c = argv[i][1];
|
c = argv[i][1];
|
||||||
|
|
||||||
@@ -355,6 +356,9 @@ int main(int argc, char** argv)
|
|||||||
case 'o':
|
case 'o':
|
||||||
process_o_cmd_line_option(settings, optarg);
|
process_o_cmd_line_option(settings, optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'p' :
|
||||||
|
fluid_settings_setstr(settings, "midi.portname", optarg);
|
||||||
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) {
|
if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) {
|
||||||
fluid_settings_setstr(settings, "synth.reverb.active", "no");
|
fluid_settings_setstr(settings, "synth.reverb.active", "no");
|
||||||
@@ -688,6 +692,8 @@ print_help()
|
|||||||
" The name of the midi driver to use [oss,alsa,alsa_seq,...]\n");
|
" The name of the midi driver to use [oss,alsa,alsa_seq,...]\n");
|
||||||
printf(" -n, --no-midi-in\n"
|
printf(" -n, --no-midi-in\n"
|
||||||
" Don't create a midi driver to read MIDI input events [default = yes]\n");
|
" Don't create a midi driver to read MIDI input events [default = yes]\n");
|
||||||
|
printf(" -p, --portname=[label]\n"
|
||||||
|
" Set MIDI port name (alsa_seq, coremidi drivers)\n");
|
||||||
printf(" -o\n"
|
printf(" -o\n"
|
||||||
" Define a setting, -o name=value (\"-o help\" to dump current values)\n");
|
" Define a setting, -o name=value (\"-o help\" to dump current values)\n");
|
||||||
printf(" -R, --reverb\n"
|
printf(" -R, --reverb\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user