diff options
author | David Robillard <d@drobilla.net> | 2020-11-29 17:14:35 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-11-29 18:03:31 +0100 |
commit | 78b359c44b67f4f1fff9e31dd9243af5e996f38a (patch) | |
tree | 59aeee028fd339894e94eb21fc5cdbf53a2b8c5d | |
parent | d3561e8cf1d5a289ff2ce4a26e4a970437a812d5 (diff) | |
download | patchage-78b359c44b67f4f1fff9e31dd9243af5e996f38a.tar.gz patchage-78b359c44b67f4f1fff9e31dd9243af5e996f38a.tar.bz2 patchage-78b359c44b67f4f1fff9e31dd9243af5e996f38a.zip |
Add AudioDriver interface
-rw-r--r-- | src/AudioDriver.hpp | 48 | ||||
-rw-r--r-- | src/JackDbusDriver.cpp | 110 | ||||
-rw-r--r-- | src/JackDbusDriver.hpp | 25 | ||||
-rw-r--r-- | src/JackDriver.cpp | 86 | ||||
-rw-r--r-- | src/JackDriver.hpp | 23 | ||||
-rw-r--r-- | src/Patchage.cpp | 2 |
6 files changed, 176 insertions, 118 deletions
diff --git a/src/AudioDriver.hpp b/src/AudioDriver.hpp new file mode 100644 index 0000000..7e1e5a7 --- /dev/null +++ b/src/AudioDriver.hpp @@ -0,0 +1,48 @@ +/* This file is part of Patchage. + * Copyright 2007-2020 David Robillard <d@drobilla.net> + * + * Patchage is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License + * along with Patchage. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PATCHAGE_AUDIODRIVER_HPP +#define PATCHAGE_AUDIODRIVER_HPP + +#include "Driver.hpp" + +#include <cstdint> + +/// Base class for drivers that work with an audio system +class AudioDriver : public Driver +{ +public: + explicit AudioDriver(EventSink emit_event) + : Driver{std::move(emit_event)} + {} + + /// Return the number of xruns (dropouts) since the last reset + virtual uint32_t xruns() = 0; + + /// Reset the xrun count + virtual void reset_xruns() = 0; + + /// Return the current buffer size in frames + virtual uint32_t buffer_size() = 0; + + /// Try to set the current buffer size in frames, return true on success + virtual bool set_buffer_size(uint32_t frames) = 0; + + /// Return the current sample rate in Hz + virtual uint32_t sample_rate() = 0; +}; + +#endif // PATCHAGE_AUDIODRIVER_HPP diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp index 4ab7b8c..add838d 100644 --- a/src/JackDbusDriver.cpp +++ b/src/JackDbusDriver.cpp @@ -55,7 +55,7 @@ PATCHAGE_RESTORE_WARNINGS #define JACKDBUS_PORT_TYPE_MIDI 1 JackDriver::JackDriver(ILog& log, EventSink emit_event) - : Driver{std::move(emit_event)} + : AudioDriver{std::move(emit_event)} , _log(log) , _dbus_error() , _dbus_connection(nullptr) @@ -722,6 +722,56 @@ JackDriver::disconnect(const PortID& tail_id, const PortID& head_id) } uint32_t +JackDriver::xruns() +{ + DBusMessage* reply_ptr = nullptr; + dbus_uint32_t xruns = 0u; + + if (_server_responding && !_server_started) { + return 0; + } + + if (!call(true, + JACKDBUS_IFACE_CONTROL, + "GetXruns", + &reply_ptr, + DBUS_TYPE_INVALID)) { + return 0; + } + + if (!dbus_message_get_args(reply_ptr, + &_dbus_error, + DBUS_TYPE_UINT32, + &xruns, + DBUS_TYPE_INVALID)) { + dbus_message_unref(reply_ptr); + dbus_error_free(&_dbus_error); + error_msg("Decoding reply of GetXruns failed"); + return 0; + } + + dbus_message_unref(reply_ptr); + + return xruns; +} + +void +JackDriver::reset_xruns() +{ + DBusMessage* reply_ptr = nullptr; + + if (!call(true, + JACKDBUS_IFACE_CONTROL, + "ResetXruns", + &reply_ptr, + DBUS_TYPE_INVALID)) { + return; + } + + dbus_message_unref(reply_ptr); +} + +uint32_t JackDriver::buffer_size() { DBusMessage* reply_ptr = nullptr; @@ -756,12 +806,10 @@ JackDriver::buffer_size() } bool -JackDriver::set_buffer_size(const uint32_t size) +JackDriver::set_buffer_size(const uint32_t frames) { DBusMessage* reply_ptr = nullptr; - dbus_uint32_t buffer_size = 0u; - - buffer_size = size; + dbus_uint32_t buffer_size = frames; if (!call(true, JACKDBUS_IFACE_CONTROL, @@ -778,7 +826,7 @@ JackDriver::set_buffer_size(const uint32_t size) return true; } -float +uint32_t JackDriver::sample_rate() { DBusMessage* reply_ptr = nullptr; @@ -808,56 +856,6 @@ JackDriver::sample_rate() return sample_rate; } -uint32_t -JackDriver::get_xruns() -{ - DBusMessage* reply_ptr = nullptr; - dbus_uint32_t xruns = 0u; - - if (_server_responding && !_server_started) { - return 0; - } - - if (!call(true, - JACKDBUS_IFACE_CONTROL, - "GetXruns", - &reply_ptr, - DBUS_TYPE_INVALID)) { - return 0; - } - - if (!dbus_message_get_args(reply_ptr, - &_dbus_error, - DBUS_TYPE_UINT32, - &xruns, - DBUS_TYPE_INVALID)) { - dbus_message_unref(reply_ptr); - dbus_error_free(&_dbus_error); - error_msg("Decoding reply of GetXruns failed"); - return 0; - } - - dbus_message_unref(reply_ptr); - - return xruns; -} - -void -JackDriver::reset_xruns() -{ - DBusMessage* reply_ptr = nullptr; - - if (!call(true, - JACKDBUS_IFACE_CONTROL, - "ResetXruns", - &reply_ptr, - DBUS_TYPE_INVALID)) { - return; - } - - dbus_message_unref(reply_ptr); -} - PortType JackDriver::patchage_port_type(const dbus_uint32_t dbus_port_type) const { diff --git a/src/JackDbusDriver.hpp b/src/JackDbusDriver.hpp index 42c70ef..068c7cc 100644 --- a/src/JackDbusDriver.hpp +++ b/src/JackDbusDriver.hpp @@ -18,7 +18,7 @@ #ifndef PATCHAGE_JACKDBUSDRIVER_HPP #define PATCHAGE_JACKDBUSDRIVER_HPP -#include "Driver.hpp" +#include "AudioDriver.hpp" #include <dbus/dbus.h> @@ -28,7 +28,7 @@ class ILog; /// Driver for JACK audio and midi ports that uses D-Bus -class JackDriver : public Driver +class JackDriver : public AudioDriver { public: explicit JackDriver(ILog& log, EventSink emit_event); @@ -41,23 +41,20 @@ public: ~JackDriver() override; + // Driver interface void attach(bool launch_daemon) override; void detach() override; - bool is_attached() const override; - void refresh(const EventSink& sink) override; - bool connect(const PortID& tail_id, const PortID& head_id) override; - bool disconnect(const PortID& tail_id, const PortID& head_id) override; - uint32_t get_xruns(); - void reset_xruns(); - - float sample_rate(); - uint32_t buffer_size(); - bool set_buffer_size(uint32_t size); + // AudioDriver interface + uint32_t xruns() override; + void reset_xruns() override; + uint32_t buffer_size() override; + bool set_buffer_size(uint32_t frames) override; + uint32_t sample_rate() override; private: PortType patchage_port_type(dbus_uint32_t dbus_port_type) const; @@ -96,8 +93,8 @@ private: DBusError _dbus_error; DBusConnection* _dbus_connection; - bool _server_responding; - bool _server_started; + mutable bool _server_responding; + bool _server_started; dbus_uint64_t _graph_version; }; diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index b30d45f..b3c7658 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -46,7 +46,7 @@ PATCHAGE_RESTORE_WARNINGS #include <utility> JackDriver::JackDriver(ILog& log, EventSink emit_event) - : Driver{std::move(emit_event)} + : AudioDriver{std::move(emit_event)} , _log{log} , _is_activated{false} {} @@ -108,6 +108,12 @@ JackDriver::detach() _emit_event(DriverDetachmentEvent{ClientType::jack}); } +bool +JackDriver::is_attached() const +{ + return _client != nullptr; +} + static std::string get_property(const jack_uuid_t subject, const char* const key) { @@ -299,6 +305,51 @@ JackDriver::disconnect(const PortID& tail_id, const PortID& head_id) return true; } +uint32_t +JackDriver::xruns() +{ + return _xruns; +} + +void +JackDriver::reset_xruns() +{ + _xruns = 0; +} + +uint32_t +JackDriver::buffer_size() +{ + return _is_activated ? _buffer_size : jack_get_buffer_size(_client); +} + +bool +JackDriver::set_buffer_size(const uint32_t frames) +{ + if (!_client) { + _buffer_size = frames; + return true; + } + + if (buffer_size() == frames) { + return true; + } + + if (jack_set_buffer_size(_client, frames)) { + _log.error("[JACK] Unable to set buffer size"); + return false; + } + + _buffer_size = frames; + return true; +} + +uint32_t +JackDriver::sample_rate() +{ + return jack_get_sample_rate(_client); +} + void JackDriver::jack_client_registration_cb(const char* const name, const int registered, @@ -375,36 +426,3 @@ JackDriver::jack_shutdown_cb(void* const jack_driver) me->_emit_event(DriverDetachmentEvent{ClientType::jack}); } - -jack_nframes_t -JackDriver::buffer_size() -{ - return _is_activated ? _buffer_size : jack_get_buffer_size(_client); -} - -void -JackDriver::reset_xruns() -{ - _xruns = 0; -} - -bool -JackDriver::set_buffer_size(jack_nframes_t size) -{ - if (!_client) { - _buffer_size = size; - return true; - } - - if (buffer_size() == size) { - return true; - } - - if (jack_set_buffer_size(_client, size)) { - _log.error("[JACK] Unable to set buffer size"); - return false; - } - - _buffer_size = size; - return true; -} diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp index d93b491..078e7d2 100644 --- a/src/JackDriver.hpp +++ b/src/JackDriver.hpp @@ -17,8 +17,8 @@ #ifndef PATCHAGE_JACKDRIVER_HPP #define PATCHAGE_JACKDRIVER_HPP +#include "AudioDriver.hpp" #include "ClientInfo.hpp" -#include "Driver.hpp" #include "PortInfo.hpp" #include <jack/jack.h> @@ -30,7 +30,7 @@ class ILog; /// Driver for JACK audio and midi ports that uses libjack -class JackDriver : public Driver +class JackDriver : public AudioDriver { public: explicit JackDriver(ILog& log, EventSink emit_event); @@ -43,23 +43,20 @@ public: ~JackDriver() override; + // Driver interface void attach(bool launch_daemon) override; void detach() override; - - bool is_attached() const override { return (_client != nullptr); } - + bool is_attached() const override; void refresh(const EventSink& sink) override; - bool connect(const PortID& tail_id, const PortID& head_id) override; - bool disconnect(const PortID& tail_id, const PortID& head_id) override; - uint32_t get_xruns() const { return _xruns; } - void reset_xruns(); - - uint32_t sample_rate() { return jack_get_sample_rate(_client); } - uint32_t buffer_size(); - bool set_buffer_size(jack_nframes_t size); + // AudioDriver interface + uint32_t xruns() override; + void reset_xruns() override; + uint32_t buffer_size() override; + bool set_buffer_size(uint32_t frames) override; + uint32_t sample_rate() override; private: ClientInfo get_client_info(const char* name); diff --git a/src/Patchage.cpp b/src/Patchage.cpp index 7ce1f07..5936107 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -430,7 +430,7 @@ Patchage::update_load() { #if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS) if (_jack_driver->is_attached()) { - const auto xruns = _jack_driver->get_xruns(); + const auto xruns = _jack_driver->xruns(); if (xruns > 0u) { _dropouts_label->set_text(fmt::format(" Dropouts: {}", xruns)); _dropouts_label->show(); |