diff options
Diffstat (limited to 'MIDI.cpp')
-rw-r--r-- | MIDI.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
@@ -1,6 +1,14 @@ #include "MIDI.h" +#include <unordered_set> +#include <string> + +namespace { + std::unordered_set<std::string> supported_devices{"AudioBox 22 VSL", "CH345", "M2"}; +} + MIDI::MIDI(): + m_client{}, seq_handle{}, in_port{}, npfd{}, @@ -17,7 +25,9 @@ MIDI::MIDI(): throw std::runtime_error("MIDI client name couldn't be set"); } - if (0 > ((in_port = snd_seq_create_simple_port(seq_handle, "24:0", + detect_port(); + + if (0 > ((in_port = snd_seq_create_simple_port(seq_handle, fmt::format("{}:0", m_client).c_str(), SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION)))) { @@ -29,7 +39,7 @@ MIDI::MIDI(): if (1) { snd_seq_addr_t sender, dest; snd_seq_port_subscribe_t *subs; - sender.client = 24; + sender.client = m_client; sender.port = 0; dest.client = snd_seq_client_id(seq_handle); dest.port = in_port; @@ -45,7 +55,7 @@ MIDI::MIDI(): throw std::runtime_error("MIDI port couldn't be connected"); } } else { - if (0 > snd_seq_connect_from(seq_handle, in_port, 24, 0)) + if (0 > snd_seq_connect_from(seq_handle, in_port, m_client, 0)) { throw std::runtime_error("MIDI port couldn't be connected"); } @@ -75,6 +85,50 @@ MIDI::MIDI(): } } +void MIDI::detect_port(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(seq_handle, 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(seq_handle, 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"); + } +} + MIDI::~MIDI() { snd_midi_event_free(midi_event_parser); |