summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/engine_dialog.cc135
-rw-r--r--gtk2_ardour/engine_dialog.h7
-rw-r--r--libs/ardour/ardour/audio_backend.h6
-rw-r--r--libs/backends/jack/jack_audiobackend.cc49
-rw-r--r--libs/backends/jack/jack_audiobackend.h1
5 files changed, 111 insertions, 87 deletions
diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc
index c55fc7008b..b03dc9a304 100644
--- a/gtk2_ardour/engine_dialog.cc
+++ b/gtk2_ardour/engine_dialog.cc
@@ -25,7 +25,6 @@
#include <boost/scoped_ptr.hpp>
-#include <glibmm/spawn.h>
#include <gtkmm/messagedialog.h>
#include "pbd/error.h"
@@ -65,6 +64,7 @@ EngineControl::EngineControl ()
, ports_spinner (ports_adjustment)
, control_app_button (_("Launch Control App"))
, basic_packer (9, 3)
+ , ignore_changes (0)
{
build_notebook ();
@@ -82,9 +82,12 @@ EngineControl::EngineControl ()
XMLNode* audio_setup = ARDOUR::Config->extra_xml ("AudioMIDISetup");
+ /* push a change as if we altered the backend */
+ backend_changed ();
+
if (audio_setup) {
set_state (*audio_setup);
- }
+ }
}
void
@@ -94,10 +97,10 @@ EngineControl::on_response (int response_id)
switch (response_id) {
case RESPONSE_APPLY:
- setup_engine (true);
+ push_state_to_backend (true);
break;
case RESPONSE_OK:
- setup_engine (true);
+ push_state_to_backend (true);
hide ();
break;
default:
@@ -120,10 +123,6 @@ EngineControl::build_notebook ()
set_popdown_strings (backend_combo, strings);
backend_combo.set_active_text (strings.front());
- backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
- backend_changed ();
-
- driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
basic_packer.set_spacings (6);
basic_packer.set_border_width (12);
@@ -153,7 +152,6 @@ EngineControl::build_notebook ()
basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
row++;
- sr_connection = sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
label = manage (left_aligned_label (_("Buffer size:")));
basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
@@ -162,21 +160,18 @@ EngineControl::build_notebook ()
basic_packer.attach (buffer_size_duration_label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
row++;
- bs_connection = buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
label = manage (left_aligned_label (_("Input Channels:")));
basic_packer.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
basic_packer.attach (input_channels, 1, 2, row, row+1, xopt, (AttachOptions) 0);
++row;
- input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
label = manage (left_aligned_label (_("Output Channels:")));
basic_packer.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
basic_packer.attach (output_channels, 1, 2, row, row+1, xopt, (AttachOptions) 0);
++row;
- output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
label = manage (left_aligned_label (_("Hardware input latency:")));
basic_packer.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
@@ -192,8 +187,6 @@ EngineControl::build_notebook ()
basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
++row;
- device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
-
basic_hbox.pack_start (basic_packer, false, false);
basic_vbox.pack_start (basic_hbox, false, false);
@@ -215,6 +208,15 @@ EngineControl::build_notebook ()
notebook.set_name ("SettingsNotebook");
+ /* Connect to signals */
+
+ backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
+ driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
+ sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
+ buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
+ input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
+ output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
+ device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
}
EngineControl::~EngineControl ()
@@ -225,11 +227,15 @@ EngineControl::~EngineControl ()
void
EngineControl::backend_changed ()
{
+ if (ignore_changes) {
+ return;
+ }
+
string backend_name = backend_combo.get_active_text();
boost::shared_ptr<ARDOUR::AudioBackend> backend;
if (!(backend = ARDOUR::AudioEngine::instance()->set_backend (backend_name, "ardour", ""))) {
- /* eh? */
+ /* eh? setting the backend failed... how ? */
return;
}
@@ -244,7 +250,7 @@ EngineControl::backend_changed ()
list_devices ();
}
- maybe_set_state ();
+ maybe_display_saved_state ();
}
bool
@@ -302,18 +308,26 @@ EngineControl::list_devices ()
void
EngineControl::driver_changed ()
{
+ if (ignore_changes) {
+ return;
+ }
+
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
assert (backend);
backend->set_driver (driver_combo.get_active_text());
list_devices ();
- maybe_set_state ();
+ maybe_display_saved_state ();
}
void
EngineControl::device_changed ()
{
+ if (ignore_changes) {
+ return;
+ }
+
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
assert (backend);
string device_name = device_combo.get_active_text ();
@@ -323,7 +337,7 @@ EngineControl::device_changed ()
recursive call to this method.
*/
- sr_connection.block ();
+ ignore_changes++;
/* sample rates */
@@ -341,7 +355,6 @@ EngineControl::device_changed ()
set_popdown_strings (sample_rate_combo, s);
sample_rate_combo.set_active_text (s.front());
- sr_connection.unblock ();
vector<uint32_t> bs = backend->available_buffer_sizes(device_name);
s.clear ();
@@ -360,12 +373,18 @@ EngineControl::device_changed ()
manage_control_app_sensitivity ();
- maybe_set_state ();
+ ignore_changes--;
+
+ maybe_display_saved_state ();
}
void
EngineControl::sample_rate_changed ()
{
+ if (ignore_changes) {
+ return;
+ }
+
/* reset the strings for buffer size to show the correct msec value
(reflecting the new sample rate).
*/
@@ -378,6 +397,10 @@ EngineControl::sample_rate_changed ()
void
EngineControl::buffer_size_changed ()
{
+ if (ignore_changes) {
+ return;
+ }
+
show_buffer_duration ();
save_state ();
}
@@ -448,8 +471,8 @@ EngineControl::get_current_state ()
if (backend) {
return get_matching_state (backend_combo.get_active_text(),
- (backend->requires_driver_selection() ? (std::string) driver_combo.get_active_text() : string()),
- device_combo.get_active_text());
+ (backend->requires_driver_selection() ? (std::string) driver_combo.get_active_text() : string()),
+ device_combo.get_active_text());
}
@@ -485,19 +508,17 @@ EngineControl::save_state ()
}
void
-EngineControl::maybe_set_state ()
+EngineControl::maybe_display_saved_state ()
{
State* state = get_current_state ();
if (state) {
- sr_connection.block ();
- bs_connection.block ();
+ ignore_changes++;
sample_rate_combo.set_active_text (state->sample_rate);
buffer_size_combo.set_active_text (state->buffer_size);
input_latency.set_value (state->input_latency);
output_latency.set_value (state->output_latency);
- bs_connection.unblock ();
- sr_connection.unblock ();
+ ignore_changes--;
}
}
@@ -628,8 +649,7 @@ EngineControl::set_state (const XMLNode& root)
for (StateList::const_iterator i = states.begin(); i != states.end(); ++i) {
if ((*i).active) {
- sr_connection.block ();
- bs_connection.block ();
+ ignore_changes++;
backend_combo.set_active_text ((*i).backend);
driver_combo.set_active_text ((*i).driver);
device_combo.set_active_text ((*i).device);
@@ -637,18 +657,23 @@ EngineControl::set_state (const XMLNode& root)
buffer_size_combo.set_active_text ((*i).buffer_size);
input_latency.set_value ((*i).input_latency);
output_latency.set_value ((*i).output_latency);
- sr_connection.unblock ();
- bs_connection.unblock ();
+ ignore_changes--;
+
+ push_state_to_backend (false);
break;
}
}
}
+
int
-EngineControl::setup_engine (bool start)
+EngineControl::push_state_to_backend (bool start)
{
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
- assert (backend);
+
+ if (!backend) {
+ return 0;
+ }
/* grab the parameters from the GUI and apply them */
@@ -792,51 +817,25 @@ EngineControl::get_device_name () const
void
EngineControl::control_app_button_clicked ()
{
- const char* env_value = g_getenv ("ARDOUR_DEVICE_CONTROL_APP");
- string appname;
-
- cerr << "Environment var for control app: " << (env_value ? env_value : "empty") << endl;
+ boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
- if (!env_value) {
- boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
-
- if (!backend) {
- return;
- }
-
- appname = backend->control_app_name();
- } else {
- appname = env_value;
- }
-
- cerr << "appname for control app " << appname << endl;
-
- if (appname.empty()) {
+ if (!backend) {
return;
}
-
- std::list<string> args;
- args.push_back (appname);
- Glib::spawn_async ("", args, Glib::SPAWN_SEARCH_PATH);
+
+ backend->launch_control_app ();
}
void
EngineControl::manage_control_app_sensitivity ()
{
- const char* env_value = g_getenv ("ARDOUR_DEVICE_CONTROL_APP");
- string appname;
+ boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
- if (!env_value) {
- boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
-
- if (!backend) {
- return;
- }
-
- appname = backend->control_app_name();
- } else {
- appname = env_value;
+ if (!backend) {
+ return;
}
+
+ string appname = backend->control_app_name();
if (appname.empty()) {
control_app_button.set_sensitive (false);
diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h
index 8f5a615228..cdeb18a2c7 100644
--- a/gtk2_ardour/engine_dialog.h
+++ b/gtk2_ardour/engine_dialog.h
@@ -41,7 +41,6 @@ class EngineControl : public ArdourDialog {
~EngineControl ();
static bool need_setup ();
- int setup_engine (bool start);
XMLNode& get_state ();
void set_state (const XMLNode&);
@@ -97,8 +96,7 @@ class EngineControl : public ArdourDialog {
Gtk::VBox basic_vbox;
Gtk::HBox midi_hbox;
- sigc::connection sr_connection;
- sigc::connection bs_connection;
+ uint32_t ignore_changes;
static bool engine_running ();
@@ -144,7 +142,7 @@ class EngineControl : public ArdourDialog {
const std::string& driver,
const std::string& device);
State* get_current_state ();
- void maybe_set_state ();
+ void maybe_display_saved_state ();
void save_state ();
static bool print_channel_count (Gtk::SpinButton*);
@@ -154,6 +152,7 @@ class EngineControl : public ArdourDialog {
void on_response (int);
void control_app_button_clicked ();
void manage_control_app_sensitivity ();
+ int push_state_to_backend (bool start);
};
#endif /* __gtk2_ardour_engine_dialog_h__ */
diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h
index b8a1818e24..ab37bea526 100644
--- a/libs/ardour/ardour/audio_backend.h
+++ b/libs/ardour/ardour/audio_backend.h
@@ -234,7 +234,11 @@ class AudioBackend {
* return an empty string.
*/
virtual std::string control_app_name() const = 0;
-
+ /** Launch the control app for the currently in-use or
+ * selected device. May do nothing if the control
+ * app is undefined or cannot be launched.
+ */
+ virtual void launch_control_app () = 0;
/* Basic state control */
/** Start using the device named in the most recent call
diff --git a/libs/backends/jack/jack_audiobackend.cc b/libs/backends/jack/jack_audiobackend.cc
index 3cbd0cd6ae..c275d37f64 100644
--- a/libs/backends/jack/jack_audiobackend.cc
+++ b/libs/backends/jack/jack_audiobackend.cc
@@ -23,6 +23,7 @@
#include <boost/scoped_ptr.hpp>
#include <glibmm/timer.h>
+#include <glibmm/spawn.h>
#include "pbd/error.h"
@@ -957,25 +958,45 @@ JACKAudioBackend::can_change_buffer_size_when_running () const
string
JACKAudioBackend::control_app_name () const
{
- string appname;
-
- std::cerr << "td = " << _target_driver << " tdev = " << _target_device << std::endl;
-
- if (_target_driver.empty() || _target_device.empty()) {
- return appname;
- }
+ /* Since JACK/ALSA really don't provide particularly integrated support
+ for the idea of a control app to be used to control a device,
+ allow the user to take some control themselves if necessary.
+ */
- if (_target_driver == "ALSA") {
+ const char* env_value = g_getenv ("ARDOUR_DEVICE_CONTROL_APP");
+ string appname;
- if (_target_device == "Hammerfall DSP") {
- appname = "hdspconf";
- } else if (_target_device == "M Audio Delta 1010") {
- appname = "mudita";
+ if (!env_value) {
+ if (_target_driver.empty() || _target_device.empty()) {
+ return appname;
+ }
+
+ if (_target_driver == "ALSA") {
+
+ if (_target_device == "Hammerfall DSP") {
+ appname = "hdspconf";
+ } else if (_target_device == "M Audio Delta 1010") {
+ appname = "mudita";
+ }
}
+ } else {
+ appname = env_value;
}
-
- std::cerr << "appname retrurned as " << appname << std::endl;
return appname;
}
+void
+JACKAudioBackend::launch_control_app ()
+{
+ string appname = control_app_name();
+
+ if (appname.empty()) {
+ error << string_compose (_("There is no control application for the device \"%1\""), _target_device) << endmsg;
+ return;
+ }
+
+ std::list<string> args;
+ args.push_back (appname);
+ Glib::spawn_async ("", args, Glib::SPAWN_SEARCH_PATH);
+}
diff --git a/libs/backends/jack/jack_audiobackend.h b/libs/backends/jack/jack_audiobackend.h
index 969a28a77a..1389e15c4a 100644
--- a/libs/backends/jack/jack_audiobackend.h
+++ b/libs/backends/jack/jack_audiobackend.h
@@ -85,6 +85,7 @@ class JACKAudioBackend : public AudioBackend {
uint32_t systemic_output_latency () const;
std::string control_app_name () const;
+ void launch_control_app ();
int start ();
int stop ();