From ffccaaf0bbd23ea655d8027f5173b45ba3258edf Mon Sep 17 00:00:00 2001 From: Sakari Bergen Date: Mon, 10 Jan 2011 21:16:49 +0000 Subject: [PATCH] Make export channels own their buffers + some other small code tidy-ups. Preparation for more stem export options git-svn-id: svn://localhost/ardour2/branches/3.0@8494 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/export_channel.h | 20 +++++--- .../ardour/export_channel_configuration.h | 2 +- libs/ardour/ardour/export_graph_builder.h | 1 - libs/ardour/export_channel.cc | 49 +++++++++++++------ libs/ardour/export_graph_builder.cc | 10 +++- 5 files changed, 55 insertions(+), 27 deletions(-) diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h index f51578c80c..34d6263976 100644 --- a/libs/ardour/ardour/export_channel.h +++ b/libs/ardour/ardour/export_channel.h @@ -25,6 +25,7 @@ #include #include +#include #include #include "pbd/signals.h" @@ -45,7 +46,9 @@ class ExportChannel : public boost::less_than_comparable virtual ~ExportChannel () {} - virtual void read (Sample * data, framecnt_t frames) const = 0; + virtual void set_max_buffer_size(framecnt_t frames) { } + + virtual void read (Sample *& data, framecnt_t frames) const = 0; virtual bool empty () const = 0; /// Adds state to node passed @@ -75,9 +78,10 @@ class PortExportChannel : public ExportChannel public: typedef std::set PortSet; - PortExportChannel () {} + PortExportChannel (); + void set_max_buffer_size(framecnt_t frames); - void read (Sample * data, framecnt_t frames) const; + void read (Sample *& data, framecnt_t frames) const; bool empty () const { return ports.empty(); } void get_state (XMLNode * node) const; @@ -90,6 +94,8 @@ class PortExportChannel : public ExportChannel private: PortSet ports; + boost::scoped_array buffer; + framecnt_t buffer_size; }; /// Handles RegionExportChannels and does actual reading from region @@ -106,7 +112,7 @@ class RegionExportChannelFactory ~RegionExportChannelFactory (); ExportChannelPtr create (uint32_t channel); - void read (uint32_t channel, Sample * data, framecnt_t frames_to_read); + void read (uint32_t channel, Sample *& data, framecnt_t frames_to_read); private: @@ -124,8 +130,8 @@ class RegionExportChannelFactory framecnt_t region_start; framecnt_t position; - Sample * mixdown_buffer; - Sample * gain_buffer; + boost::scoped_array mixdown_buffer; + boost::scoped_array gain_buffer; PBD::ScopedConnection export_connection; }; @@ -136,7 +142,7 @@ class RegionExportChannel : public ExportChannel friend class RegionExportChannelFactory; public: - void read (Sample * data, framecnt_t frames_to_read) const { factory.read (channel, data, frames_to_read); } + void read (Sample *& data, framecnt_t frames_to_read) const { factory.read (channel, data, frames_to_read); } void get_state (XMLNode * /*node*/) const {}; void set_state (XMLNode * /*node*/, Session & /*session*/) {}; bool empty () const { return false; } diff --git a/libs/ardour/ardour/export_channel_configuration.h b/libs/ardour/ardour/export_channel_configuration.h index d50ec0365d..b5b9b65bf7 100644 --- a/libs/ardour/ardour/export_channel_configuration.h +++ b/libs/ardour/ardour/export_channel_configuration.h @@ -82,7 +82,7 @@ class ExportChannelConfiguration : public boost::enable_shared_from_this normalizers; diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc index c612b1f668..4cf510a971 100644 --- a/libs/ardour/export_channel.cc +++ b/libs/ardour/export_channel.cc @@ -31,6 +31,17 @@ using namespace ARDOUR; +PortExportChannel::PortExportChannel () + : buffer_size(0) +{ +} + +void PortExportChannel::set_max_buffer_size(framecnt_t frames) +{ + buffer_size = frames; + buffer.reset (new Sample[frames]); +} + bool PortExportChannel::operator< (ExportChannel const & other) const { @@ -42,19 +53,29 @@ PortExportChannel::operator< (ExportChannel const & other) const } void -PortExportChannel::read (Sample * data, framecnt_t frames) const +PortExportChannel::read (Sample *& data, framecnt_t frames) const { - memset (data, 0, frames * sizeof (float)); + assert(buffer); + assert(frames <= buffer_size); + + if (ports.size() == 1) { + data = (*ports.begin())->get_audio_buffer(frames).data(); + return; + } + + memset (buffer.get(), 0, frames * sizeof (Sample)); for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) { if (*it != 0) { Sample* port_buffer = (*it)->get_audio_buffer(frames).data(); for (uint32_t i = 0; i < frames; ++i) { - data[i] += (float) port_buffer[i]; + buffer[i] += (float) port_buffer[i]; } } } + + data = buffer.get(); } void @@ -93,10 +114,7 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio frames_per_cycle (session->engine().frames_per_cycle ()), buffers_up_to_date (false), region_start (region.position()), - position (region_start), - - mixdown_buffer (0), - gain_buffer (0) + position (region_start) { switch (type) { case Raw: @@ -105,9 +123,9 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio case Fades: n_channels = region.n_channels(); - mixdown_buffer = new Sample [frames_per_cycle]; - gain_buffer = new Sample [frames_per_cycle]; - memset (gain_buffer, 1.0, sizeof (Sample) * frames_per_cycle); + mixdown_buffer.reset (new Sample [frames_per_cycle]); + gain_buffer.reset (new Sample [frames_per_cycle]); + memset (gain_buffer.get(), 1.0, sizeof (Sample) * frames_per_cycle); break; case Processed: @@ -125,8 +143,6 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio RegionExportChannelFactory::~RegionExportChannelFactory () { - delete[] mixdown_buffer; - delete[] gain_buffer; } ExportChannelPtr @@ -137,7 +153,7 @@ RegionExportChannelFactory::create (uint32_t channel) } void -RegionExportChannelFactory::read (uint32_t channel, Sample * data, framecnt_t frames_to_read) +RegionExportChannelFactory::read (uint32_t channel, Sample *& data, framecnt_t frames_to_read) { assert (channel < n_channels); assert (frames_to_read <= frames_per_cycle); @@ -147,7 +163,7 @@ RegionExportChannelFactory::read (uint32_t channel, Sample * data, framecnt_t fr buffers_up_to_date = true; } - memcpy (data, buffers.get_audio (channel).data(), frames_to_read * sizeof (Sample)); + data = buffers.get_audio (channel).data(); } void @@ -164,8 +180,8 @@ RegionExportChannelFactory::update_buffers (framecnt_t frames) case Fades: assert (mixdown_buffer && gain_buffer); for (size_t channel = 0; channel < n_channels; ++channel) { - memset (mixdown_buffer, 0, sizeof (Sample) * frames); - region.read_at (buffers.get_audio (channel).data(), mixdown_buffer, gain_buffer, position, frames, channel); + memset (mixdown_buffer.get(), 0, sizeof (Sample) * frames); + region.read_at (buffers.get_audio (channel).data(), mixdown_buffer.get(), gain_buffer.get(), position, frames, channel); } break; case Processed: @@ -177,3 +193,4 @@ RegionExportChannelFactory::update_buffers (framecnt_t frames) position += frames; } + diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index 51b4c7042c..d0ce883385 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -30,12 +30,10 @@ ExportGraphBuilder::ExportGraphBuilder (Session const & session) , thread_pool (4) // FIXME thread amount to cores amount { process_buffer_frames = session.engine().frames_per_cycle(); - process_buffer = new Sample[process_buffer_frames]; } ExportGraphBuilder::~ExportGraphBuilder () { - delete [] process_buffer; } int @@ -44,6 +42,7 @@ ExportGraphBuilder::process (framecnt_t frames, bool last_cycle) assert(frames <= process_buffer_frames); for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) { + Sample * process_buffer = 0; it->first->read (process_buffer, frames); ProcessContext context(process_buffer, frames, 1); if (last_cycle) { context.set_flag (ProcessContext::EndOfInput); } @@ -85,6 +84,13 @@ ExportGraphBuilder::set_current_timespan (boost::shared_ptr span void ExportGraphBuilder::add_config (FileSpec const & config) { + 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_frames); + } + // 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); -- 2.30.2