From df59a000b79f891f17ec8a05b390982dac67e5ff Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 1 Aug 2013 18:49:40 -0400 Subject: start code reorganization needed to deal with backend choices. compiles, links and runs as far as the startup screen now --- libs/ardour/ardour/audio_backend.h | 2 +- libs/ardour/ardour/audioengine.h | 24 +++++----- libs/ardour/ardour/jack_audiobackend.h | 1 - libs/ardour/ardour/jack_portengine.h | 2 + libs/ardour/ardour/port_engine.h | 2 + libs/ardour/ardour/port_manager.h | 8 +++- libs/ardour/audioengine.cc | 46 +++++++++++-------- libs/ardour/globals.cc | 11 +++++ libs/ardour/io.cc | 4 +- libs/ardour/jack_audiobackend.cc | 27 +++++++++++ libs/ardour/jack_portengine.cc | 38 ++++++++++++++++ libs/ardour/port_manager.cc | 83 ++++++++++++++++++++++++++++++++++ 12 files changed, 212 insertions(+), 36 deletions(-) (limited to 'libs/ardour') 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 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 Xrun; - /* this signal is if the backend notifies us of a graph order event */ - - PBD::Signal0 GraphReordered; - + #ifdef HAVE_JACK_SESSION PBD::Signal1 JackSessionEvent; #endif @@ -176,6 +170,13 @@ public: PBD::Signal0 Running; PBD::Signal0 Stopped; + + /* these two are emitted as we create backends that + can actually be used to do stuff (e.g. register ports) + */ + + PBD::Signal0 BackendAvailable; + PBD::Signal0 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 &); /* 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 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 GraphReordered; + /** Emitted if a Port is registered or unregistered */ PBD::Signal0 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::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& 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& s) { + if (!_impl) { + return; + } _impl->get_physical_outputs (type, s); } void PortManager::get_physical_inputs (DataType type, std::vector& 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 PortManager::get_port_by_name (const string& portname) { + if (!_impl) { + return boost::shared_ptr(); + } + if (!port_is_mine (portname)) { /* not an ardour port */ return boost::shared_ptr (); @@ -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& 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) 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; +} -- cgit v1.2.3