consistent API name for region-list
[ardour.git] / libs / ardour / ardour / export_channel.h
1 /*
2     Copyright (C) 2008 Paul Davis
3     Author: Sakari Bergen
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #ifndef __ardour_export_channel_h__
22 #define __ardour_export_channel_h__
23
24 #include <set>
25
26 #include <boost/scoped_array.hpp>
27 #include <boost/shared_ptr.hpp>
28
29 #include "pbd/signals.h"
30
31 #include "ardour/buffer_set.h"
32 #include "ardour/export_pointers.h"
33
34 namespace ARDOUR {
35
36 class Session;
37 class AudioTrack;
38 class AudioPort;
39 class AudioRegion;
40 class CapturingProcessor;
41
42 /// Export channel base class interface for different source types
43 class LIBARDOUR_API ExportChannel : public boost::less_than_comparable<ExportChannel>
44 {
45   public:
46
47         virtual ~ExportChannel () {}
48
49         virtual void set_max_buffer_size(framecnt_t) { }
50
51         virtual void read (Sample const *& data, framecnt_t frames) const = 0;
52         virtual bool empty () const = 0;
53
54         /// Adds state to node passed
55         virtual void get_state (XMLNode * node) const = 0;
56
57         /// Sets state from node passed
58         virtual void set_state (XMLNode * node, Session & session) = 0;
59
60         // Operator< must be defined for usage in e.g. std::map or std::set to disallow duplicates when necessary
61         virtual bool operator< (ExportChannel const & other) const = 0;
62 };
63
64 /// Basic export channel that reads from AudioPorts
65 class LIBARDOUR_API PortExportChannel : public ExportChannel
66 {
67   public:
68         typedef std::set<boost::weak_ptr<AudioPort> > PortSet;
69
70         PortExportChannel ();
71         void set_max_buffer_size(framecnt_t frames);
72
73         void read (Sample const *& data, framecnt_t frames) const;
74         bool empty () const { return ports.empty(); }
75
76         void get_state (XMLNode * node) const;
77         void set_state (XMLNode * node, Session & session);
78
79         bool operator< (ExportChannel const & other) const;
80
81         void add_port (boost::weak_ptr<AudioPort> port) { ports.insert (port); }
82         PortSet const & get_ports () { return ports; }
83
84   private:
85         PortSet ports;
86         boost::scoped_array<Sample> buffer;
87         framecnt_t buffer_size;
88 };
89
90
91 /// Handles RegionExportChannels and does actual reading from region
92 class LIBARDOUR_API RegionExportChannelFactory
93 {
94   public:
95         enum Type {
96                 None,
97                 Raw,
98                 Fades,
99                 Processed
100         };
101
102         RegionExportChannelFactory (Session * session, AudioRegion const & region, AudioTrack & track, Type type);
103         ~RegionExportChannelFactory ();
104
105         ExportChannelPtr create (uint32_t channel);
106         void read (uint32_t channel, Sample const *& data, framecnt_t frames_to_read);
107
108   private:
109
110         int new_cycle_started (framecnt_t) { buffers_up_to_date = false; return 0; }
111         void update_buffers (framecnt_t frames);
112
113         AudioRegion const & region;
114         AudioTrack & track;
115         Type type;
116
117         framecnt_t frames_per_cycle;
118         size_t n_channels;
119         BufferSet buffers;
120         bool buffers_up_to_date;
121         framecnt_t region_start;
122         framecnt_t position;
123
124         boost::scoped_array<Sample> mixdown_buffer;
125         boost::scoped_array<Sample> gain_buffer;
126
127         PBD::ScopedConnection export_connection;
128 };
129
130 /// Export channel that reads from region channel
131 class LIBARDOUR_API RegionExportChannel : public ExportChannel
132 {
133         friend class RegionExportChannelFactory;
134
135   public:
136         void read (Sample const *& data, framecnt_t frames_to_read) const { factory.read (channel, data, frames_to_read); }
137         void get_state (XMLNode * /*node*/) const {};
138         void set_state (XMLNode * /*node*/, Session & /*session*/) {};
139         bool empty () const { return false; }
140         // Region export should never have duplicate channels, so there need not be any semantics here
141         bool operator< (ExportChannel const & other) const { return this < &other; }
142
143   private:
144
145         RegionExportChannel (RegionExportChannelFactory & factory, uint32_t channel)
146                 : factory (factory)
147                 , channel (channel)
148         {}
149
150         RegionExportChannelFactory & factory;
151         uint32_t channel;
152 };
153
154 /// Export channel for exporting from different positions in a route
155 class LIBARDOUR_API RouteExportChannel : public ExportChannel
156 {
157         class ProcessorRemover; // fwd declaration
158
159   public:
160         RouteExportChannel(boost::shared_ptr<CapturingProcessor> processor, size_t channel,
161                            boost::shared_ptr<ProcessorRemover> remover);
162         ~RouteExportChannel();
163
164         static void create_from_route(std::list<ExportChannelPtr> & result, boost::shared_ptr<Route> route);
165
166   public: // ExportChannel interface
167         void set_max_buffer_size(framecnt_t frames);
168
169         void read (Sample const *& data, framecnt_t frames) const;
170         bool empty () const { return false; }
171
172         void get_state (XMLNode * node) const;
173         void set_state (XMLNode * node, Session & session);
174
175         bool operator< (ExportChannel const & other) const;
176
177   private:
178
179         // Removes the processor from the track when deleted
180         class ProcessorRemover {
181           public:
182                  ProcessorRemover (boost::shared_ptr<Route> route, boost::shared_ptr<CapturingProcessor> processor)
183                         : route (route), processor (processor) {}
184                 ~ProcessorRemover();
185           private:
186                 boost::shared_ptr<Route> route;
187                 boost::shared_ptr<CapturingProcessor> processor;
188         };
189
190         boost::shared_ptr<CapturingProcessor> processor;
191         size_t channel;
192         // Each channel keeps a ref to the remover. Last one alive
193         // will cause the processor to be removed on deletion.
194         boost::shared_ptr<ProcessorRemover> remover;
195 };
196
197 } // namespace ARDOUR
198
199 #endif