diff options
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/ardev_common.sh.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 92 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.cc | 1067 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.h | 146 | ||||
-rw-r--r-- | gtk2_ardour/gain_meter.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/global_port_matrix.cc | 26 | ||||
-rw-r--r-- | gtk2_ardour/main.cc | 36 | ||||
-rw-r--r-- | gtk2_ardour/nsm.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/opts.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/opts.h | 4 | ||||
-rw-r--r-- | gtk2_ardour/port_group.cc | 30 | ||||
-rw-r--r-- | gtk2_ardour/port_insert_ui.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/rc_option_editor.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/route_params_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/startup.cc | 7 | ||||
-rw-r--r-- | gtk2_ardour/utils.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/window_manager.cc | 2 |
19 files changed, 395 insertions, 1046 deletions
diff --git a/gtk2_ardour/ardev_common.sh.in b/gtk2_ardour/ardev_common.sh.in index 897bfcf7c2..2bd9c51515 100644 --- a/gtk2_ardour/ardev_common.sh.in +++ b/gtk2_ardour/ardev_common.sh.in @@ -17,6 +17,7 @@ export ARDOUR_DATA_PATH=$TOP:$TOP/build:$TOP/gtk2_ardour:$TOP/build/gtk2_ardour: export ARDOUR_MIDIMAPS_PATH=$TOP/midi_maps:. export ARDOUR_MCP_PATH=$TOP/mcp:. export ARDOUR_EXPORT_FORMATS_PATH=$TOP/export:. +export ARDOUR_BACKEND_PATH=$TOP/build/libs/ardour # # even though we set the above variables, ardour requires that these diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 97726cd7ae..a3ea2b1612 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -61,6 +61,7 @@ #include "midi++/manager.h" #include "ardour/ardour.h" +#include "ardour/audio_backend.h" #include "ardour/audioengine.h" #include "ardour/audiofilesource.h" #include "ardour/automation_watch.h" @@ -376,6 +377,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) _process_thread->init (); DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets)); + + attach_to_engine (); } GlobalPortMatrixWindow* @@ -387,24 +390,10 @@ ARDOUR_UI::create_global_port_matrix (ARDOUR::DataType type) return new GlobalPortMatrixWindow (_session, type); } -int -ARDOUR_UI::create_engine () +void +ARDOUR_UI::attach_to_engine () { - // this gets called every time by new_session() - - if (engine) { - return 0; - } - - loading_message (_("Starting audio engine")); - - try { - engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name, ARDOUR_COMMAND_LINE::jack_session_uuid); - - } catch (...) { - - return -1; - } + engine = AudioEngine::instance(); engine->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context()); engine->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context()); @@ -414,15 +403,23 @@ ARDOUR_UI::create_engine () ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports); - post_engine (); + /* if there is only one audio/midi backend, and it does not require setup, get our use of it underway + * right here (we need to know the client name and potential session ID + * to do this, which is why this is here, rather than in, say, + * ARDOUR::init(). + */ - return 0; + if (!AudioEngine::instance()->setup_required()) { + const AudioBackendInfo* backend = AudioEngine::instance()->available_backends().front(); + AudioEngine::instance()->set_backend (backend->name, ARDOUR_COMMAND_LINE::backend_client_name, ARDOUR_COMMAND_LINE::backend_session_uuid); + AudioEngine::instance()->start (); + } } void ARDOUR_UI::post_engine () { - /* Things to be done once we create the AudioEngine + /* Things to be done once we have a backend running in the AudioEngine */ ARDOUR::init_post_engine (); @@ -490,23 +487,12 @@ ARDOUR_UI::post_engine () update_disk_space (); update_cpu_load (); - update_sample_rate (engine->frame_rate()); + update_sample_rate (engine->sample_rate()); update_timecode_format (); Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context()); boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1)); Config->map_parameters (pc); - - /* now start and maybe save state */ - - if (do_engine_start () == 0) { - if (_session && _session_is_new) { - /* we need to retain initial visual - settings for a new session - */ - _session->save_state (""); - } - } } ARDOUR_UI::~ARDOUR_UI () @@ -692,6 +678,7 @@ ARDOUR_UI::startup () { Application* app = Application::instance (); char *nsm_url; + app->ShouldQuit.connect (sigc::mem_fun (*this, &ARDOUR_UI::queue_finish)); app->ShouldLoad.connect (sigc::mem_fun (*this, &ARDOUR_UI::idle_load)); @@ -926,7 +913,7 @@ If you still wish to quit, please use the\n\n\ _session = 0; } - engine->stop (true); + engine->stop (); quit (); } @@ -1061,16 +1048,16 @@ ARDOUR_UI::update_sample_rate (framecnt_t) } else { - framecnt_t rate = engine->frame_rate(); + framecnt_t rate = engine->sample_rate(); if (fmod (rate, 1000.0) != 0.0) { snprintf (buf, sizeof (buf), _("JACK: <span foreground=\"green\">%.1f kHz / %4.1f ms</span>"), - (float) rate/1000.0f, - (engine->frames_per_cycle() / (float) rate) * 1000.0f); + (float) rate / 1000.0f, + (engine->usecs_per_cycle() / 1000.0f)); } else { snprintf (buf, sizeof (buf), _("JACK: <span foreground=\"green\">%" PRId64 " kHz / %4.1f ms</span>"), rate/1000, - (engine->frames_per_cycle() / (float) rate) * 1000.0f); + (engine->usecs_per_cycle() * 1000.0f)); } } @@ -2049,14 +2036,15 @@ ARDOUR_UI::engine_stopped () void ARDOUR_UI::engine_running () { - ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_running) + post_engine(); + ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true); ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false); Glib::RefPtr<Action> action; const char* action_name = 0; - switch (engine->frames_per_cycle()) { + switch (engine->samples_per_cycle()) { case 32: action_name = X_("JACKLatency32"); break; @@ -2141,24 +2129,6 @@ JACK, reconnect and save the session."), PROGRAM_NAME); } } -int32_t -ARDOUR_UI::do_engine_start () -{ - try { - engine->start(); - } - - catch (...) { - engine->stop (); - error << _("Unable to start the session running") - << endmsg; - unload_session (); - return -2; - } - - return 0; -} - void ARDOUR_UI::update_clocks () { @@ -2709,10 +2679,6 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri } } - if (create_engine ()) { - break; - } - if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { if (likely_new && !nsm) { @@ -3836,7 +3802,7 @@ void ARDOUR_UI::disconnect_from_jack () { if (engine) { - if (engine->disconnect_from_jack ()) { + if (engine->pause ()) { MessageDialog msg (*editor, _("Could not disconnect from JACK")); msg.run (); } @@ -3849,7 +3815,7 @@ void ARDOUR_UI::reconnect_to_jack () { if (engine) { - if (engine->reconnect_to_jack ()) { + if (engine->start ()) { MessageDialog msg (*editor, _("Could not reconnect to JACK")); msg.run (); } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 6365e28ea2..1dcaeb0e9e 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -264,7 +264,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr session_add_midi_route (false); }*/ - int create_engine (); + void attach_to_engine (); void post_engine (); gint exit_on_main_window_close (GdkEventAny *); diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 05cd9a661e..58d7bd5fec 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -17,6 +17,7 @@ */ +#include <exception> #include <vector> #include <cmath> #include <fstream> @@ -27,32 +28,18 @@ #include <glibmm.h> #include <gtkmm/messagedialog.h> -#include "pbd/epa.h" +#include "pbd/error.h" #include "pbd/xml++.h" -#ifdef __APPLE__ -#include <CoreAudio/CoreAudio.h> -#include <CoreFoundation/CFString.h> -#include <sys/param.h> -#include <mach-o/dyld.h> -#elif !defined(__FreeBSD__) -#include <alsa/asoundlib.h> -#endif - -#include <jack/jack.h> - #include <gtkmm/stock.h> #include <gtkmm2ext/utils.h> +#include "ardour/audio_backend.h" +#include "ardour/audioengine.h" #include "ardour/rc_configuration.h" #include "pbd/convert.h" #include "pbd/error.h" -#include "pbd/pathscanner.h" - -#ifdef __APPLE -#include <CFBundle.h> -#endif #include "engine_dialog.h" #include "i18n.h" @@ -64,33 +51,25 @@ using namespace PBD; using namespace Glib; EngineControl::EngineControl () - : periods_adjustment (2, 2, 16, 1, 2), - periods_spinner (periods_adjustment), - ports_adjustment (128, 8, 1024, 1, 16), - ports_spinner (ports_adjustment), - input_latency_adjustment (0, 0, 99999, 1), - input_latency (input_latency_adjustment), - output_latency_adjustment (0, 0, 99999, 1), - output_latency (output_latency_adjustment), - realtime_button (_("Realtime")), - no_memory_lock_button (_("Do not lock memory")), - unlock_memory_button (_("Unlock memory")), - soft_mode_button (_("No zombies")), - monitor_button (_("Provide monitor ports")), - force16bit_button (_("Force 16 bit")), - hw_monitor_button (_("H/W monitoring")), - hw_meter_button (_("H/W metering")), - verbose_output_button (_("Verbose output")), - start_button (_("Start")), - stop_button (_("Stop")), + : input_latency_adjustment (0, 0, 99999, 1) + , 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 (input_channels_adjustment) + , output_channels_adjustment (2, 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 (5, 2), - options_packer (4, 2), - device_packer (4, 2) + , basic_packer (6, 2) + , options_packer (4, 2) + , device_packer (4, 2) #else - basic_packer (8, 2), - options_packer (14, 2), - device_packer (6, 2) + , basic_packer (9, 2) + , options_packer (14, 2) + , device_packer (6, 2) #endif { using namespace Notebook_Helpers; @@ -100,59 +79,24 @@ EngineControl::EngineControl () _used = false; - strings.push_back (_("8000Hz")); - strings.push_back (_("22050Hz")); - strings.push_back (_("44100Hz")); - strings.push_back (_("48000Hz")); - strings.push_back (_("88200Hz")); - strings.push_back (_("96000Hz")); - strings.push_back (_("192000Hz")); - set_popdown_strings (sample_rate_combo, strings); - sample_rate_combo.set_active_text ("48000Hz"); + /* basic parameters */ - strings.clear (); - strings.push_back ("32"); - strings.push_back ("64"); - strings.push_back ("128"); - strings.push_back ("256"); - strings.push_back ("512"); - strings.push_back ("1024"); - strings.push_back ("2048"); - strings.push_back ("4096"); - strings.push_back ("8192"); - set_popdown_strings (period_size_combo, strings); - period_size_combo.set_active_text ("1024"); + basic_packer.set_spacings (6); strings.clear (); - strings.push_back (_("None")); - strings.push_back (_("Triangular")); - strings.push_back (_("Rectangular")); - strings.push_back (_("Shaped")); - set_popdown_strings (dither_mode_combo, strings); - dither_mode_combo.set_active_text (_("None")); - /* basic parameters */ + 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); + } - basic_packer.set_spacings (6); + set_popdown_strings (backend_combo, strings); + backend_combo.set_active_text (strings.front()); - strings.clear (); -#ifdef __APPLE__ - strings.push_back (X_("CoreAudio")); -#else -#ifndef __FreeBSD__ - strings.push_back (X_("ALSA")); -#endif - strings.push_back (X_("OSS")); - strings.push_back (X_("FreeBoB")); - strings.push_back (X_("FFADO")); -#endif - strings.push_back (X_("NetJACK")); - strings.push_back (X_("Dummy")); - set_popdown_strings (driver_combo, strings); - driver_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)); - driver_changed (); strings.clear (); strings.push_back (_("Playback/recording on 1 device")); @@ -178,6 +122,11 @@ EngineControl::EngineControl () row = 0; + label = manage (left_aligned_label (_("Audio Driver:"))); + 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); + 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); @@ -195,16 +144,8 @@ EngineControl::EngineControl () label = manage (left_aligned_label (_("Buffer size:"))); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (period_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - row++; - -#if !defined(__APPLE__) && !defined(__FreeBSD__) - label = manage (left_aligned_label (_("Number of buffers:"))); - basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - basic_packer.attach (periods_spinner, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - periods_spinner.set_value (2); + basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); row++; -#endif label = manage (left_aligned_label (_("Approximate latency:"))); basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); @@ -212,8 +153,7 @@ EngineControl::EngineControl () row++; sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); - periods_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); - period_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); + buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency)); redisplay_latency(); row++; /* no audio mode with CoreAudio, its duplex or nuthin' */ @@ -229,22 +169,7 @@ EngineControl::EngineControl () input_device_combo.set_size_request (250, -1); output_device_combo.set_size_request (250, -1); - /* - - if (engine_running()) { - start_button.set_sensitive (false); - } else { - stop_button.set_sensitive (false); - } - - start_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine)); - stop_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine)); - */ - - button_box.pack_start (start_button, false, false); - button_box.pack_start (stop_button, false, false); - - // basic_packer.attach (button_box, 0, 2, 8, 9, FILL|EXPAND, (AttachOptions) 0); + interface_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::interface_changed)); /* options */ @@ -256,46 +181,6 @@ EngineControl::EngineControl () realtime_button.set_active (true); -#if PROVIDE_TOO_MANY_OPTIONS - -#if !defined(__APPLE__) && !defined(__FreeBSD__) - options_packer.attach (no_memory_lock_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (unlock_memory_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (soft_mode_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (monitor_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (force16bit_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (hw_monitor_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (hw_meter_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - options_packer.attach (verbose_output_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; -#else - options_packer.attach (verbose_output_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; -#endif - - strings.clear (); - strings.push_back (_("Ignore")); - strings.push_back ("500 msec"); - strings.push_back ("1 sec"); - strings.push_back ("2 sec"); - strings.push_back ("10 sec"); - set_popdown_strings (timeout_combo, strings); - timeout_combo.set_active_text (strings.front ()); - - label = manage (new Label (_("Client timeout"))); - label->set_alignment (1.0, 0.5); - options_packer.attach (timeout_combo, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0)); - options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - -#endif /* PROVIDE_TOO_MANY_OPTIONS */ label = manage (left_aligned_label (_("Number of ports:"))); options_packer.attach (ports_spinner, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0)); options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); @@ -313,23 +198,6 @@ EngineControl::EngineControl () ++row; #endif - find_jack_servers (server_strings); - - if (server_strings.empty()) { - fatal << _("No JACK server found anywhere on this system. Please install JACK and restart") << endmsg; - /*NOTREACHED*/ - } - - set_popdown_strings (serverpath_combo, server_strings); - serverpath_combo.set_active_text (server_strings.front()); - - if (server_strings.size() > 1) { - label = manage (left_aligned_label (_("Server:"))); - options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - options_packer.attach (serverpath_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0); - ++row; - } - /* device settings */ device_packer.set_spacings (6); @@ -388,579 +256,117 @@ EngineControl::~EngineControl () } void -EngineControl::build_command_line (vector<string>& cmd) +EngineControl::backend_changed () { - string str; - string driver; - bool using_alsa = false; - bool using_coreaudio = false; - bool using_dummy = false; - bool using_ffado = false; - - /* first, path to jackd */ - - cmd.push_back (serverpath_combo.get_active_text ()); - - /* now jackd arguments */ - - str = timeout_combo.get_active_text (); - - if (str != _("Ignore")) { + string backend_name = backend_combo.get_active_text(); + boost::shared_ptr<ARDOUR::AudioBackend> backend; - double secs = 0; - uint32_t msecs; - secs = atof (str); - msecs = (uint32_t) floor (secs * 1000.0); - - if (msecs > 0) { - cmd.push_back ("-t"); - cmd.push_back (to_string (msecs, std::dec)); - } - } - - if (no_memory_lock_button.get_active()) { - cmd.push_back ("-m"); /* no munlock */ + if (!(backend = ARDOUR::AudioEngine::instance()->set_backend (backend_name, "ardour", ""))) { + /* eh? */ + return; } - cmd.push_back ("-p"); /* port max */ - cmd.push_back (to_string ((uint32_t) floor (ports_spinner.get_value()), std::dec)); - - if (realtime_button.get_active()) { - cmd.push_back ("-R"); + if (backend->requires_driver_selection()) { + vector<string> drivers = backend->enumerate_drivers(); + set_popdown_strings (driver_combo, drivers); + driver_combo.set_active_text (drivers.front()); + driver_changed (); } else { - cmd.push_back ("-r"); /* override jackd's default --realtime */ - } - - if (unlock_memory_button.get_active()) { - cmd.push_back ("-u"); - } - - if (verbose_output_button.get_active()) { - cmd.push_back ("-v"); - } - - /* now add fixed arguments (not user-selectable) */ - - cmd.push_back ("-T"); // temporary */ - - /* setup coremidi before the driver, otherwise jack won't start */ - - if (midi_driver_combo.get_active_text() == _("coremidi")) { - cmd.push_back ("-X coremidi"); - } - - /* next the driver */ - - cmd.push_back ("-d"); - - driver = driver_combo.get_active_text (); - - if (driver == X_("ALSA")) { - using_alsa = true; - cmd.push_back ("alsa"); - } else if (driver == X_("OSS")) { - cmd.push_back ("oss"); - } else if (driver == X_("CoreAudio")) { - using_coreaudio = true; - cmd.push_back ("coreaudio"); - } else if (driver == X_("NetJACK")) { - cmd.push_back ("netjack"); - } else if (driver == X_("FreeBoB")) { - cmd.push_back ("freebob"); - } else if (driver == X_("FFADO")) { - using_ffado = true; - cmd.push_back ("firewire"); - } else if ( driver == X_("Dummy")) { - using_dummy = true; - cmd.push_back ("dummy"); + list_devices (); } - - /* driver arguments */ - - if (!using_coreaudio) { - str = audio_mode_combo.get_active_text(); - - if (str == _("Playback/recording on 1 device")) { - - /* relax */ - - } else if (str == _("Playback/recording on 2 devices")) { - - string input_device = get_device_name (driver, input_device_combo.get_active_text()); - string output_device = get_device_name (driver, output_device_combo.get_active_text()); - - if (input_device.empty() || output_device.empty()) { - cmd.clear (); - return; - } - - cmd.push_back ("-C"); - cmd.push_back (input_device); - - cmd.push_back ("-P"); - cmd.push_back (output_device); - - } else if (str == _("Playback only")) { - cmd.push_back ("-P"); - } else if (str == _("Recording only")) { - cmd.push_back ("-C"); - } - - if (!using_dummy) { - cmd.push_back ("-n"); - cmd.push_back (to_string ((uint32_t) floor (periods_spinner.get_value()), std::dec)); - } - } - - cmd.push_back ("-r"); - cmd.push_back (to_string (get_rate(), std::dec)); - - cmd.push_back ("-p"); - cmd.push_back (period_size_combo.get_active_text()); - - if (using_alsa || using_ffado || using_coreaudio) { - - double val = input_latency_adjustment.get_value(); - - if (val) { - cmd.push_back ("-I"); - cmd.push_back (to_string ((uint32_t) val, std::dec)); - } - - val = output_latency_adjustment.get_value(); - - if (val) { - cmd.push_back ("-O"); - cmd.push_back (to_string ((uint32_t) val, std::dec)); - } - } - - if (using_alsa) { - - if (audio_mode_combo.get_active_text() != _("Playback/recording on 2 devices")) { - - string device = get_device_name (driver, interface_combo.get_active_text()); - if (device.empty()) { - cmd.clear (); - return; - } - - cmd.push_back ("-d"); - cmd.push_back (device); - } - - if (hw_meter_button.get_active()) { - cmd.push_back ("-M"); - } - - if (hw_monitor_button.get_active()) { - cmd.push_back ("-H"); - } - - str = dither_mode_combo.get_active_text(); - - if (str == _("None")) { - } else if (str == _("Triangular")) { - cmd.push_back ("-z triangular"); - } else if (str == _("Rectangular")) { - cmd.push_back ("-z rectangular"); - } else if (str == _("Shaped")) { - cmd.push_back ("-z shaped"); - } - - if (force16bit_button.get_active()) { - cmd.push_back ("-S"); - } - - if (soft_mode_button.get_active()) { - cmd.push_back ("-s"); - } - - str = midi_driver_combo.get_active_text (); - - if (str == _("seq")) { - cmd.push_back ("-X seq"); - } else if (str == _("raw")) { - cmd.push_back ("-X raw"); - } - } else if (using_coreaudio) { - -#ifdef __APPLE__ - // note: older versions of the CoreAudio JACK backend use -n instead of -d here - - string device = get_device_name (driver, interface_combo.get_active_text()); - if (device.empty()) { - cmd.clear (); - return; - } - - cmd.push_back ("-d"); - cmd.push_back (device); -#endif - - } -} - -bool -EngineControl::need_setup () -{ - return !engine_running(); -} - -bool -EngineControl::engine_running () -{ - EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa (); - boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa; - - /* revert all environment settings back to whatever they were when - * ardour started, because ardour's startup script may have reset - * something in ways that interfere with finding/starting JACK. - */ - - if (global_epa) { - current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */ - global_epa->restore (); - } - - jack_status_t status; - jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status); - - if (status == 0) { - jack_client_close (c); - return true; - } - return false; -} - -int -EngineControl::setup_engine () -{ - vector<string> args; - std::string cwd = "/tmp"; - - build_command_line (args); - - if (args.empty()) { - return 1; // try again - } - - std::string jackdrc_path = Glib::get_home_dir(); - jackdrc_path += "/.jackdrc"; - - ofstream jackdrc (jackdrc_path.c_str()); - if (!jackdrc) { - error << string_compose (_("cannot open JACK rc file %1 to store parameters"), jackdrc_path) << endmsg; - return -1; - } - - for (vector<string>::iterator i = args.begin(); i != args.end(); ++i) { - jackdrc << (*i) << ' '; - } - - jackdrc << endl; - jackdrc.close (); - - _used = true; - - return 0; } void -EngineControl::enumerate_devices (const string& driver) -{ - /* note: case matters for the map keys */ - - if (driver == "CoreAudio") { -#ifdef __APPLE__ - devices[driver] = enumerate_coreaudio_devices (); -#endif - -#if !defined(__APPLE__) && !defined(__FreeBSD__) - } else if (driver == "ALSA") { - devices[driver] = enumerate_alsa_devices (); - } else if (driver == "FreeBOB") { - devices[driver] = enumerate_freebob_devices (); - } else if (driver == "FFADO") { - devices[driver] = enumerate_ffado_devices (); - } else if (driver == "OSS") { - devices[driver] = enumerate_oss_devices (); - } else if (driver == "Dummy") { - devices[driver] = enumerate_dummy_devices (); - } else if (driver == "NetJACK") { - devices[driver] = enumerate_netjack_devices (); - } -#else - } -#endif -} - -#ifdef __APPLE__ -static OSStatus -getDeviceUIDFromID( AudioDeviceID id, char *name, size_t nsize) -{ - UInt32 size = sizeof(CFStringRef); - CFStringRef UI; - OSStatus res = AudioDeviceGetProperty(id, 0, false, - kAudioDevicePropertyDeviceUID, &size, &UI); - if (res == noErr) - CFStringGetCString(UI,name,nsize,CFStringGetSystemEncoding()); - CFRelease(UI); - return res; -} - -vector<string> -EngineControl::enumerate_coreaudio_devices () -{ - vector<string> devs; - - // Find out how many Core Audio devices are there, if any... - // (code snippet gently "borrowed" from St?hane Letz jackdmp;) - OSStatus err; - Boolean isWritable; - UInt32 outSize = sizeof(isWritable); - - backend_devs.clear (); - - err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, - &outSize, &isWritable); - if (err == noErr) { - // Calculate the number of device available... - int numCoreDevices = outSize / sizeof(AudioDeviceID); - // Make space for the devices we are about to get... - AudioDeviceID *coreDeviceIDs = new AudioDeviceID [numCoreDevices]; - err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, - &outSize, (void *) coreDeviceIDs); - if (err == noErr) { - // Look for the CoreAudio device name... - char coreDeviceName[256]; - UInt32 nameSize; - - for (int i = 0; i < numCoreDevices; i++) { - - nameSize = sizeof (coreDeviceName); - - /* enforce duplex devices only */ - - err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], - 0, true, kAudioDevicePropertyStreams, - &outSize, &isWritable); - - if (err != noErr || outSize == 0) { - continue; - } - - err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], - 0, false, kAudioDevicePropertyStreams, - &outSize, &isWritable); - - if (err != noErr || outSize == 0) { - continue; - } - - err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], - 0, true, kAudioDevicePropertyDeviceName, - &outSize, &isWritable); - if (err == noErr) { - err = AudioDeviceGetProperty(coreDeviceIDs[i], - 0, true, kAudioDevicePropertyDeviceName, - &nameSize, (void *) coreDeviceName); - if (err == noErr) { - char drivername[128]; - - // this returns the unique id for the device - // that must be used on the commandline for jack - - if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) { - devs.push_back (coreDeviceName); - backend_devs.push_back (drivername); - } - } - } - } - } - delete [] coreDeviceIDs; - } - - - if (devs.size() == 0) { - MessageDialog msg (string_compose (_("\ -You do not have any audio devices capable of\n\ -simultaneous playback and recording.\n\n\ -Please use Applications -> Utilities -> Audio MIDI Setup\n\ -to create an \"aggregrate\" device, or install a suitable\n\ -audio interface.\n\n\ -Please send email to Apple and ask them why new Macs\n\ -have no duplex audio device.\n\n\ -Alternatively, if you really want just playback\n\ -or recording but not both, start JACK before running\n\ -%1 and choose the relevant device then." - ), PROGRAM_NAME), - true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK); - msg.set_title (_("No suitable audio devices")); - msg.set_position (Gtk::WIN_POS_MOUSE); - msg.run (); - exit (1); - } - - - return devs; -} -#else - -#if !defined(__FreeBSD__) -vector<string> -EngineControl::enumerate_alsa_devices () +EngineControl::list_devices () { - vector<string> devs; - - snd_ctl_t *handle; - snd_ctl_card_info_t *info; - snd_pcm_info_t *pcminfo; - snd_ctl_card_info_alloca(&info); - snd_pcm_info_alloca(&pcminfo); - string devname; - int cardnum = -1; - int device = -1; + boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend(); + assert (backend); - backend_devs.clear (); - - while (snd_card_next (&cardnum) >= 0 && cardnum >= 0) { - - devname = "hw:"; - devname += to_string (cardnum, std::dec); - - if (snd_ctl_open (&handle, devname.c_str(), 0) >= 0 && snd_ctl_card_info (handle, info) >= 0) { - - while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) { - - snd_pcm_info_set_device (pcminfo, device); - snd_pcm_info_set_subdevice (pcminfo, 0); - snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_PLAYBACK); + /* now fill out devices, mark sample rates, buffer sizes insensitive */ + + vector<ARDOUR::AudioBackend::DeviceStatus> all_devices = backend->enumerate_devices (); + + /* NOTE: Ardour currently does not display the "available" field of the + * returned devices. + * + * Doing so would require a different GUI widget than the combo + * box/popdown that we currently use, since it has no way to list + * items that are not selectable. Something more like a popup menu, + * which could have unselectable items, would be appropriate. + */ - if (snd_ctl_pcm_info (handle, pcminfo) >= 0) { - devs.push_back (snd_pcm_info_get_name (pcminfo)); - devname += ','; - devname += to_string (device, std::dec); - backend_devs.push_back (devname); - } - } + vector<string> available_devices; - snd_ctl_close(handle); - } + for (vector<ARDOUR::AudioBackend::DeviceStatus>::const_iterator i = all_devices.begin(); i != all_devices.end(); ++i) { + available_devices.push_back (i->name); } - return devs; -} -#endif - -vector<string> -EngineControl::enumerate_ffado_devices () -{ - vector<string> devs; - backend_devs.clear (); - return devs; + set_popdown_strings (interface_combo, available_devices); + interface_combo.set_active_text (available_devices.front()); + set_popdown_strings (input_device_combo, available_devices); + input_device_combo.set_active_text (available_devices.front()); + set_popdown_strings (output_device_combo, available_devices); + output_device_combo.set_active_text (available_devices.front()); + + interface_changed (); } - -vector<string> -EngineControl::enumerate_freebob_devices () + +void +EngineControl::driver_changed () { - vector<string> devs; - return devs; -} + boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend(); + assert (backend); -vector<string> -EngineControl::enumerate_oss_devices () -{ - vector<string> devs; - return devs; -} -vector<string> -EngineControl::enumerate_dummy_devices () -{ - vector<string> devs; - return devs; -} -vector<string> -EngineControl::enumerate_netjack_devices () -{ - vector<string> devs; - return devs; + backend->set_driver (driver_combo.get_active_text()); + list_devices (); } -#endif void -EngineControl::driver_changed () +EngineControl::interface_changed () { - string driver = driver_combo.get_active_text(); - string::size_type maxlen = 0; - int n = 0; - - enumerate_devices (driver); - - vector<string>& strings = devices[driver]; - - if (strings.empty() && driver != "FreeBoB" && driver != "FFADO" && driver != "Dummy") { - return; - } - - for (vector<string>::iterator i = strings.begin(); i != strings.end(); ++i, ++n) { - if ((*i).length() > maxlen) { - maxlen = (*i).length(); + boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend(); + assert (backend); + string device_name = interface_combo.get_active_text (); + vector<string> s; + + /* sample rates */ + + vector<float> sr = backend->available_sample_rates (device_name); + for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) { + char buf[32]; + if (fmod (*x, 1000.0f)) { + snprintf (buf, sizeof (buf), "%.1f kHz", (*x)/1000.0); + } else { + snprintf (buf, sizeof (buf), "%.0f kHz", (*x)/1000.0); } + s.push_back (buf); } - set_popdown_strings (interface_combo, strings); - set_popdown_strings (input_device_combo, strings); - set_popdown_strings (output_device_combo, strings); + set_popdown_strings (sample_rate_combo, s); + sample_rate_combo.set_active_text (s.front()); - if (!strings.empty()) { - interface_combo.set_active_text (strings.front()); - input_device_combo.set_active_text (strings.front()); - output_device_combo.set_active_text (strings.front()); - } + /* buffer sizes */ - if (driver == "ALSA") { - soft_mode_button.set_sensitive (true); - force16bit_button.set_sensitive (true); - hw_monitor_button.set_sensitive (true); - hw_meter_button.set_sensitive (true); - monitor_button.set_sensitive (true); - } else { - soft_mode_button.set_sensitive (false); - force16bit_button.set_sensitive (false); - hw_monitor_button.set_sensitive (false); - hw_meter_button.set_sensitive (false); - monitor_button.set_sensitive (false); + s.clear (); + vector<uint32_t> bs = backend->available_buffer_sizes(device_name); + for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) { + char buf[32]; + snprintf (buf, sizeof (buf), "%u", *x); + s.push_back (buf); } -} -uint32_t -EngineControl::get_rate () -{ - double r = atof (sample_rate_combo.get_active_text ()); - /* the string may have been translated with an abbreviation for - * thousands, so use a crude heuristic to fix this. - */ - if (r < 1000.0) { - r *= 1000.0; - } - return lrint (r); -} + set_popdown_strings (buffer_size_combo, s); + buffer_size_combo.set_active_text (s.front()); +} void EngineControl::redisplay_latency () { uint32_t rate = get_rate(); -#if defined(__APPLE__) || defined(__FreeBSD__) - float periods = 2; -#else - float periods = periods_adjustment.get_value(); -#endif - float period_size = atof (period_size_combo.get_active_text()); + float period_size = atof (buffer_size_combo.get_active_text()); char buf[32]; - snprintf (buf, sizeof(buf), "%.1fmsec", (periods * period_size) / (rate/1000.0)); + snprintf (buf, sizeof(buf), "%.1fmsec", (2 * period_size) / (rate/1000.0)); latency_label.set_text (buf); latency_label.set_alignment (0, 0.5); @@ -986,127 +392,6 @@ EngineControl::audio_mode_changed () } } -static bool jack_server_filter(const string& str, void */*arg*/) -{ - return str == "jackd" || str == "jackdmp"; -} - -void -EngineControl::find_jack_servers (vector<string>& strings) -{ -#ifdef __APPLE__ - /* this magic lets us finds the path to the OSX bundle, and then - we infer JACK's location from there - */ - - char execpath[MAXPATHLEN+1]; - uint32_t pathsz = sizeof (execpath); - - _NSGetExecutablePath (execpath, &pathsz); - - string path (Glib::path_get_dirname (execpath)); - path += "/jackd"; - - if (Glib::file_test (path, FILE_TEST_EXISTS)) { - strings.push_back (path); - } - - if (getenv ("ARDOUR_WITH_JACK")) { - /* no other options - only use the JACK we supply */ - if (strings.empty()) { - fatal << string_compose (_("JACK appears to be missing from the %1 bundle"), PROGRAM_NAME) << endmsg; - /*NOTREACHED*/ - } - return; - } -#else - string path; -#endif - - PathScanner scanner; - vector<string *> *jack_servers; - std::map<string,int> un; - char *p; - bool need_minimal_path = false; - - p = getenv ("PATH"); - - if (p && *p) { - path = p; - } else { - need_minimal_path = true; - } - -#ifdef __APPLE__ - // many mac users don't have PATH set up to include - // likely installed locations of JACK - need_minimal_path = true; -#endif - - if (need_minimal_path) { - if (path.empty()) { - path = "/usr/bin:/bin:/usr/local/bin:/opt/local/bin"; - } else { - path += ":/usr/local/bin:/opt/local/bin"; - } - } - -#ifdef __APPLE__ - // push it back into the environment so that auto-started JACK can find it. - // XXX why can't we just expect OS X users to have PATH set correctly? we can't ... - setenv ("PATH", path.c_str(), 1); -#endif - - jack_servers = scanner (path, jack_server_filter, 0, false, true); - if (!jack_servers) { - return; - } - - vector<string *>::iterator iter; - - for (iter = jack_servers->begin(); iter != jack_servers->end(); iter++) { - string p = **iter; - - if (un[p]++ == 0) { - strings.push_back(p); - } - } -} - - -string -EngineControl::get_device_name (const string& driver, const string& human_readable) -{ - vector<string>::iterator n; - vector<string>::iterator i; - - if (human_readable.empty()) { - /* this can happen if the user's .ardourrc file has a device name from - another computer system in it - */ - MessageDialog msg (_("You need to choose an audio device first.")); - msg.set_position (WIN_POS_MOUSE); - msg.run (); - return string(); - } - - if (backend_devs.empty()) { - return human_readable; - } - - for (i = devices[driver].begin(), n = backend_devs.begin(); i != devices[driver].end(); ++i, ++n) { - if (human_readable == (*i)) { - return (*n); - } - } - - if (i == devices[driver].end()) { - warning << string_compose (_("Audio device \"%1\" not known on this computer."), human_readable) << endmsg; - } - - return string(); -} - XMLNode& EngineControl::get_state () { @@ -1114,6 +399,7 @@ EngineControl::get_state () XMLNode* child; std::string path; +#if 0 child = new XMLNode ("periods"); child->add_property ("val", to_string (periods_adjustment.get_value(), std::dec)); root->add_child_nocopy (*child); @@ -1205,13 +491,14 @@ EngineControl::get_state () child = new XMLNode ("mididriver"); child->add_property ("val", midi_driver_combo.get_active_text()); root->add_child_nocopy (*child); - +#endif return *root; } void EngineControl::set_state (const XMLNode& root) { +#if 0 XMLNodeList clist; XMLNodeConstIterator citer; XMLNode* child; @@ -1356,4 +643,124 @@ EngineControl::set_state (const XMLNode& root) midi_driver_combo.set_active_text(strval); } } +#endif +} + +int +EngineControl::setup_engine (bool start) +{ + boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend(); + assert (backend); + + /* grab the parameters from the GUI and apply them */ + + try { + if (backend->requires_driver_selection()) { + if (backend->set_driver (get_driver())) { + return -1; + } + } + + if (backend->set_device_name (get_device_name())) { + return -1; + } + + if (backend->set_sample_rate (get_rate())) { + error << string_compose (_("Cannot set sample rate to %1"), get_rate()) << endmsg; + return -1; + } + if (backend->set_buffer_size (get_buffer_size())) { + error << string_compose (_("Cannot set buffer size to %1"), get_buffer_size()) << endmsg; + return -1; + } + if (backend->set_input_channels (get_input_channels())) { + error << string_compose (_("Cannot set input channels to %1"), get_input_channels()) << endmsg; + return -1; + } + if (backend->set_output_channels (get_output_channels())) { + error << string_compose (_("Cannot set output channels to %1"), get_output_channels()) << endmsg; + return -1; + } + if (backend->set_systemic_input_latency (get_input_latency())) { + error << string_compose (_("Cannot set input latency to %1"), get_input_latency()) << endmsg; + return -1; + } + if (backend->set_systemic_output_latency (get_output_latency())) { + error << string_compose (_("Cannot set output latency to %1"), get_output_latency()) << endmsg; + return -1; + } + + if (start) { + return ARDOUR::AudioEngine::instance()->start(); + } + + return 0; + + } catch (...) { + cerr << "exception thrown...\n"; + return -1; + } } + +uint32_t +EngineControl::get_rate () const +{ + double r = atof (sample_rate_combo.get_active_text ()); + /* the string may have been translated with an abbreviation for + * thousands, so use a crude heuristic to fix this. + */ + if (r < 1000.0) { + r *= 1000.0; + } + return lrint (r); +} + +uint32_t +EngineControl::get_buffer_size () const +{ + string txt = buffer_size_combo.get_active_text (); + uint32_t samples; + + if (sscanf (txt.c_str(), "%d", &samples) != 1) { + throw exception (); + } + + return samples; +} + +uint32_t +EngineControl::get_input_channels() const +{ + return (uint32_t) input_channels_adjustment.get_value(); +} + +uint32_t +EngineControl::get_output_channels() const +{ + return (uint32_t) output_channels_adjustment.get_value(); +} + +uint32_t +EngineControl::get_input_latency() const +{ + return (uint32_t) input_latency_adjustment.get_value(); +} + +uint32_t +EngineControl::get_output_latency() const +{ + return (uint32_t) output_latency_adjustment.get_value(); +} + +string +EngineControl::get_driver () const +{ + return driver_combo.get_active_text (); +} + +string +EngineControl::get_device_name () const +{ + return interface_combo.get_active_text (); +} + diff --git a/gtk2_ardour/engine_dialog.h b/gtk2_ardour/engine_dialog.h index 0d7ce29b46..07cf0afa8f 100644 --- a/gtk2_ardour/engine_dialog.h +++ b/gtk2_ardour/engine_dialog.h @@ -40,87 +40,83 @@ class EngineControl : public Gtk::VBox { ~EngineControl (); static bool need_setup (); - int setup_engine (); + int setup_engine (bool start); bool was_used() const { return _used; } XMLNode& get_state (); void set_state (const XMLNode&); private: - Gtk::Adjustment periods_adjustment; - Gtk::SpinButton periods_spinner; - Gtk::Adjustment ports_adjustment; - Gtk::SpinButton ports_spinner; - Gtk::Adjustment input_latency_adjustment; - Gtk::SpinButton input_latency; - Gtk::Adjustment output_latency_adjustment; - Gtk::SpinButton output_latency; - Gtk::Label latency_label; - - Gtk::CheckButton realtime_button; - Gtk::CheckButton no_memory_lock_button; - Gtk::CheckButton unlock_memory_button; - Gtk::CheckButton soft_mode_button; - Gtk::CheckButton monitor_button; - Gtk::CheckButton force16bit_button; - Gtk::CheckButton hw_monitor_button; - Gtk::CheckButton hw_meter_button; - Gtk::CheckButton verbose_output_button; - - Gtk::Button start_button; - Gtk::Button stop_button; - Gtk::HButtonBox button_box; - - Gtk::ComboBoxText sample_rate_combo; - Gtk::ComboBoxText period_size_combo; - - Gtk::ComboBoxText preset_combo; - Gtk::ComboBoxText serverpath_combo; - Gtk::ComboBoxText driver_combo; - Gtk::ComboBoxText interface_combo; - Gtk::ComboBoxText timeout_combo; - Gtk::ComboBoxText dither_mode_combo; - Gtk::ComboBoxText audio_mode_combo; - Gtk::ComboBoxText input_device_combo; - Gtk::ComboBoxText output_device_combo; - Gtk::ComboBoxText midi_driver_combo; - - Gtk::Table basic_packer; - Gtk::Table options_packer; - Gtk::Table device_packer; - Gtk::HBox basic_hbox; - Gtk::HBox options_hbox; - Gtk::HBox device_hbox; - Gtk::Notebook notebook; - - bool _used; - - static bool engine_running (); - - void driver_changed (); - void build_command_line (std::vector<std::string>&); - - std::map<std::string,std::vector<std::string> > devices; - std::vector<std::string> backend_devs; - void enumerate_devices (const std::string& driver); - -#ifdef __APPLE__ - std::vector<std::string> enumerate_coreaudio_devices (); -#else - std::vector<std::string> enumerate_alsa_devices (); - std::vector<std::string> enumerate_oss_devices (); - std::vector<std::string> enumerate_netjack_devices (); - std::vector<std::string> enumerate_freebob_devices (); - std::vector<std::string> enumerate_ffado_devices (); - std::vector<std::string> enumerate_dummy_devices (); -#endif - - void redisplay_latency (); - uint32_t get_rate(); - void audio_mode_changed (); - std::vector<std::string> server_strings; - void find_jack_servers (std::vector<std::string>&); - std::string get_device_name (const std::string& driver, const std::string& human_readable_name); + /* core fields used by all backends */ + + Gtk::ComboBoxText backend_combo; + Gtk::ComboBoxText input_device_combo; + Gtk::ComboBoxText output_device_combo; + Gtk::ComboBoxText sample_rate_combo; + Gtk::ComboBoxText buffer_size_combo; + Gtk::Adjustment input_latency_adjustment; + Gtk::SpinButton input_latency; + Gtk::Adjustment output_latency_adjustment; + Gtk::SpinButton output_latency; + Gtk::Adjustment input_channels_adjustment; + Gtk::SpinButton input_channels; + Gtk::Adjustment output_channels_adjustment; + Gtk::SpinButton output_channels; + Gtk::Adjustment ports_adjustment; + Gtk::SpinButton ports_spinner; + Gtk::Label latency_label; + + /* JACK specific */ + + Gtk::CheckButton realtime_button; + Gtk::CheckButton no_memory_lock_button; + Gtk::CheckButton unlock_memory_button; + Gtk::CheckButton soft_mode_button; + Gtk::CheckButton monitor_button; + Gtk::CheckButton force16bit_button; + Gtk::CheckButton hw_monitor_button; + Gtk::CheckButton hw_meter_button; + Gtk::CheckButton verbose_output_button; + + + Gtk::ComboBoxText preset_combo; + Gtk::ComboBoxText serverpath_combo; + Gtk::ComboBoxText driver_combo; + Gtk::ComboBoxText interface_combo; + Gtk::ComboBoxText timeout_combo; + Gtk::ComboBoxText dither_mode_combo; + Gtk::ComboBoxText audio_mode_combo; + Gtk::ComboBoxText midi_driver_combo; + + Gtk::Table basic_packer; + Gtk::Table options_packer; + Gtk::Table device_packer; + Gtk::HBox basic_hbox; + Gtk::HBox options_hbox; + Gtk::HBox device_hbox; + Gtk::Notebook notebook; + + bool _used; + + static bool engine_running (); + + void driver_changed (); + void backend_changed (); + + void redisplay_latency (); + + uint32_t get_rate() const; + uint32_t get_buffer_size() const; + uint32_t get_input_channels() const; + uint32_t get_output_channels() const; + uint32_t get_input_latency() const; + uint32_t get_output_latency() const; + std::string get_device_name() const; + std::string get_driver() const; + + void audio_mode_changed (); + void interface_changed (); + void list_devices (); }; #endif /* __gtk2_ardour_engine_dialog_h__ */ diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index 67f9ce9370..10512b24d0 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -864,7 +864,7 @@ GainMeterBase::update_meters() } } -void GainMeterBase::color_handler(bool dpi) +void GainMeterBase::color_handler(bool /*dpi*/) { setup_meters(); } diff --git a/gtk2_ardour/global_port_matrix.cc b/gtk2_ardour/global_port_matrix.cc index 8c1fde3082..cdba7f5c27 100644 --- a/gtk2_ardour/global_port_matrix.cc +++ b/gtk2_ardour/global_port_matrix.cc @@ -82,9 +82,9 @@ GlobalPortMatrix::set_state (BundleChannel c[2], bool s) } else { /* two non-Ardour ports */ if (s) { - jack_connect (_session->engine().jack (), j->c_str(), i->c_str()); + AudioEngine::instance()->connect (*j, *i); } else { - jack_disconnect (_session->engine().jack (), j->c_str(), i->c_str()); + AudioEngine::instance()->disconnect (*j, *i); } } } @@ -113,33 +113,23 @@ GlobalPortMatrix::get_state (BundleChannel c[2]) const for (Bundle::PortList::const_iterator i = in_ports.begin(); i != in_ports.end(); ++i) { for (Bundle::PortList::const_iterator j = out_ports.begin(); j != out_ports.end(); ++j) { - boost::shared_ptr<Port> p = _session->engine().get_port_by_name (*i); - boost::shared_ptr<Port> q = _session->engine().get_port_by_name (*j); + boost::shared_ptr<Port> p = AudioEngine::instance()->get_port_by_name (*i); + boost::shared_ptr<Port> q = AudioEngine::instance()->get_port_by_name (*j); if (!p && !q) { /* two non-Ardour ports; things are slightly more involved */ /* XXX: is this the easiest way to do this? */ /* XXX: isn't this very inefficient? */ - jack_client_t* jack = _session->engine().jack (); - jack_port_t* jp = jack_port_by_name (jack, i->c_str()); - if (jp == 0) { + PortEngine::PortHandle ph = AudioEngine::instance()->port_engine().get_port_by_name (*i); + if (!ph) { return PortMatrixNode::NOT_ASSOCIATED; } - char const ** c = jack_port_get_all_connections (jack, jp); - - char const ** p = c; - - while (p && *p != 0) { - if (strcmp (*p, j->c_str()) == 0) { - free (c); - return PortMatrixNode::ASSOCIATED; - } - ++p; + if (AudioEngine::instance()->port_engine().connected (ph)) { + return PortMatrixNode::ASSOCIATED; } - free (c); return PortMatrixNode::NOT_ASSOCIATED; } diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 21e5343979..e9b5da3e04 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -372,34 +372,30 @@ static void load_custom_fonts() { #endif static gboolean -tell_about_jack_death (void* /* ignored */) +tell_about_backend_death (void* /* ignored */) { if (AudioEngine::instance()->processed_frames() == 0) { /* died during startup */ - MessageDialog msg (_("JACK exited"), false); + MessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false); msg.set_position (Gtk::WIN_POS_CENTER); msg.set_secondary_text (string_compose (_( -"JACK exited unexpectedly, and without notifying %1.\n\ +"%2 exited unexpectedly, and without notifying %1.\n\ \n\ -This could be due to misconfiguration or to an error inside JACK.\n\ +This could be due to misconfiguration or to an error inside %2.\n\ \n\ -Click OK to exit %1."), PROGRAM_NAME)); +Click OK to exit %1."), PROGRAM_NAME, AudioEngine::instance()->current_backend_name())); msg.run (); _exit (0); } else { - /* engine has already run, so this is a mid-session JACK death */ - - MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false)); - msg->set_secondary_text (string_compose (_( -"JACK exited unexpectedly, and without notifying %1.\n\ -\n\ -This is probably due to an error inside JACK. You should restart JACK\n\ -and reconnect %1 to it, or exit %1 now. You cannot save your\n\ -session at this time, because we would lose your connection information.\n"), PROGRAM_NAME)); - msg->present (); + /* engine has already run, so this is a mid-session backend death */ + + MessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false); + msg.set_secondary_text (string_compose (_("%2 exited unexpectedly, and without notifying %1."), + PROGRAM_NAME, AudioEngine::instance()->current_backend_name())); + msg.present (); } return false; /* do not call again */ } @@ -407,15 +403,15 @@ session at this time, because we would lose your connection information.\n"), PR static void sigpipe_handler (int /*signal*/) { - /* XXX fix this so that we do this again after a reconnect to JACK + /* XXX fix this so that we do this again after a reconnect to the backend */ - static bool done_the_jack_thing = false; + static bool done_the_backend_thing = false; - if (!done_the_jack_thing) { + if (!done_the_backend_thing) { AudioEngine::instance()->died (); - g_idle_add (tell_about_jack_death, 0); - done_the_jack_thing = true; + g_idle_add (tell_about_backend_death, 0); + done_the_backend_thing = true; } } diff --git a/gtk2_ardour/nsm.cc b/gtk2_ardour/nsm.cc index 18d88fec0a..e3ceba355f 100644 --- a/gtk2_ardour/nsm.cc +++ b/gtk2_ardour/nsm.cc @@ -50,7 +50,7 @@ NSM_Client::command_open(const char* name, int r = ERR_OK; ARDOUR_COMMAND_LINE::session_name = name; - ARDOUR_COMMAND_LINE::jack_client_name = client_id; + ARDOUR_COMMAND_LINE::backend_client_name = client_id; if (ARDOUR_UI::instance()->get_session_parameters(true, false, "")) { return ERR_GENERAL; diff --git a/gtk2_ardour/opts.cc b/gtk2_ardour/opts.cc index b29f106bfe..90d753af4c 100644 --- a/gtk2_ardour/opts.cc +++ b/gtk2_ardour/opts.cc @@ -32,7 +32,8 @@ using namespace std; string ARDOUR_COMMAND_LINE::session_name = ""; -string ARDOUR_COMMAND_LINE::jack_client_name = "ardour"; +string ARDOUR_COMMAND_LINE::backend_client_name = "ardour"; +string ARDOUR_COMMAND_LINE::backend_session_uuid; bool ARDOUR_COMMAND_LINE::show_key_actions = false; bool ARDOUR_COMMAND_LINE::no_splash = false; bool ARDOUR_COMMAND_LINE::just_version = false; @@ -45,7 +46,6 @@ string ARDOUR_COMMAND_LINE::keybindings_path = ""; /* empty means use builtin de std::string ARDOUR_COMMAND_LINE::menus_file = "ardour.menus"; bool ARDOUR_COMMAND_LINE::finder_invoked_ardour = false; string ARDOUR_COMMAND_LINE::immediate_save; -string ARDOUR_COMMAND_LINE::jack_session_uuid; string ARDOUR_COMMAND_LINE::load_template; bool ARDOUR_COMMAND_LINE::check_announcements = true; @@ -60,7 +60,7 @@ print_help (const char *execname) << _(" -h, --help Print this message\n") << _(" -a, --no-announcements Do not contact website for announcements\n") << _(" -b, --bindings Print all possible keyboard binding names\n") - << _(" -c, --name <name> Use a specific jack client name, default is ardour\n") + << _(" -c, --name <name> Use a specific backend client name, default is ardour\n") << _(" -d, --disable-plugins Disable all plugins in an existing session\n") << _(" -D, --debug <options> Set debug flags. Use \"-D list\" to see available options\n") << _(" -n, --no-splash Do not show splash screen\n") @@ -199,7 +199,7 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) break; case 'c': - jack_client_name = optarg; + backend_client_name = optarg; break; case 'C': @@ -215,7 +215,7 @@ ARDOUR_COMMAND_LINE::parse_opts (int argc, char *argv[]) break; case 'U': - jack_session_uuid = optarg; + backend_session_uuid = optarg; break; default: diff --git a/gtk2_ardour/opts.h b/gtk2_ardour/opts.h index b9faa36d72..fdf29157d2 100644 --- a/gtk2_ardour/opts.h +++ b/gtk2_ardour/opts.h @@ -28,7 +28,8 @@ extern std::string session_name; extern bool show_key_actions; extern bool no_splash; extern bool just_version; -extern std::string jack_client_name; +extern std::string backend_client_name; +extern std::string backend_session_uuid; extern bool use_vst; extern bool new_session; extern char* curvetest_file; @@ -39,7 +40,6 @@ extern std::string keybindings_path; extern std::string menus_file; extern bool finder_invoked_ardour; extern std::string immediate_save; -extern std::string jack_session_uuid; extern std::string load_template; extern bool check_announcements; diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index 531a5cf2c4..5b4f151da8 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -499,20 +499,12 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp string lpnc = lpn; lpnc += ':'; - const char ** ports = 0; - if (type == DataType::NIL) { - ports = session->engine().get_ports ("", "", inputs ? JackPortIsInput : JackPortIsOutput); - } else { - ports = session->engine().get_ports ("", type.to_jack_type(), inputs ? JackPortIsInput : JackPortIsOutput); - } - - if (ports) { + vector<string> ports; + if (AudioEngine::instance()->get_ports ("", type, inputs ? IsInput : IsOutput, ports) > 0) { - int n = 0; + for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ) { - while (ports[n]) { - - std::string const p = ports[n]; + std::string const p = *s; if (!system->has_port(p) && !bus->has_port(p) && @@ -526,7 +518,7 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp */ if (p.find ("Midi-Through") != string::npos) { - ++n; + ++s; continue; } @@ -539,15 +531,15 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp if ((lp.find (N_(":monitor")) != string::npos) && (lp.find (lpn) != string::npos)) { - ++n; + ++s; continue; } /* can't use the audio engine for this as we are looking at non-Ardour ports */ - jack_port_t* jp = jack_port_by_name (session->engine().jack(), p.c_str()); - if (jp) { - DataType t (jack_port_type (jp)); + PortEngine::PortHandle ph = AudioEngine::instance()->port_engine().get_port_by_name (p); + if (ph) { + DataType t (AudioEngine::instance()->port_engine().port_data_type (ph)); if (t != DataType::NIL) { if (port_has_prefix (p, N_("system:")) || port_has_prefix (p, N_("alsa_pcm")) || @@ -560,10 +552,8 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp } } - ++n; + ++s; } - - free (ports); } for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) { diff --git a/gtk2_ardour/port_insert_ui.cc b/gtk2_ardour/port_insert_ui.cc index 0511b357db..3c495f0e79 100644 --- a/gtk2_ardour/port_insert_ui.cc +++ b/gtk2_ardour/port_insert_ui.cc @@ -66,7 +66,7 @@ PortInsertUI::PortInsertUI (Gtk::Window* parent, ARDOUR::Session* sess, boost::s void PortInsertUI::update_latency_display () { - framecnt_t const sample_rate = input_selector.session()->engine().frame_rate(); + framecnt_t const sample_rate = AudioEngine::instance()->sample_rate(); if (sample_rate == 0) { latency_display.set_text (_("Disconnected from audio engine")); } else { @@ -93,7 +93,7 @@ PortInsertUI::check_latency_measurement () } char buf[128]; - framecnt_t const sample_rate = AudioEngine::instance()->frame_rate(); + framecnt_t const sample_rate = AudioEngine::instance()->sample_rate(); if (sample_rate == 0) { latency_display.set_text (_("Disconnected from audio engine")); diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index 98a4ffd014..54b96bbb8d 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -1468,8 +1468,8 @@ RCOptionEditor::RCOptionEditor () #ifndef __APPLE__ /* no JACK monitoring on CoreAudio */ - if (AudioEngine::instance()->can_request_hardware_monitoring()) { - mm->add (HardwareMonitoring, _("JACK")); + if (AudioEngine::instance()->port_engine().can_monitor_input()) { + mm->add (HardwareMonitoring, _("via Audio Driver")); } #endif mm->add (SoftwareMonitoring, _("ardour")); diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc index bb10bea16f..76f3d4e264 100644 --- a/gtk2_ardour/route_params_ui.cc +++ b/gtk2_ardour/route_params_ui.cc @@ -277,7 +277,7 @@ RouteParams_UI::cleanup_latency_frame () void RouteParams_UI::setup_latency_frame () { - latency_widget = new LatencyGUI (*(_route->output()), _session->frame_rate(), _session->engine().frames_per_cycle()); + latency_widget = new LatencyGUI (*(_route->output()), _session->frame_rate(), AudioEngine::instance()->samples_per_cycle()); char buf[128]; snprintf (buf, sizeof (buf), _("Playback delay: %" PRId64 " samples"), _route->initial_delay()); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index c1dde89c39..8cc1512d3b 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -1692,7 +1692,7 @@ RouteUI::map_frozen () void RouteUI::adjust_latency () { - LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), _session->engine().frames_per_cycle()); + LatencyDialog dialog (_route->name() + _(" latency"), *(_route->output()), _session->frame_rate(), AudioEngine::instance()->samples_per_cycle()); } void diff --git a/gtk2_ardour/startup.cc b/gtk2_ardour/startup.cc index e24e7d6989..bfd9c88633 100644 --- a/gtk2_ardour/startup.cc +++ b/gtk2_ardour/startup.cc @@ -34,6 +34,7 @@ #include "pbd/stacktrace.h" #include "pbd/openuri.h" +#include "ardour/audioengine.h" #include "ardour/filesystem_paths.h" #include "ardour/recent_sessions.h" #include "ardour/session.h" @@ -91,7 +92,7 @@ ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, , _existing_session_chooser_used (false) { new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS); - need_audio_setup = EngineControl::need_setup (); + need_audio_setup = AudioEngine::instance()->setup_required (); need_session_info = (session_name.empty() || require_new); _provided_session_name = session_name; @@ -661,8 +662,10 @@ ArdourStartup::on_delete_event (GdkEventAny*) void ArdourStartup::on_apply () { + cerr << "apply, engine = " << engine_dialog << endl; if (engine_dialog) { - if (engine_dialog->setup_engine ()) { + cerr << "Set up engine\n"; + if (engine_dialog->setup_engine (true)) { set_current_page (audio_page_index); return; } diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 97368a7863..8b05eb7108 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -395,7 +395,7 @@ emulate_key_event (Gtk::Widget* w, unsigned int keyval) ev.state = 0; ev.keyval = keyval; ev.length = 0; - ev.string = ""; + ev.string = (const gchar*) ""; ev.hardware_keycode = keymapkey[0].keycode; ev.group = keymapkey[0].group; g_free(keymapkey); diff --git a/gtk2_ardour/window_manager.cc b/gtk2_ardour/window_manager.cc index 5fa1b6c7b0..3ab9e1adff 100644 --- a/gtk2_ardour/window_manager.cc +++ b/gtk2_ardour/window_manager.cc @@ -410,7 +410,7 @@ ProxyBase::hide () } bool -ProxyBase::handle_win_event (GdkEventAny *ev) +ProxyBase::handle_win_event (GdkEventAny* /*ev*/) { hide(); return true; |