summaryrefslogtreecommitdiff
path: root/libs/ardour/export_graph_builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/export_graph_builder.cc')
-rw-r--r--libs/ardour/export_graph_builder.cc48
1 files changed, 35 insertions, 13 deletions
diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc
index f4d6d21f2d..eb74d44fd4 100644
--- a/libs/ardour/export_graph_builder.cc
+++ b/libs/ardour/export_graph_builder.cc
@@ -77,20 +77,33 @@ ExportGraphBuilder::~ExportGraphBuilder ()
{
}
-int
+samplecnt_t
ExportGraphBuilder::process (samplecnt_t samples, bool last_cycle)
{
assert(samples <= process_buffer_samples);
+ sampleoffset_t off = 0;
for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) {
Sample const * process_buffer = 0;
it->first->read (process_buffer, samples);
- ConstProcessContext<Sample> context(process_buffer, samples, 1);
+
+ if (session.remaining_latency_preroll () >= _master_align + samples) {
+ /* Skip processing during pre-roll, only read/write export ringbuffers */
+ return 0;
+ }
+
+ off = 0;
+ if (session.remaining_latency_preroll () > _master_align) {
+ off = session.remaining_latency_preroll () - _master_align;
+ assert (off < samples);
+ }
+
+ ConstProcessContext<Sample> context(&process_buffer[off], samples - off, 1);
if (last_cycle) { context().set_flag (ProcessContext<Sample>::EndOfInput); }
it->second->process (context);
}
- return 0;
+ return samples - off;
}
bool
@@ -126,6 +139,7 @@ ExportGraphBuilder::reset ()
intermediates.clear ();
analysis_map.clear();
_realtime = false;
+ _master_align = 0;
}
void
@@ -148,17 +162,25 @@ ExportGraphBuilder::set_current_timespan (boost::shared_ptr<ExportTimespan> span
void
ExportGraphBuilder::add_config (FileSpec const & config, bool rt)
{
- ExportChannelConfiguration::ChannelList const & channels =
- config.channel_config->get_channels();
- for(ExportChannelConfiguration::ChannelList::const_iterator it = channels.begin();
- it != channels.end(); ++it) {
- (*it)->set_max_buffer_size(process_buffer_samples);
+ /* calculate common latency, shave off master-bus hardware playback latency (if any) */
+ _master_align = session.master_out() ? session.master_out()->output()->connected_latency (true) : 0;
+
+ ExportChannelConfiguration::ChannelList const & channels = config.channel_config->get_channels();
+
+ for(ExportChannelConfiguration::ChannelList::const_iterator it = channels.begin(); it != channels.end(); ++it) {
+ _master_align = std::min (_master_align, (*it)->common_port_playback_latency ());
+ }
+
+ /* now set-up port-data sniffing and delay-ringbuffers */
+ for(ExportChannelConfiguration::ChannelList::const_iterator it = channels.begin(); it != channels.end(); ++it) {
+ (*it)->prepare_export (process_buffer_samples, _master_align);
}
_realtime = rt;
- // If the sample rate is "session rate", change it to the real value.
- // However, we need to copy it to not change the config which is saved...
+ /* If the sample rate is "session rate", change it to the real value.
+ * However, we need to copy it to not change the config which is saved...
+ */
FileSpec new_config (config);
new_config.format.reset(new ExportFormatSpecification(*new_config.format, false));
if(new_config.format->sample_rate() == ExportFormatBase::SR_Session) {
@@ -166,14 +188,14 @@ ExportGraphBuilder::add_config (FileSpec const & config, bool rt)
new_config.format->set_sample_rate(ExportFormatBase::nearest_sample_rate(session_rate));
}
-
if (!new_config.channel_config->get_split ()) {
add_split_config (new_config);
return;
}
- // Split channel configurations are split into several channel configurations,
- // each corresponding to a file, at this stage
+ /* Split channel configurations are split into several channel configurations,
+ * each corresponding to a file, at this stage
+ */
typedef std::list<boost::shared_ptr<ExportChannelConfiguration> > ConfigList;
ConfigList file_configs;
new_config.channel_config->configurations_for_files (file_configs);