mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-15 11:06:32 +01:00
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:
parent
b67be86cbf
commit
ffccaaf0bb
5 changed files with 55 additions and 27 deletions
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue