From dd7caa01654dc58d3259eeed0e0f2b8ddb293b66 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 10 Jan 2011 16:23:54 +0000 Subject: Optimise BufferSet::attach_buffers code to avoid memory allocation in the RT thread and speed things up a bit. git-svn-id: svn://localhost/ardour2/branches/3.0@8490 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/buffer_set.h | 3 ++- libs/ardour/ardour/io.h | 4 +++- libs/ardour/buffer_set.cc | 34 +++++++++++++++++++++++++++++++--- libs/ardour/delivery.cc | 4 ++-- libs/ardour/io.cc | 7 +++---- 5 files changed, 41 insertions(+), 11 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h index c3358f4436..fc5ef96449 100644 --- a/libs/ardour/ardour/buffer_set.h +++ b/libs/ardour/ardour/buffer_set.h @@ -66,7 +66,8 @@ public: void clear(); - void attach_buffers(PortSet& ports, framecnt_t nframes, framecnt_t offset = 0); + void attach_buffers (PortSet& ports); + void get_jack_port_addresses (PortSet &, framecnt_t, framecnt_t); /* the capacity here is a size_t and has a different interpretation depending on the DataType of the buffers. for audio, its a frame count. for MIDI diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 8335225f3c..8a3884b95f 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -42,6 +42,7 @@ #include "ardour/session_object.h" #include "ardour/types.h" #include "ardour/utils.h" +#include "ardour/buffer_set.h" class XMLNode; @@ -50,7 +51,6 @@ namespace ARDOUR { class Amp; class AudioEngine; class AudioPort; -class BufferSet; class Bundle; class MidiPort; class PeakMeter; @@ -249,6 +249,8 @@ class IO : public SessionObject, public Latent void setup_bundle (); std::string bundle_channel_name (uint32_t, uint32_t, DataType) const; + + BufferSet _buffers; }; } // namespace ARDOUR diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc index c60c0ac2b9..159a24c217 100644 --- a/libs/ardour/buffer_set.cc +++ b/libs/ardour/buffer_set.cc @@ -82,10 +82,12 @@ BufferSet::clear() #endif } -/** Make this BufferSet a direct mirror of a PortSet's buffers. +/** Set up this BufferSet so that its data structures mirror a PortSet's buffers. + * This is quite expensive and not RT-safe, so it should not be called in a process context; + * get_jack_port_addresses() will fill in a structure set up by this method. */ void -BufferSet::attach_buffers (PortSet& ports, framecnt_t nframes, framecnt_t offset) +BufferSet::attach_buffers (PortSet& ports) { clear(); @@ -95,7 +97,7 @@ BufferSet::attach_buffers (PortSet& ports, framecnt_t nframes, framecnt_t offset for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) { assert(p->type() == *t); - v.push_back(&(p->get_buffer(nframes, offset))); + v.push_back (0); } } @@ -105,6 +107,32 @@ BufferSet::attach_buffers (PortSet& ports, framecnt_t nframes, framecnt_t offset _is_mirror = true; } +/** Write the JACK port addresses from a PortSet into our data structures. This + * call assumes that attach_buffers() has already been called for the same PortSet. + * Does not allocate, so RT-safe. + */ +void +BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes, framecnt_t offset) +{ + assert (_count == ports.count ()); + assert (_available == ports.count ()); + assert (_is_mirror); + + assert (_buffers.size() == DataType::num_types); + + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + BufferVec& v = _buffers[*t]; + + assert (v.size() == ports.num_ports (*t)); + + int i = 0; + for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) { + v[i] = &p->get_buffer (nframes, offset); + ++i; + } + } +} + /** Ensure that there are @a num_buffers buffers of type @a type available, * each of size at least @a buffer_size */ diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 9bf597ef66..80135baf28 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -246,7 +246,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf processing pathway that wants to use this->output_buffers() for some reason. */ - output_buffers().attach_buffers (ports, nframes, _output_offset); + output_buffers().get_jack_port_addresses (ports, nframes, _output_offset); // this Delivery processor is not a derived type, and thus we assume // we really can modify the buffers passed in (it is almost certainly @@ -544,6 +544,6 @@ Delivery::output_changed (IOChange change, void* /*src*/) { if (change.type & IOChange::ConfigurationChanged) { reset_panner (); + _output_buffers->attach_buffers (_output->ports ()); } } - diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 17a1da231b..21afdbae56 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -447,6 +447,7 @@ IO::ensure_ports (ChanCount count, bool clear, void* src) change.after = _ports.count (); change.type = IOChange::ConfigurationChanged; this->changed (change, src); /* EMIT SIGNAL */ + _buffers.attach_buffers (_ports); setup_bundle (); _session.set_dirty (); } @@ -1522,12 +1523,10 @@ IO::connected_to (boost::shared_ptr other) const void IO::process_input (boost::shared_ptr proc, framepos_t start_frame, framepos_t end_frame, pframes_t nframes) { - BufferSet bufs; - /* don't read the data into new buffers - just use the port buffers directly */ - bufs.attach_buffers (_ports, nframes, 0); - proc->run (bufs, start_frame, end_frame, nframes, true); + _buffers.get_jack_port_addresses (_ports, nframes, 0); + proc->run (_buffers, start_frame, end_frame, nframes, true); } void -- cgit v1.2.3