From d90e2b42211ead2a38afd5590e2937992312795e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 8 Aug 2013 16:31:08 -0400 Subject: rationalize (a bit) engine start/stop/restart so that it is possible to start up, disconnect from JACK and then reconnect --- libs/ardour/ardour/jack_audiobackend.h | 12 ++--- libs/ardour/ardour/jack_portengine.h | 1 + libs/ardour/ardour/port_engine.h | 2 + libs/ardour/audioengine.cc | 80 +++++++++++++++++----------------- libs/ardour/jack_audiobackend.cc | 41 ++++++++--------- libs/ardour/jack_portengine.cc | 6 +++ libs/ardour/ladspa_plugin.cc | 2 + libs/ardour/midi_buffer.cc | 6 ++- libs/ardour/midi_port.cc | 1 + libs/ardour/port.cc | 14 +++++- libs/ardour/port_manager.cc | 4 +- 11 files changed, 97 insertions(+), 72 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h index ada7ce8e33..5ba9ee63d7 100644 --- a/libs/ardour/ardour/jack_audiobackend.h +++ b/libs/ardour/ardour/jack_audiobackend.h @@ -165,14 +165,10 @@ class JACKAudioBackend : public AudioBackend { bool _target_interleaved; uint32_t _target_input_channels; uint32_t _target_output_channels; - uint32_t _target_systemic_input_latency; - uint32_t _target_systemic_output_latency; - - uint32_t _current_sample_rate; - uint32_t _current_buffer_size; - uint32_t _current_usecs_per_cycle; - uint32_t _current_systemic_input_latency; - uint32_t _current_systemic_output_latency; + uint32_t _target_systemic_input_latency; + uint32_t _target_systemic_output_latency; + uint32_t _current_sample_rate; + uint32_t _current_buffer_size; typedef std::set DeviceList; typedef std::map DriverDeviceMap; diff --git a/libs/ardour/ardour/jack_portengine.h b/libs/ardour/ardour/jack_portengine.h index d595b638fa..a267ebb32b 100644 --- a/libs/ardour/ardour/jack_portengine.h +++ b/libs/ardour/ardour/jack_portengine.h @@ -43,6 +43,7 @@ class JACKPortEngine : public PortEngine ~JACKPortEngine(); void* private_handle() const; + bool connected() const; const std::string& my_name() const; diff --git a/libs/ardour/ardour/port_engine.h b/libs/ardour/ardour/port_engine.h index 8e36ad8b09..bb7ec5cb66 100644 --- a/libs/ardour/ardour/port_engine.h +++ b/libs/ardour/ardour/port_engine.h @@ -98,6 +98,8 @@ class PortEngine { */ virtual void* private_handle() const = 0; + virtual bool connected() const = 0; + /** Return the name of this process as used by the port manager * when naming ports. */ diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 9c04529384..2307e9bd52 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -346,8 +346,6 @@ AudioEngine::set_session (Session *s) if (_session) { - start_metering_thread (); - pframes_t blocksize = _backend->buffer_size (); /* page in as much of the session process code as we @@ -567,32 +565,30 @@ AudioEngine::start () _processed_frames = 0; last_monitor_check = 0; - if (_backend->start() == 0) { + if (_backend->start()) { + return -1; + } - _running = true; - last_monitor_check = 0; + _running = true; + + if (_session) { + _session->set_frame_rate (_backend->sample_rate()); - if (_session) { - _session->set_frame_rate (_backend->sample_rate()); - - if (_session->config.get_jack_time_master()) { - _backend->set_time_master (true); - } + if (_session->config.get_jack_time_master()) { + _backend->set_time_master (true); } - - if (!have_ports) { - PortManager::create_ports (); - } - + } + + if (!have_ports) { + PortManager::create_ports (); _mmc.set_ports (mmc_input_port(), mmc_output_port()); - - Running(); /* EMIT SIGNAL */ - - return 0; - } - - /* should report error ... */ - return -1; + } + + start_metering_thread (); + + Running(); /* EMIT SIGNAL */ + + return 0; } int @@ -604,17 +600,18 @@ AudioEngine::stop () Glib::Threads::Mutex::Lock lm (_process_lock); - if (_backend->stop () == 0) { - _running = false; - _processed_frames = 0; - stop_metering_thread (); - - Stopped (); /* EMIT SIGNAL */ - - return 0; + if (_backend->stop ()) { + return -1; } - - return -1; + + _running = false; + _processed_frames = 0; + stop_metering_thread (); + + Port::PortDrop (); + Stopped (); /* EMIT SIGNAL */ + + return 0; } int @@ -624,13 +621,14 @@ AudioEngine::pause () return 0; } - if (_backend->pause () == 0) { - _running = false; - Stopped(); /* EMIT SIGNAL */ - return 0; + if (_backend->pause ()) { + return -1; } - return -1; + _running = false; + + Stopped(); /* EMIT SIGNAL */ + return 0; } int @@ -957,7 +955,9 @@ void AudioEngine::halted_callback (const char* why) { stop_metering_thread (); - Halted (why); /* EMIT SIGNAL */ + + Port::PortDrop (); /* EMIT SIGNAL */ + Halted (why); /* EMIT SIGNAL */ } bool diff --git a/libs/ardour/jack_audiobackend.cc b/libs/ardour/jack_audiobackend.cc index 2e0d90202f..a3bbaecb2d 100644 --- a/libs/ardour/jack_audiobackend.cc +++ b/libs/ardour/jack_audiobackend.cc @@ -40,6 +40,8 @@ using namespace ARDOUR; using namespace PBD; using std::string; using std::vector; +using std::cerr; +using std::endl; #define GET_PRIVATE_JACK_POINTER(localvar) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; } #define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; } @@ -57,6 +59,8 @@ JACKAudioBackend::JACKAudioBackend (AudioEngine& e, boost::shared_ptrDisconnected.connect_same_thread (disconnect_connection, boost::bind (&JACKAudioBackend::disconnected, this, _1)); } @@ -388,13 +392,13 @@ JACKAudioBackend::output_channels () const uint32_t JACKAudioBackend::systemic_input_latency () const { - return _current_systemic_output_latency; + return _target_systemic_output_latency; } uint32_t JACKAudioBackend::systemic_output_latency () const { - return _current_systemic_output_latency; + return _target_systemic_output_latency; } size_t @@ -455,28 +459,26 @@ JACKAudioBackend::start () setup_jack_startup_command (); } - _jack_connection->open (); - } - - engine.reestablish_ports (); - - if (!jack_port_type_get_buffer_size) { - warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg; + if (_jack_connection->open ()) { + return -1; + } } GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1); - engine.sample_rate_change (jack_get_sample_rate (_priv_jack)); + /* get the buffer size and sample rates established */ + + jack_sample_rate_callback (jack_get_sample_rate (_priv_jack)); + jack_bufsize_callback (jack_get_buffer_size (_priv_jack)); - /* testing the nullity of this function name is a proxy for - * whether jack_activate() will definitely call the buffer size - * callback. with older versions of JACK, this function symbol - * will be null. this is sort of reliable, but not clean since - * weak symbol support is highly platform and compiler - * specific. - */ + /* Now that we have buffer size and sample rate established, the engine + can go ahead and do its stuff + */ + + engine.reestablish_ports (); + if (!jack_port_type_get_buffer_size) { - jack_bufsize_callback (jack_get_buffer_size (_priv_jack)); + warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg; } set_jack_callbacks (); @@ -486,7 +488,7 @@ JACKAudioBackend::start () } else { // error << _("cannot activate JACK client") << endmsg; } - + engine.reconnect_ports (); return 0; @@ -869,7 +871,6 @@ JACKAudioBackend::jack_bufsize_callback (pframes_t nframes) GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 1); _current_buffer_size = nframes; - _current_usecs_per_cycle = (int) floor ((((double) nframes / sample_rate())) * 1000000.0); if (jack_port_type_get_buffer_size) { _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE); diff --git a/libs/ardour/jack_portengine.cc b/libs/ardour/jack_portengine.cc index 82b4502cb6..b0597f8269 100644 --- a/libs/ardour/jack_portengine.cc +++ b/libs/ardour/jack_portengine.cc @@ -124,6 +124,12 @@ JACKPortEngine::private_handle() const return _jack_connection->jack(); } +bool +JACKPortEngine::connected() const +{ + return _jack_connection->connected(); +} + int JACKPortEngine::set_port_name (PortHandle port, const std::string& name) { diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 6a2636e4f4..bc3a83799b 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -112,7 +112,9 @@ LadspaPlugin::init (void *mod, uint32_t index, framecnt_t rate) port_cnt = parameter_count(); _control_data = new LADSPA_Data[port_cnt]; + memset (_control_data, 0, sizeof (LADSPA_Data) * port_cnt); _shadow_data = new LADSPA_Data[port_cnt]; + memset (_shadow_data, 0, sizeof (LADSPA_Data) * port_cnt); for (i = 0; i < port_cnt; ++i) { if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index 0b0e61000d..d75b861ea1 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -22,6 +22,7 @@ #include "pbd/malign.h" #include "pbd/compose.h" #include "pbd/debug.h" +#include "pbd/stacktrace.h" #include "ardour/debug.h" #include "ardour/midi_buffer.h" @@ -133,6 +134,7 @@ MidiBuffer::push_back(const Evoral::MIDIEvent& ev) if (_size + stamp_size + ev.size() >= _capacity) { cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; + PBD::stacktrace (cerr, 20); return false; } @@ -171,7 +173,9 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data) #endif if (_size + stamp_size + size >= _capacity) { - cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; + cerr << "MidiBuffer::push_back2 failed (buffer is full; _size = " << _size << " capacity " + << _capacity << " stamp " << stamp_size << " size = " << size << ")" << endl; + PBD::stacktrace (cerr, 20); return false; } diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc index 9191a57080..5589c6e501 100644 --- a/libs/ardour/midi_port.cc +++ b/libs/ardour/midi_port.cc @@ -206,6 +206,7 @@ MidiPort::reset () { Port::reset (); delete _buffer; + cerr << name() << " new MIDI buffer of size " << AudioEngine::instance()->raw_buffer_size (DataType::MIDI) << endl; _buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)); } diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 7dc11c6d3d..d37761b6f2 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -88,6 +88,7 @@ void Port::drop () { if (_port_handle) { + DEBUG_TRACE (DEBUG::Ports, string_compose ("drop handle for port %1\n", name())); port_engine.unregister_port (_port_handle); _port_handle = 0; } @@ -120,12 +121,21 @@ Port::disconnect_all () bool Port::connected_to (std::string const & o) const { + if (!port_engine.connected()) { + return false; + } + return port_engine.connected_to (_port_handle, AudioEngine::instance()->make_port_name_non_relative (o)); } int Port::get_connections (std::vector & c) const { + if (!port_engine.connected()) { + c.insert (c.end(), _connections.begin(), _connections.end()); + return c.size(); + } + return port_engine.get_connections (_port_handle, c); } @@ -142,9 +152,9 @@ Port::connect (std::string const & other) } if (sends_output ()) { - port_engine.connect (our_name, other_name); + r = port_engine.connect (our_name, other_name); } else { - port_engine.connect (other_name, our_name); + r = port_engine.connect (other_name, our_name); } if (r == 0) { diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc index 41331fe3a5..4e467e3008 100644 --- a/libs/ardour/port_manager.cc +++ b/libs/ardour/port_manager.cc @@ -439,6 +439,8 @@ PortManager::reestablish_ports () for (i = p->begin(); i != p->end(); ++i) { if (i->second->reestablish ()) { + error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg; + cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endl; break; } } @@ -458,7 +460,7 @@ PortManager::reconnect_ports () boost::shared_ptr p = ports.reader (); /* re-establish connections */ - + DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size())); for (Ports::iterator i = p->begin(); i != p->end(); ++i) { -- cgit v1.2.3