summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-08-03 11:57:56 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-08-03 11:57:56 -0400
commit1c4d00e8b70785ce58f868645dad93afa1855193 (patch)
treec6d4687d54945139ac25f0f89e8f987fc7cb54d3
parentdf59a000b79f891f17ec8a05b390982dac67e5ff (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.cc36
-rw-r--r--gtk2_ardour/ardour_ui.h2
-rw-r--r--gtk2_ardour/engine_dialog.cc32
-rw-r--r--libs/ardour/ardour/audio_backend.h11
-rw-r--r--libs/ardour/ardour/audioengine.h2
-rw-r--r--libs/ardour/ardour/jack_audiobackend.h4
-rw-r--r--libs/ardour/ardour/jack_connection.h3
-rw-r--r--libs/ardour/ardour/jack_portengine.h5
-rw-r--r--libs/ardour/audioengine.cc16
-rw-r--r--libs/ardour/globals.cc10
-rw-r--r--libs/ardour/jack_audiobackend.cc14
-rw-r--r--libs/ardour/jack_connection.cc27
-rw-r--r--libs/ardour/jack_portengine.cc41
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);
+ }
}
}