diff options
author | Roland Reichwein <mail@reichwein.it> | 2025-01-17 20:19:51 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2025-01-17 20:19:51 +0100 |
commit | d9ace12fee24965baf6cf065691ed99c0d229ab1 (patch) | |
tree | 368705985079f432a17a4275867db03de7a601b5 /MIDIPlayer.cpp | |
parent | 641df30129ed241cda2440280b5282410d5ee5b3 (diff) |
Detect MIDI port
Diffstat (limited to 'MIDIPlayer.cpp')
-rw-r--r-- | MIDIPlayer.cpp | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/MIDIPlayer.cpp b/MIDIPlayer.cpp index f2bba8c..2c0bc6a 100644 --- a/MIDIPlayer.cpp +++ b/MIDIPlayer.cpp @@ -6,13 +6,19 @@ #include <algorithm> #include <chrono> #include <iostream> +#include <string> #include <thread> +#include <unordered_set> namespace bp = boost::process; namespace fs = std::filesystem; using namespace std::chrono_literals; +namespace { + std::unordered_set<std::string> 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<std::string> 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; +} + |