diff options
Diffstat (limited to 'libs/ardour/export_graph_builder.cc')
-rw-r--r-- | libs/ardour/export_graph_builder.cc | 48 |
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); |