mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-17 04:06:26 +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/signals2.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/scoped_array.hpp>
|
||||||
#include <boost/operators.hpp>
|
#include <boost/operators.hpp>
|
||||||
|
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
|
|
@ -45,7 +46,9 @@ class ExportChannel : public boost::less_than_comparable<ExportChannel>
|
||||||
|
|
||||||
virtual ~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;
|
virtual bool empty () const = 0;
|
||||||
|
|
||||||
/// Adds state to node passed
|
/// Adds state to node passed
|
||||||
|
|
@ -75,9 +78,10 @@ class PortExportChannel : public ExportChannel
|
||||||
public:
|
public:
|
||||||
typedef std::set<AudioPort *> PortSet;
|
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(); }
|
bool empty () const { return ports.empty(); }
|
||||||
|
|
||||||
void get_state (XMLNode * node) const;
|
void get_state (XMLNode * node) const;
|
||||||
|
|
@ -90,6 +94,8 @@ class PortExportChannel : public ExportChannel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PortSet ports;
|
PortSet ports;
|
||||||
|
boost::scoped_array<Sample> buffer;
|
||||||
|
framecnt_t buffer_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handles RegionExportChannels and does actual reading from region
|
/// Handles RegionExportChannels and does actual reading from region
|
||||||
|
|
@ -106,7 +112,7 @@ class RegionExportChannelFactory
|
||||||
~RegionExportChannelFactory ();
|
~RegionExportChannelFactory ();
|
||||||
|
|
||||||
ExportChannelPtr create (uint32_t channel);
|
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:
|
private:
|
||||||
|
|
||||||
|
|
@ -124,8 +130,8 @@ class RegionExportChannelFactory
|
||||||
framecnt_t region_start;
|
framecnt_t region_start;
|
||||||
framecnt_t position;
|
framecnt_t position;
|
||||||
|
|
||||||
Sample * mixdown_buffer;
|
boost::scoped_array<Sample> mixdown_buffer;
|
||||||
Sample * gain_buffer;
|
boost::scoped_array<Sample> gain_buffer;
|
||||||
|
|
||||||
PBD::ScopedConnection export_connection;
|
PBD::ScopedConnection export_connection;
|
||||||
};
|
};
|
||||||
|
|
@ -136,7 +142,7 @@ class RegionExportChannel : public ExportChannel
|
||||||
friend class RegionExportChannelFactory;
|
friend class RegionExportChannelFactory;
|
||||||
|
|
||||||
public:
|
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 get_state (XMLNode * /*node*/) const {};
|
||||||
void set_state (XMLNode * /*node*/, Session & /*session*/) {};
|
void set_state (XMLNode * /*node*/, Session & /*session*/) {};
|
||||||
bool empty () const { return false; }
|
bool empty () const { return false; }
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class ExportChannelConfiguration : public boost::enable_shared_from_this<ExportC
|
||||||
|
|
||||||
ChannelList channels;
|
ChannelList channels;
|
||||||
bool split; // Split to mono files
|
bool split; // Split to mono files
|
||||||
std::string _name;
|
std::string _name;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,6 @@ class ExportGraphBuilder
|
||||||
// The sources of all data, each channel is read only once
|
// The sources of all data, each channel is read only once
|
||||||
ChannelMap channels;
|
ChannelMap channels;
|
||||||
|
|
||||||
Sample * process_buffer;
|
|
||||||
framecnt_t process_buffer_frames;
|
framecnt_t process_buffer_frames;
|
||||||
|
|
||||||
std::list<Normalizer *> normalizers;
|
std::list<Normalizer *> normalizers;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,17 @@
|
||||||
|
|
||||||
using namespace ARDOUR;
|
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
|
bool
|
||||||
PortExportChannel::operator< (ExportChannel const & other) const
|
PortExportChannel::operator< (ExportChannel const & other) const
|
||||||
{
|
{
|
||||||
|
|
@ -42,19 +53,29 @@ PortExportChannel::operator< (ExportChannel const & other) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
|
||||||
if (*it != 0) {
|
if (*it != 0) {
|
||||||
Sample* port_buffer = (*it)->get_audio_buffer(frames).data();
|
Sample* port_buffer = (*it)->get_audio_buffer(frames).data();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < frames; ++i) {
|
for (uint32_t i = 0; i < frames; ++i) {
|
||||||
data[i] += (float) port_buffer[i];
|
buffer[i] += (float) port_buffer[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = buffer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -93,10 +114,7 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio
|
||||||
frames_per_cycle (session->engine().frames_per_cycle ()),
|
frames_per_cycle (session->engine().frames_per_cycle ()),
|
||||||
buffers_up_to_date (false),
|
buffers_up_to_date (false),
|
||||||
region_start (region.position()),
|
region_start (region.position()),
|
||||||
position (region_start),
|
position (region_start)
|
||||||
|
|
||||||
mixdown_buffer (0),
|
|
||||||
gain_buffer (0)
|
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Raw:
|
case Raw:
|
||||||
|
|
@ -105,9 +123,9 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio
|
||||||
case Fades:
|
case Fades:
|
||||||
n_channels = region.n_channels();
|
n_channels = region.n_channels();
|
||||||
|
|
||||||
mixdown_buffer = new Sample [frames_per_cycle];
|
mixdown_buffer.reset (new Sample [frames_per_cycle]);
|
||||||
gain_buffer = new Sample [frames_per_cycle];
|
gain_buffer.reset (new Sample [frames_per_cycle]);
|
||||||
memset (gain_buffer, 1.0, sizeof (Sample) * frames_per_cycle);
|
memset (gain_buffer.get(), 1.0, sizeof (Sample) * frames_per_cycle);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Processed:
|
case Processed:
|
||||||
|
|
@ -125,8 +143,6 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio
|
||||||
|
|
||||||
RegionExportChannelFactory::~RegionExportChannelFactory ()
|
RegionExportChannelFactory::~RegionExportChannelFactory ()
|
||||||
{
|
{
|
||||||
delete[] mixdown_buffer;
|
|
||||||
delete[] gain_buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportChannelPtr
|
ExportChannelPtr
|
||||||
|
|
@ -137,7 +153,7 @@ RegionExportChannelFactory::create (uint32_t channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 (channel < n_channels);
|
||||||
assert (frames_to_read <= frames_per_cycle);
|
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;
|
buffers_up_to_date = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (data, buffers.get_audio (channel).data(), frames_to_read * sizeof (Sample));
|
data = buffers.get_audio (channel).data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -164,8 +180,8 @@ RegionExportChannelFactory::update_buffers (framecnt_t frames)
|
||||||
case Fades:
|
case Fades:
|
||||||
assert (mixdown_buffer && gain_buffer);
|
assert (mixdown_buffer && gain_buffer);
|
||||||
for (size_t channel = 0; channel < n_channels; ++channel) {
|
for (size_t channel = 0; channel < n_channels; ++channel) {
|
||||||
memset (mixdown_buffer, 0, sizeof (Sample) * frames);
|
memset (mixdown_buffer.get(), 0, sizeof (Sample) * frames);
|
||||||
region.read_at (buffers.get_audio (channel).data(), mixdown_buffer, gain_buffer, position, frames, channel);
|
region.read_at (buffers.get_audio (channel).data(), mixdown_buffer.get(), gain_buffer.get(), position, frames, channel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Processed:
|
case Processed:
|
||||||
|
|
@ -177,3 +193,4 @@ RegionExportChannelFactory::update_buffers (framecnt_t frames)
|
||||||
|
|
||||||
position += frames;
|
position += frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,10 @@ ExportGraphBuilder::ExportGraphBuilder (Session const & session)
|
||||||
, thread_pool (4) // FIXME thread amount to cores amount
|
, thread_pool (4) // FIXME thread amount to cores amount
|
||||||
{
|
{
|
||||||
process_buffer_frames = session.engine().frames_per_cycle();
|
process_buffer_frames = session.engine().frames_per_cycle();
|
||||||
process_buffer = new Sample[process_buffer_frames];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportGraphBuilder::~ExportGraphBuilder ()
|
ExportGraphBuilder::~ExportGraphBuilder ()
|
||||||
{
|
{
|
||||||
delete [] process_buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -44,6 +42,7 @@ ExportGraphBuilder::process (framecnt_t frames, bool last_cycle)
|
||||||
assert(frames <= process_buffer_frames);
|
assert(frames <= process_buffer_frames);
|
||||||
|
|
||||||
for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) {
|
for (ChannelMap::iterator it = channels.begin(); it != channels.end(); ++it) {
|
||||||
|
Sample * process_buffer = 0;
|
||||||
it->first->read (process_buffer, frames);
|
it->first->read (process_buffer, frames);
|
||||||
ProcessContext<Sample> context(process_buffer, frames, 1);
|
ProcessContext<Sample> context(process_buffer, frames, 1);
|
||||||
if (last_cycle) { context.set_flag (ProcessContext<Sample>::EndOfInput); }
|
if (last_cycle) { context.set_flag (ProcessContext<Sample>::EndOfInput); }
|
||||||
|
|
@ -85,6 +84,13 @@ ExportGraphBuilder::set_current_timespan (boost::shared_ptr<ExportTimespan> span
|
||||||
void
|
void
|
||||||
ExportGraphBuilder::add_config (FileSpec const & config)
|
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.
|
// 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...
|
// However, we need to copy it to not change the config which is saved...
|
||||||
FileSpec new_config (config);
|
FileSpec new_config (config);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue