From d9ace12fee24965baf6cf065691ed99c0d229ab1 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 17 Jan 2025 20:19:51 +0100 Subject: Detect MIDI port --- MIDIPlayer.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) (limited to 'MIDIPlayer.cpp') diff --git a/MIDIPlayer.cpp b/MIDIPlayer.cpp index f2bba8c..2c0bc6a 100644 --- a/MIDIPlayer.cpp +++ b/MIDIPlayer.cpp @@ -6,13 +6,19 @@ #include #include #include +#include #include +#include namespace bp = boost::process; namespace fs = std::filesystem; using namespace std::chrono_literals; +namespace { + std::unordered_set supported_devices{"AudioBox 22 VSL", "CH345"}; +} + MIDIPlayer::MIDIPlayer(const std::filesystem::path& path): m_child{}, m_dir{path}, @@ -23,6 +29,10 @@ MIDIPlayer::MIDIPlayer(const std::filesystem::path& path): if (list.size() > 0) { m_file = list[0]; } + + init_seq(); + iterate_ports(); + close_seq(); } void MIDIPlayer::start() @@ -30,7 +40,7 @@ void MIDIPlayer::start() if (m_child.valid() && m_child.running()) { stop(); } else { - m_child = bp::child(fmt::format("aplaymidi -p24 \"{}\"", m_file).c_str());//, bp::std_out > bp::null); + m_child = bp::child(fmt::format("aplaymidi -p{} \"{}\"", m_client, m_file).c_str());//, bp::std_out > bp::null); } } @@ -87,3 +97,71 @@ std::vector MIDIPlayer::get_filelist() return result; } +void MIDIPlayer::init_seq(void) +{ + /* open sequencer */ + int err = snd_seq_open(&m_seq, "default", SND_SEQ_OPEN_DUPLEX, 0); + if (err < 0) + { + throw std::runtime_error("snd_seq_open()"); + } +} + +void MIDIPlayer::close_seq(void) +{ + int err = snd_seq_close(m_seq); + if (err < 0) + { + throw std::runtime_error("snd_seq_close()"); + } +} + +void MIDIPlayer::iterate_ports(void) +{ + bool found{}; + + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); + + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(m_seq, cinfo) >= 0) { + int client = snd_seq_client_info_get_client(cinfo); + + snd_seq_port_info_set_client(pinfo, client); + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(m_seq, pinfo) >= 0) { + /* port must understand MIDI messages */ + if (!(snd_seq_port_info_get_type(pinfo) + & SND_SEQ_PORT_TYPE_MIDI_GENERIC)) + continue; + /* we need both WRITE and SUBS_WRITE */ + if ((snd_seq_port_info_get_capability(pinfo) + & (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) + != (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) + continue; + if (supported_devices.contains(std::string{snd_seq_client_info_get_name(cinfo)})) { + m_client = snd_seq_port_info_get_client(pinfo); + found = true; + } + //std::cout << fmt::format("DEBUG: {}", get_midi_port()) << std::endl; + //printf("%3d:%-3d %-32.32s %s\n", + // snd_seq_port_info_get_client(pinfo), + // snd_seq_port_info_get_port(pinfo), + // snd_seq_client_info_get_name(cinfo), + // snd_seq_port_info_get_name(pinfo)); + } + } + + if (!found) { + throw std::runtime_error("No MIDI device found"); + } +} + +int MIDIPlayer::get_midi_port() +{ + return m_client; +} + -- cgit v1.2.3