Skip to content

Commit

Permalink
Merge pull request #2661 from Ghabry/alsa-midi
Browse files Browse the repository at this point in the history
Alsa midi: Prefer fluid and timidity
  • Loading branch information
fdelapena authored Oct 21, 2021
2 parents 6fd0a2e + 25c6467 commit 9ebc22a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 16 deletions.
35 changes: 21 additions & 14 deletions src/audio_generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <cstring>
#include <cassert>
#include <memory>
#include "audio_decoder_midi.h"
#include "audio_generic.h"
#include "audio_generic_midiout.h"
Expand Down Expand Up @@ -203,24 +204,30 @@ bool GenericAudio::PlayOnChannel(BgmChannel& chan, Filesystem_Stream::InputStrea
// There should be a way to configure the order
if (!MidiDecoder::CreateFluidsynth(filestream, true) && !MidiDecoder::CreateWildMidi(filestream, true)) {
if (!midi_thread) {
midi_thread.reset(new GenericAudioMidiOut());
midi_thread->StartThread();
midi_thread = std::make_unique<GenericAudioMidiOut>();
if (midi_thread->IsInitialized()) {
midi_thread->StartThread();
} else {
midi_thread.reset();
}
}

midi_thread->LockMutex();
auto& midi_out = midi_thread->GetMidiOut();
if (midi_out.Open(std::move(filestream))) {
midi_out.SetPitch(pitch);
midi_out.SetVolume(0);
midi_out.SetFade(volume, std::chrono::milliseconds(fadein));
midi_out.SetLooping(true);
midi_out.Resume();
chan.paused = false;
chan.midi_out_used = true;
if (midi_thread) {
midi_thread->LockMutex();
auto &midi_out = midi_thread->GetMidiOut();
if (midi_out.Open(std::move(filestream))) {
midi_out.SetPitch(pitch);
midi_out.SetVolume(0);
midi_out.SetFade(volume, std::chrono::milliseconds(fadein));
midi_out.SetLooping(true);
midi_out.Resume();
chan.paused = false;
chan.midi_out_used = true;
midi_thread->UnlockMutex();
return true;
}
midi_thread->UnlockMutex();
return true;
}
midi_thread->UnlockMutex();
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/audio_generic_midiout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ void GenericAudioMidiOut::ThreadFunction() {
}
}

bool GenericAudioMidiOut::IsInitialized() const {
return midi_out != nullptr;
}

bool GenericAudioMidiOut::IsSupported(Filesystem_Stream::InputStream& stream) {
char magic[4] = { 0 };
if (!stream.ReadIntoObj(magic)) {
Expand Down
4 changes: 4 additions & 0 deletions src/audio_generic_midiout.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class GenericAudioMidiOut final {
void StartThread();
void StopThread();
void ThreadFunction();
bool IsInitialized() const;

static bool IsSupported(Filesystem_Stream::InputStream& stream);
private:
Expand Down Expand Up @@ -80,6 +81,9 @@ class GenericAudioMidiOut final {

void StartThread() {};
void StopThread() {};
bool IsInitialized() const {
return false;
}

static bool IsSupported(Filesystem_Stream::InputStream&) {
return false;
Expand Down
16 changes: 14 additions & 2 deletions src/platform/linux/midiout_device_alsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,21 @@ AlsaMidiOutDevice::AlsaMidiOutDevice() {
snd_seq_client_info_alloca(&client_info);
snd_seq_port_info_alloca(&port_info);

// TODO: This simply enumerates all devices and connects to the last matching one
// TODO: This simply enumerates all devices and attempts to find a suitable device
// Currently prefers fluidsynth or timidity
// If they are not found connects to a different one and likely has no sound
// There should be a way to configure this
// The last is usually timidity++ or fluidsynth, so this works
std::string dst_client_name;
std::string dst_port_name;
bool candidate_found = false;

snd_seq_client_info_set_client(client_info, -1);
while (snd_seq_query_next_client(midi_out, client_info) == 0) {
const char* client_name = snd_seq_client_info_get_name(client_info);
if (StringView(client_name) == "Midi Through") {
continue;
}

int dst_client_candidate = snd_seq_client_info_get_client(client_info);
snd_seq_port_info_set_client(port_info, dst_client_candidate);
snd_seq_port_info_set_port(port_info, -1);
Expand All @@ -58,9 +63,16 @@ AlsaMidiOutDevice::AlsaMidiOutDevice() {
dst_port = snd_seq_port_info_get_port(port_info);
dst_port_name = snd_seq_port_info_get_name(port_info);
candidate_found = true;

// FIXME: Hardcoded, no config scene yet
if (StringView(client_name).starts_with("FLUID") || StringView(client_name).starts_with("TiMidity")) {
// Perfect candidate found, stop searching
goto done;
}
}
}
}
done:;

if (!candidate_found) {
Output::Debug("ALSA MIDI: No suitable client found");
Expand Down

0 comments on commit 9ebc22a

Please sign in to comment.