diff options
author | Robin Gareus <robin@gareus.org> | 2017-09-26 17:49:24 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-09-29 05:03:48 +0200 |
commit | 24ec0b974d84df061cbbe645668dc62fa7120678 (patch) | |
tree | ce9274b55976d535ace89ba9e8781cef1b778b66 /libs/ardour/export_channel.cc | |
parent | a6cc58d7574ba03f0f8860e130fc4bdef305d3f3 (diff) |
Properly aligned export (Stem + Session)
Delay ports being exported by their playback latency.
Diffstat (limited to 'libs/ardour/export_channel.cc')
-rw-r--r-- | libs/ardour/export_channel.cc | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc index 9a7e6a9ace..66fec3a53b 100644 --- a/libs/ardour/export_channel.cc +++ b/libs/ardour/export_channel.cc @@ -35,14 +35,33 @@ using namespace ARDOUR; PortExportChannel::PortExportChannel () - : buffer_size(0) + : _buffer_size (0) { } +PortExportChannel::~PortExportChannel () +{ + _delaylines.clear (); +} + void PortExportChannel::set_max_buffer_size(samplecnt_t samples) { - buffer_size = samples; - buffer.reset (new Sample[samples]); + _buffer_size = samples; + _buffer.reset (new Sample[samples]); + + _delaylines.clear (); + + for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) { + boost::shared_ptr<AudioPort> p = it->lock (); + if (!p) { continue; } + samplecnt_t latency = p->private_latency_range (true).max; + PBD::RingBuffer<Sample>* rb = new PBD::RingBuffer<Sample> (latency + 1 + _buffer_size); + for (samplepos_t i = 0; i < latency; ++i) { + Sample zero = 0; + rb->write (&zero, 1); + } + _delaylines.push_back (boost::shared_ptr<PBD::RingBuffer<Sample> >(rb)); + } } bool @@ -58,10 +77,10 @@ PortExportChannel::operator< (ExportChannel const & other) const void PortExportChannel::read (Sample const *& data, samplecnt_t samples) const { - assert(buffer); - assert(samples <= buffer_size); + assert(_buffer); + assert(samples <= _buffer_size); - if (ports.size() == 1) { + if (ports.size() == 1 && _delaylines.size() ==1 && _delaylines.front()->bufsize () == _buffer_size + 1) { boost::shared_ptr<AudioPort> p = ports.begin()->lock (); AudioBuffer& ab (p->get_audio_buffer(samples)); // unsets AudioBuffer::_written data = ab.data(); @@ -69,22 +88,28 @@ PortExportChannel::read (Sample const *& data, samplecnt_t samples) const return; } - memset (buffer.get(), 0, samples * sizeof (Sample)); + memset (_buffer.get(), 0, samples * sizeof (Sample)); + std::list <boost::shared_ptr<PBD::RingBuffer<Sample> > >::const_iterator di = _delaylines.begin (); for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) { boost::shared_ptr<AudioPort> p = it->lock (); - if (p) { - AudioBuffer& ab (p->get_audio_buffer(samples)); // unsets AudioBuffer::_written - Sample* port_buffer = ab.data(); - ab.set_written (true); - - for (uint32_t i = 0; i < samples; ++i) { - buffer[i] += (float) port_buffer[i]; - } + if (!p) { + continue; + } + AudioBuffer& ab (p->get_audio_buffer(samples)); // unsets AudioBuffer::_written + Sample* port_buffer = ab.data(); + ab.set_written (true); + (*di)->write (port_buffer, samples); + // TODO optimze, get_read_vector() + for (uint32_t i = 0; i < samples; ++i) { + Sample spl; + (*di)->read (&spl, 1); + _buffer[i] += spl; } + ++di; } - data = buffer.get(); + data = _buffer.get(); } void |