diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-03 11:57:56 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2013-08-03 11:57:56 -0400 |
commit | 1c4d00e8b70785ce58f868645dad93afa1855193 (patch) | |
tree | c6d4687d54945139ac25f0f89e8f987fc7cb54d3 | |
parent | df59a000b79f891f17ec8a05b390982dac67e5ff (diff) |
audioengine branch can now load and run at least one test session.
currently hard-coded to deal only with the situation where JACK is already running
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 36 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.cc | 32 | ||||
-rw-r--r-- | libs/ardour/ardour/audio_backend.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/jack_audiobackend.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/jack_connection.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/jack_portengine.h | 5 | ||||
-rw-r--r-- | libs/ardour/audioengine.cc | 16 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 10 | ||||
-rw-r--r-- | libs/ardour/jack_audiobackend.cc | 14 | ||||
-rw-r--r-- | libs/ardour/jack_connection.cc | 27 | ||||
-rw-r--r-- | libs/ardour/jack_portengine.cc | 41 |
13 files changed, 131 insertions, 72 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 12f3feafa1..e764c50d4e 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" @@ -373,6 +374,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* @@ -384,18 +387,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")); - - AudioEngine* engine = AudioEngine::instance(); + 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()); @@ -405,8 +400,6 @@ ARDOUR_UI::create_engine () engine->BackendAvailable.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::post_engine, this)); ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports); - - return 0; } void @@ -414,7 +407,7 @@ ARDOUR_UI::post_engine () { cerr << "Backend available!\n"; - /* 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 (); @@ -2572,6 +2565,17 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri int ret = -1; bool likely_new = false; + /* if the audio/midi backend does not require setup, get our use of it underway + * right here + */ + + if (!EngineControl::need_setup()) { + vector<const AudioBackendInfo*> backends = AudioEngine::instance()->available_backends(); + cerr << "Setting up backend " << backends.front()->name; + AudioEngine::instance()->set_backend (backends.front()->name, ARDOUR_COMMAND_LINE::backend_client_name, ARDOUR_COMMAND_LINE::backend_session_uuid); + AudioEngine::instance()->start (); + } + /* deal with any existing DIRTY session now, rather than later. don't * treat a non-dirty session this way, so that it stays visible * as we bring up the new session dialog. @@ -2693,10 +2697,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) { diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 5817293b29..c4ac0e67d7 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -263,7 +263,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 a9e04d8db0..2db93d75ec 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -44,6 +44,8 @@ #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" @@ -594,33 +596,13 @@ EngineControl::build_command_line (vector<string>& cmd) 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. - */ + vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends(); - 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; + if (backends.size() == 1 && backends.front()->already_configured()) { + return false; } - return false; + + return true; } int diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index 6aee33a507..18c8cb8931 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -340,7 +340,7 @@ class AudioBackend { virtual int create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize) = 0; virtual void update_latencies () = 0; - + protected: AudioEngine& engine; }; @@ -353,6 +353,15 @@ struct AudioBackendInfo { boost::shared_ptr<AudioBackend> (*backend_factory) (AudioEngine&); boost::shared_ptr<PortEngine> (*portengine_factory) (PortManager&); + + /** Return true if the underlying mechanism/API has been + * configured and does not need (re)configuration in order + * to be usable. Return false otherwise. + * + * Note that this may return true if (re)configuration is possible, + * but not required. + */ + bool (*already_configured)(); }; } // namespace diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index cf22925565..4412faca22 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -72,7 +72,7 @@ public: virtual ~AudioEngine (); int discover_backends(); - std::vector<std::string> available_backends() const; + std::vector<const AudioBackendInfo*> available_backends() const; std::string current_backend_name () const; int set_backend (const std::string&, const std::string& arg1, const std::string& arg2); diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h index 05638f6c73..4f44bdba5f 100644 --- a/libs/ardour/ardour/jack_audiobackend.h +++ b/libs/ardour/ardour/jack_audiobackend.h @@ -101,6 +101,8 @@ class JACKAudioBackend : public AudioBackend { void update_latencies (); + static bool already_configured(); + private: boost::shared_ptr<JackConnection> _jack_connection; //< shared with JACKPortEngine bool _running; @@ -144,6 +146,8 @@ class JACKAudioBackend : public AudioBackend { static void* _start_process_thread (void*); ChanCount n_physical (unsigned long) const; + + void preset_jack_startup_command (); /* pffooo */ diff --git a/libs/ardour/ardour/jack_connection.h b/libs/ardour/ardour/jack_connection.h index 543a70c439..cd45f3b9ba 100644 --- a/libs/ardour/ardour/jack_connection.h +++ b/libs/ardour/ardour/jack_connection.h @@ -21,11 +21,14 @@ class JackConnection { jack_client_t* jack() const { return _jack; } + PBD::Signal0<void> Connected; PBD::Signal1<void,const char*> Disconnected; void halted_callback (); void halted_info_callback (jack_status_t, const char*); + static bool server_running(); + private: jack_client_t* volatile _jack; std::string _client_name; diff --git a/libs/ardour/ardour/jack_portengine.h b/libs/ardour/ardour/jack_portengine.h index 638d3382ad..d595b638fa 100644 --- a/libs/ardour/ardour/jack_portengine.h +++ b/libs/ardour/ardour/jack_portengine.h @@ -27,6 +27,8 @@ #include <boost/shared_ptr.hpp> +#include "pbd/signals.h" + #include "ardour/port_engine.h" #include "ardour/types.h" @@ -115,6 +117,9 @@ class JACKPortEngine : public PortEngine ChanCount n_physical (unsigned long flags) const; void get_physical (DataType type, unsigned long flags, std::vector<std::string>& phy) const; + PBD::ScopedConnection jack_connection_connection; + void connected_to_jack (); + }; } // namespace diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index eee21cad1f..a7682bac70 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -537,13 +537,13 @@ AudioEngine::backend_discover (const string& path) return info; } -vector<string> +vector<const AudioBackendInfo*> AudioEngine::available_backends() const { - vector<string> r; + vector<const AudioBackendInfo*> r; for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) { - r.push_back (i->first); + r.push_back (i->second); } return r; @@ -581,17 +581,21 @@ AudioEngine::set_backend (const std::string& name, const std::string& arg1, cons drop_backend (); try { + cerr << "Instantiate " << b->second->name << " with " << arg1 << " + " << arg2 << endl; if (b->second->instantiate (arg1, arg2)) { + cerr << "i failed\n"; throw failed_constructor (); } + cerr << "bf\n"; _backend = b->second->backend_factory (*this); + cerr << "pf\n"; _impl = b->second->portengine_factory (*this); + cerr << "done\n"; - - } catch (...) { - error << string_compose (_("Could not create backend for %1"), name) << endmsg; + } catch (exception& e) { + error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg; return -1; } diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 132a5fb35d..e890838bfb 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -72,6 +72,7 @@ #include "ardour/analyser.h" #include "ardour/audio_library.h" +#include "ardour/audio_backend.h" #include "ardour/audioengine.h" #include "ardour/audioplaylist.h" #include "ardour/audioregion.h" @@ -333,15 +334,12 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir ARDOUR::AudioEngine::create (); - uint32_t backend_cnt; + vector<const AudioBackendInfo*> backends = AudioEngine::instance()->available_backends(); - if ((backend_cnt = AudioEngine::instance()->available_backends().size()) == 0) { - error << _("No audio/MIDI backends are available") << endmsg; - return -1; + for (vector<const AudioBackendInfo*>::const_iterator i = backends.begin(); i != backends.end(); ++i) { + cerr << "BACKEND: [" << (*i)->name << "] already configured " << (*i)->already_configured() << endl; } - cerr << "We have " << backend_cnt << endl; - return 0; } diff --git a/libs/ardour/jack_audiobackend.cc b/libs/ardour/jack_audiobackend.cc index 420f104077..1bdd70c0f6 100644 --- a/libs/ardour/jack_audiobackend.cc +++ b/libs/ardour/jack_audiobackend.cc @@ -354,12 +354,26 @@ JACKAudioBackend::raw_buffer_size(DataType t) return (s != _raw_buffer_sizes.end()) ? s->second : 0; } +void +JACKAudioBackend::preset_jack_startup_command () +{ + /* write parameter settings to ~/.jackdrc file so that next invocation + * of JACK (presumably from a call to jack_client_open() from this + * process) will do the right thing. + */ +} + /* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */ int JACKAudioBackend::start () { if (!connected()) { + + if (!_jack_connection->server_running()) { + preset_jack_startup_command (); + } + std::cerr << "Open JACK connection\n"; _jack_connection->open (); } diff --git a/libs/ardour/jack_connection.cc b/libs/ardour/jack_connection.cc index d2b69c31fb..cbd9b3fbcc 100644 --- a/libs/ardour/jack_connection.cc +++ b/libs/ardour/jack_connection.cc @@ -55,6 +55,33 @@ JackConnection::~JackConnection () close (); } +bool +JackConnection::server_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 JackConnection::open () { diff --git a/libs/ardour/jack_portengine.cc b/libs/ardour/jack_portengine.cc index 1dc323576a..d0716e555f 100644 --- a/libs/ardour/jack_portengine.cc +++ b/libs/ardour/jack_portengine.cc @@ -20,13 +20,16 @@ #include <string.h> #include <stdint.h> -#include "pbd/failed_constructor.h" +#include "pbd/error.h" #include "ardour/jack_portengine.h" #include "ardour/jack_connection.h" #include "ardour/port_manager.h" +#include "i18n.h" + using namespace ARDOUR; +using namespace PBD; using std::string; using std::vector; @@ -85,17 +88,7 @@ JACKPortEngine::JACKPortEngine (PortManager& pm, boost::shared_ptr<JackConnectio : PortEngine (pm) , _jack_connection (jc) { - jack_client_t* client = _jack_connection->jack(); - - if (!client) { - throw failed_constructor (); - } - - /* register callbacks for stuff that is our responsibility */ - - jack_set_port_registration_callback (client, _registration_callback, this); - jack_set_port_connect_callback (client, _connect_callback, this); - jack_set_graph_order_callback (client, _graph_order_callback, this); + _jack_connection->Connected.connect_same_thread (jack_connection_connection, boost::bind (&JACKPortEngine::connected_to_jack, this)); } JACKPortEngine::~JACKPortEngine () @@ -107,6 +100,24 @@ JACKPortEngine::~JACKPortEngine () _jack_connection.reset (); } +void +JACKPortEngine::connected_to_jack () +{ + /* register callbacks for stuff that is our responsibility */ + + jack_client_t* client = _jack_connection->jack(); + + if (!client) { + /* how could this happen? it could ... */ + error << _("Already disconnected from JACK before PortEngine could register callbacks") << endmsg; + return; + } + + jack_set_port_registration_callback (client, _registration_callback, this); + jack_set_port_connect_callback (client, _connect_callback, this); + jack_set_graph_order_callback (client, _graph_order_callback, this); +} + void* JACKPortEngine::private_handle() const { @@ -294,8 +305,10 @@ JACKPortEngine::n_physical (unsigned long flags) const if (ports) { for (uint32_t i = 0; ports[i]; ++i) { if (!strstr (ports[i], "Midi-Through")) { - DataType t (jack_port_type (jack_port_by_name (_priv_jack, ports[i]))); - c.set (t, c.get (t) + 1); + DataType t = port_data_type (jack_port_by_name (_priv_jack, ports[i])); + if (t != DataType::NIL) { + c.set (t, c.get (t) + 1); + } } } |