From e435f22793641263e88bd44a8f47fc266db920b5 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 6 Sep 2013 21:00:01 -0400 Subject: [PATCH] add input/output channel counts and reorganize table somewhat --- gtk2_ardour/engine_dialog.cc | 187 +++++++++++++++++------------------ gtk2_ardour/engine_dialog.h | 5 +- 2 files changed, 92 insertions(+), 100 deletions(-) diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 22889cf038..46df096e69 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -56,31 +56,20 @@ EngineControl::EngineControl () , input_latency (input_latency_adjustment) , output_latency_adjustment (0, 0, 99999, 1) , output_latency (output_latency_adjustment) - , input_channels_adjustment (2, 0, 256, 1) + , input_channels_adjustment (0, 0, 256, 1) , input_channels (input_channels_adjustment) - , output_channels_adjustment (2, 0, 256, 1) + , output_channels_adjustment (0, 0, 256, 1) , output_channels (output_channels_adjustment) , ports_adjustment (128, 8, 1024, 1, 16) , ports_spinner (ports_adjustment) , realtime_button (_("Realtime")) -#ifdef __APPLE___ - , basic_packer (6, 2) -#else - , basic_packer (9, 2) -#endif + , basic_packer (9, 3) { using namespace Notebook_Helpers; Label* label; vector strings; int row = 0; - - /* basic parameters */ - - basic_packer.set_spacings (6); - - strings.clear (); - vector backends = ARDOUR::AudioEngine::instance()->available_backends(); for (vector::const_iterator b = backends.begin(); b != backends.end(); ++b) { strings.push_back ((*b)->name); @@ -88,77 +77,82 @@ EngineControl::EngineControl () 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)); - strings.clear (); - strings.push_back (_("None")); -#ifdef __APPLE__ - strings.push_back (_("coremidi")); -#else - strings.push_back (_("seq")); - strings.push_back (_("raw")); -#endif - set_popdown_strings (midi_driver_combo, strings); - midi_driver_combo.set_active_text (strings.front ()); + basic_packer.set_spacings (6); + basic_packer.set_border_width (12); + basic_packer.set_homogeneous (true); row = 0; + const AttachOptions xopt = AttachOptions (FILL|EXPAND); + label = manage (left_aligned_label (_("Audio System:"))); - basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (backend_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0); + basic_packer.attach (backend_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0); row++; label = manage (left_aligned_label (_("Driver:"))); - basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (driver_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0); + basic_packer.attach (driver_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0); row++; label = manage (left_aligned_label (_("Device:"))); - basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (device_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0); + basic_packer.attach (device_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0); row++; label = manage (left_aligned_label (_("Sample rate:"))); - basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0); + 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, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0); + basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0); + buffer_size_duration_label.set_alignment (0.0); /* left-align */ + 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, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (input_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0); + basic_packer.attach (input_latency, 1, 2, row, row+1, xopt, (AttachOptions) 0); label = manage (left_aligned_label (_("samples"))); - basic_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0); ++row; label = manage (left_aligned_label (_("Hardware output latency:"))); - basic_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (output_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0); + basic_packer.attach (output_latency, 1, 2, row, row+1, xopt, (AttachOptions) 0); label = manage (left_aligned_label (_("samples"))); - basic_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0); + basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0); ++row; - device_combo.set_size_request (250, -1); - input_device_combo.set_size_request (250, -1); - output_device_combo.set_size_request (250, -1); - device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed)); basic_hbox.pack_start (basic_packer, false, false); - basic_packer.set_border_width (12); midi_packer.set_border_width (12); notebook.pages().push_back (TabElem (basic_hbox, _("Audio"))); @@ -212,6 +206,20 @@ EngineControl::backend_changed () maybe_set_state (); } +bool +EngineControl::print_channel_count (Gtk::SpinButton* sb) +{ + uint32_t cnt = (uint32_t) sb->get_value(); + if (cnt == 0) { + sb->set_text (_("all available channels")); + } else { + char buf[32]; + snprintf (buf, sizeof (buf), "%d", cnt); + sb->set_text (buf); + } + return true; +} + void EngineControl::list_devices () { @@ -292,10 +300,23 @@ EngineControl::device_changed () set_popdown_strings (sample_rate_combo, s); sample_rate_combo.set_active_text (s.front()); - reshow_buffer_sizes (true); - sr_connection.unblock (); - + + vector bs = backend->available_buffer_sizes(device_name); + s.clear (); + for (vector::const_iterator x = bs.begin(); x != bs.end(); ++x) { + char buf[32]; + /* Translators: "samples" is always plural here, so no + need for plural+singular forms. + */ + snprintf (buf, sizeof (buf), _("%u samples"), *x); + s.push_back (buf); + } + + set_popdown_strings (buffer_size_combo, s); + buffer_size_combo.set_active_text (s.front()); + show_buffer_duration (); + maybe_set_state (); } @@ -303,10 +324,10 @@ void EngineControl::sample_rate_changed () { /* reset the strings for buffer size to show the correct msec value - (reflecting the new sample rate + (reflecting the new sample rate). */ - reshow_buffer_sizes (false); + show_buffer_duration (); save_state (); } @@ -314,61 +335,32 @@ EngineControl::sample_rate_changed () void EngineControl::buffer_size_changed () { + show_buffer_duration (); save_state (); } void -EngineControl::reshow_buffer_sizes (bool size_choice_changed) +EngineControl::show_buffer_duration () { - boost::shared_ptr backend = ARDOUR::AudioEngine::instance()->current_backend(); - assert (backend); - string device_name = device_combo.get_active_text (); - vector s; - uint32_t existing_size_choice = 0; - string new_target_string; /* 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(), "%" PRIu32, &existing_size_choice); - } - - s.clear (); - vector bs = backend->available_buffer_sizes(device_name); + string bs_text = buffer_size_combo.get_active_text (); + uint32_t samples = atoi (bs_text); /* will ignore trailing text */ uint32_t rate = get_rate(); - 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); - - 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 (); + /* Translators: "msecs" is ALWAYS plural here, so we do not + need singular form as well. + */ + /* Developers: note the hard-coding of a double buffered model + in the (2 * samples) computation of latency. we always start + the audiobackend in this configuration. + */ + char buf[32]; + snprintf (buf, sizeof (buf), _("(%.1f msecs)"), (2 * samples) / (rate/1000.0)); + buffer_size_duration_label.set_text (buf); } void @@ -441,6 +433,8 @@ EngineControl::save_state () state->sample_rate = sample_rate_combo.get_active_text (); state->input_latency = (uint32_t) input_latency.get_value(); state->output_latency = (uint32_t) output_latency.get_value(); + state->input_channels = (uint32_t) input_channels.get_value(); + state->output_channels = (uint32_t) output_channels.get_value(); if (!existing) { states.push_back (*state); @@ -456,10 +450,6 @@ EngineControl::maybe_set_state () sr_connection.block (); bs_connection.block (); sample_rate_combo.set_active_text (state->sample_rate); - /* need to reset possible strings for buffer size before we do - this - */ - reshow_buffer_sizes (false); buffer_size_combo.set_active_text (state->buffer_size); input_latency.set_value (state->input_latency); output_latency.set_value (state->output_latency); @@ -518,7 +508,6 @@ EngineControl::set_state (const XMLNode& root) states.clear (); - for (citer = clist.begin(); citer != clist.end(); ++citer) { child = *citer; diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h index 534eb6a6a3..553563cafb 100644 --- a/gtk2_ardour/engine_dialog.h +++ b/gtk2_ardour/engine_dialog.h @@ -54,6 +54,7 @@ class EngineControl : public Gtk::VBox { Gtk::ComboBoxText output_device_combo; Gtk::ComboBoxText sample_rate_combo; Gtk::ComboBoxText buffer_size_combo; + Gtk::Label buffer_size_duration_label; Gtk::Adjustment input_latency_adjustment; Gtk::SpinButton input_latency; Gtk::Adjustment output_latency_adjustment; @@ -114,7 +115,7 @@ class EngineControl : public Gtk::VBox { void audio_mode_changed (); void device_changed (); void list_devices (); - void reshow_buffer_sizes (bool choice_changed); + void show_buffer_duration (); struct State { std::string backend; @@ -141,6 +142,8 @@ class EngineControl : public Gtk::VBox { State* get_current_state (); void maybe_set_state (); void save_state (); + + static bool print_channel_count (Gtk::SpinButton*); }; #endif /* __gtk2_ardour_engine_dialog_h__ */