summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/export_channel.h9
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/export_channel.cc57
-rw-r--r--libs/ardour/export_handler.cc30
-rw-r--r--libs/ardour/session.cc1
-rw-r--r--libs/ardour/session_export.cc42
6 files changed, 63 insertions, 79 deletions
diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h
index a94d65fbdc..8f4d8fc27c 100644
--- a/libs/ardour/ardour/export_channel.h
+++ b/libs/ardour/ardour/export_channel.h
@@ -22,11 +22,13 @@
#define __ardour_export_channel_h__
#include <set>
+#include <list>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include "pbd/signals.h"
+#include "pbd/ringbuffer.h"
#include "ardour/buffer_set.h"
#include "ardour/export_pointers.h"
@@ -68,6 +70,8 @@ class LIBARDOUR_API PortExportChannel : public ExportChannel
typedef std::set<boost::weak_ptr<AudioPort> > PortSet;
PortExportChannel ();
+ ~PortExportChannel ();
+
void set_max_buffer_size(samplecnt_t samples);
void read (Sample const *& data, samplecnt_t samples) const;
@@ -83,8 +87,9 @@ class LIBARDOUR_API PortExportChannel : public ExportChannel
private:
PortSet ports;
- boost::scoped_array<Sample> buffer;
- samplecnt_t buffer_size;
+ samplecnt_t _buffer_size;
+ boost::scoped_array<Sample> _buffer;
+ std::list <boost::shared_ptr<PBD::RingBuffer<Sample> > > _delaylines;
};
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index e04e99de88..66ab5ce082 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -751,7 +751,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
boost::shared_ptr<ExportHandler> get_export_handler ();
boost::shared_ptr<ExportStatus> get_export_status ();
- int start_audio_export (samplepos_t position, bool realtime = false, bool region_export = false, bool comensate_master_latency = false);
+ int start_audio_export (samplepos_t position, bool realtime = false, bool region_export = false);
PBD::Signal1<int, samplecnt_t> ProcessExport;
static PBD::Signal2<void,std::string, std::string> Exported;
@@ -1345,7 +1345,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
bool _realtime_export;
bool _region_export;
samplepos_t _export_preroll;
- samplepos_t _export_latency;
boost::shared_ptr<ExportHandler> export_handler;
boost::shared_ptr<ExportStatus> export_status;
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
diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc
index 7301e12b68..df74bda065 100644
--- a/libs/ardour/export_handler.cc
+++ b/libs/ardour/export_handler.cc
@@ -193,7 +193,6 @@ ExportHandler::start_timespan ()
handle_duplicate_format_extensions();
bool realtime = current_timespan->realtime ();
bool region_export = true;
- bool incl_master_bus = false;
for (ConfigMap::iterator it = timespan_bounds.first; it != timespan_bounds.second; ++it) {
// Filenames can be shared across timespans
FileSpec & spec = it->second;
@@ -206,33 +205,6 @@ ExportHandler::start_timespan ()
default:
break;
}
-#if 1 // hack alert -- align master bus, compensate master latency
-
- /* there's no easier way to get this information here.
- * Ports are configured in the PortExportChannelSelector GUI,
- * This ExportHandler has no context of routes.
- */
- boost::shared_ptr<Route> master_bus = session.master_out ();
- if (master_bus) {
- const PortSet& ps = master_bus->output ()->ports();
-
- const ExportChannelConfiguration::ChannelList& channels = spec.channel_config->get_channels ();
- for (ExportChannelConfiguration::ChannelList::const_iterator it = channels.begin(); it != channels.end(); ++it) {
-
- boost::shared_ptr <PortExportChannel> pep = boost::dynamic_pointer_cast<PortExportChannel> (*it);
- if (!pep) {
- continue;
- }
- PortExportChannel::PortSet const& ports = pep->get_ports ();
- for (PortExportChannel::PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
- boost::shared_ptr<AudioPort> ap = (*it).lock();
- if (ps.contains (ap)) {
- incl_master_bus = true;
- }
- }
- }
- }
-#endif
graph_builder->add_config (spec, realtime);
}
@@ -245,7 +217,7 @@ ExportHandler::start_timespan ()
session.ProcessExport.connect_same_thread (process_connection, boost::bind (&ExportHandler::process, this, _1));
process_position = current_timespan->get_start();
// TODO check if it's a RegionExport.. set flag to skip process_without_events()
- session.start_audio_export (process_position, realtime, region_export, incl_master_bus);
+ session.start_audio_export (process_position, realtime, region_export);
}
void
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 8bf18fc730..df8ae9fc51 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -224,7 +224,6 @@ Session::Session (AudioEngine &eng,
, _realtime_export (false)
, _region_export (false)
, _export_preroll (0)
- , _export_latency (0)
, _pre_export_mmc_enabled (false)
, _name (snapshot_name)
, _is_new (true)
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index 33ede3cadc..879f34020a 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -104,7 +104,7 @@ Session::pre_export ()
/** Called for each range that is being exported */
int
-Session::start_audio_export (samplepos_t position, bool realtime, bool region_export, bool comensate_master_latency)
+Session::start_audio_export (samplepos_t position, bool realtime, bool region_export)
{
if (!_exporting) {
pre_export ();
@@ -127,31 +127,6 @@ Session::start_audio_export (samplepos_t position, bool realtime, bool region_ex
_export_preroll = 1;
}
- /* "worst_track_latency" is the correct value for stem-exports
- * see to Route::add_export_point(),
- *
- * For master-bus export, we also need to add the master's latency.
- * (or actually longest-total-session-latency - worst-track-latency)
- * to align the export to 00:00:00:00.
- *
- * We must not use worst_playback_latency because that
- * includes external (hardware) latencies and would overcompensate
- * during file-export.
- *
- * (this is all still very [w]hacky. Individual Bus and Track outputs
- * are not aligned but one can select them in the PortExportChannelSelector)
- */
- _export_latency = worst_track_out_latency ();
-
- boost::shared_ptr<Route> master = master_out ();
- if (master && comensate_master_latency) {
- _export_latency += master->signal_latency ();
- }
-
- if (region_export) {
- _export_latency = 0;
- }
-
/* We're about to call Track::seek, so the butler must have finished everything
up otherwise it could be doing do_refill in its thread while we are doing
it here.
@@ -181,6 +156,12 @@ Session::start_audio_export (samplepos_t position, bool realtime, bool region_ex
*/
_transport_sample = position;
+
+ if (!region_export) {
+ _remaining_latency_preroll = worst_latency_preroll ();
+ } else {
+ _remaining_latency_preroll = 0;
+ }
export_status->stop = false;
/* get transport ready. note how this is calling butler functions
@@ -277,18 +258,21 @@ Session::process_export_fw (pframes_t nframes)
return;
}
- if (_export_latency > 0) {
- samplepos_t remain = std::min ((samplepos_t)nframes, _export_latency);
+ if (_remaining_latency_preroll > 0) {
+ samplepos_t remain = std::min ((samplepos_t)nframes, _remaining_latency_preroll);
if (need_buffers) {
_engine.main_thread()->get_buffers ();
}
+
process_without_events (remain);
+
if (need_buffers) {
_engine.main_thread()->drop_buffers ();
}
- _export_latency -= remain;
+ _remaining_latency_preroll -= remain;
+ _transport_sample -= remain;
nframes -= remain;
if (nframes == 0) {