summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorSakari Bergen <sakari.bergen@beatwaves.net>2011-01-16 19:41:11 +0000
committerSakari Bergen <sakari.bergen@beatwaves.net>2011-01-16 19:41:11 +0000
commita406d9183adc67075a4e802fd8254c2560df9964 (patch)
tree2bb5cfa9a25f5951e37a1a9e8c041cca6c960925 /libs
parent113e6b505a27b3cbdb26f96b96c92cf35fe311dd (diff)
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
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/buffer_set.h6
-rw-r--r--libs/ardour/ardour/capturing_processor.h53
-rw-r--r--libs/ardour/ardour/export_channel.h52
-rw-r--r--libs/ardour/ardour/export_channel_configuration.h5
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/capturing_processor.cc75
-rw-r--r--libs/ardour/export_channel.cc78
-rw-r--r--libs/ardour/export_graph_builder.cc6
-rw-r--r--libs/ardour/route.cc16
-rw-r--r--libs/ardour/wscript1
10 files changed, 285 insertions, 9 deletions
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index fc5ef96449..f5ac1aee61 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -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.
diff --git a/libs/ardour/ardour/capturing_processor.h b/libs/ardour/ardour/capturing_processor.h
new file mode 100644
index 0000000000..2e2db78091
--- /dev/null
+++ b/libs/ardour/ardour/capturing_processor.h
@@ -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__
diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h
index 34d6263976..5e42956cdb 100644
--- a/libs/ardour/ardour/export_channel.h
+++ b/libs/ardour/ardour/export_channel.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
diff --git a/libs/ardour/ardour/export_channel_configuration.h b/libs/ardour/ardour/export_channel_configuration.h
index b5b9b65bf7..5701be576b 100644
--- a/libs/ardour/ardour/export_channel_configuration.h
+++ b/libs/ardour/ardour/export_channel_configuration.h
@@ -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.
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 60970d5d20..90f5664eba 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -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.
diff --git a/libs/ardour/capturing_processor.cc b/libs/ardour/capturing_processor.cc
new file mode 100644
index 0000000000..2fa83ace81
--- /dev/null
+++ b/libs/ardour/capturing_processor.cc
@@ -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
diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc
index 4cf510a971..f36716761b 100644
--- a/libs/ardour/export_channel.cc
+++ b/libs/ardour/export_channel.cc
@@ -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);
+}
diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc
index d0ce883385..1180d5eace 100644
--- a/libs/ardour/export_graph_builder.cc
+++ b/libs/ardour/export_graph_builder.cc
@@ -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);
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 5fe287c2bf..c1004a18f9 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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 ()
{
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 03e602ee5a..ac1c80c0cf 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -62,6 +62,7 @@ libardour_sources = [
'bundle.cc',
'butler.cc',
'callback.cc',
+ 'capturing_processor.cc',
'chan_count.cc',
'chan_mapping.cc',
'configuration.cc',