Skip to content

Commit

Permalink
Fluidsynth: Implement SendSysExMessage. Remove fluid_synth_system_res…
Browse files Browse the repository at this point in the history
…et because this reenabled voices, causing glitched audio for a brief moment when switching MIDIs.

Change the SysEx Api from void* to uint8_t* to make the API better to use.
  • Loading branch information
Ghabry committed Aug 28, 2021
1 parent 6fb1c2c commit 6e3b94f
Show file tree
Hide file tree
Showing 14 changed files with 28 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/audio_decoder_midi.cpp
Expand Up @@ -344,7 +344,7 @@ void AudioDecoderMidi::midi_message(int, uint_least32_t message) {
}

void AudioDecoderMidi::sysex_message(int, const void* data, std::size_t size) {
mididec->SendSysExMessage(data, size);
mididec->SendSysExMessage(reinterpret_cast<const uint8_t*>(data), size);
}

void AudioDecoderMidi::meta_event(int event, const void* data, std::size_t size) {
Expand Down
2 changes: 1 addition & 1 deletion src/audio_midi.h
Expand Up @@ -149,7 +149,7 @@ class MidiDecoder {
* @param data sysex content
* @param size length of sysex content (data)
*/
virtual void SendSysExMessage(const void* data, size_t size) {
virtual void SendSysExMessage(const uint8_t* data, size_t size) {
(void)data;
(void)size;
}
Expand Down
15 changes: 12 additions & 3 deletions src/decoder_fluidsynth.cpp
Expand Up @@ -119,6 +119,10 @@ namespace {

static fluid_synth_t* create_synth(std::string& error_message) {
fluid_synth_t* syn = new_fluid_synth(global_settings.get());
if (!syn) {
error_message = "new_fluid_synth failed";
return nullptr;
}

#if defined(HAVE_FLUIDSYNTH) && FLUIDSYNTH_VERSION_MAJOR > 1
fluid_synth_add_sfloader(syn, global_loader);
Expand Down Expand Up @@ -178,6 +182,9 @@ bool FluidSynthDecoder::Initialize(std::string& error_message) {

if (!global_settings) {
global_settings.reset(new_fluid_settings());
if (!global_settings) {
return false;
}
fluid_settings_setstr(global_settings.get(), "player.timing-source", "sample");
fluid_settings_setint(global_settings.get(), "synth.lock-memory", 0);

Expand Down Expand Up @@ -268,12 +275,14 @@ void FluidSynthDecoder::SendMidiMessage(uint32_t message) {
}
}

void FluidSynthDecoder::SendMidiReset() {
if (!instance_synth || shutdown) {
void FluidSynthDecoder::SendSysExMessage(const uint8_t* data, std::size_t size) {
// FmMidi has F0 and F7 in SysEx, Fluidsynth wants them removed
if (size <= 2) {
return;
}

fluid_synth_system_reset(instance_synth);
fluid_synth_sysex(instance_synth, reinterpret_cast<const char*>(data + 1), static_cast<int>(size - 2),
nullptr, nullptr, nullptr, 0);
}

#endif
2 changes: 1 addition & 1 deletion src/decoder_fluidsynth.h
Expand Up @@ -50,7 +50,7 @@ class FluidSynthDecoder : public MidiDecoder {

void SendMidiMessage(uint32_t message) override;

void SendMidiReset() override;
void SendSysExMessage(const uint8_t* data, size_t size) override;

std::string GetName() override {
#if defined(HAVE_FLUIDSYNTH)
Expand Down
2 changes: 1 addition & 1 deletion src/decoder_fmmidi.cpp
Expand Up @@ -45,7 +45,7 @@ void FmMidiDecoder::SendMidiMessage(uint32_t message) {
synth->midi_event(message);
}

void FmMidiDecoder::SendSysExMessage(const void * data, std::size_t size) {
void FmMidiDecoder::SendSysExMessage(const uint8_t* data, std::size_t size) {
synth->sysex_message(data, size);
}

Expand Down
2 changes: 1 addition & 1 deletion src/decoder_fmmidi.h
Expand Up @@ -35,7 +35,7 @@ class FmMidiDecoder : public MidiDecoder {
int FillBuffer(uint8_t* buffer, int length) override;

void SendMidiMessage(uint32_t message) override;
void SendSysExMessage(const void* data, size_t size) override;
void SendSysExMessage(const uint8_t* data, size_t size) override;
void SendMidiReset() override;

std::unique_ptr<midisynth::synthesizer> synth;
Expand Down
6 changes: 2 additions & 4 deletions src/platform/libretro/midiout_device_libretro.cpp
Expand Up @@ -59,11 +59,9 @@ void LibretroMidiOutDevice::SendMidiMessage(uint32_t message) {
midi_out.flush();
}

void LibretroMidiOutDevice::SendSysExMessage(const void* data, size_t size) {
auto mdata = reinterpret_cast<const uint8_t*>(data);

void LibretroMidiOutDevice::SendSysExMessage(const uint8_t* data, size_t size) {
for (size_t i = 0; i < size; ++i) {
midi_out.write(mdata[i], 0);
midi_out.write(data[i], 0);
}
midi_out.flush();
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform/libretro/midiout_device_libretro.h
Expand Up @@ -30,7 +30,7 @@ class LibretroMidiOutDevice : public MidiDecoder {
LibretroMidiOutDevice();

void SendMidiMessage(uint32_t message) override;
void SendSysExMessage(const void* data, size_t size) override;
void SendSysExMessage(const uint8_t* data, size_t size) override;
void SendMidiReset() override;
std::string GetName() override;
bool IsInitialized() const;
Expand Down
6 changes: 3 additions & 3 deletions src/platform/linux/midiout_device_alsa.cpp
Expand Up @@ -152,13 +152,13 @@ void AlsaMidiOutDevice::SendMidiMessage(uint32_t message) {
}
}

void AlsaMidiOutDevice::SendSysExMessage(const void* data, size_t size) {
void AlsaMidiOutDevice::SendSysExMessage(const uint8_t* data, size_t size) {
snd_seq_event_t evt = {};
snd_seq_ev_set_source(&evt, 0);
evt.queue = queue;
snd_seq_ev_set_dest(&evt, dst_client, dst_port);

snd_seq_ev_set_sysex(&evt, size, const_cast<void*>(data));
snd_seq_ev_set_sysex(&evt, size, const_cast<void*>(reinterpret_cast<const void*>(data)));

int status = snd_seq_event_output_direct(midi_out, &evt);
if (status < 0) {
Expand All @@ -167,7 +167,7 @@ void AlsaMidiOutDevice::SendSysExMessage(const void* data, size_t size) {
}

void AlsaMidiOutDevice::SendMidiReset() {
unsigned char gm_reset[] = {0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7};
const uint8_t gm_reset[] = {0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7};
SendSysExMessage(gm_reset, sizeof(gm_reset));
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform/linux/midiout_device_alsa.h
Expand Up @@ -31,7 +31,7 @@ class AlsaMidiOutDevice : public MidiDecoder {
~AlsaMidiOutDevice();

void SendMidiMessage(uint32_t message) override;
void SendSysExMessage(const void* data, size_t size) override;
void SendSysExMessage(const uint8_t* data, size_t size) override;
void SendMidiReset() override;
std::string GetName() override;
bool IsInitialized() const;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/macos/midiout_device_coreaudio.cpp
Expand Up @@ -90,7 +90,7 @@ void CoreAudioMidiOutDevice::SendMidiMessage(uint32_t message) {
MusicDeviceMIDIEvent(midi_out, status, value1, value2, 0);
}

void CoreAudioMidiOutDevice::SendSysExMessage(const void* data, size_t size) {
void CoreAudioMidiOutDevice::SendSysExMessage(const uint8_t* data, size_t size) {
MusicDeviceSysEx(midi_out, (const UInt8*) data, (UInt32) size);
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform/macos/midiout_device_coreaudio.h
Expand Up @@ -30,7 +30,7 @@ class CoreAudioMidiOutDevice : public MidiDecoder {
~CoreAudioMidiOutDevice();

void SendMidiMessage(uint32_t message) override;
void SendSysExMessage(const void* data, size_t size) override;
void SendSysExMessage(const uint8_t* data, size_t size) override;
void SendMidiReset() override;
std::string GetName() override;
bool IsInitialized() const;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/windows/midiout_device_win32.cpp
Expand Up @@ -51,7 +51,7 @@ void Win32MidiOutDevice::SendMidiMessage(uint32_t message) {
midiOutShortMsg(midi_out, message);
}

void Win32MidiOutDevice::SendSysExMessage(const void* data, size_t size) {
void Win32MidiOutDevice::SendSysExMessage(const uint8_t* data, size_t size) {
MIDIHDR hdr;
MMRESULT res;
hdr.dwBufferLength = size;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/windows/midiout_device_win32.h
Expand Up @@ -35,7 +35,7 @@ class Win32MidiOutDevice : public MidiDecoder {
~Win32MidiOutDevice();

void SendMidiMessage(uint32_t message) override;
void SendSysExMessage(const void* data, size_t size) override;
void SendSysExMessage(const uint8_t* data, size_t size) override;
void SendMidiReset() override;
std::string GetName() override;
bool IsInitialized() const;
Expand Down

0 comments on commit 6e3b94f

Please sign in to comment.