show a different audio/MIDI option screen if JACK is already running. try to fix problem with using AudioBackend::<property-value>() functions before anything has been set.
This commit is contained in:
parent
20fa19e69e
commit
57d24608e7
|
@ -399,14 +399,10 @@ ARDOUR_UI::engine_stopped ()
|
|||
void
|
||||
ARDOUR_UI::engine_running ()
|
||||
{
|
||||
cerr << "ENGINE RUNNING\n";
|
||||
|
||||
if (first_time_engine_run) {
|
||||
post_engine();
|
||||
first_time_engine_run = false;
|
||||
} else {
|
||||
cerr << "AGAIN...\n";
|
||||
}
|
||||
}
|
||||
|
||||
update_disk_space ();
|
||||
update_cpu_load ();
|
||||
|
@ -1084,8 +1080,6 @@ ARDOUR_UI::update_sample_rate (framecnt_t)
|
|||
{
|
||||
char buf[64];
|
||||
|
||||
cerr << "USR\n";
|
||||
|
||||
ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored)
|
||||
|
||||
if (!AudioEngine::instance()->connected()) {
|
||||
|
@ -1112,8 +1106,6 @@ ARDOUR_UI::update_sample_rate (framecnt_t)
|
|||
}
|
||||
}
|
||||
}
|
||||
cerr << "SRL = " << buf << endl;
|
||||
|
||||
sample_rate_label.set_markup (buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,20 +78,146 @@ EngineControl::EngineControl ()
|
|||
, aj_button (_("Start MIDI ALSA/JACK bridge"))
|
||||
, ignore_changes (0)
|
||||
, _desired_sample_rate (0)
|
||||
, no_push (true)
|
||||
{
|
||||
if (!ARDOUR::AudioEngine::instance()->setup_required()) {
|
||||
_have_control = false;
|
||||
} else {
|
||||
_have_control = true;
|
||||
}
|
||||
using namespace Notebook_Helpers;
|
||||
vector<string> strings;
|
||||
Label* label;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row;
|
||||
|
||||
set_name (X_("AudioMIDISetup"));
|
||||
|
||||
build_notebook ();
|
||||
/* the backend combo is the one thing that is ALWAYS visible
|
||||
*/
|
||||
|
||||
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
|
||||
for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
|
||||
strings.push_back ((*b)->name);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/* setup basic packing characteristics for the table used on the main
|
||||
* tab of the notebook
|
||||
*/
|
||||
|
||||
basic_packer.set_spacings (6);
|
||||
basic_packer.set_border_width (12);
|
||||
basic_packer.set_homogeneous (true);
|
||||
|
||||
/* pack it in */
|
||||
|
||||
basic_hbox.pack_start (basic_packer, false, false);
|
||||
|
||||
/* latency tab */
|
||||
|
||||
/* latency measurement tab */
|
||||
|
||||
lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
|
||||
|
||||
row = 0;
|
||||
lm_table.set_row_spacings (12);
|
||||
|
||||
lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
Gtk::Label* preamble;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
label = manage (new Label (_("Output channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_output_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
label = manage (new Label (_("Input channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_input_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
xopt = AttachOptions(0);
|
||||
|
||||
lm_measure_button.add (lm_start_stop_label);
|
||||
|
||||
lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
|
||||
lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
|
||||
lm_use_button.set_sensitive (false);
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
lm_results.set_markup ("<i>No measurement results yet</i>");
|
||||
|
||||
lm_vbox.set_border_width (12);
|
||||
lm_vbox.pack_start (lm_table, false, false);
|
||||
|
||||
/* pack it all up */
|
||||
|
||||
notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
|
||||
notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
|
||||
notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
|
||||
notebook.set_border_width (12);
|
||||
|
||||
notebook.set_tab_pos (POS_RIGHT);
|
||||
notebook.show_all ();
|
||||
|
||||
notebook.set_name ("SettingsNotebook");
|
||||
|
||||
/* packup the notebook */
|
||||
|
||||
get_vbox()->set_border_width (12);
|
||||
get_vbox()->pack_start (notebook);
|
||||
|
||||
/* need a special function to print "all available channels" when the
|
||||
* channel counts hit zero.
|
||||
*/
|
||||
|
||||
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));
|
||||
|
||||
control_app_button.signal_clicked().connect (mem_fun (*this, &EngineControl::control_app_button_clicked));
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
|
@ -103,12 +229,31 @@ EngineControl::EngineControl ()
|
|||
|
||||
XMLNode* audio_setup = ARDOUR::Config->extra_xml ("AudioMIDISetup");
|
||||
|
||||
/* push a change as if we altered the backend */
|
||||
ARDOUR::AudioEngine::instance()->Running.connect (running_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_running, this), gui_context());
|
||||
ARDOUR::AudioEngine::instance()->Stopped.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
|
||||
ARDOUR::AudioEngine::instance()->Halted.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
|
||||
|
||||
backend_changed ();
|
||||
|
||||
if (audio_setup) {
|
||||
set_state (*audio_setup);
|
||||
}
|
||||
}
|
||||
|
||||
/* Connect to signals */
|
||||
|
||||
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));
|
||||
device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
|
||||
|
||||
input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
|
||||
notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
|
||||
|
||||
no_push = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -139,36 +284,58 @@ EngineControl::on_response (int response_id)
|
|||
void
|
||||
EngineControl::build_notebook ()
|
||||
{
|
||||
Label* label;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
|
||||
/* clear the table */
|
||||
|
||||
Gtkmm2ext::container_clear (basic_vbox);
|
||||
Gtkmm2ext::container_clear (basic_packer);
|
||||
|
||||
label = manage (left_aligned_label (_("Audio System:")));
|
||||
basic_packer.attach (*label, 0, 1, 0, 1, xopt, (AttachOptions) 0);
|
||||
basic_packer.attach (backend_combo, 1, 2, 0, 1, xopt, (AttachOptions) 0);
|
||||
|
||||
if (_have_control) {
|
||||
build_full_control_notebook ();
|
||||
} else {
|
||||
build_no_control_notebook ();
|
||||
}
|
||||
|
||||
basic_vbox.pack_start (basic_hbox, false, false);
|
||||
|
||||
if (_have_control) {
|
||||
Gtk::HBox* hpacker = manage (new HBox);
|
||||
hpacker->set_border_width (12);
|
||||
hpacker->pack_start (control_app_button, false, false);
|
||||
hpacker->show ();
|
||||
control_app_button.show();
|
||||
basic_vbox.pack_start (*hpacker);
|
||||
}
|
||||
|
||||
basic_vbox.show_all ();
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::build_full_control_notebook ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
using namespace Notebook_Helpers;
|
||||
Label* label;
|
||||
vector<string> strings;
|
||||
int row = 0;
|
||||
|
||||
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
|
||||
for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
|
||||
strings.push_back ((*b)->name);
|
||||
}
|
||||
|
||||
set_popdown_strings (backend_combo, strings);
|
||||
backend_combo.set_active_text (strings.front());
|
||||
|
||||
basic_packer.set_spacings (6);
|
||||
basic_packer.set_border_width (12);
|
||||
basic_packer.set_homogeneous (true);
|
||||
|
||||
row = 0;
|
||||
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row = 1; // row zero == backend combo
|
||||
|
||||
label = manage (left_aligned_label (_("Audio System:")));
|
||||
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++;
|
||||
/* start packing it up */
|
||||
|
||||
label = manage (left_aligned_label (_("Driver:")));
|
||||
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++;
|
||||
if (backend->requires_driver_selection()) {
|
||||
label = manage (left_aligned_label (_("Driver:")));
|
||||
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, xopt, (AttachOptions) 0);
|
||||
|
@ -236,126 +403,46 @@ EngineControl::build_notebook ()
|
|||
basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
basic_hbox.pack_start (basic_packer, false, false);
|
||||
basic_vbox.pack_start (basic_hbox, false, false);
|
||||
}
|
||||
|
||||
Gtk::HBox* hpacker = manage (new HBox);
|
||||
hpacker->set_border_width (12);
|
||||
hpacker->pack_start (control_app_button, false, false);
|
||||
hpacker->show ();
|
||||
control_app_button.show();
|
||||
basic_vbox.pack_start (*hpacker);
|
||||
void
|
||||
EngineControl::build_no_control_notebook ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
/* latency measurement tab */
|
||||
|
||||
lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
|
||||
|
||||
row = 0;
|
||||
lm_table.set_row_spacings (12);
|
||||
using namespace Notebook_Helpers;
|
||||
Label* label;
|
||||
vector<string> strings;
|
||||
AttachOptions xopt = AttachOptions (FILL|EXPAND);
|
||||
int row = 1; // row zero == backend combo
|
||||
const string msg = string_compose (_("The %1 audio backend was configured and started externally.\nThis limits your control over it."), backend->name());
|
||||
|
||||
lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
label = manage (new Label);
|
||||
label->set_markup (string_compose ("<span weight=\"bold\" foreground=\"red\">%1</span>", msg));
|
||||
basic_packer.attach (*label, 0, 2, row, row + 1, xopt, (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
Gtk::Label* preamble;
|
||||
if (backend->can_change_sample_rate_when_running()) {
|
||||
label = manage (left_aligned_label (_("Sample rate:")));
|
||||
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++;
|
||||
}
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
|
||||
if (backend->can_change_buffer_size_when_running()) {
|
||||
label = manage (left_aligned_label (_("Buffer size:")));
|
||||
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++;
|
||||
}
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
connect_disconnect_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::connect_disconnect_click));
|
||||
|
||||
basic_packer.attach (connect_disconnect_button, 0, 2, row, row+1, FILL, AttachOptions (0));
|
||||
row++;
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
|
||||
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
label = manage (new Label (_("Output channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_output_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
label = manage (new Label (_("Input channel")));
|
||||
lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
|
||||
|
||||
misc_align = manage (new Alignment (0.0, 0.5));
|
||||
misc_align->add (lm_input_channel_combo);
|
||||
lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
xopt = AttachOptions(0);
|
||||
|
||||
lm_measure_button.add (lm_start_stop_label);
|
||||
|
||||
lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
|
||||
lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
|
||||
lm_use_button.set_sensitive (false);
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
|
||||
preamble = manage (new Label);
|
||||
preamble->set_width_chars (60);
|
||||
preamble->set_line_wrap (true);
|
||||
preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
|
||||
lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
|
||||
row++;
|
||||
|
||||
lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
|
||||
++row;
|
||||
|
||||
lm_results.set_markup ("<i>No measurement results yet</i>");
|
||||
|
||||
lm_vbox.set_border_width (12);
|
||||
lm_vbox.pack_start (lm_table, false, false);
|
||||
|
||||
/* pack it all up */
|
||||
|
||||
notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
|
||||
notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
|
||||
notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
|
||||
notebook.set_border_width (12);
|
||||
|
||||
notebook.set_tab_pos (POS_RIGHT);
|
||||
notebook.show_all ();
|
||||
|
||||
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));
|
||||
device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
|
||||
|
||||
input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
|
||||
output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_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));
|
||||
|
||||
notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
|
||||
}
|
||||
|
||||
EngineControl::~EngineControl ()
|
||||
|
@ -470,6 +557,11 @@ EngineControl::refresh_midi_display ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::update_sensitivity ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::backend_changed ()
|
||||
{
|
||||
|
@ -485,16 +577,29 @@ EngineControl::backend_changed ()
|
|||
return;
|
||||
}
|
||||
|
||||
_have_control = ARDOUR::AudioEngine::instance()->setup_required ();
|
||||
|
||||
build_notebook ();
|
||||
setup_midi_tab_for_backend ();
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
vector<string> drivers = backend->enumerate_drivers();
|
||||
driver_combo.set_sensitive (true);
|
||||
set_popdown_strings (driver_combo, drivers);
|
||||
driver_combo.set_active_text (drivers.front());
|
||||
driver_changed ();
|
||||
|
||||
if (!drivers.empty()) {
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
set_popdown_strings (driver_combo, drivers);
|
||||
driver_combo.set_active_text (drivers.front());
|
||||
}
|
||||
|
||||
driver_changed ();
|
||||
}
|
||||
|
||||
} else {
|
||||
driver_combo.set_sensitive (false);
|
||||
/* this will change the device text which will cause a call to
|
||||
* device changed which will set up parameters
|
||||
*/
|
||||
list_devices ();
|
||||
}
|
||||
|
||||
|
@ -540,33 +645,33 @@ EngineControl::list_devices ()
|
|||
available_devices.push_back (i->name);
|
||||
}
|
||||
|
||||
ignore_changes++;
|
||||
set_popdown_strings (device_combo, available_devices);
|
||||
ignore_changes--;
|
||||
|
||||
if (!available_devices.empty()) {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
input_latency.set_sensitive (true);
|
||||
output_latency.set_sensitive (true);
|
||||
input_channels.set_sensitive (true);
|
||||
output_channels.set_sensitive (true);
|
||||
|
||||
update_sensitivity ();
|
||||
|
||||
/* changing the text in the combo will trigger device_changed()
|
||||
which should populate the parameter controls
|
||||
*/
|
||||
|
||||
device_combo.set_active_text (available_devices.front());
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
set_popdown_strings (device_combo, available_devices);
|
||||
device_combo.set_active_text (available_devices.front());
|
||||
}
|
||||
|
||||
device_changed ();
|
||||
|
||||
ok_button->set_sensitive (true);
|
||||
apply_button->set_sensitive (true);
|
||||
|
||||
} else {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
input_latency.set_sensitive (true);
|
||||
output_latency.set_sensitive (true);
|
||||
input_channels.set_sensitive (true);
|
||||
output_channels.set_sensitive (true);
|
||||
sample_rate_combo.set_sensitive (false);
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
input_latency.set_sensitive (false);
|
||||
output_latency.set_sensitive (false);
|
||||
input_channels.set_sensitive (false);
|
||||
output_channels.set_sensitive (false);
|
||||
ok_button->set_sensitive (false);
|
||||
apply_button->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EngineControl::driver_changed ()
|
||||
{
|
||||
|
@ -595,58 +700,94 @@ EngineControl::device_changed ()
|
|||
string device_name = device_combo.get_active_text ();
|
||||
vector<string> s;
|
||||
|
||||
/* don't allow programmatic change to sample_rate_combo to cause a
|
||||
recursive call to this method.
|
||||
*/
|
||||
|
||||
ignore_changes++;
|
||||
{
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
|
||||
/* sample rates */
|
||||
|
||||
string desired;
|
||||
/* don't allow programmatic change to combos to cause a
|
||||
recursive call to this method.
|
||||
*/
|
||||
|
||||
/* sample rates */
|
||||
|
||||
string desired;
|
||||
|
||||
vector<float> sr;
|
||||
|
||||
vector<float> sr = backend->available_sample_rates (device_name);
|
||||
for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
|
||||
s.push_back (rate_as_string (*x));
|
||||
if (*x == _desired_sample_rate) {
|
||||
desired = s.back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
set_popdown_strings (sample_rate_combo, s);
|
||||
|
||||
if (desired.empty()) {
|
||||
sample_rate_combo.set_active_text (s.front());
|
||||
if (_have_control) {
|
||||
sr = backend->available_sample_rates (device_name);
|
||||
} else {
|
||||
sample_rate_combo.set_active_text (desired);
|
||||
|
||||
sr.push_back (8000.0f);
|
||||
sr.push_back (16000.0f);
|
||||
sr.push_back (32000.0f);
|
||||
sr.push_back (44100.0f);
|
||||
sr.push_back (48000.0f);
|
||||
sr.push_back (88200.0f);
|
||||
sr.push_back (96000.0f);
|
||||
sr.push_back (192000.0f);
|
||||
sr.push_back (384000.0f);
|
||||
}
|
||||
} else {
|
||||
/* hmm ... how to tell the user about the fact that we have no
|
||||
* available sample rates.
|
||||
|
||||
for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
|
||||
s.push_back (rate_as_string (*x));
|
||||
if (*x == _desired_sample_rate) {
|
||||
desired = s.back();
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
set_popdown_strings (sample_rate_combo, s);
|
||||
|
||||
if (desired.empty()) {
|
||||
sample_rate_combo.set_active_text (s.front());
|
||||
} else {
|
||||
sample_rate_combo.set_active_text (desired);
|
||||
}
|
||||
|
||||
} else {
|
||||
sample_rate_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
/* buffer sizes */
|
||||
|
||||
vector<uint32_t> bs;
|
||||
|
||||
if (_have_control) {
|
||||
bs = backend->available_buffer_sizes(device_name);
|
||||
} else if (backend->can_change_buffer_size_when_running()) {
|
||||
bs.push_back (8);
|
||||
bs.push_back (16);
|
||||
bs.push_back (32);
|
||||
bs.push_back (64);
|
||||
bs.push_back (128);
|
||||
bs.push_back (256);
|
||||
bs.push_back (512);
|
||||
bs.push_back (1024);
|
||||
bs.push_back (2048);
|
||||
bs.push_back (4096);
|
||||
bs.push_back (8192);
|
||||
}
|
||||
s.clear ();
|
||||
for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
|
||||
s.push_back (bufsize_as_string (*x));
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
set_popdown_strings (buffer_size_combo, s);
|
||||
|
||||
buffer_size_combo.set_active_text (s.front());
|
||||
show_buffer_duration ();
|
||||
} else {
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
/* XXX theoretically need to set min + max channel counts here
|
||||
*/
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
}
|
||||
|
||||
|
||||
vector<uint32_t> bs = backend->available_buffer_sizes(device_name);
|
||||
s.clear ();
|
||||
for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
|
||||
s.push_back (bufsize_as_string (*x));
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
set_popdown_strings (buffer_size_combo, s);
|
||||
buffer_size_combo.set_active_text (s.front());
|
||||
show_buffer_duration ();
|
||||
} else {
|
||||
/* hmm ... how to tell the user about the fact that we have no
|
||||
* available buffer sizes.
|
||||
*/
|
||||
}
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
ignore_changes--;
|
||||
|
||||
/* pick up any saved state for this device */
|
||||
|
||||
|
@ -774,6 +915,10 @@ EngineControl::get_saved_state_for_currently_displayed_backend_and_device ()
|
|||
EngineControl::State*
|
||||
EngineControl::save_state ()
|
||||
{
|
||||
if (!_have_control) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool existing = true;
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
|
@ -808,10 +953,15 @@ EngineControl::store_state (State& state)
|
|||
void
|
||||
EngineControl::maybe_display_saved_state ()
|
||||
{
|
||||
if (!_have_control) {
|
||||
return;
|
||||
}
|
||||
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (state) {
|
||||
ignore_changes++;
|
||||
PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
|
||||
|
||||
if (!_desired_sample_rate) {
|
||||
sample_rate_combo.set_active_text (rate_as_string (state->sample_rate));
|
||||
}
|
||||
|
@ -822,7 +972,6 @@ EngineControl::maybe_display_saved_state ()
|
|||
show_buffer_duration ();
|
||||
input_latency.set_value (state->input_latency);
|
||||
output_latency.set_value (state->output_latency);
|
||||
ignore_changes--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -952,6 +1101,7 @@ EngineControl::set_state (const XMLNode& root)
|
|||
/* now see if there was an active state and switch the setup to it */
|
||||
|
||||
for (StateList::const_iterator i = states.begin(); i != states.end(); ++i) {
|
||||
|
||||
if ((*i).active) {
|
||||
ignore_changes++;
|
||||
backend_combo.set_active_text ((*i).backend);
|
||||
|
@ -971,6 +1121,10 @@ EngineControl::set_state (const XMLNode& root)
|
|||
int
|
||||
EngineControl::push_state_to_backend (bool start)
|
||||
{
|
||||
if (no_push) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
|
||||
if (!backend) {
|
||||
|
@ -992,47 +1146,60 @@ EngineControl::push_state_to_backend (bool start)
|
|||
uint32_t ichan = get_input_channels ();
|
||||
|
||||
if (_have_control) {
|
||||
|
||||
/* we can control the backend */
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
if (get_driver() != backend->driver_name()) {
|
||||
change_driver = true;
|
||||
if (started_at_least_once) {
|
||||
|
||||
/* we can control the backend */
|
||||
|
||||
if (backend->requires_driver_selection()) {
|
||||
if (get_driver() != backend->driver_name()) {
|
||||
change_driver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_device_name() != backend->device_name()) {
|
||||
change_device = true;
|
||||
}
|
||||
|
||||
if (get_rate() != backend->sample_rate()) {
|
||||
change_rate = true;
|
||||
}
|
||||
|
||||
if (get_buffer_size() != backend->buffer_size()) {
|
||||
change_bufsize = true;
|
||||
}
|
||||
|
||||
/* zero-requested channels means "all available" */
|
||||
|
||||
if (get_device_name() != backend->device_name()) {
|
||||
if (ichan == 0) {
|
||||
ichan = backend->input_channels();
|
||||
}
|
||||
|
||||
if (ochan == 0) {
|
||||
ochan = backend->output_channels();
|
||||
}
|
||||
|
||||
if (ichan != backend->input_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (ochan != backend->output_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (get_input_latency() != backend->systemic_input_latency() ||
|
||||
get_output_latency() != backend->systemic_output_latency()) {
|
||||
change_latency = true;
|
||||
}
|
||||
} else {
|
||||
/* backend never started, so we have to force a group
|
||||
of settings.
|
||||
*/
|
||||
change_driver = true;
|
||||
change_device = true;
|
||||
}
|
||||
|
||||
if (get_rate() != backend->sample_rate()) {
|
||||
change_rate = true;
|
||||
}
|
||||
|
||||
if (get_buffer_size() != backend->buffer_size()) {
|
||||
change_bufsize = true;
|
||||
}
|
||||
|
||||
/* zero-requested channels means "all available" */
|
||||
|
||||
if (ichan == 0) {
|
||||
ichan = backend->input_channels();
|
||||
}
|
||||
|
||||
if (ochan == 0) {
|
||||
ochan = backend->output_channels();
|
||||
}
|
||||
|
||||
if (ichan != backend->input_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (ochan != backend->output_channels()) {
|
||||
change_channels = true;
|
||||
}
|
||||
|
||||
if (get_input_latency() != backend->systemic_input_latency() ||
|
||||
get_output_latency() != backend->systemic_output_latency()) {
|
||||
change_latency = true;
|
||||
}
|
||||
|
||||
|
@ -1175,26 +1342,28 @@ EngineControl::post_push ()
|
|||
* necessary
|
||||
*/
|
||||
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (!state) {
|
||||
state = save_state ();
|
||||
assert (state);
|
||||
if (_have_control) {
|
||||
State* state = get_saved_state_for_currently_displayed_backend_and_device ();
|
||||
|
||||
if (!state) {
|
||||
state = save_state ();
|
||||
assert (state);
|
||||
}
|
||||
|
||||
/* all off */
|
||||
|
||||
for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
|
||||
(*i).active = false;
|
||||
}
|
||||
|
||||
/* mark this one active (to be used next time the dialog is
|
||||
* shown)
|
||||
*/
|
||||
|
||||
state->active = true;
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
}
|
||||
|
||||
/* all off */
|
||||
|
||||
for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
|
||||
(*i).active = false;
|
||||
}
|
||||
|
||||
/* mark this one active (to be used next time the dialog is
|
||||
* shown)
|
||||
*/
|
||||
|
||||
state->active = true;
|
||||
|
||||
manage_control_app_sensitivity ();
|
||||
|
||||
/* schedule a redisplay of MIDI ports */
|
||||
|
||||
|
@ -1482,3 +1651,51 @@ EngineControl::on_delete_event (GdkEventAny* ev)
|
|||
return ArdourDialog::on_delete_event (ev);
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::engine_running ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
buffer_size_combo.set_active_text (bufsize_as_string (backend->buffer_size()));
|
||||
sample_rate_combo.set_active_text (rate_as_string (backend->sample_rate()));
|
||||
|
||||
if (backend->can_change_buffer_size_when_running()) {
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
} else {
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
if (backend->can_change_sample_rate_when_running()) {
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
} else {
|
||||
sample_rate_combo.set_sensitive (false);
|
||||
}
|
||||
|
||||
connect_disconnect_button.set_label (string_compose (_("Disconnect from %1"), backend->name()));
|
||||
|
||||
started_at_least_once = true;
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::engine_stopped ()
|
||||
{
|
||||
boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
|
||||
assert (backend);
|
||||
|
||||
buffer_size_combo.set_sensitive (false);
|
||||
connect_disconnect_button.set_label (string_compose (_("Connect to %1"), backend->name()));
|
||||
|
||||
sample_rate_combo.set_sensitive (true);
|
||||
buffer_size_combo.set_sensitive (true);
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::connect_disconnect_click()
|
||||
{
|
||||
if (ARDOUR::AudioEngine::instance()->running()) {
|
||||
ARDOUR_UI::instance()->disconnect_from_engine ();
|
||||
} else {
|
||||
ARDOUR_UI::instance()->reconnect_to_engine ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,11 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
Gtk::Adjustment ports_adjustment;
|
||||
Gtk::SpinButton ports_spinner;
|
||||
|
||||
Gtk::Label have_control_text;
|
||||
Gtk::Button control_app_button;
|
||||
|
||||
Gtk::Button connect_disconnect_button;
|
||||
|
||||
/* latency measurement */
|
||||
|
||||
Gtk::ComboBoxText lm_output_channel_combo;
|
||||
|
@ -106,9 +109,9 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
|
||||
uint32_t ignore_changes;
|
||||
uint32_t _desired_sample_rate;
|
||||
|
||||
static bool engine_running ();
|
||||
|
||||
bool no_push;
|
||||
bool started_at_least_once;
|
||||
|
||||
void driver_changed ();
|
||||
void backend_changed ();
|
||||
void sample_rate_changed ();
|
||||
|
@ -174,6 +177,8 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
static bool print_channel_count (Gtk::SpinButton*);
|
||||
|
||||
void build_notebook ();
|
||||
void build_full_control_notebook ();
|
||||
void build_no_control_notebook ();
|
||||
|
||||
void on_response (int);
|
||||
void control_app_button_clicked ();
|
||||
|
@ -181,6 +186,7 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
void manage_control_app_sensitivity ();
|
||||
int push_state_to_backend (bool start);
|
||||
void post_push ();
|
||||
void update_sensitivity ();
|
||||
|
||||
/* latency measurement */
|
||||
void latency_button_toggled ();
|
||||
|
@ -190,9 +196,16 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
|
|||
void disable_latency_tab ();
|
||||
void start_latency_detection ();
|
||||
void end_latency_detection ();
|
||||
|
||||
|
||||
void on_switch_page (GtkNotebookPage*, guint page_num);
|
||||
bool on_delete_event (GdkEventAny*);
|
||||
|
||||
void engine_running ();
|
||||
void engine_stopped ();
|
||||
PBD::ScopedConnection running_connection;
|
||||
PBD::ScopedConnection stopped_connection;
|
||||
|
||||
void connect_disconnect_click ();
|
||||
};
|
||||
|
||||
#endif /* __gtk2_ardour_engine_dialog_h__ */
|
||||
|
|
|
@ -960,6 +960,7 @@ JACKAudioBackend::disconnected (const char* why)
|
|||
engine.halted_callback (why); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
JACKAudioBackend::cpu_load() const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue