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:
Sakari Bergen 2011-01-16 19:41:11 +00:00
parent 113e6b505a
commit a406d9183a
12 changed files with 306 additions and 24 deletions

View File

@ -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
@ -577,8 +577,10 @@ 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());
}

View File

@ -230,23 +230,23 @@ class TrackExportChannelSelector : public ExportChannelSelector
{
public:
TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager);
virtual void sync_with_manager ();
private:
void fill_list();
void add_track(ARDOUR::IO * io);
void add_track(ARDOUR::Route * route);
void update_config();
ChannelConfigList configs;
struct TrackCols : public Gtk::TreeModelColumnRecord
{
public:
Gtk::TreeModelColumn<ARDOUR::IO *> track;
Gtk::TreeModelColumn<std::string> label;
Gtk::TreeModelColumn<bool> selected;
Gtk::TreeModelColumn<ARDOUR::Route *> track;
Gtk::TreeModelColumn<std::string> label;
Gtk::TreeModelColumn<bool> selected;
TrackCols () { add (track); add(label); add(selected); }
};

View File

@ -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.

View 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__

View File

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

View File

@ -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.

View File

@ -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.

View 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

View File

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

View File

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

View File

@ -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 ()
{

View File

@ -62,6 +62,7 @@ libardour_sources = [
'bundle.cc',
'butler.cc',
'callback.cc',
'capturing_processor.cc',
'chan_count.cc',
'chan_mapping.cc',
'configuration.cc',