Make stem export export from right before any processors.
The dialog does not support exporting from the outputs anymore, sorry. Will add options later... git-svn-id: svn://localhost/ardour2/branches/3.0@8520 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
113e6b505a
commit
a406d9183a
@ -548,20 +548,20 @@ TrackExportChannelSelector::fill_list()
|
||||
for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
|
||||
Route * route = it->get();
|
||||
if(dynamic_cast<AudioTrack *>(route)) {
|
||||
add_track(route->output().get());
|
||||
add_track(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TrackExportChannelSelector::add_track(IO * io)
|
||||
TrackExportChannelSelector::add_track(Route * route)
|
||||
{
|
||||
Gtk::TreeModel::iterator iter = track_list->append();
|
||||
Gtk::TreeModel::Row row = *iter;
|
||||
|
||||
row[track_cols.selected] = true;
|
||||
row[track_cols.label] = io->name();
|
||||
row[track_cols.track] = io;
|
||||
row[track_cols.label] = route->name();
|
||||
row[track_cols.track] = route;
|
||||
}
|
||||
|
||||
void
|
||||
@ -578,7 +578,9 @@ TrackExportChannelSelector::update_config()
|
||||
|
||||
ExportProfileManager::ChannelConfigStatePtr state = manager->add_channel_config();
|
||||
|
||||
IO * track = row[track_cols.track];
|
||||
Route * track = row[track_cols.track];
|
||||
|
||||
/* Output of track code. TODO make this an option also
|
||||
uint32_t outs = track->n_ports().n_audio();
|
||||
for (uint32_t i = 0; i < outs; ++i) {
|
||||
AudioPort * port = track->audio (i);
|
||||
@ -589,7 +591,11 @@ TrackExportChannelSelector::update_config()
|
||||
state->config->register_channel(channel);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
std::list<ExportChannelPtr> list;
|
||||
RouteExportChannel::create_from_route (list, *track);
|
||||
state->config->register_channels (list);
|
||||
state->config->set_name(track->name());
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ class TrackExportChannelSelector : public ExportChannelSelector
|
||||
private:
|
||||
|
||||
void fill_list();
|
||||
void add_track(ARDOUR::IO * io);
|
||||
void add_track(ARDOUR::Route * route);
|
||||
void update_config();
|
||||
|
||||
ChannelConfigList configs;
|
||||
@ -244,7 +244,7 @@ class TrackExportChannelSelector : public ExportChannelSelector
|
||||
struct TrackCols : public Gtk::TreeModelColumnRecord
|
||||
{
|
||||
public:
|
||||
Gtk::TreeModelColumn<ARDOUR::IO *> track;
|
||||
Gtk::TreeModelColumn<ARDOUR::Route *> track;
|
||||
Gtk::TreeModelColumn<std::string> label;
|
||||
Gtk::TreeModelColumn<bool> selected;
|
||||
|
||||
|
@ -97,10 +97,16 @@ public:
|
||||
AudioBuffer& get_audio(size_t i) {
|
||||
return (AudioBuffer&)get(DataType::AUDIO, i);
|
||||
}
|
||||
const AudioBuffer& get_audio(size_t i) const {
|
||||
return (const AudioBuffer&)get(DataType::AUDIO, i);
|
||||
}
|
||||
|
||||
MidiBuffer& get_midi(size_t i) {
|
||||
return (MidiBuffer&)get(DataType::MIDI, i);
|
||||
}
|
||||
const MidiBuffer& get_midi(size_t i) const {
|
||||
return (const MidiBuffer&)get(DataType::MIDI, i);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SLV2
|
||||
/** Get a MIDI buffer translated into an LV2 MIDI buffer for use with plugins.
|
||||
|
53
libs/ardour/ardour/capturing_processor.h
Normal file
53
libs/ardour/ardour/capturing_processor.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (C) 2011 Paul Davis
|
||||
Author: Sakari Bergen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_capturing_processor_h__
|
||||
#define __ardour_capturing_processor_h__
|
||||
|
||||
#include "ardour/processor.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class CapturingProcessor : public Processor
|
||||
{
|
||||
public:
|
||||
CapturingProcessor (Session & session);
|
||||
~CapturingProcessor();
|
||||
|
||||
public: // main interface
|
||||
BufferSet const & get_capture_buffers() const { return capture_buffers; }
|
||||
|
||||
public: // Processor overrides
|
||||
bool display_to_user() const { return false; }
|
||||
int set_block_size (pframes_t nframes);
|
||||
void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required);
|
||||
bool configure_io (ChanCount in, ChanCount out);
|
||||
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||
|
||||
private:
|
||||
|
||||
void realloc_buffers();
|
||||
|
||||
framecnt_t block_size;
|
||||
BufferSet capture_buffers;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif // __ardour_capturing_processor_h__
|
@ -38,6 +38,7 @@ class Session;
|
||||
class AudioTrack;
|
||||
class AudioPort;
|
||||
class AudioRegion;
|
||||
class CapturingProcessor;
|
||||
|
||||
/// Export channel base class interface for different source types
|
||||
class ExportChannel : public boost::less_than_comparable<ExportChannel>
|
||||
@ -48,7 +49,7 @@ class ExportChannel : public boost::less_than_comparable<ExportChannel>
|
||||
|
||||
virtual void set_max_buffer_size(framecnt_t frames) { }
|
||||
|
||||
virtual void read (Sample *& data, framecnt_t frames) const = 0;
|
||||
virtual void read (Sample const *& data, framecnt_t frames) const = 0;
|
||||
virtual bool empty () const = 0;
|
||||
|
||||
/// Adds state to node passed
|
||||
@ -81,7 +82,7 @@ class PortExportChannel : public ExportChannel
|
||||
PortExportChannel ();
|
||||
void set_max_buffer_size(framecnt_t frames);
|
||||
|
||||
void read (Sample *& data, framecnt_t frames) const;
|
||||
void read (Sample const *& data, framecnt_t frames) const;
|
||||
bool empty () const { return ports.empty(); }
|
||||
|
||||
void get_state (XMLNode * node) const;
|
||||
@ -112,7 +113,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 const *& data, framecnt_t frames_to_read);
|
||||
|
||||
private:
|
||||
|
||||
@ -142,7 +143,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 const *& 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; }
|
||||
@ -160,6 +161,49 @@ class RegionExportChannel : public ExportChannel
|
||||
uint32_t channel;
|
||||
};
|
||||
|
||||
/// Export channel for exporting from different positions in a route
|
||||
class RouteExportChannel : public ExportChannel
|
||||
{
|
||||
class ProcessorRemover; // fwd declaration
|
||||
|
||||
public:
|
||||
RouteExportChannel(boost::shared_ptr<CapturingProcessor> processor, size_t channel,
|
||||
boost::shared_ptr<ProcessorRemover> remover);
|
||||
~RouteExportChannel();
|
||||
|
||||
static void create_from_route(std::list<ExportChannelPtr> & result, Route & route);
|
||||
|
||||
public: // ExportChannel interface
|
||||
void set_max_buffer_size(framecnt_t frames);
|
||||
|
||||
void read (Sample const *& data, framecnt_t frames) const;
|
||||
bool empty () const { return false; }
|
||||
|
||||
void get_state (XMLNode * node) const;
|
||||
void set_state (XMLNode * node, Session & session);
|
||||
|
||||
bool operator< (ExportChannel const & other) const;
|
||||
|
||||
private:
|
||||
|
||||
// Removes the processor from the track when deleted
|
||||
class ProcessorRemover {
|
||||
public:
|
||||
ProcessorRemover (Route & route, boost::shared_ptr<CapturingProcessor> processor)
|
||||
: route (route), processor (processor) {}
|
||||
~ProcessorRemover();
|
||||
private:
|
||||
Route & route;
|
||||
boost::shared_ptr<CapturingProcessor> processor;
|
||||
};
|
||||
|
||||
boost::shared_ptr<CapturingProcessor> processor;
|
||||
size_t channel;
|
||||
// Each channel keeps a ref to the remover. Last one alive
|
||||
// will cause the processor to be removed on deletion.
|
||||
boost::shared_ptr<ProcessorRemover> remover;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include "ardour/export_channel.h"
|
||||
@ -70,6 +72,9 @@ class ExportChannelConfiguration : public boost::enable_shared_from_this<ExportC
|
||||
uint32_t get_n_chans () const { return channels.size(); }
|
||||
|
||||
void register_channel (ExportChannelPtr channel) { channels.push_back (channel); }
|
||||
void register_channels (ChannelList const & new_channels) {
|
||||
std::copy (new_channels.begin(), new_channels.end(), std::back_inserter(channels));
|
||||
}
|
||||
void clear_channels () { channels.clear (); }
|
||||
|
||||
/** Returns a list of channel configurations that match the files created.
|
||||
|
@ -59,6 +59,7 @@ class RouteGroup;
|
||||
class Send;
|
||||
class InternalReturn;
|
||||
class MonitorProcessor;
|
||||
class CapturingProcessor;
|
||||
|
||||
class Route : public SessionObject, public Automatable, public RouteGroupMember, public GraphNode
|
||||
{
|
||||
@ -217,6 +218,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||
BufferSet* get_return_buffer () const;
|
||||
void release_return_buffer () const;
|
||||
void put_monitor_send_at (Placement);
|
||||
boost::shared_ptr<CapturingProcessor> add_export_point(/* Add some argument for placement later */);
|
||||
|
||||
/** A record of the stream configuration at some point in the processor list.
|
||||
* Used to return where and why an processor list configuration request failed.
|
||||
|
75
libs/ardour/capturing_processor.cc
Normal file
75
libs/ardour/capturing_processor.cc
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2011 Paul Davis
|
||||
Author: Sakari Bergen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "ardour/capturing_processor.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/audioengine.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
CapturingProcessor::CapturingProcessor (Session & session)
|
||||
: Processor (session, X_("capture point"))
|
||||
, block_size (session.engine().frames_per_cycle())
|
||||
{
|
||||
realloc_buffers ();
|
||||
}
|
||||
|
||||
CapturingProcessor::~CapturingProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
CapturingProcessor::set_block_size (pframes_t nframes)
|
||||
{
|
||||
block_size = nframes;
|
||||
realloc_buffers();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CapturingProcessor::run (BufferSet& bufs, framepos_t, framepos_t, pframes_t nframes, bool)
|
||||
{
|
||||
if (active()) {
|
||||
capture_buffers.read_from (bufs, nframes);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CapturingProcessor::configure_io (ChanCount in, ChanCount out)
|
||||
{
|
||||
Processor::configure_io (in, out);
|
||||
realloc_buffers();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
|
||||
{
|
||||
out = in;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CapturingProcessor::realloc_buffers()
|
||||
{
|
||||
capture_buffers.ensure_buffers (_configured_input, block_size);
|
||||
}
|
||||
|
||||
} // namespace ARDOUR
|
@ -23,6 +23,7 @@
|
||||
#include "ardour/audio_track.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/audioregion.h"
|
||||
#include "ardour/capturing_processor.h"
|
||||
#include "ardour/export_channel.h"
|
||||
#include "ardour/export_failed.h"
|
||||
#include "ardour/session.h"
|
||||
@ -53,7 +54,7 @@ PortExportChannel::operator< (ExportChannel const & other) const
|
||||
}
|
||||
|
||||
void
|
||||
PortExportChannel::read (Sample *& data, framecnt_t frames) const
|
||||
PortExportChannel::read (Sample const *& data, framecnt_t frames) const
|
||||
{
|
||||
assert(buffer);
|
||||
assert(frames <= buffer_size);
|
||||
@ -153,7 +154,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 const *& data, framecnt_t frames_to_read)
|
||||
{
|
||||
assert (channel < n_channels);
|
||||
assert (frames_to_read <= frames_per_cycle);
|
||||
@ -194,3 +195,76 @@ RegionExportChannelFactory::update_buffers (framecnt_t frames)
|
||||
position += frames;
|
||||
}
|
||||
|
||||
|
||||
RouteExportChannel::RouteExportChannel(boost::shared_ptr<CapturingProcessor> processor, size_t channel,
|
||||
boost::shared_ptr<ProcessorRemover> remover)
|
||||
: processor (processor)
|
||||
, channel (channel)
|
||||
, remover (remover)
|
||||
{
|
||||
}
|
||||
|
||||
RouteExportChannel::~RouteExportChannel()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RouteExportChannel::create_from_route(std::list<ExportChannelPtr> & result, Route & route)
|
||||
{
|
||||
boost::shared_ptr<CapturingProcessor> processor = route.add_export_point();
|
||||
uint32_t channels = processor->input_streams().n_audio();
|
||||
|
||||
boost::shared_ptr<ProcessorRemover> remover (new ProcessorRemover (route, processor));
|
||||
result.clear();
|
||||
for (uint32_t i = 0; i < channels; ++i) {
|
||||
result.push_back (ExportChannelPtr (new RouteExportChannel (processor, i, remover)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteExportChannel::set_max_buffer_size(framecnt_t frames)
|
||||
{
|
||||
if (processor) {
|
||||
processor->set_block_size (frames);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteExportChannel::read (Sample const *& data, framecnt_t frames) const
|
||||
{
|
||||
assert(processor);
|
||||
AudioBuffer const & buffer = processor->get_capture_buffers().get_audio (channel);
|
||||
assert (frames <= (framecnt_t) buffer.size());
|
||||
data = buffer.data();
|
||||
}
|
||||
|
||||
void
|
||||
RouteExportChannel::get_state (XMLNode * node) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
RouteExportChannel::set_state (XMLNode * node, Session & session)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool
|
||||
RouteExportChannel::operator< (ExportChannel const & other) const
|
||||
{
|
||||
RouteExportChannel const * rec;
|
||||
if ((rec = dynamic_cast<RouteExportChannel const *>(&other)) == 0) {
|
||||
return this < &other;
|
||||
}
|
||||
|
||||
if (processor.get() == rec->processor.get()) {
|
||||
return channel < rec->channel;
|
||||
}
|
||||
return processor.get() < rec->processor.get();
|
||||
}
|
||||
|
||||
RouteExportChannel::ProcessorRemover::~ProcessorRemover()
|
||||
{
|
||||
route.remove_processor (processor);
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ 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;
|
||||
Sample const * 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); }
|
||||
ConstProcessContext<Sample> context(process_buffer, frames, 1);
|
||||
if (last_cycle) { context().set_flag (ProcessContext<Sample>::EndOfInput); }
|
||||
it->second->process (context);
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "ardour/utils.h"
|
||||
#include "ardour/graph.h"
|
||||
#include "ardour/unknown_processor.h"
|
||||
#include "ardour/capturing_processor.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
@ -3057,6 +3058,21 @@ Route::put_monitor_send_at (Placement p)
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<CapturingProcessor>
|
||||
Route::add_export_point()
|
||||
{
|
||||
// Check if it exists already
|
||||
boost::shared_ptr<CapturingProcessor> processor;
|
||||
if ((processor = boost::dynamic_pointer_cast<CapturingProcessor> (*_processors.begin()))) {
|
||||
return processor;
|
||||
}
|
||||
|
||||
// ...else add it
|
||||
processor.reset (new CapturingProcessor (_session));
|
||||
add_processor (processor, _processors.begin());
|
||||
return processor;
|
||||
}
|
||||
|
||||
framecnt_t
|
||||
Route::update_total_latency ()
|
||||
{
|
||||
|
@ -62,6 +62,7 @@ libardour_sources = [
|
||||
'bundle.cc',
|
||||
'butler.cc',
|
||||
'callback.cc',
|
||||
'capturing_processor.cc',
|
||||
'chan_count.cc',
|
||||
'chan_mapping.cc',
|
||||
'configuration.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user