diff options
author | Chris Robinson <[email protected]> | 2013-12-17 22:36:25 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-12-17 22:36:25 -0800 |
commit | ee92b3142d70a50945b4a4aa021f7a846061d28e (patch) | |
tree | ae6cb11fe16837a597b9660745fb2815ea99e556 | |
parent | ef0341c180789aaf95daabc5bc76b02bad174f80 (diff) |
Move FluidSynth to its own file
-rw-r--r-- | Alc/midi/fluidsynth.c | 359 | ||||
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | OpenAL32/Include/alMidi.h | 2 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 347 |
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; } |