change VCA number to signed.
[ardour.git] / libs / ardour / ardour / export_channel.h
index 51ecabee25c8156e74d3cc2530c0f80d5199c3c4..894406874e40ec8b1e249be71c4e7ba80ba26718 100644 (file)
 
 #include <set>
 
-#include <boost/signals2.hpp>
+#include <boost/scoped_array.hpp>
 #include <boost/shared_ptr.hpp>
-#include <boost/operators.hpp>
 
-#include "ardour/audioregion.h"
+#include "pbd/signals.h"
+
 #include "ardour/buffer_set.h"
+#include "ardour/export_pointers.h"
 
 namespace ARDOUR {
 
 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>
+class LIBARDOUR_API ExportChannel : public boost::less_than_comparable<ExportChannel>
 {
   public:
 
        virtual ~ExportChannel () {}
 
-       virtual void read (Sample * data, nframes_t frames) const = 0;
+       virtual void set_max_buffer_size(framecnt_t) { }
+
+       virtual void read (Sample const *& data, framecnt_t frames) const = 0;
        virtual bool empty () const = 0;
 
        /// Adds state to node passed
@@ -56,26 +61,16 @@ class ExportChannel : public boost::less_than_comparable<ExportChannel>
        virtual bool operator< (ExportChannel const & other) const = 0;
 };
 
-/// Safe pointer for storing ExportChannels in ordered STL containers
-class ExportChannelPtr : public boost::shared_ptr<ExportChannel>
-                       , public boost::less_than_comparable<ExportChannel>
-{
-  public:
-       ExportChannelPtr () {}
-       template<typename Y> explicit ExportChannelPtr (Y * ptr) : boost::shared_ptr<ExportChannel> (ptr) {}
-
-       bool operator< (ExportChannelPtr const & other) const { return **this < *other; }
-};
-
 /// Basic export channel that reads from AudioPorts
-class PortExportChannel : public ExportChannel
+class LIBARDOUR_API PortExportChannel : public ExportChannel
 {
   public:
-       typedef std::set<AudioPort *> PortSet;
+       typedef std::set<boost::weak_ptr<AudioPort> > PortSet;
 
-       PortExportChannel () {}
+       PortExportChannel ();
+       void set_max_buffer_size(framecnt_t frames);
 
-       void read (Sample * data, nframes_t frames) const;
+       void read (Sample const *& data, framecnt_t frames) const;
        bool empty () const { return ports.empty(); }
 
        void get_state (XMLNode * node) const;
@@ -83,18 +78,22 @@ class PortExportChannel : public ExportChannel
 
        bool operator< (ExportChannel const & other) const;
 
-       void add_port (AudioPort * port) { ports.insert (port); }
+       void add_port (boost::weak_ptr<AudioPort> port) { ports.insert (port); }
        PortSet const & get_ports () { return ports; }
 
   private:
        PortSet ports;
+       boost::scoped_array<Sample> buffer;
+       framecnt_t buffer_size;
 };
 
+
 /// Handles RegionExportChannels and does actual reading from region
-class RegionExportChannelFactory 
+class LIBARDOUR_API RegionExportChannelFactory
 {
   public:
        enum Type {
+               None,
                Raw,
                Fades,
                Processed
@@ -104,37 +103,37 @@ class RegionExportChannelFactory
        ~RegionExportChannelFactory ();
 
        ExportChannelPtr create (uint32_t channel);
-       void read (uint32_t channel, Sample * data, nframes_t frames_to_read);
+       void read (uint32_t channel, Sample const *& data, framecnt_t frames_to_read);
 
   private:
 
-       int new_cycle_started (nframes_t) { buffers_up_to_date = false; return 0; }
-       void update_buffers (nframes_t frames);
+       int new_cycle_started (framecnt_t) { buffers_up_to_date = false; return 0; }
+       void update_buffers (framecnt_t frames);
 
        AudioRegion const & region;
        AudioTrack & track;
        Type type;
 
-       nframes_t frames_per_cycle;
+       framecnt_t frames_per_cycle;
        size_t n_channels;
        BufferSet buffers;
        bool buffers_up_to_date;
-       nframes_t region_start;
-       nframes_t position;
+       framecnt_t region_start;
+       framecnt_t position;
 
-       Sample * mixdown_buffer;
-       Sample * gain_buffer;
+       boost::scoped_array<Sample> mixdown_buffer;
+       boost::scoped_array<Sample> gain_buffer;
 
        PBD::ScopedConnection export_connection;
 };
 
 /// Export channel that reads from region channel
-class RegionExportChannel : public ExportChannel
+class LIBARDOUR_API RegionExportChannel : public ExportChannel
 {
        friend class RegionExportChannelFactory;
 
   public:
-       void read (Sample * data, nframes_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; }
@@ -152,6 +151,49 @@ class RegionExportChannel : public ExportChannel
        uint32_t channel;
 };
 
+/// Export channel for exporting from different positions in a route
+class LIBARDOUR_API 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, boost::shared_ptr<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 (boost::shared_ptr<Route> route, boost::shared_ptr<CapturingProcessor> processor)
+                       : route (route), processor (processor) {}
+               ~ProcessorRemover();
+         private:
+                boost::shared_ptr<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