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
This commit is contained in:
Sakari Bergen 2011-01-10 21:16:49 +00:00
parent b67be86cbf
commit ffccaaf0bb
5 changed files with 55 additions and 27 deletions

View file

@ -25,6 +25,7 @@
#include <boost/signals2.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/operators.hpp>
#include "pbd/signals.h"
@ -45,7 +46,9 @@ class ExportChannel : public boost::less_than_comparable<ExportChannel>
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<AudioPort *> 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<Sample> 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<Sample> mixdown_buffer;
boost::scoped_array<Sample> 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; }

View file

@ -82,7 +82,7 @@ class ExportChannelConfiguration : public boost::enable_shared_from_this<ExportC
ChannelList channels;
bool split; // Split to mono files
std::string _name;
std::string _name;
};
} // namespace ARDOUR

View file

@ -224,7 +224,6 @@ class ExportGraphBuilder
// The sources of all data, each channel is read only once
ChannelMap channels;
Sample * process_buffer;
framecnt_t process_buffer_frames;
std::list<Normalizer *> normalizers;

View file

@ -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;
}

View file

@ -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<Sample> context(process_buffer, frames, 1);
if (last_cycle) { context.set_flag (ProcessContext<Sample>::EndOfInput); }
@ -85,6 +84,13 @@ ExportGraphBuilder::set_current_timespan (boost::shared_ptr<ExportTimespan> 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);