summaryrefslogtreecommitdiff
path: root/libs/ardour/export_channel.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-09-26 17:49:24 +0200
committerRobin Gareus <robin@gareus.org>2017-09-29 05:03:48 +0200
commit24ec0b974d84df061cbbe645668dc62fa7120678 (patch)
treece9274b55976d535ace89ba9e8781cef1b778b66 /libs/ardour/export_channel.cc
parenta6cc58d7574ba03f0f8860e130fc4bdef305d3f3 (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.cc57
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