From 663a5d01b1931b97370ed8feff3ae229a9cc7ea4 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 2 Jan 2021 14:02:44 +0100 Subject: Format all code with clang-format --- src/AlsaDriver.cpp | 793 ++++++++++++++++++++++++++--------------------------- 1 file changed, 390 insertions(+), 403 deletions(-) (limited to 'src/AlsaDriver.cpp') diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index c1d2531..5fd038c 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -55,500 +55,487 @@ namespace { class AlsaDriver : public Driver { public: - explicit AlsaDriver(ILog& log, EventSink emit_event); + explicit AlsaDriver(ILog& log, EventSink emit_event); - AlsaDriver(const AlsaDriver&) = delete; - AlsaDriver& operator=(const AlsaDriver&) = delete; + AlsaDriver(const AlsaDriver&) = delete; + AlsaDriver& operator=(const AlsaDriver&) = delete; - AlsaDriver(AlsaDriver&&) = delete; - AlsaDriver& operator=(AlsaDriver&&) = delete; + AlsaDriver(AlsaDriver&&) = delete; + AlsaDriver& operator=(AlsaDriver&&) = delete; - ~AlsaDriver() override; + ~AlsaDriver() override; - void attach(bool launch_daemon) override; - void detach() override; + void attach(bool launch_daemon) override; + void detach() override; - bool is_attached() const override { return (_seq != nullptr); } + bool is_attached() const override { return (_seq != nullptr); } - void refresh(const EventSink& sink) override; + void refresh(const EventSink& sink) override; - bool connect(const PortID& tail_id, const PortID& head_id) override; + bool connect(const PortID& tail_id, const PortID& head_id) override; - bool disconnect(const PortID& tail_id, const PortID& head_id) override; + bool disconnect(const PortID& tail_id, const PortID& head_id) override; private: - bool create_refresh_port(); - static void* refresh_main(void* me); - void _refresh_main(); + bool create_refresh_port(); + static void* refresh_main(void* me); + void _refresh_main(); - ILog& _log; - snd_seq_t* _seq; - pthread_t _refresh_thread; + ILog& _log; + snd_seq_t* _seq; + pthread_t _refresh_thread; - struct SeqAddrComparator - { - bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const - { - return ((a.client < b.client) || - ((a.client == b.client) && a.port < b.port)); - } - }; + struct SeqAddrComparator { + bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const + { + return ((a.client < b.client) || + ((a.client == b.client) && a.port < b.port)); + } + }; - using Ignored = std::set; + using Ignored = std::set; - Ignored _ignored; + Ignored _ignored; - bool ignore(const snd_seq_addr_t& addr, bool add = true); + bool ignore(const snd_seq_addr_t& addr, bool add = true); }; PortID addr_to_id(const snd_seq_addr_t& addr, const bool is_input) { - return PortID::alsa(addr.client, addr.port, is_input); + return PortID::alsa(addr.client, addr.port, is_input); } SignalDirection port_direction(const snd_seq_port_info_t* const pinfo) { - const int caps = snd_seq_port_info_get_capability(pinfo); + const int caps = snd_seq_port_info_get_capability(pinfo); - if ((caps & SND_SEQ_PORT_CAP_READ) && (caps & SND_SEQ_PORT_CAP_WRITE)) { - return SignalDirection::duplex; - } + if ((caps & SND_SEQ_PORT_CAP_READ) && (caps & SND_SEQ_PORT_CAP_WRITE)) { + return SignalDirection::duplex; + } - if (caps & SND_SEQ_PORT_CAP_READ) { - return SignalDirection::output; - } + if (caps & SND_SEQ_PORT_CAP_READ) { + return SignalDirection::output; + } - if (caps & SND_SEQ_PORT_CAP_WRITE) { - return SignalDirection::input; - } + if (caps & SND_SEQ_PORT_CAP_WRITE) { + return SignalDirection::input; + } - return SignalDirection::duplex; + return SignalDirection::duplex; } ClientInfo client_info(snd_seq_client_info_t* const cinfo) { - return {snd_seq_client_info_get_name(cinfo)}; + return {snd_seq_client_info_get_name(cinfo)}; } PortInfo port_info(const snd_seq_port_info_t* const pinfo) { - const int type = snd_seq_port_info_get_type(pinfo); + const int type = snd_seq_port_info_get_type(pinfo); - return {snd_seq_port_info_get_name(pinfo), - PortType::alsa_midi, - port_direction(pinfo), - snd_seq_port_info_get_port(pinfo), - (type & SND_SEQ_PORT_TYPE_APPLICATION) == 0}; + return {snd_seq_port_info_get_name(pinfo), + PortType::alsa_midi, + port_direction(pinfo), + snd_seq_port_info_get_port(pinfo), + (type & SND_SEQ_PORT_TYPE_APPLICATION) == 0}; } AlsaDriver::AlsaDriver(ILog& log, EventSink emit_event) - : Driver{std::move(emit_event)} - , _log(log) - , _seq(nullptr) - , _refresh_thread{} + : Driver{std::move(emit_event)} + , _log(log) + , _seq(nullptr) + , _refresh_thread{} {} AlsaDriver::~AlsaDriver() { - detach(); + detach(); } void AlsaDriver::attach(bool /*launch_daemon*/) { - int ret = snd_seq_open(&_seq, "default", SND_SEQ_OPEN_DUPLEX, 0); - if (ret) { - _log.error("[ALSA] Unable to attach"); - _seq = nullptr; - } else { - _emit_event(DriverAttachmentEvent{ClientType::alsa}); - - snd_seq_set_client_name(_seq, "Patchage"); - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, 50000); - - ret = pthread_create( - &_refresh_thread, &attr, &AlsaDriver::refresh_main, this); - if (ret) { - _log.error("[ALSA] Failed to start refresh thread"); - } - } + int ret = snd_seq_open(&_seq, "default", SND_SEQ_OPEN_DUPLEX, 0); + if (ret) { + _log.error("[ALSA] Unable to attach"); + _seq = nullptr; + } else { + _emit_event(DriverAttachmentEvent{ClientType::alsa}); + + snd_seq_set_client_name(_seq, "Patchage"); + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 50000); + + ret = + pthread_create(&_refresh_thread, &attr, &AlsaDriver::refresh_main, this); + if (ret) { + _log.error("[ALSA] Failed to start refresh thread"); + } + } } void AlsaDriver::detach() { - if (_seq) { - pthread_cancel(_refresh_thread); - pthread_join(_refresh_thread, nullptr); - snd_seq_close(_seq); - _seq = nullptr; - _emit_event(DriverDetachmentEvent{ClientType::alsa}); - } + if (_seq) { + pthread_cancel(_refresh_thread); + pthread_join(_refresh_thread, nullptr); + snd_seq_close(_seq); + _seq = nullptr; + _emit_event(DriverDetachmentEvent{ClientType::alsa}); + } } void AlsaDriver::refresh(const EventSink& sink) { - if (!is_attached() || !_seq) { - return; - } - - _ignored.clear(); - - snd_seq_client_info_t* cinfo = nullptr; - snd_seq_client_info_alloca(&cinfo); - snd_seq_client_info_set_client(cinfo, -1); - - snd_seq_port_info_t* pinfo = nullptr; - snd_seq_port_info_alloca(&pinfo); - - // Emit all clients - snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(_seq, cinfo) >= 0) { - const auto client_id = snd_seq_client_info_get_client(cinfo); - - assert(client_id < std::numeric_limits::max()); - sink({ClientCreationEvent{ - ClientID::alsa(static_cast(client_id)), - client_info(cinfo)}}); - } - - // Emit all ports - snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(_seq, cinfo) >= 0) { - const auto client_id = snd_seq_client_info_get_client(cinfo); - - snd_seq_port_info_set_client(pinfo, client_id); - snd_seq_port_info_set_port(pinfo, -1); - while (snd_seq_query_next_port(_seq, pinfo) >= 0) { - const auto addr = *snd_seq_port_info_get_addr(pinfo); - if (!ignore(addr)) { - const auto caps = snd_seq_port_info_get_capability(pinfo); - auto info = port_info(pinfo); - - if (caps & SND_SEQ_PORT_CAP_READ) { - info.direction = SignalDirection::input; - sink({PortCreationEvent{addr_to_id(addr, true), info}}); - } - - if (caps & SND_SEQ_PORT_CAP_WRITE) { - info.direction = SignalDirection::output; - sink({PortCreationEvent{addr_to_id(addr, false), info}}); - } - } - } - } - - // Emit all connections - snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(_seq, cinfo) >= 0) { - const auto client_id = snd_seq_client_info_get_client(cinfo); - - snd_seq_port_info_set_client(pinfo, client_id); - snd_seq_port_info_set_port(pinfo, -1); - while (snd_seq_query_next_port(_seq, pinfo) >= 0) { - const auto tail_addr = *snd_seq_port_info_get_addr(pinfo); - const auto tail_id = addr_to_id(tail_addr, false); - if (ignore(tail_addr)) { - continue; - } - - snd_seq_query_subscribe_t* sinfo = nullptr; - snd_seq_query_subscribe_alloca(&sinfo); - snd_seq_query_subscribe_set_root(sinfo, &tail_addr); - snd_seq_query_subscribe_set_index(sinfo, 0); - while (!snd_seq_query_port_subscribers(_seq, sinfo)) { - const auto head_addr = *snd_seq_query_subscribe_get_addr(sinfo); - const auto head_id = addr_to_id(head_addr, true); - - sink({ConnectionEvent{tail_id, head_id}}); - - snd_seq_query_subscribe_set_index( - sinfo, snd_seq_query_subscribe_get_index(sinfo) + 1); - } - } - } + if (!is_attached() || !_seq) { + return; + } + + _ignored.clear(); + + snd_seq_client_info_t* cinfo = nullptr; + snd_seq_client_info_alloca(&cinfo); + snd_seq_client_info_set_client(cinfo, -1); + + snd_seq_port_info_t* pinfo = nullptr; + snd_seq_port_info_alloca(&pinfo); + + // Emit all clients + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(_seq, cinfo) >= 0) { + const auto client_id = snd_seq_client_info_get_client(cinfo); + + assert(client_id < std::numeric_limits::max()); + sink({ClientCreationEvent{ClientID::alsa(static_cast(client_id)), + client_info(cinfo)}}); + } + + // Emit all ports + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(_seq, cinfo) >= 0) { + const auto client_id = snd_seq_client_info_get_client(cinfo); + + snd_seq_port_info_set_client(pinfo, client_id); + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(_seq, pinfo) >= 0) { + const auto addr = *snd_seq_port_info_get_addr(pinfo); + if (!ignore(addr)) { + const auto caps = snd_seq_port_info_get_capability(pinfo); + auto info = port_info(pinfo); + + if (caps & SND_SEQ_PORT_CAP_READ) { + info.direction = SignalDirection::input; + sink({PortCreationEvent{addr_to_id(addr, true), info}}); + } + + if (caps & SND_SEQ_PORT_CAP_WRITE) { + info.direction = SignalDirection::output; + sink({PortCreationEvent{addr_to_id(addr, false), info}}); + } + } + } + } + + // Emit all connections + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(_seq, cinfo) >= 0) { + const auto client_id = snd_seq_client_info_get_client(cinfo); + + snd_seq_port_info_set_client(pinfo, client_id); + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(_seq, pinfo) >= 0) { + const auto tail_addr = *snd_seq_port_info_get_addr(pinfo); + const auto tail_id = addr_to_id(tail_addr, false); + if (ignore(tail_addr)) { + continue; + } + + snd_seq_query_subscribe_t* sinfo = nullptr; + snd_seq_query_subscribe_alloca(&sinfo); + snd_seq_query_subscribe_set_root(sinfo, &tail_addr); + snd_seq_query_subscribe_set_index(sinfo, 0); + while (!snd_seq_query_port_subscribers(_seq, sinfo)) { + const auto head_addr = *snd_seq_query_subscribe_get_addr(sinfo); + const auto head_id = addr_to_id(head_addr, true); + + sink({ConnectionEvent{tail_id, head_id}}); + + snd_seq_query_subscribe_set_index( + sinfo, snd_seq_query_subscribe_get_index(sinfo) + 1); + } + } + } } bool AlsaDriver::ignore(const snd_seq_addr_t& addr, bool add) { - if (_ignored.find(addr) != _ignored.end()) { - return true; - } - - if (!add) { - return false; - } - - snd_seq_client_info_t* cinfo = nullptr; - snd_seq_client_info_alloca(&cinfo); - snd_seq_client_info_set_client(cinfo, addr.client); - snd_seq_get_any_client_info(_seq, addr.client, cinfo); - - snd_seq_port_info_t* pinfo = nullptr; - snd_seq_port_info_alloca(&pinfo); - snd_seq_port_info_set_client(pinfo, addr.client); - snd_seq_port_info_set_port(pinfo, addr.port); - snd_seq_get_any_port_info(_seq, addr.client, addr.port, pinfo); - - const int type = snd_seq_port_info_get_type(pinfo); - const int caps = snd_seq_port_info_get_capability(pinfo); - - if (caps & SND_SEQ_PORT_CAP_NO_EXPORT) { - _ignored.insert(addr); - return true; - } - - if (!((caps & SND_SEQ_PORT_CAP_READ) || (caps & SND_SEQ_PORT_CAP_WRITE) || - (caps & SND_SEQ_PORT_CAP_DUPLEX))) { - _ignored.insert(addr); - return true; - } - - if ((snd_seq_client_info_get_type(cinfo) != SND_SEQ_USER_CLIENT) && - ((type == SND_SEQ_PORT_SYSTEM_TIMER || - type == SND_SEQ_PORT_SYSTEM_ANNOUNCE))) { - _ignored.insert(addr); - return true; - } - - return false; + if (_ignored.find(addr) != _ignored.end()) { + return true; + } + + if (!add) { + return false; + } + + snd_seq_client_info_t* cinfo = nullptr; + snd_seq_client_info_alloca(&cinfo); + snd_seq_client_info_set_client(cinfo, addr.client); + snd_seq_get_any_client_info(_seq, addr.client, cinfo); + + snd_seq_port_info_t* pinfo = nullptr; + snd_seq_port_info_alloca(&pinfo); + snd_seq_port_info_set_client(pinfo, addr.client); + snd_seq_port_info_set_port(pinfo, addr.port); + snd_seq_get_any_port_info(_seq, addr.client, addr.port, pinfo); + + const int type = snd_seq_port_info_get_type(pinfo); + const int caps = snd_seq_port_info_get_capability(pinfo); + + if (caps & SND_SEQ_PORT_CAP_NO_EXPORT) { + _ignored.insert(addr); + return true; + } + + if (!((caps & SND_SEQ_PORT_CAP_READ) || (caps & SND_SEQ_PORT_CAP_WRITE) || + (caps & SND_SEQ_PORT_CAP_DUPLEX))) { + _ignored.insert(addr); + return true; + } + + if ((snd_seq_client_info_get_type(cinfo) != SND_SEQ_USER_CLIENT) && + ((type == SND_SEQ_PORT_SYSTEM_TIMER || + type == SND_SEQ_PORT_SYSTEM_ANNOUNCE))) { + _ignored.insert(addr); + return true; + } + + return false; } bool AlsaDriver::connect(const PortID& tail_id, const PortID& head_id) { - if (tail_id.type() != PortID::Type::alsa || - head_id.type() != PortID::Type::alsa) { - _log.error("[ALSA] Attempt to connect non-ALSA ports"); - return false; - } - - const snd_seq_addr_t tail_addr = {tail_id.alsa_client(), - tail_id.alsa_port()}; - - const snd_seq_addr_t head_addr = {head_id.alsa_client(), - head_id.alsa_port()}; - - if (tail_addr.client == head_addr.client && - tail_addr.port == head_addr.port) { - _log.warning("[ALSA] Refusing to connect port to itself"); - return false; - } - - bool result = true; - - snd_seq_port_subscribe_t* subs = nullptr; - snd_seq_port_subscribe_malloc(&subs); - snd_seq_port_subscribe_set_sender(subs, &tail_addr); - snd_seq_port_subscribe_set_dest(subs, &head_addr); - snd_seq_port_subscribe_set_exclusive(subs, 0); - snd_seq_port_subscribe_set_time_update(subs, 0); - snd_seq_port_subscribe_set_time_real(subs, 0); - - // Already connected (shouldn't happen) - if (!snd_seq_get_port_subscription(_seq, subs)) { - _log.error("[ALSA] Attempt to double subscribe ports"); - result = false; - } - - int ret = snd_seq_subscribe_port(_seq, subs); - if (ret < 0) { - _log.error( - fmt::format("[ALSA] Subscription failed ({})", snd_strerror(ret))); - result = false; - } - - if (!result) { - _log.error( - fmt::format("[ALSA] Failed to connect {} => {}", tail_id, head_id)); - } - - return (!result); + if (tail_id.type() != PortID::Type::alsa || + head_id.type() != PortID::Type::alsa) { + _log.error("[ALSA] Attempt to connect non-ALSA ports"); + return false; + } + + const snd_seq_addr_t tail_addr = {tail_id.alsa_client(), tail_id.alsa_port()}; + + const snd_seq_addr_t head_addr = {head_id.alsa_client(), head_id.alsa_port()}; + + if (tail_addr.client == head_addr.client && + tail_addr.port == head_addr.port) { + _log.warning("[ALSA] Refusing to connect port to itself"); + return false; + } + + bool result = true; + + snd_seq_port_subscribe_t* subs = nullptr; + snd_seq_port_subscribe_malloc(&subs); + snd_seq_port_subscribe_set_sender(subs, &tail_addr); + snd_seq_port_subscribe_set_dest(subs, &head_addr); + snd_seq_port_subscribe_set_exclusive(subs, 0); + snd_seq_port_subscribe_set_time_update(subs, 0); + snd_seq_port_subscribe_set_time_real(subs, 0); + + // Already connected (shouldn't happen) + if (!snd_seq_get_port_subscription(_seq, subs)) { + _log.error("[ALSA] Attempt to double subscribe ports"); + result = false; + } + + int ret = snd_seq_subscribe_port(_seq, subs); + if (ret < 0) { + _log.error( + fmt::format("[ALSA] Subscription failed ({})", snd_strerror(ret))); + result = false; + } + + if (!result) { + _log.error( + fmt::format("[ALSA] Failed to connect {} => {}", tail_id, head_id)); + } + + return (!result); } bool AlsaDriver::disconnect(const PortID& tail_id, const PortID& head_id) { - if (tail_id.type() != PortID::Type::alsa || - head_id.type() != PortID::Type::alsa) { - _log.error("[ALSA] Attempt to disconnect non-ALSA ports"); - return false; - } - - const snd_seq_addr_t tail_addr = {tail_id.alsa_client(), - tail_id.alsa_port()}; - - const snd_seq_addr_t head_addr = {head_id.alsa_client(), - head_id.alsa_port()}; - - snd_seq_port_subscribe_t* subs = nullptr; - snd_seq_port_subscribe_malloc(&subs); - snd_seq_port_subscribe_set_sender(subs, &tail_addr); - snd_seq_port_subscribe_set_dest(subs, &head_addr); - snd_seq_port_subscribe_set_exclusive(subs, 0); - snd_seq_port_subscribe_set_time_update(subs, 0); - snd_seq_port_subscribe_set_time_real(subs, 0); - - // Not connected (shouldn't happen) - if (snd_seq_get_port_subscription(_seq, subs) != 0) { - _log.error( - "[ALSA] Attempt to unsubscribe ports that are not subscribed"); - return false; - } - - int ret = snd_seq_unsubscribe_port(_seq, subs); - if (ret < 0) { - _log.error(fmt::format("[ALSA] Failed to disconnect {} => {} ({})", - tail_id, - head_id, - snd_strerror(ret))); - return false; - } - - return true; + if (tail_id.type() != PortID::Type::alsa || + head_id.type() != PortID::Type::alsa) { + _log.error("[ALSA] Attempt to disconnect non-ALSA ports"); + return false; + } + + const snd_seq_addr_t tail_addr = {tail_id.alsa_client(), tail_id.alsa_port()}; + + const snd_seq_addr_t head_addr = {head_id.alsa_client(), head_id.alsa_port()}; + + snd_seq_port_subscribe_t* subs = nullptr; + snd_seq_port_subscribe_malloc(&subs); + snd_seq_port_subscribe_set_sender(subs, &tail_addr); + snd_seq_port_subscribe_set_dest(subs, &head_addr); + snd_seq_port_subscribe_set_exclusive(subs, 0); + snd_seq_port_subscribe_set_time_update(subs, 0); + snd_seq_port_subscribe_set_time_real(subs, 0); + + // Not connected (shouldn't happen) + if (snd_seq_get_port_subscription(_seq, subs) != 0) { + _log.error("[ALSA] Attempt to unsubscribe ports that are not subscribed"); + return false; + } + + int ret = snd_seq_unsubscribe_port(_seq, subs); + if (ret < 0) { + _log.error(fmt::format("[ALSA] Failed to disconnect {} => {} ({})", + tail_id, + head_id, + snd_strerror(ret))); + return false; + } + + return true; } bool AlsaDriver::create_refresh_port() { - snd_seq_port_info_t* port_info = nullptr; - snd_seq_port_info_alloca(&port_info); - snd_seq_port_info_set_name(port_info, "System Announcement Receiver"); - snd_seq_port_info_set_type(port_info, SND_SEQ_PORT_TYPE_APPLICATION); - snd_seq_port_info_set_capability(port_info, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE | - SND_SEQ_PORT_CAP_NO_EXPORT); - - int ret = snd_seq_create_port(_seq, port_info); - if (ret) { - _log.error( - fmt::format("[ALSA] Error creating port ({})", snd_strerror(ret))); - return false; - } - - // Subscribe the port to the system announcer - ret = snd_seq_connect_from(_seq, - snd_seq_port_info_get_port(port_info), - SND_SEQ_CLIENT_SYSTEM, - SND_SEQ_PORT_SYSTEM_ANNOUNCE); - if (ret) { - _log.error( - fmt::format("[ALSA] Failed to connect to system announce port ({})", - snd_strerror(ret))); - return false; - } - - return true; + snd_seq_port_info_t* port_info = nullptr; + snd_seq_port_info_alloca(&port_info); + snd_seq_port_info_set_name(port_info, "System Announcement Receiver"); + snd_seq_port_info_set_type(port_info, SND_SEQ_PORT_TYPE_APPLICATION); + snd_seq_port_info_set_capability(port_info, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE | + SND_SEQ_PORT_CAP_NO_EXPORT); + + int ret = snd_seq_create_port(_seq, port_info); + if (ret) { + _log.error( + fmt::format("[ALSA] Error creating port ({})", snd_strerror(ret))); + return false; + } + + // Subscribe the port to the system announcer + ret = snd_seq_connect_from(_seq, + snd_seq_port_info_get_port(port_info), + SND_SEQ_CLIENT_SYSTEM, + SND_SEQ_PORT_SYSTEM_ANNOUNCE); + if (ret) { + _log.error( + fmt::format("[ALSA] Failed to connect to system announce port ({})", + snd_strerror(ret))); + return false; + } + + return true; } void* AlsaDriver::refresh_main(void* me) { - auto* ad = static_cast(me); - ad->_refresh_main(); - return nullptr; + auto* ad = static_cast(me); + ad->_refresh_main(); + return nullptr; } void AlsaDriver::_refresh_main() { - if (!create_refresh_port()) { - _log.error( - "[ALSA] Could not create listen port, auto-refresh disabled"); - return; - } - - int caps = 0; - - snd_seq_client_info_t* cinfo = nullptr; - snd_seq_client_info_alloca(&cinfo); - - snd_seq_port_info_t* pinfo = nullptr; - snd_seq_port_info_alloca(&pinfo); - - snd_seq_event_t* ev = nullptr; - while (snd_seq_event_input(_seq, &ev) > 0) { - assert(ev); - - switch (ev->type) { - case SND_SEQ_EVENT_CLIENT_START: - snd_seq_get_any_client_info(_seq, ev->data.addr.client, cinfo); - _emit_event(ClientCreationEvent{ - ClientID::alsa(ev->data.addr.client), - client_info(cinfo), - }); - break; - - case SND_SEQ_EVENT_CLIENT_EXIT: - _emit_event(ClientDestructionEvent{ - ClientID::alsa(ev->data.addr.client), - }); - break; - - case SND_SEQ_EVENT_CLIENT_CHANGE: - break; - - case SND_SEQ_EVENT_PORT_START: - snd_seq_get_any_client_info(_seq, ev->data.addr.client, cinfo); - snd_seq_get_any_port_info( - _seq, ev->data.addr.client, ev->data.addr.port, pinfo); - caps = snd_seq_port_info_get_capability(pinfo); - - if (!ignore(ev->data.addr)) { - _emit_event(PortCreationEvent{ - addr_to_id(ev->data.addr, (caps & SND_SEQ_PORT_CAP_READ)), - port_info(pinfo), - }); - } - break; - - case SND_SEQ_EVENT_PORT_EXIT: - if (!ignore(ev->data.addr, false)) { - // Note: getting caps at this point does not work - // Delete both inputs and outputs (to handle duplex ports) - _emit_event( - PortDestructionEvent{addr_to_id(ev->data.addr, true)}); - _emit_event( - PortDestructionEvent{addr_to_id(ev->data.addr, false)}); - } - break; - - case SND_SEQ_EVENT_PORT_CHANGE: - break; - - case SND_SEQ_EVENT_PORT_SUBSCRIBED: - if (!ignore(ev->data.connect.sender) && - !ignore(ev->data.connect.dest)) { - _emit_event( - ConnectionEvent{addr_to_id(ev->data.connect.sender, false), - addr_to_id(ev->data.connect.dest, true)}); - } - break; - - case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: - if (!ignore(ev->data.connect.sender) && - !ignore(ev->data.connect.dest)) { - _emit_event(DisconnectionEvent{ - addr_to_id(ev->data.connect.sender, false), - addr_to_id(ev->data.connect.dest, true)}); - } - break; - - case SND_SEQ_EVENT_RESET: - default: - break; - } - } + if (!create_refresh_port()) { + _log.error("[ALSA] Could not create listen port, auto-refresh disabled"); + return; + } + + int caps = 0; + + snd_seq_client_info_t* cinfo = nullptr; + snd_seq_client_info_alloca(&cinfo); + + snd_seq_port_info_t* pinfo = nullptr; + snd_seq_port_info_alloca(&pinfo); + + snd_seq_event_t* ev = nullptr; + while (snd_seq_event_input(_seq, &ev) > 0) { + assert(ev); + + switch (ev->type) { + case SND_SEQ_EVENT_CLIENT_START: + snd_seq_get_any_client_info(_seq, ev->data.addr.client, cinfo); + _emit_event(ClientCreationEvent{ + ClientID::alsa(ev->data.addr.client), + client_info(cinfo), + }); + break; + + case SND_SEQ_EVENT_CLIENT_EXIT: + _emit_event(ClientDestructionEvent{ + ClientID::alsa(ev->data.addr.client), + }); + break; + + case SND_SEQ_EVENT_CLIENT_CHANGE: + break; + + case SND_SEQ_EVENT_PORT_START: + snd_seq_get_any_client_info(_seq, ev->data.addr.client, cinfo); + snd_seq_get_any_port_info( + _seq, ev->data.addr.client, ev->data.addr.port, pinfo); + caps = snd_seq_port_info_get_capability(pinfo); + + if (!ignore(ev->data.addr)) { + _emit_event(PortCreationEvent{ + addr_to_id(ev->data.addr, (caps & SND_SEQ_PORT_CAP_READ)), + port_info(pinfo), + }); + } + break; + + case SND_SEQ_EVENT_PORT_EXIT: + if (!ignore(ev->data.addr, false)) { + // Note: getting caps at this point does not work + // Delete both inputs and outputs (to handle duplex ports) + _emit_event(PortDestructionEvent{addr_to_id(ev->data.addr, true)}); + _emit_event(PortDestructionEvent{addr_to_id(ev->data.addr, false)}); + } + break; + + case SND_SEQ_EVENT_PORT_CHANGE: + break; + + case SND_SEQ_EVENT_PORT_SUBSCRIBED: + if (!ignore(ev->data.connect.sender) && !ignore(ev->data.connect.dest)) { + _emit_event(ConnectionEvent{addr_to_id(ev->data.connect.sender, false), + addr_to_id(ev->data.connect.dest, true)}); + } + break; + + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + if (!ignore(ev->data.connect.sender) && !ignore(ev->data.connect.dest)) { + _emit_event( + DisconnectionEvent{addr_to_id(ev->data.connect.sender, false), + addr_to_id(ev->data.connect.dest, true)}); + } + break; + + case SND_SEQ_EVENT_RESET: + default: + break; + } + } } } // namespace @@ -556,7 +543,7 @@ AlsaDriver::_refresh_main() std::unique_ptr make_alsa_driver(ILog& log, Driver::EventSink emit_event) { - return std::unique_ptr{new AlsaDriver{log, std::move(emit_event)}}; + return std::unique_ptr{new AlsaDriver{log, std::move(emit_event)}}; } } // namespace patchage -- cgit v1.2.1