summaryrefslogtreecommitdiff
path: root/libs/backends
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-09-18 14:50:31 +0200
committerRobin Gareus <robin@gareus.org>2017-09-18 14:50:31 +0200
commit128a9853614e4c4a8e3b831de3ada60f0679d0b8 (patch)
treec9bbccba31deff046eae695bcdc1e6c7c3cda6a4 /libs/backends
parent71424c9db5b1f660f662171f12dfa8b4f7de3463 (diff)
ALSA Backend: Separate Device Reservation into its own class
Diffstat (limited to 'libs/backends')
-rw-r--r--libs/backends/alsa/alsa_audiobackend.cc182
-rw-r--r--libs/backends/alsa/alsa_audiobackend.h24
2 files changed, 114 insertions, 92 deletions
diff --git a/libs/backends/alsa/alsa_audiobackend.cc b/libs/backends/alsa/alsa_audiobackend.cc
index 525ff2e757..93ec8dead8 100644
--- a/libs/backends/alsa/alsa_audiobackend.cc
+++ b/libs/backends/alsa/alsa_audiobackend.cc
@@ -59,7 +59,6 @@ AlsaAudioBackend::AlsaAudioBackend (AudioEngine& e, AudioBackendInfo& info)
, _input_audio_device("")
, _output_audio_device("")
, _midi_driver_option(get_standard_device_name(DeviceNone))
- , _device_reservation(0)
, _samplerate (48000)
, _samples_per_period (1024)
, _periods_per_cycle (2)
@@ -142,83 +141,6 @@ AlsaAudioBackend::enumerate_output_devices () const
return _output_audio_device_status;
}
-void
-AlsaAudioBackend::reservation_stdout (std::string d, size_t /* s */)
-{
- if (d.substr(0, 19) == "Acquired audio-card") {
- _reservation_succeeded = true;
- }
-}
-
-void
-AlsaAudioBackend::release_device()
-{
- _reservation_connection.drop_connections();
- ARDOUR::SystemExec * tmp = _device_reservation;
- _device_reservation = 0;
- delete tmp;
-}
-
-bool
-AlsaAudioBackend::acquire_device(const char* device_name)
-{
- /* This is quick hack, ideally we'll link against libdbus and implement a dbus-listener
- * that owns the device. here we try to get away by just requesting it and then block it...
- * (pulseaudio periodically checks anyway)
- *
- * dbus-send --session --print-reply --type=method_call --dest=org.freedesktop.ReserveDevice1.Audio2 /org/freedesktop/ReserveDevice1/Audio2 org.freedesktop.ReserveDevice1.RequestRelease int32:4
- * -> should not return 'boolean false'
- */
- int device_number = card_to_num(device_name);
- if (device_number < 0) return false;
-
- assert(_device_reservation == 0);
- _reservation_succeeded = false;
-
- std::string request_device_exe;
- if (!PBD::find_file (
- PBD::Searchpath(Glib::build_filename(ARDOUR::ardour_dll_directory(), "ardouralsautil")
- + G_SEARCHPATH_SEPARATOR_S + ARDOUR::ardour_dll_directory()),
- "ardour-request-device", request_device_exe))
- {
- PBD::warning << "ardour-request-device binary was not found..'" << endmsg;
- return false;
- }
- else
- {
- char **argp;
- char tmp[128];
- argp=(char**) calloc(5,sizeof(char*));
- argp[0] = strdup(request_device_exe.c_str());
- argp[1] = strdup("-P");
- snprintf(tmp, sizeof(tmp), "%d", getpid());
- argp[2] = strdup(tmp);
- snprintf(tmp, sizeof(tmp), "Audio%d", device_number);
- argp[3] = strdup(tmp);
- argp[4] = 0;
-
- _device_reservation = new ARDOUR::SystemExec(request_device_exe, argp);
- _device_reservation->ReadStdout.connect_same_thread (_reservation_connection, boost::bind (&AlsaAudioBackend::reservation_stdout, this, _1 ,_2));
- _device_reservation->Terminated.connect_same_thread (_reservation_connection, boost::bind (&AlsaAudioBackend::release_device, this));
- if (_device_reservation->start(0)) {
- PBD::warning << _("AlsaAudioBackend: Device Request failed.") << endmsg;
- release_device();
- return false;
- }
- }
- // wait to check if reservation suceeded.
- int timeout = 500; // 5 sec
- while (_device_reservation && !_reservation_succeeded && --timeout > 0) {
- Glib::usleep(10000);
- }
- if (timeout == 0 || !_reservation_succeeded) {
- PBD::warning << _("AlsaAudioBackend: Device Reservation failed.") << endmsg;
- release_device();
- return false;
- }
- return true;
-}
-
std::vector<float>
AlsaAudioBackend::available_sample_rates2 (const std::string& input_device, const std::string& output_device) const
{
@@ -834,7 +756,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
_freewheel = false;
_last_process_start = 0;
- release_device();
+ _device_reservation.release_device();
assert(_rmidi_in.size() == 0);
assert(_rmidi_out.size() == 0);
@@ -881,7 +803,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
return AudioDeviceNotAvailableError;
}
- acquire_device(alsa_device.c_str());
+ _device_reservation.acquire_device(alsa_device.c_str());
_pcmi = new Alsa_pcmi (
(duplex & 2) ? alsa_device.c_str() : NULL,
(duplex & 1) ? alsa_device.c_str() : NULL,
@@ -929,7 +851,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
if (_pcmi->state ()) {
delete _pcmi; _pcmi = 0;
- release_device();
+ _device_reservation.release_device();
return error_code;
}
@@ -974,7 +896,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
if (register_system_audio_ports()) {
PBD::error << _("AlsaAudioBackend: failed to register system ports.") << endmsg;
delete _pcmi; _pcmi = 0;
- release_device();
+ _device_reservation.release_device();
return PortRegistrationError;
}
@@ -984,7 +906,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
if (engine.reestablish_ports ()) {
PBD::error << _("AlsaAudioBackend: Could not re-establish ports.") << endmsg;
delete _pcmi; _pcmi = 0;
- release_device();
+ _device_reservation.release_device();
return PortReconnectError;
}
@@ -999,7 +921,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
{
PBD::error << _("AlsaAudioBackend: failed to create process thread.") << endmsg;
delete _pcmi; _pcmi = 0;
- release_device();
+ _device_reservation.release_device();
_run = false;
return ProcessThreadStartError;
} else {
@@ -1013,7 +935,7 @@ AlsaAudioBackend::_start (bool for_latency_measurement)
if (timeout == 0 || !_active) {
PBD::error << _("AlsaAudioBackend: failed to start process thread.") << endmsg;
delete _pcmi; _pcmi = 0;
- release_device();
+ _device_reservation.release_device();
_run = false;
return ProcessThreadStartError;
}
@@ -1051,7 +973,7 @@ AlsaAudioBackend::stop ()
unregister_ports();
delete _pcmi; _pcmi = 0;
_midi_ins = _midi_outs = 0;
- release_device();
+ _device_reservation.release_device();
_measure_latency = false;
return (_active == false) ? 0 : -1;
@@ -2377,3 +2299,91 @@ AlsaMidiEvent::AlsaMidiEvent (const AlsaMidiEvent& other)
memcpy (_data, other._data, other._size);
}
};
+
+/******************************************************************************/
+
+AlsaDeviceReservation::AlsaDeviceReservation ()
+ : _device_reservation (0)
+{}
+
+AlsaDeviceReservation::AlsaDeviceReservation (const char* device_name)
+ : _device_reservation (0)
+{
+ acquire_device (device_name);
+}
+
+AlsaDeviceReservation::~AlsaDeviceReservation ()
+{
+ release_device ();
+}
+
+bool
+AlsaDeviceReservation::acquire_device (const char* device_name)
+{
+ int device_number = card_to_num(device_name);
+ if (device_number < 0) return false;
+
+ assert(_device_reservation == 0);
+ _reservation_succeeded = false;
+
+ std::string request_device_exe;
+ if (!PBD::find_file (
+ PBD::Searchpath(Glib::build_filename(ARDOUR::ardour_dll_directory(), "ardouralsautil")
+ + G_SEARCHPATH_SEPARATOR_S + ARDOUR::ardour_dll_directory()),
+ "ardour-request-device", request_device_exe))
+ {
+ PBD::warning << "ardour-request-device binary was not found..'" << endmsg;
+ return false;
+ }
+
+ char **argp;
+ char tmp[128];
+ argp=(char**) calloc(5,sizeof(char*));
+ argp[0] = strdup(request_device_exe.c_str());
+ argp[1] = strdup("-P");
+ snprintf(tmp, sizeof(tmp), "%d", getpid());
+ argp[2] = strdup(tmp);
+ snprintf(tmp, sizeof(tmp), "Audio%d", device_number);
+ argp[3] = strdup(tmp);
+ argp[4] = 0;
+
+ _device_reservation = new ARDOUR::SystemExec(request_device_exe, argp);
+ _device_reservation->ReadStdout.connect_same_thread (_reservation_connection, boost::bind (&AlsaDeviceReservation::reservation_stdout, this, _1 ,_2));
+ _device_reservation->Terminated.connect_same_thread (_reservation_connection, boost::bind (&AlsaDeviceReservation::release_device, this));
+
+ if (_device_reservation->start(0)) {
+ PBD::warning << _("AlsaAudioBackend: Device Request failed.") << endmsg;
+ release_device();
+ return false;
+ }
+
+ /* wait to check if reservation suceeded. */
+ int timeout = 500; // 5 sec
+ while (_device_reservation && !_reservation_succeeded && --timeout > 0) {
+ Glib::usleep(10000);
+ }
+
+ if (timeout == 0 || !_reservation_succeeded) {
+ PBD::warning << _("AlsaAudioBackend: Device Reservation failed.") << endmsg;
+ release_device();
+ return false;
+ }
+ return true;
+}
+
+void
+AlsaDeviceReservation::release_device ()
+{
+ _reservation_connection.drop_connections();
+ ARDOUR::SystemExec* tmp = _device_reservation;
+ _device_reservation = 0;
+ delete tmp;
+}
+
+void
+AlsaDeviceReservation::reservation_stdout (std::string d, size_t /* s */)
+{
+ if (d.substr(0, 19) == "Acquired audio-card") {
+ _reservation_succeeded = true;
+ }
+}
diff --git a/libs/backends/alsa/alsa_audiobackend.h b/libs/backends/alsa/alsa_audiobackend.h
index c175a1950b..e90bec5df9 100644
--- a/libs/backends/alsa/alsa_audiobackend.h
+++ b/libs/backends/alsa/alsa_audiobackend.h
@@ -158,6 +158,23 @@ class AlsaMidiPort : public AlsaPort {
int _bufperiod;
}; // class AlsaMidiPort
+class AlsaDeviceReservation
+{
+ public:
+ AlsaDeviceReservation ();
+ AlsaDeviceReservation (const char* device_name);
+ ~AlsaDeviceReservation ();
+
+ bool acquire_device (const char* device_name);
+ void release_device ();
+
+ private:
+ ARDOUR::SystemExec* _device_reservation;
+ PBD::ScopedConnectionList _reservation_connection;
+ void reservation_stdout (std::string, size_t);
+ bool _reservation_succeeded;
+};
+
class AlsaAudioBackend : public AudioBackend {
friend class AlsaPort;
public:
@@ -345,12 +362,7 @@ class AlsaAudioBackend : public AudioBackend {
std::string _midi_driver_option;
/* audio device reservation */
- ARDOUR::SystemExec *_device_reservation;
- PBD::ScopedConnectionList _reservation_connection;
- void reservation_stdout (std::string, size_t);
- bool acquire_device(const char* device_name);
- void release_device();
- bool _reservation_succeeded;
+ AlsaDeviceReservation _device_reservation;
/* audio settings */
float _samplerate;