aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-12-17 22:36:25 -0800
committerChris Robinson <[email protected]>2013-12-17 22:36:25 -0800
commitee92b3142d70a50945b4a4aa021f7a846061d28e (patch)
treeae6cb11fe16837a597b9660745fb2815ea99e556
parentef0341c180789aaf95daabc5bc76b02bad174f80 (diff)
Move FluidSynth to its own file
-rw-r--r--Alc/midi/fluidsynth.c359
-rw-r--r--CMakeLists.txt7
-rw-r--r--OpenAL32/Include/alMidi.h2
-rw-r--r--OpenAL32/alMidi.c347
4 files changed, 380 insertions, 335 deletions
diff --git a/Alc/midi/fluidsynth.c b/Alc/midi/fluidsynth.c
new file mode 100644
index 00000000..c2cde00c
--- /dev/null
+++ b/Alc/midi/fluidsynth.c
@@ -0,0 +1,359 @@
+
+#include "config.h"
+
+#ifdef HAVE_FLUIDSYNTH
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <fluidsynth.h>
+
+#include "alMidi.h"
+#include "alMain.h"
+#include "alError.h"
+#include "evtqueue.h"
+#include "rwlock.h"
+#include "alu.h"
+
+
+/* MIDI events */
+#define SYSEX_EVENT (0xF0)
+
+/* MIDI controllers */
+#define CTRL_BANKSELECT_MSB (0)
+#define CTRL_BANKSELECT_LSB (32)
+#define CTRL_ALLNOTESOFF (123)
+
+
+typedef struct FSynth {
+ DERIVE_FROM_TYPE(MidiSynth);
+
+ fluid_settings_t *Settings;
+ fluid_synth_t *Synth;
+ int FontID;
+
+ ALboolean ForceGM2BankSelect;
+} FSynth;
+
+static void FSynth_Construct(FSynth *self, ALCdevice *device);
+static void FSynth_Destruct(FSynth *self);
+static ALboolean FSynth_init(FSynth *self, ALCdevice *device);
+static ALboolean FSynth_isSoundfont(FSynth *self, const char *filename);
+static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename);
+static void FSynth_setGain(FSynth *self, ALfloat gain);
+static void FSynth_setState(FSynth *self, ALenum state);
+static void FSynth_stop(FSynth *self);
+static void FSynth_reset(FSynth *self);
+static void FSynth_update(FSynth *self, ALCdevice *device);
+static void FSynth_processQueue(FSynth *self, ALuint64 time);
+static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]);
+static void FSynth_Delete(FSynth *self);
+DEFINE_MIDISYNTH_VTABLE(FSynth);
+
+
+static void FSynth_Construct(FSynth *self, ALCdevice *device)
+{
+ MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device);
+ SET_VTABLE2(FSynth, MidiSynth, self);
+
+ self->Settings = NULL;
+ self->Synth = NULL;
+ self->FontID = FLUID_FAILED;
+ self->ForceGM2BankSelect = AL_FALSE;
+}
+
+static void FSynth_Destruct(FSynth *self)
+{
+ if(self->FontID != FLUID_FAILED)
+ fluid_synth_sfunload(self->Synth, self->FontID, 0);
+ self->FontID = FLUID_FAILED;
+
+ if(self->Synth != NULL)
+ delete_fluid_synth(self->Synth);
+ self->Synth = NULL;
+
+ if(self->Settings != NULL)
+ delete_fluid_settings(self->Settings);
+ self->Settings = NULL;
+
+ MidiSynth_Destruct(STATIC_CAST(MidiSynth, self));
+}
+
+static ALboolean FSynth_init(FSynth *self, ALCdevice *device)
+{
+ self->Settings = new_fluid_settings();
+ if(!self->Settings)
+ {
+ ERR("Failed to create FluidSettings\n");
+ return AL_FALSE;
+ }
+
+ fluid_settings_setint(self->Settings, "synth.polyphony", 256);
+ fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
+
+ self->Synth = new_fluid_synth(self->Settings);
+ if(!self->Synth)
+ {
+ ERR("Failed to create FluidSynth\n");
+ return AL_FALSE;
+ }
+
+ return AL_TRUE;
+}
+
+
+static ALboolean FSynth_isSoundfont(FSynth *self, const char *filename)
+{
+ filename = MidiSynth_getFontName(STATIC_CAST(MidiSynth, self), filename);
+ if(!filename[0]) return AL_FALSE;
+
+ if(!fluid_is_soundfont(filename))
+ return AL_FALSE;
+ return AL_TRUE;
+}
+
+static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename)
+{
+ int fontid;
+
+ filename = MidiSynth_getFontName(STATIC_CAST(MidiSynth, self), filename);
+ if(!filename[0]) return AL_INVALID_VALUE;
+
+ fontid = fluid_synth_sfload(self->Synth, filename, 1);
+ if(fontid == FLUID_FAILED)
+ {
+ ERR("Failed to load soundfont '%s'\n", filename);
+ return AL_INVALID_VALUE;
+ }
+
+ if(self->FontID != FLUID_FAILED)
+ fluid_synth_sfunload(self->Synth, self->FontID, 1);
+ self->FontID = fontid;
+
+ return AL_NO_ERROR;
+}
+
+
+static void FSynth_setGain(FSynth *self, ALfloat gain)
+{
+ /* Scale gain by an additional 0.2 (-14dB), to help keep the mix from clipping. */
+ fluid_settings_setnum(self->Settings, "synth.gain", 0.2 * gain);
+ fluid_synth_set_gain(self->Synth, 0.2f * gain);
+ MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain);
+}
+
+
+static void FSynth_setState(FSynth *self, ALenum state)
+{
+ if(state == AL_PLAYING && self->FontID == FLUID_FAILED)
+ FSynth_loadSoundfont(self, NULL);
+
+ MidiSynth_setState(STATIC_CAST(MidiSynth, self), state);
+}
+
+static void FSynth_stop(FSynth *self)
+{
+ MidiSynth *synth = STATIC_CAST(MidiSynth, self);
+ ALsizei chan;
+
+ /* Make sure all pending events are processed. */
+ while(!(synth->SamplesToNext >= 1.0))
+ {
+ ALuint64 time = synth->NextEvtTime;
+ if(time == UINT64_MAX)
+ break;
+
+ synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
+ synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
+ synth->LastEvtTime = time;
+ FSynth_processQueue(self, time);
+
+ synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
+ if(synth->NextEvtTime != UINT64_MAX)
+ synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
+ }
+
+ /* All notes off */
+ for(chan = 0;chan < 16;chan++)
+ fluid_synth_cc(self->Synth, chan, CTRL_ALLNOTESOFF, 0);
+
+ MidiSynth_stop(STATIC_CAST(MidiSynth, self));
+}
+
+static void FSynth_reset(FSynth *self)
+{
+ /* Reset to power-up status. */
+ fluid_synth_system_reset(self->Synth);
+
+ MidiSynth_reset(STATIC_CAST(MidiSynth, self));
+}
+
+
+static void FSynth_update(FSynth *self, ALCdevice *device)
+{
+ fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
+ fluid_synth_set_sample_rate(self->Synth, device->Frequency);
+ MidiSynth_update(STATIC_CAST(MidiSynth, self), device);
+}
+
+
+static void FSynth_processQueue(FSynth *self, ALuint64 time)
+{
+ EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue;
+
+ while(queue->pos < queue->size && queue->events[queue->pos].time <= time)
+ {
+ const MidiEvent *evt = &queue->events[queue->pos];
+
+ if(evt->event == SYSEX_EVENT)
+ {
+ static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 };
+ static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 };
+ int handled = 0;
+
+ fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0);
+ if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on))
+ {
+ if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0)
+ self->ForceGM2BankSelect = AL_TRUE;
+ else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0)
+ self->ForceGM2BankSelect = AL_FALSE;
+ }
+ }
+ else switch((evt->event&0xF0))
+ {
+ case AL_NOTEOFF_SOFT:
+ fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]);
+ break;
+ case AL_NOTEON_SOFT:
+ fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
+ break;
+ case AL_AFTERTOUCH_SOFT:
+ break;
+
+ case AL_CONTROLLERCHANGE_SOFT:
+ if(self->ForceGM2BankSelect)
+ {
+ int chan = (evt->event&0x0F);
+ if(evt->param.val[0] == CTRL_BANKSELECT_MSB)
+ {
+ if(evt->param.val[1] == 120 && (chan == 9 || chan == 10))
+ fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM);
+ else if(evt->param.val[1] == 121)
+ fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC);
+ break;
+ }
+ if(evt->param.val[0] == CTRL_BANKSELECT_LSB)
+ {
+ fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]);
+ break;
+ }
+ }
+ fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
+ break;
+ case AL_PROGRAMCHANGE_SOFT:
+ fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]);
+ break;
+
+ case AL_CHANNELPRESSURE_SOFT:
+ fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]);
+ break;
+
+ case AL_PITCHBEND_SOFT:
+ fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) |
+ ((evt->param.val[1]&0x7F)<<7));
+ break;
+ }
+
+ queue->pos++;
+ }
+}
+
+static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE])
+{
+ MidiSynth *synth = STATIC_CAST(MidiSynth, self);
+ ALenum state = synth->State;
+ ALuint total = 0;
+
+ if(state == AL_INITIAL)
+ return;
+ if(state != AL_PLAYING)
+ {
+ fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1,
+ DryBuffer[FrontRight], 0, 1);
+ return;
+ }
+
+ while(total < SamplesToDo)
+ {
+ if(synth->SamplesToNext >= 1.0)
+ {
+ ALuint todo = minu(SamplesToDo - total, fastf2u(synth->SamplesToNext));
+
+ fluid_synth_write_float(self->Synth, todo,
+ &DryBuffer[FrontLeft][total], 0, 1,
+ &DryBuffer[FrontRight][total], 0, 1);
+ total += todo;
+ synth->SamplesSinceLast += todo;
+ synth->SamplesToNext -= todo;
+ }
+ else
+ {
+ ALuint64 time = synth->NextEvtTime;
+ if(time == UINT64_MAX)
+ {
+ synth->SamplesSinceLast += SamplesToDo-total;
+ fluid_synth_write_float(self->Synth, SamplesToDo-total,
+ &DryBuffer[FrontLeft][total], 0, 1,
+ &DryBuffer[FrontRight][total], 0, 1);
+ break;
+ }
+
+ synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
+ synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
+ synth->LastEvtTime = time;
+ FSynth_processQueue(self, time);
+
+ synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
+ if(synth->NextEvtTime != UINT64_MAX)
+ synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
+ }
+ }
+}
+
+
+static void FSynth_Delete(FSynth *self)
+{
+ free(self);
+}
+
+
+MidiSynth *FSynth_create(ALCdevice *device)
+{
+ FSynth *synth = calloc(1, sizeof(*synth));
+ if(!synth)
+ {
+ ERR("Failed to allocate FSynth\n");
+ return NULL;
+ }
+ FSynth_Construct(synth, device);
+
+ if(FSynth_init(synth, device) == AL_FALSE)
+ {
+ DELETE_OBJ(STATIC_CAST(MidiSynth, synth));
+ return NULL;
+ }
+
+ return STATIC_CAST(MidiSynth, synth);
+}
+
+#else
+
+MidiSynth *FSynth_create(ALCdevice* UNUSED(device))
+{
+ return NULL;
+}
+
+#endif \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7fbc095..847e7b84 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -557,7 +557,12 @@ IF(ALSOFT_REQUIRE_NEON AND NOT HAVE_NEON)
ENDIF()
-SET(HAVE_MIDI_SYNTH 0)
+SET(ALC_OBJS ${ALC_OBJS}
+ Alc/midi/fluidsynth.c
+)
+
+SET(HAVE_FLUIDSYNTH 0)
+
# Check for FluidSynth support
IF(ALSOFT_MIDI_FLUIDSYNTH)
FIND_PACKAGE(FluidSynth)
diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h
index cbe06303..2461265d 100644
--- a/OpenAL32/Include/alMidi.h
+++ b/OpenAL32/Include/alMidi.h
@@ -101,6 +101,8 @@ static const struct MidiSynthVtable T##_MidiSynth_vtable = { \
}
+MidiSynth *FSynth_create(ALCdevice *device);
+
MidiSynth *SynthCreate(ALCdevice *device);
#ifdef __cplusplus
diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c
index c288b3c7..dda4c655 100644
--- a/OpenAL32/alMidi.c
+++ b/OpenAL32/alMidi.c
@@ -151,316 +151,6 @@ ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *
}
-#ifdef HAVE_FLUIDSYNTH
-
-#include <fluidsynth.h>
-
-typedef struct FSynth {
- DERIVE_FROM_TYPE(MidiSynth);
-
- fluid_settings_t *Settings;
- fluid_synth_t *Synth;
- int FontID;
-
- ALboolean ForceGM2BankSelect;
-} FSynth;
-
-static void FSynth_Construct(FSynth *self, ALCdevice *device);
-static void FSynth_Destruct(FSynth *self);
-static ALboolean FSynth_init(FSynth *self, ALCdevice *device);
-static ALboolean FSynth_isSoundfont(FSynth *self, const char *filename);
-static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename);
-static void FSynth_setGain(FSynth *self, ALfloat gain);
-static void FSynth_setState(FSynth *self, ALenum state);
-static void FSynth_stop(FSynth *self);
-static void FSynth_reset(FSynth *self);
-static void FSynth_update(FSynth *self, ALCdevice *device);
-static void FSynth_processQueue(FSynth *self, ALuint64 time);
-static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]);
-static void FSynth_Delete(FSynth *self);
-DEFINE_MIDISYNTH_VTABLE(FSynth);
-
-
-static void FSynth_Construct(FSynth *self, ALCdevice *device)
-{
- MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device);
- SET_VTABLE2(FSynth, MidiSynth, self);
-
- self->Settings = NULL;
- self->Synth = NULL;
- self->FontID = FLUID_FAILED;
- self->ForceGM2BankSelect = AL_FALSE;
-}
-
-static void FSynth_Destruct(FSynth *self)
-{
- if(self->FontID != FLUID_FAILED)
- fluid_synth_sfunload(self->Synth, self->FontID, 0);
- self->FontID = FLUID_FAILED;
-
- if(self->Synth != NULL)
- delete_fluid_synth(self->Synth);
- self->Synth = NULL;
-
- if(self->Settings != NULL)
- delete_fluid_settings(self->Settings);
- self->Settings = NULL;
-
- MidiSynth_Destruct(STATIC_CAST(MidiSynth, self));
-}
-
-static ALboolean FSynth_init(FSynth *self, ALCdevice *device)
-{
- self->Settings = new_fluid_settings();
- if(!self->Settings)
- {
- ERR("Failed to create FluidSettings\n");
- return AL_FALSE;
- }
-
- fluid_settings_setint(self->Settings, "synth.polyphony", 256);
- fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
-
- self->Synth = new_fluid_synth(self->Settings);
- if(!self->Synth)
- {
- ERR("Failed to create FluidSynth\n");
- return AL_FALSE;
- }
-
- return AL_TRUE;
-}
-
-
-static ALboolean FSynth_isSoundfont(FSynth *self, const char *filename)
-{
- filename = MidiSynth_getFontName(STATIC_CAST(MidiSynth, self), filename);
- if(!filename[0]) return AL_FALSE;
-
- if(!fluid_is_soundfont(filename))
- return AL_FALSE;
- return AL_TRUE;
-}
-
-static ALenum FSynth_loadSoundfont(FSynth *self, const char *filename)
-{
- int fontid;
-
- filename = MidiSynth_getFontName(STATIC_CAST(MidiSynth, self), filename);
- if(!filename[0]) return AL_INVALID_VALUE;
-
- fontid = fluid_synth_sfload(self->Synth, filename, 1);
- if(fontid == FLUID_FAILED)
- {
- ERR("Failed to load soundfont '%s'\n", filename);
- return AL_INVALID_VALUE;
- }
-
- if(self->FontID != FLUID_FAILED)
- fluid_synth_sfunload(self->Synth, self->FontID, 1);
- self->FontID = fontid;
-
- return AL_NO_ERROR;
-}
-
-
-static void FSynth_setGain(FSynth *self, ALfloat gain)
-{
- /* Scale gain by an additional 0.2 (-14dB), to help keep the mix from clipping. */
- fluid_settings_setnum(self->Settings, "synth.gain", 0.2 * gain);
- fluid_synth_set_gain(self->Synth, 0.2f * gain);
- MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain);
-}
-
-
-static void FSynth_setState(FSynth *self, ALenum state)
-{
- if(state == AL_PLAYING && self->FontID == FLUID_FAILED)
- FSynth_loadSoundfont(self, NULL);
-
- MidiSynth_setState(STATIC_CAST(MidiSynth, self), state);
-}
-
-static void FSynth_stop(FSynth *self)
-{
- MidiSynth *synth = STATIC_CAST(MidiSynth, self);
- ALsizei chan;
-
- /* Make sure all pending events are processed. */
- while(!(synth->SamplesToNext >= 1.0))
- {
- ALuint64 time = synth->NextEvtTime;
- if(time == UINT64_MAX)
- break;
-
- synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
- synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
- synth->LastEvtTime = time;
- FSynth_processQueue(self, time);
-
- synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
- if(synth->NextEvtTime != UINT64_MAX)
- synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
- }
-
- /* All notes off */
- for(chan = 0;chan < 16;chan++)
- fluid_synth_cc(self->Synth, chan, CTRL_ALLNOTESOFF, 0);
-
- MidiSynth_stop(STATIC_CAST(MidiSynth, self));
-}
-
-static void FSynth_reset(FSynth *self)
-{
- /* Reset to power-up status. */
- fluid_synth_system_reset(self->Synth);
-
- MidiSynth_reset(STATIC_CAST(MidiSynth, self));
-}
-
-
-static void FSynth_update(FSynth *self, ALCdevice *device)
-{
- fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
- fluid_synth_set_sample_rate(self->Synth, device->Frequency);
- MidiSynth_update(STATIC_CAST(MidiSynth, self), device);
-}
-
-
-static void FSynth_processQueue(FSynth *self, ALuint64 time)
-{
- EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue;
-
- while(queue->pos < queue->size && queue->events[queue->pos].time <= time)
- {
- const MidiEvent *evt = &queue->events[queue->pos];
-
- if(evt->event == SYSEX_EVENT)
- {
- static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 };
- static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 };
- int handled = 0;
-
- fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0);
- if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on))
- {
- if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0)
- self->ForceGM2BankSelect = AL_TRUE;
- else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0)
- self->ForceGM2BankSelect = AL_FALSE;
- }
- }
- else switch((evt->event&0xF0))
- {
- case AL_NOTEOFF_SOFT:
- fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]);
- break;
- case AL_NOTEON_SOFT:
- fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
- break;
- case AL_AFTERTOUCH_SOFT:
- break;
-
- case AL_CONTROLLERCHANGE_SOFT:
- if(self->ForceGM2BankSelect)
- {
- int chan = (evt->event&0x0F);
- if(evt->param.val[0] == CTRL_BANKSELECT_MSB)
- {
- if(evt->param.val[1] == 120 && (chan == 9 || chan == 10))
- fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM);
- else if(evt->param.val[1] == 121)
- fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC);
- break;
- }
- if(evt->param.val[0] == CTRL_BANKSELECT_LSB)
- {
- fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]);
- break;
- }
- }
- fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
- break;
- case AL_PROGRAMCHANGE_SOFT:
- fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]);
- break;
-
- case AL_CHANNELPRESSURE_SOFT:
- fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]);
- break;
-
- case AL_PITCHBEND_SOFT:
- fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) |
- ((evt->param.val[1]&0x7F)<<7));
- break;
- }
-
- queue->pos++;
- }
-}
-
-static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE])
-{
- MidiSynth *synth = STATIC_CAST(MidiSynth, self);
- ALenum state = synth->State;
- ALuint total = 0;
-
- if(state == AL_INITIAL)
- return;
- if(state != AL_PLAYING)
- {
- fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1,
- DryBuffer[FrontRight], 0, 1);
- return;
- }
-
- while(total < SamplesToDo)
- {
- if(synth->SamplesToNext >= 1.0)
- {
- ALuint todo = minu(SamplesToDo - total, fastf2u(synth->SamplesToNext));
-
- fluid_synth_write_float(self->Synth, todo,
- &DryBuffer[FrontLeft][total], 0, 1,
- &DryBuffer[FrontRight][total], 0, 1);
- total += todo;
- synth->SamplesSinceLast += todo;
- synth->SamplesToNext -= todo;
- }
- else
- {
- ALuint64 time = synth->NextEvtTime;
- if(time == UINT64_MAX)
- {
- synth->SamplesSinceLast += SamplesToDo-total;
- fluid_synth_write_float(self->Synth, SamplesToDo-total,
- &DryBuffer[FrontLeft][total], 0, 1,
- &DryBuffer[FrontRight][total], 0, 1);
- break;
- }
-
- synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
- synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
- synth->LastEvtTime = time;
- FSynth_processQueue(self, time);
-
- synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
- if(synth->NextEvtTime != UINT64_MAX)
- synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
- }
- }
-}
-
-
-static void FSynth_Delete(FSynth *self)
-{
- free(self);
-}
-
-
-#endif /* HAVE_FLUIDSYNTH */
-
-
typedef struct DSynth {
DERIVE_FROM_TYPE(MidiSynth);
} DSynth;
@@ -566,35 +256,24 @@ static void DSynth_Delete(DSynth *self)
}
-MidiSynth *SynthCreate(ALCdevice *device)
+MidiSynth *DSynth_create(ALCdevice *device)
{
-#ifdef HAVE_FLUIDSYNTH
+ DSynth *synth = calloc(1, sizeof(*synth));
+ if(!synth)
{
- FSynth *synth = calloc(1, sizeof(*synth));
- if(!synth)
- ERR("Failed to allocate FSynth\n");
- else
- {
- FSynth_Construct(synth, device);
- if(FSynth_init(synth, device))
- return STATIC_CAST(MidiSynth, synth);
- DELETE_OBJ(STATIC_CAST(MidiSynth, synth));
- }
+ ERR("Failed to allocate DSynth\n");
+ return NULL;
}
-#endif
+ DSynth_Construct(synth, device);
+ return STATIC_CAST(MidiSynth, synth);
+}
- {
- DSynth *synth = calloc(1, sizeof(*synth));
- if(!synth)
- ERR("Failed to allocate DSynth\n");
- else
- {
- DSynth_Construct(synth, device);
- return STATIC_CAST(MidiSynth, synth);
- }
- }
- return NULL;
+MidiSynth *SynthCreate(ALCdevice *device)
+{
+ MidiSynth *synth = FSynth_create(device);
+ if(!synth) synth = DSynth_create(device);
+ return synth;
}