From 58dd0198e6dcf40ec684c32019e104f0b1a58472 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 4 Sep 2013 15:45:54 -0400 Subject: [PATCH] save and restore settings for different backend/driver/device combinations So far, this is only internal - never saved to disk --- gtk2_ardour/ardour_ui_ed.cc | 20 ++--- gtk2_ardour/engine_dialog.cc | 145 +++++++++++++++++++++++++++++++---- gtk2_ardour/engine_dialog.h | 23 +++++- 3 files changed, 164 insertions(+), 24 deletions(-) diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 82d32315c5..c30627fdec 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -195,25 +195,25 @@ ARDOUR_UI::install_actions () act = ActionManager::register_action (engine_actions, X_("JACKDisconnect"), _("Disconnect"), sigc::mem_fun (*(ARDOUR_UI::instance()), &ARDOUR_UI::disconnect_from_jack)); ActionManager::engine_sensitive_actions.push_back (act); - RadioAction::Group jack_latency_group; + RadioAction::Group latency_group; - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency32"), X_("32"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 32)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency32"), X_("32"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 32)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency64"), X_("64"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 64)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency64"), X_("64"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 64)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency128"), X_("128"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 128)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency128"), X_("128"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 128)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency256"), X_("256"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 256)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency256"), X_("256"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 256)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency512"), X_("512"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 512)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency512"), X_("512"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 512)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency1024"), X_("1024"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 1024)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency1024"), X_("1024"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 1024)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency2048"), X_("2048"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 2048)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency2048"), X_("2048"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 2048)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency4096"), X_("4096"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 4096)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency4096"), X_("4096"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 4096)); ActionManager::engine_sensitive_actions.push_back (act); - act = ActionManager::register_radio_action (engine_actions, jack_latency_group, X_("JACKLatency8192"), X_("8192"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 8192)); + act = ActionManager::register_radio_action (engine_actions, latency_group, X_("JACKLatency8192"), X_("8192"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::set_jack_buffer_size), (pframes_t) 8192)); ActionManager::engine_sensitive_actions.push_back (act); /* these actions are intended to be shared across all windows */ diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 3ffb7dc6da..0ad27e29d4 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -128,11 +128,15 @@ EngineControl::EngineControl () basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, FILL|EXPAND, (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, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; + bs_connection = buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed)); + label = manage (left_aligned_label (_("Hardware input latency:"))); basic_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); basic_packer.attach (input_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); @@ -147,8 +151,6 @@ EngineControl::EngineControl () basic_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0); ++row; - sr_connection = sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::reshow_buffer_sizes)); - device_combo.set_size_request (250, -1); input_device_combo.set_size_request (250, -1); output_device_combo.set_size_request (250, -1); @@ -207,6 +209,8 @@ EngineControl::backend_changed () driver_combo.set_sensitive (false); list_devices (); } + + maybe_set_state (); } void @@ -255,6 +259,8 @@ EngineControl::driver_changed () backend->set_driver (driver_combo.get_active_text()); list_devices (); + + maybe_set_state (); } void @@ -287,20 +293,78 @@ EngineControl::device_changed () set_popdown_strings (sample_rate_combo, s); sample_rate_combo.set_active_text (s.front()); - reshow_buffer_sizes (); - + reshow_buffer_sizes (true); + sr_connection.unblock (); + + maybe_set_state (); } +void +EngineControl::sample_rate_changed () +{ + bool existing = true; + State* state = get_current_state (); + + if (!state) { + existing = false; + state = new State; + state->backend = backend_combo.get_active_text (); + state->driver = driver_combo.get_active_text (); + state->device = device_combo.get_active_text (); + state->buffer_size = buffer_size_combo.get_active_text (); + } + + state->sample_rate = sample_rate_combo.get_active_text (); + + if (!existing) { + states.push_back (*state); + } + + reshow_buffer_sizes (false); +} + +void +EngineControl::buffer_size_changed () +{ + bool existing = true; + State* state = get_current_state (); + + if (!state) { + existing = false; + state = new State; + state->backend = backend_combo.get_active_text (); + state->driver = driver_combo.get_active_text (); + state->device = device_combo.get_active_text (); + state->sample_rate = sample_rate_combo.get_active_text (); + } + + state->buffer_size = buffer_size_combo.get_active_text (); + + if (!existing) { + states.push_back (*state); + } +} + void -EngineControl::reshow_buffer_sizes () +EngineControl::reshow_buffer_sizes (bool size_choice_changed) { boost::shared_ptr backend = ARDOUR::AudioEngine::instance()->current_backend(); assert (backend); string device_name = device_combo.get_active_text (); vector s; + int existing_size_choice = 0; + string new_target_string; - /* buffer sizes */ + /* buffer sizes - convert from just samples to samples + msecs for + * the displayed string + */ + + bs_connection.block (); + + if (!size_choice_changed) { + sscanf (buffer_size_combo.get_active_text().c_str(), "%d", &existing_size_choice); + } s.clear (); vector bs = backend->available_buffer_sizes(device_name); @@ -308,15 +372,32 @@ EngineControl::reshow_buffer_sizes () for (vector::const_iterator x = bs.begin(); x != bs.end(); ++x) { char buf[32]; + /* Translators: "samples" is ALWAYS plural here, so we do not need singular form as well. Same for msecs. */ snprintf (buf, sizeof (buf), _("%u samples (%.1f msecs)"), *x, (2 * (*x)) / (rate/1000.0)); s.push_back (buf); + + /* if this is the size previously chosen, this is the string we + * will want to be active in the combo. + */ + + if (existing_size_choice == *x) { + new_target_string = buf; + } + } set_popdown_strings (buffer_size_combo, s); - buffer_size_combo.set_active_text (s.front()); + + if (!new_target_string.empty()) { + buffer_size_combo.set_active_text (new_target_string); + } else { + buffer_size_combo.set_active_text (s.front()); + } + + bs_connection.unblock (); } void @@ -339,15 +420,53 @@ EngineControl::audio_mode_changed () } } -struct EngineStateKey +EngineControl::State* +EngineControl::get_matching_state (const string& backend, + const string& driver, + const string& device) { - std::string system; - std::string driver; - std::string device; -}; + for (StateList::iterator i = states.begin(); i != states.end(); ++i) { + if ((*i).backend == backend && + (*i).driver == driver && + (*i).device == device) { + return &(*i); + } + } + return 0; +} -typedef std::map EngineStateMap; +EngineControl::State* +EngineControl::get_current_state () +{ + boost::shared_ptr backend = ARDOUR::AudioEngine::instance()->current_backend(); + 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()); + } + + + return get_matching_state (backend_combo.get_active_text(), + string(), + device_combo.get_active_text()); +} + +void +EngineControl::maybe_set_state () +{ + State* state = get_current_state (); + + if (state) { + sr_connection.block (); + bs_connection.block (); + sample_rate_combo.set_active_text (state->sample_rate); + buffer_size_combo.set_active_text (state->buffer_size); + bs_connection.unblock (); + sr_connection.unblock (); + } +} + XMLNode& EngineControl::get_state () { diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h index 4dd34d9fab..6bd7fb2be0 100644 --- a/gtk2_ardour/engine_dialog.h +++ b/gtk2_ardour/engine_dialog.h @@ -94,6 +94,7 @@ class EngineControl : public Gtk::VBox { Gtk::HBox midi_hbox; sigc::connection sr_connection; + sigc::connection bs_connection; bool _used; @@ -101,6 +102,8 @@ class EngineControl : public Gtk::VBox { void driver_changed (); void backend_changed (); + void sample_rate_changed (); + void buffer_size_changed (); uint32_t get_rate() const; uint32_t get_buffer_size() const; @@ -114,7 +117,25 @@ class EngineControl : public Gtk::VBox { void audio_mode_changed (); void device_changed (); void list_devices (); - void reshow_buffer_sizes (); + void reshow_buffer_sizes (bool choice_changed); + + struct State { + std::string backend; + std::string driver; + std::string device; + std::string sample_rate; + std::string buffer_size; + }; + + typedef std::list StateList; + + StateList states; + + State* get_matching_state (const std::string& backend, + const std::string& driver, + const std::string& device); + State* get_current_state (); + void maybe_set_state (); }; #endif /* __gtk2_ardour_engine_dialog_h__ */