From a406d9183adc67075a4e802fd8254c2560df9964 Mon Sep 17 00:00:00 2001 From: Sakari Bergen Date: Sun, 16 Jan 2011 19:41:11 +0000 Subject: 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 --- gtk2_ardour/export_channel_selector.cc | 20 ++++-- gtk2_ardour/export_channel_selector.h | 16 ++--- libs/ardour/ardour/buffer_set.h | 6 ++ libs/ardour/ardour/capturing_processor.h | 53 +++++++++++++++ libs/ardour/ardour/export_channel.h | 52 +++++++++++++-- libs/ardour/ardour/export_channel_configuration.h | 5 ++ libs/ardour/ardour/route.h | 2 + libs/ardour/capturing_processor.cc | 75 ++++++++++++++++++++++ libs/ardour/export_channel.cc | 78 ++++++++++++++++++++++- libs/ardour/export_graph_builder.cc | 6 +- libs/ardour/route.cc | 16 +++++ libs/ardour/wscript | 1 + 12 files changed, 306 insertions(+), 24 deletions(-) create mode 100644 libs/ardour/ardour/capturing_processor.h create mode 100644 libs/ardour/capturing_processor.cc diff --git a/gtk2_ardour/export_channel_selector.cc b/gtk2_ardour/export_channel_selector.cc index 6881b032a4..019bb161e7 100644 --- a/gtk2_ardour/export_channel_selector.cc +++ b/gtk2_ardour/export_channel_selector.cc @@ -548,20 +548,20 @@ TrackExportChannelSelector::fill_list() for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) { Route * route = it->get(); if(dynamic_cast(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 list; + RouteExportChannel::create_from_route (list, *track); + state->config->register_channels (list); state->config->set_name(track->name()); } diff --git a/gtk2_ardour/export_channel_selector.h b/gtk2_ardour/export_channel_selector.h index 63af76e77d..e7b2dc11ee 100644 --- a/gtk2_ardour/export_channel_selector.h +++ b/gtk2_ardour/export_channel_selector.h @@ -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 track; - Gtk::TreeModelColumn label; - Gtk::TreeModelColumn selected; + Gtk::TreeModelColumn track; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn selected; TrackCols () { add (track); add(label); add(selected); } }; 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 @@ -48,7 +49,7 @@ class ExportChannel : public boost::less_than_comparable 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 processor, size_t channel, + boost::shared_ptr remover); + ~RouteExportChannel(); + + static void create_from_route(std::list & 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 processor) + : route (route), processor (processor) {} + ~ProcessorRemover(); + private: + Route & route; + boost::shared_ptr processor; + }; + + boost::shared_ptr 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 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 #include +#include + #include #include "ardour/export_channel.h" @@ -70,6 +72,9 @@ class ExportChannelConfiguration : public boost::enable_shared_from_this 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 processor, size_t channel, + boost::shared_ptr remover) + : processor (processor) + , channel (channel) + , remover (remover) +{ +} + +RouteExportChannel::~RouteExportChannel() +{ +} + +void +RouteExportChannel::create_from_route(std::list & result, Route & route) +{ + boost::shared_ptr processor = route.add_export_point(); + uint32_t channels = processor->input_streams().n_audio(); + + boost::shared_ptr 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(&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 context(process_buffer, frames, 1); - if (last_cycle) { context.set_flag (ProcessContext::EndOfInput); } + ConstProcessContext context(process_buffer, frames, 1); + if (last_cycle) { context().set_flag (ProcessContext::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 +Route::add_export_point() +{ + // Check if it exists already + boost::shared_ptr processor; + if ((processor = boost::dynamic_pointer_cast (*_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', -- cgit v1.2.3