summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-08-01 18:49:40 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-08-01 18:49:40 -0400
commitdf59a000b79f891f17ec8a05b390982dac67e5ff (patch)
tree79d0fd947618c2bf0192d10865ed477afc6da64b /libs/ardour
parent682ebad62bdc85df151ad0b81dc27cc9f3e71cec (diff)
start code reorganization needed to deal with backend choices. compiles, links and runs as far as the startup screen now
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audio_backend.h2
-rw-r--r--libs/ardour/ardour/audioengine.h24
-rw-r--r--libs/ardour/ardour/jack_audiobackend.h1
-rw-r--r--libs/ardour/ardour/jack_portengine.h2
-rw-r--r--libs/ardour/ardour/port_engine.h2
-rw-r--r--libs/ardour/ardour/port_manager.h8
-rw-r--r--libs/ardour/audioengine.cc46
-rw-r--r--libs/ardour/globals.cc11
-rw-r--r--libs/ardour/io.cc4
-rw-r--r--libs/ardour/jack_audiobackend.cc27
-rw-r--r--libs/ardour/jack_portengine.cc38
-rw-r--r--libs/ardour/port_manager.cc83
12 files changed, 212 insertions, 36 deletions
diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h
index 3b68432b6f..6aee33a507 100644
--- a/libs/ardour/ardour/audio_backend.h
+++ b/libs/ardour/ardour/audio_backend.h
@@ -284,7 +284,7 @@ class AudioBackend {
virtual int set_time_master (bool /*yn*/) { return 0; }
virtual int usecs_per_cycle () const { return 1000000 * (buffer_size() / sample_rate()); }
- virtual size_t raw_buffer_size (DataType t);
+ virtual size_t raw_buffer_size (DataType t) = 0;
/* Process time */
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 0bbbe90ef4..cf22925565 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -67,19 +67,17 @@ class AudioEngine : public SessionHandlePtr, public PortManager
{
public:
- static AudioEngine* create (const std::string& client_name, const std::string& session_uuid);
+ static AudioEngine* create ();
virtual ~AudioEngine ();
int discover_backends();
std::vector<std::string> available_backends() const;
std::string current_backend_name () const;
- int set_backend (const std::string&);
+ int set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
ProcessThread* main_thread() const { return _main_thread; }
- std::string client_name() const { return backend_client_name; }
-
/* START BACKEND PROXY API
*
* See audio_backend.h for full documentation and semantics. These wrappers
@@ -144,7 +142,6 @@ public:
int reset_timebase ();
void update_latencies ();
-
/* this signal is sent for every process() cycle while freewheeling.
(the regular process() call to session->process() is not made)
@@ -154,10 +151,7 @@ public:
PBD::Signal0<void> Xrun;
- /* this signal is if the backend notifies us of a graph order event */
-
- PBD::Signal0<void> GraphReordered;
-
+
#ifdef HAVE_JACK_SESSION
PBD::Signal1<void,jack_session_event_t *> JackSessionEvent;
#endif
@@ -176,6 +170,13 @@ public:
PBD::Signal0<void> Running;
PBD::Signal0<void> Stopped;
+
+ /* these two are emitted as we create backends that
+ can actually be used to do stuff (e.g. register ports)
+ */
+
+ PBD::Signal0<void> BackendAvailable;
+ PBD::Signal0<void> BackendRemoved;
static AudioEngine* instance() { return _instance; }
static void destroy();
@@ -197,7 +198,7 @@ public:
static void thread_init_callback (void *);
private:
- AudioEngine (const std::string& client_name, const std::string& session_uuid);
+ AudioEngine ();
static AudioEngine* _instance;
@@ -227,9 +228,6 @@ public:
Glib::Threads::Thread* m_meter_thread;
ProcessThread* _main_thread;
- std::string backend_client_name;
- std::string backend_session_uuid;
-
void meter_thread ();
void start_metering_thread ();
void stop_metering_thread ();
diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h
index 7104b814c2..05638f6c73 100644
--- a/libs/ardour/ardour/jack_audiobackend.h
+++ b/libs/ardour/ardour/jack_audiobackend.h
@@ -144,7 +144,6 @@ class JACKAudioBackend : public AudioBackend {
static void* _start_process_thread (void*);
ChanCount n_physical (unsigned long) const;
- void get_physical (DataType, unsigned long, std::vector<std::string> &);
/* pffooo */
diff --git a/libs/ardour/ardour/jack_portengine.h b/libs/ardour/ardour/jack_portengine.h
index bee87532d3..638d3382ad 100644
--- a/libs/ardour/ardour/jack_portengine.h
+++ b/libs/ardour/ardour/jack_portengine.h
@@ -44,6 +44,8 @@ class JACKPortEngine : public PortEngine
const std::string& my_name() const;
+ uint32_t port_name_size() const;
+
int set_port_name (PortHandle, const std::string&);
std::string get_port_name (PortHandle) const;
PortHandle* get_port_by_name (const std::string&) const;
diff --git a/libs/ardour/ardour/port_engine.h b/libs/ardour/ardour/port_engine.h
index e63c52630d..f03a8e263f 100644
--- a/libs/ardour/ardour/port_engine.h
+++ b/libs/ardour/ardour/port_engine.h
@@ -93,6 +93,8 @@ class PortEngine {
virtual const std::string& my_name() const = 0;
+ virtual uint32_t port_name_size() const = 0;
+
virtual int set_port_name (PortHandle, const std::string&) = 0;
virtual std::string get_port_name (PortHandle) const = 0;
virtual PortHandle* get_port_by_name (const std::string&) const = 0;
diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h
index d88143d110..06e4939101 100644
--- a/libs/ardour/ardour/port_manager.h
+++ b/libs/ardour/ardour/port_manager.h
@@ -47,7 +47,10 @@ class PortManager
void set_port_engine (PortEngine& pe);
PortEngine& port_engine() { return *_impl; }
-
+
+ uint32_t port_name_size() const;
+ std::string my_name() const;
+
/* Port registration */
boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname);
@@ -114,6 +117,9 @@ class PortManager
bool port_remove_in_progress() const { return _port_remove_in_progress; }
+ /** Emitted if the backend notifies us of a graph order event */
+ PBD::Signal0<void> GraphReordered;
+
/** Emitted if a Port is registered or unregistered */
PBD::Signal0<void> PortRegisteredOrUnregistered;
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 05f59707a8..eee21cad1f 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -63,7 +63,7 @@ using namespace PBD;
gint AudioEngine::m_meter_exit;
AudioEngine* AudioEngine::_instance = 0;
-AudioEngine::AudioEngine (const std::string& bcn, const std::string& bsu)
+AudioEngine::AudioEngine ()
: session_remove_pending (false)
, session_removal_countdown (-1)
, monitor_check_interval (INT32_MAX)
@@ -75,10 +75,9 @@ AudioEngine::AudioEngine (const std::string& bcn, const std::string& bsu)
, port_remove_in_progress (false)
, m_meter_thread (0)
, _main_thread (0)
- , backend_client_name (bcn)
- , backend_session_uuid (bsu)
{
g_atomic_int_set (&m_meter_exit, 0);
+ discover_backends ();
}
AudioEngine::~AudioEngine ()
@@ -95,12 +94,15 @@ AudioEngine::~AudioEngine ()
}
AudioEngine*
-AudioEngine::create (const std::string& bcn, const std::string& bsu)
+AudioEngine::create ()
{
if (_instance) {
return _instance;
}
- return new AudioEngine (bcn, bsu);
+
+ _instance = new AudioEngine ();
+
+ return _instance;
}
void
@@ -120,8 +122,6 @@ _thread_init_callback (void * /*arg*/)
MIDI::JackMIDIPort::set_process_thread (pthread_self());
}
-
-
void
AudioEngine::split_cycle (pframes_t offset)
{
@@ -488,8 +488,8 @@ AudioEngine::discover_backends ()
_backends.clear ();
- Glib::PatternSpec so_extension_pattern("*.so");
- Glib::PatternSpec dylib_extension_pattern("*.dylib");
+ Glib::PatternSpec so_extension_pattern("*backend.so");
+ Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
find_matching_files_in_search_path (backend_search_path (),
so_extension_pattern, backend_modules);
@@ -497,7 +497,7 @@ AudioEngine::discover_backends ()
find_matching_files_in_search_path (backend_search_path (),
dylib_extension_pattern, backend_modules);
- DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1"), backend_search_path().to_string()));
+ DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
@@ -514,26 +514,26 @@ AudioEngine::discover_backends ()
AudioBackendInfo*
AudioEngine::backend_discover (const string& path)
{
- Glib::Module* module = new Glib::Module(path);
+ Glib::Module module (path);
AudioBackendInfo* info;
void* sym = 0;
if (!module) {
error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
- Glib::Module::get_last_error()) << endmsg;
- delete module;
+ Glib::Module::get_last_error()) << endmsg;
return 0;
}
-
- if (!module->get_symbol("descriptor", sym)) {
+
+ if (!module.get_symbol ("descriptor", sym)) {
error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
error << Glib::Module::get_last_error() << endmsg;
- delete module;
return 0;
}
+ module.make_resident ();
+
info = (AudioBackendInfo*) sym;
-
+
return info;
}
@@ -564,11 +564,13 @@ AudioEngine::drop_backend ()
if (_backend) {
_backend->stop ();
_backend.reset ();
+
+ BackendRemoved(); /* EMIT SIGNAL */
}
}
int
-AudioEngine::set_backend (const std::string& name)
+AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
{
BackendMap::iterator b = _backends.find (name);
@@ -580,14 +582,21 @@ AudioEngine::set_backend (const std::string& name)
try {
+ if (b->second->instantiate (arg1, arg2)) {
+ throw failed_constructor ();
+ }
+
_backend = b->second->backend_factory (*this);
_impl = b->second->portengine_factory (*this);
+
} catch (...) {
error << string_compose (_("Could not create backend for %1"), name) << endmsg;
return -1;
}
+ BackendAvailable (); /* EMIT SIGNAL */
+
return 0;
}
@@ -993,3 +1002,4 @@ AudioEngine::halted_callback (const char* why)
MIDI::JackMIDIPort::EngineHalted (); /* EMIT SIGNAL */
Halted (why); /* EMIT SIGNAL */
}
+
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index b2833db4fa..132a5fb35d 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -331,6 +331,17 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
EventTypeMap::instance().new_parameter(EnvelopeAutomation);
EventTypeMap::instance().new_parameter(MidiCCAutomation);
+ ARDOUR::AudioEngine::create ();
+
+ uint32_t backend_cnt;
+
+ if ((backend_cnt = AudioEngine::instance()->available_backends().size()) == 0) {
+ error << _("No audio/MIDI backends are available") << endmsg;
+ return -1;
+ }
+
+ cerr << "We have " << backend_cnt << endl;
+
return 0;
}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 21fdca6e96..c517defe1a 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -1337,7 +1337,7 @@ IO::bundle_changed (Bundle::Change /*c*/)
string
IO::build_legal_port_name (DataType type)
{
- const int name_size = jack_port_name_size();
+ const int name_size = AudioEngine::instance()->port_name_size();
int limit;
string suffix;
@@ -1371,7 +1371,7 @@ IO::build_legal_port_name (DataType type)
// allow up to 4 digits for the output port number, plus the slash, suffix and extra space
- limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
+ limit = name_size - AudioEngine::instance()->my_name().length() - (suffix.length() + 5);
char buf1[name_size+1];
char buf2[name_size+1];
diff --git a/libs/ardour/jack_audiobackend.cc b/libs/ardour/jack_audiobackend.cc
index 04ee94a80c..420f104077 100644
--- a/libs/ardour/jack_audiobackend.cc
+++ b/libs/ardour/jack_audiobackend.cc
@@ -58,6 +58,10 @@ JACKAudioBackend::JACKAudioBackend (AudioEngine& e, boost::shared_ptr<JackConnec
{
}
+JACKAudioBackend::~JACKAudioBackend()
+{
+}
+
string
JACKAudioBackend::name() const
{
@@ -825,3 +829,26 @@ JACKAudioBackend::update_latencies ()
GET_PRIVATE_JACK_POINTER (_priv_jack);
jack_recompute_total_latencies (_priv_jack);
}
+
+ChanCount
+JACKAudioBackend::n_physical (unsigned long flags) const
+{
+ ChanCount c;
+
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, c);
+
+ const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
+
+ 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);
+ }
+ }
+
+ jack_free (ports);
+ }
+
+ return c;
+}
diff --git a/libs/ardour/jack_portengine.cc b/libs/ardour/jack_portengine.cc
index 7280c9ff24..1dc323576a 100644
--- a/libs/ardour/jack_portengine.cc
+++ b/libs/ardour/jack_portengine.cc
@@ -222,6 +222,21 @@ JACKPortEngine::physically_connected (PortHandle p)
return false;
}
+int
+JACKPortEngine::get_connections (PortHandle port, vector<string>& s)
+{
+ const char** ports = jack_port_get_connections ((jack_port_t*) port);
+
+ if (ports) {
+ for (int i = 0; ports[i]; ++i) {
+ s.push_back (ports[i]);
+ }
+ jack_free (ports);
+ }
+
+ return s.size();
+}
+
DataType
JACKPortEngine::port_data_type (PortHandle p) const
{
@@ -357,6 +372,23 @@ JACKPortEngine::can_monitor_input () const
return true;
}
+int
+JACKPortEngine::request_input_monitoring (PortHandle port, bool yn)
+{
+ return jack_port_request_monitor ((jack_port_t*) port, yn);
+}
+int
+JACKPortEngine::ensure_input_monitoring (PortHandle port, bool yn)
+{
+ return jack_port_ensure_monitor ((jack_port_t*) port, yn);
+}
+bool
+JACKPortEngine::monitoring_input (PortHandle port)
+{
+ return jack_port_monitoring_input ((jack_port_t*) port);
+}
+
+
pframes_t
JACKPortEngine::sample_time_at_cycle_start ()
{
@@ -480,3 +512,9 @@ JACKPortEngine::get_buffer (PortHandle port, pframes_t nframes)
{
return jack_port_get_buffer ((jack_port_t*) port, nframes);
}
+
+uint32_t
+JACKPortEngine::port_name_size() const
+{
+ return jack_port_name_size ();
+}
diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc
index b5f280292e..5c807a6979 100644
--- a/libs/ardour/port_manager.cc
+++ b/libs/ardour/port_manager.cc
@@ -67,6 +67,10 @@ PortManager::remove_all_ports ()
string
PortManager::make_port_name_relative (const string& portname) const
{
+ if (!_impl) {
+ return portname;
+ }
+
string::size_type len;
string::size_type n;
string self = _impl->my_name();
@@ -105,6 +109,10 @@ PortManager::make_port_name_non_relative (const string& portname) const
bool
PortManager::port_is_mine (const string& portname) const
{
+ if (!_impl) {
+ return true;
+ }
+
string self = _impl->my_name();
if (portname.find_first_of (':') != string::npos) {
@@ -119,6 +127,10 @@ PortManager::port_is_mine (const string& portname) const
bool
PortManager::port_is_physical (const std::string& portname) const
{
+ if (!_impl) {
+ return false;
+ }
+
PortEngine::PortHandle ph = _impl->get_port_by_name (portname);
if (!ph) {
return false;
@@ -130,24 +142,38 @@ PortManager::port_is_physical (const std::string& portname) const
void
PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
{
+ if (!_impl) {
+ return;
+ }
_impl->get_physical_outputs (type, s);
}
void
PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
{
+ if (!_impl) {
+ return;
+ }
+
_impl->get_physical_inputs (type, s);
}
ChanCount
PortManager::n_physical_outputs () const
{
+ if (!_impl) {
+ return ChanCount::ZERO;
+ }
+
return _impl->n_physical_outputs ();
}
ChanCount
PortManager::n_physical_inputs () const
{
+ if (!_impl) {
+ return ChanCount::ZERO;
+ }
return _impl->n_physical_inputs ();
}
@@ -158,6 +184,10 @@ PortManager::n_physical_inputs () const
boost::shared_ptr<Port>
PortManager::get_port_by_name (const string& portname)
{
+ if (!_impl) {
+ return boost::shared_ptr<Port>();
+ }
+
if (!port_is_mine (portname)) {
/* not an ardour port */
return boost::shared_ptr<Port> ();
@@ -200,12 +230,20 @@ PortManager::port_renamed (const std::string& old_relative_name, const std::stri
int
PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
{
+ if (!_impl) {
+ return 0;
+ }
+
return _impl->get_ports (port_name_pattern, type, flags, s);
}
void
PortManager::port_registration_failure (const std::string& portname)
{
+ if (!_impl) {
+ return;
+ }
+
string full_portname = _impl->my_name();
full_portname += ':';
full_portname += portname;
@@ -293,6 +331,10 @@ PortManager::unregister_port (boost::shared_ptr<Port> port)
bool
PortManager::connected (const string& port_name)
{
+ if (!_impl) {
+ return false;
+ }
+
PortEngine::PortHandle handle = _impl->get_port_by_name (port_name);
if (!handle) {
@@ -437,12 +479,20 @@ PortManager::registration_callback ()
bool
PortManager::can_request_input_monitoring () const
{
+ if (!_impl) {
+ return false;
+ }
+
return _impl->can_monitor_input ();
}
void
PortManager::request_input_monitoring (const string& name, bool yn) const
{
+ if (!_impl) {
+ return;
+ }
+
PortEngine::PortHandle ph = _impl->get_port_by_name (name);
if (ph) {
@@ -453,6 +503,10 @@ PortManager::request_input_monitoring (const string& name, bool yn) const
void
PortManager::ensure_input_monitoring (const string& name, bool yn) const
{
+ if (!_impl) {
+ return;
+ }
+
PortEngine::PortHandle ph = _impl->get_port_by_name (name);
if (ph) {
@@ -460,3 +514,32 @@ PortManager::ensure_input_monitoring (const string& name, bool yn) const
}
}
+uint32_t
+PortManager::port_name_size() const
+{
+ if (!_impl) {
+ return 0;
+ }
+
+ return _impl->port_name_size ();
+}
+
+string
+PortManager::my_name() const
+{
+ if (!_impl) {
+ return string();
+ }
+
+ return _impl->my_name();
+}
+
+int
+PortManager::graph_order_callback ()
+{
+ if (!_port_remove_in_progress) {
+ GraphReordered(); /* EMIT SIGNAL */
+ }
+
+ return 0;
+}