ardour
export_channel.cc
Go to the documentation of this file.
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 #include "ardour/audio_buffer.h"
22 #include "ardour/audio_port.h"
23 #include "ardour/audio_track.h"
24 #include "ardour/audioengine.h"
25 #include "ardour/audioregion.h"
27 #include "ardour/export_channel.h"
28 #include "ardour/export_failed.h"
29 #include "ardour/session.h"
30 
31 #include "pbd/error.h"
32 
33 #include "i18n.h"
34 
35 using namespace ARDOUR;
36 
38  : buffer_size(0)
39 {
40 }
41 
43 {
44  buffer_size = frames;
45  buffer.reset (new Sample[frames]);
46 }
47 
48 bool
50 {
51  PortExportChannel const * pec;
52  if (!(pec = dynamic_cast<PortExportChannel const *> (&other))) {
53  return this < &other;
54  }
55  return ports < pec->ports;
56 }
57 
58 void
59 PortExportChannel::read (Sample const *& data, framecnt_t frames) const
60 {
61  assert(buffer);
62  assert(frames <= buffer_size);
63 
64  if (ports.size() == 1) {
65  boost::shared_ptr<AudioPort> p = ports.begin()->lock ();
66  data = p->get_audio_buffer(frames).data();
67  return;
68  }
69 
70  memset (buffer.get(), 0, frames * sizeof (Sample));
71 
72  for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
73  boost::shared_ptr<AudioPort> p = it->lock ();
74  if (p) {
75  Sample* port_buffer = p->get_audio_buffer(frames).data();
76 
77  for (uint32_t i = 0; i < frames; ++i) {
78  buffer[i] += (float) port_buffer[i];
79  }
80  }
81  }
82 
83  data = buffer.get();
84 }
85 
86 void
88 {
89  XMLNode * port_node;
90  for (PortSet::const_iterator it = ports.begin(); it != ports.end(); ++it) {
91  boost::shared_ptr<Port> p = it->lock ();
92  if (p && (port_node = node->add_child ("Port"))) {
93  port_node->add_property ("name", p->name());
94  }
95  }
96 }
97 
98 void
100 {
101  XMLProperty * prop;
102  XMLNodeList xml_ports = node->children ("Port");
103  for (XMLNodeList::iterator it = xml_ports.begin(); it != xml_ports.end(); ++it) {
104  if ((prop = (*it)->property ("name"))) {
105  std::string const & name = prop->value();
107  if (port) {
108  ports.insert (port);
109  } else {
110  PBD::warning << string_compose (_("Could not get port for export channel \"%1\", dropping the channel"), name) << endmsg;
111  }
112  }
113  }
114 }
115 
117  : region (region)
118  , track (track)
119  , type (type)
120  , frames_per_cycle (session->engine().samples_per_cycle ())
121  , buffers_up_to_date (false)
122  , region_start (region.position())
123  , position (region_start)
124 {
125  switch (type) {
126  case Raw:
127  n_channels = region.n_channels();
128  break;
129  case Fades:
130  n_channels = region.n_channels();
131 
132  mixdown_buffer.reset (new Sample [frames_per_cycle]);
133  gain_buffer.reset (new Sample [frames_per_cycle]);
134  std::fill_n (gain_buffer.get(), frames_per_cycle, Sample (1.0));
135 
136  break;
137  case Processed:
138  n_channels = track.n_outputs().n_audio();
139  break;
140  default:
141  throw ExportFailed ("Unhandled type in ExportChannelFactory constructor");
142  }
143 
144  session->ProcessExport.connect_same_thread (export_connection, boost::bind (&RegionExportChannelFactory::new_cycle_started, this, _1));
145 
148 }
149 
151 {
152 }
153 
156 {
157  assert (channel < n_channels);
158  return ExportChannelPtr (new RegionExportChannel (*this, channel));
159 }
160 
161 void
162 RegionExportChannelFactory::read (uint32_t channel, Sample const *& data, framecnt_t frames_to_read)
163 {
164  assert (channel < n_channels);
165  assert (frames_to_read <= frames_per_cycle);
166 
167  if (!buffers_up_to_date) {
168  update_buffers(frames_to_read);
169  buffers_up_to_date = true;
170  }
171 
172  data = buffers.get_audio (channel).data();
173 }
174 
175 void
177 {
178  assert (frames <= frames_per_cycle);
179 
180  switch (type) {
181  case Raw:
182  for (size_t channel = 0; channel < n_channels; ++channel) {
183  region.read (buffers.get_audio (channel).data(), position - region_start, frames, channel);
184  }
185  break;
186  case Fades:
187  assert (mixdown_buffer && gain_buffer);
188  for (size_t channel = 0; channel < n_channels; ++channel) {
189  memset (mixdown_buffer.get(), 0, sizeof (Sample) * frames);
190  buffers.get_audio (channel).silence(frames);
191  region.read_at (buffers.get_audio (channel).data(), mixdown_buffer.get(), gain_buffer.get(), position, frames, channel);
192  }
193  break;
194  case Processed:
195  track.export_stuff (buffers, position, frames, track.main_outs(), true, true, false);
196  break;
197  default:
198  throw ExportFailed ("Unhandled type in ExportChannelFactory::update_buffers");
199  }
200 
201  position += frames;
202 }
203 
204 
207  : processor (processor)
208  , channel (channel)
209  , remover (remover)
210 {
211 }
212 
214 {
215 }
216 
217 void
218 RouteExportChannel::create_from_route(std::list<ExportChannelPtr> & result, boost::shared_ptr<Route> route)
219 {
221  uint32_t channels = processor->input_streams().n_audio();
222 
224  result.clear();
225  for (uint32_t i = 0; i < channels; ++i) {
226  result.push_back (ExportChannelPtr (new RouteExportChannel (processor, i, remover)));
227  }
228 }
229 
230 void
232 {
233  if (processor) {
234  processor->set_block_size (frames);
235  }
236 }
237 
238 void
239 RouteExportChannel::read (Sample const *& data, framecnt_t frames) const
240 {
241  assert(processor);
242  AudioBuffer const & buffer = processor->get_capture_buffers().get_audio (channel);
243 #ifndef NDEBUG
244  (void) frames;
245 #else
246  assert (frames <= (framecnt_t) buffer.capacity());
247 #endif
248  data = buffer.data();
249 }
250 
251 void
253 {
254  // TODO
255 }
256 
257 void
259 {
260  // TODO
261 }
262 
263 bool
265 {
266  RouteExportChannel const * rec;
267  if ((rec = dynamic_cast<RouteExportChannel const *>(&other)) == 0) {
268  return this < &other;
269  }
270 
271  if (processor.get() == rec->processor.get()) {
272  return channel < rec->channel;
273  }
274  return processor.get() < rec->processor.get();
275 }
276 
278 {
280 }
boost::shared_ptr< CapturingProcessor > processor
Export channel for exporting from different positions in a route.
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
Definition: buffer_set.cc:149
void set_max_buffer_size(framecnt_t frames)
static void create_from_route(std::list< ExportChannelPtr > &result, boost::shared_ptr< Route > route)
boost::shared_ptr< CapturingProcessor > processor
AudioBuffer & get_audio_buffer(pframes_t nframes)
Definition: audio_port.cc:74
const std::string & value() const
Definition: xml++.h:159
void set_count(const ChanCount &count)
Definition: buffer_set.h:93
virtual framecnt_t read(Sample *, framepos_t pos, framecnt_t cnt, int channel) const
Definition: audioregion.cc:446
boost::scoped_array< Sample > buffer
void get_state(XMLNode *node) const
Adds state to node passed.
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
void set_state(XMLNode *node, Session &session)
Sets state from node passed.
void read(uint32_t channel, Sample const *&data, framecnt_t frames_to_read)
uint32_t n_audio() const
Definition: chan_count.h:63
Basic export channel that reads from AudioPorts.
LIBPBD_API Transmitter warning
int remove_processor(boost::shared_ptr< Processor >, ProcessorStreams *err=0, bool need_process_lock=true)
Definition: route.cc:1574
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
int export_stuff(BufferSet &bufs, framepos_t start_frame, framecnt_t nframes, boost::shared_ptr< Processor > endpoint, bool include_endpoint, bool for_export, bool for_freeze)
Definition: audio_track.cc:395
boost::scoped_array< Sample > mixdown_buffer
std::string name() const
Definition: port.h:54
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
void update_buffers(framecnt_t frames)
XMLNode * add_child(const char *)
Definition: xml++.cc:351
ComparableSharedPtr< ExportChannel > ExportChannelPtr
AudioBuffer & get_audio(size_t i)
Definition: buffer_set.h:100
void read(Sample const *&data, framecnt_t frames) const
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
#define _(Text)
Definition: i18n.h:11
int64_t framecnt_t
Definition: types.h:76
float Sample
Definition: types.h:54
void silence(framecnt_t len, framecnt_t offset=0)
Definition: audio_buffer.cc:83
boost::shared_ptr< Delivery > main_outs() const
Definition: route.h:237
Definition: amp.h:29
ChanCount n_outputs() const
Definition: route.h:93
void set_max_buffer_size(framecnt_t frames)
RouteExportChannel(boost::shared_ptr< CapturingProcessor > processor, size_t channel, boost::shared_ptr< ProcessorRemover > remover)
Export channel base class interface for different source types.
PBD::Signal1< int, framecnt_t > ProcessExport
Definition: session.h:621
XMLProperty * add_property(const char *name, const std::string &value)
RegionExportChannelFactory(Session *session, AudioRegion const &region, AudioTrack &track, Type type)
size_t capacity() const
Definition: buffer.h:51
const char * name
uint32_t n_channels() const
Definition: region.h:259
boost::shared_ptr< CapturingProcessor > add_export_point()
Definition: route.cc:3553
boost::shared_ptr< Port > get_port_by_name(const std::string &)
Definition: xml++.h:95
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
Definition: region.cc:65
boost::shared_ptr< ProcessorRemover > remover
boost::scoped_array< Sample > gain_buffer
virtual framecnt_t read_at(Sample *buf, Sample *mixdown_buf, float *gain_buf, framepos_t position, framecnt_t cnt, uint32_t chan_n=0) const
Definition: audioregion.cc:473
void get_state(XMLNode *node) const
Adds state to node passed.
bool operator<(ExportChannel const &other) const
const Sample * data(framecnt_t offset=0) const
Definition: audio_buffer.h:187
void set_state(XMLNode *node, Session &session)
Sets state from node passed.
bool operator<(ExportChannel const &other) const
virtual ChanCount input_streams() const
Definition: processor.h:88
Export channel that reads from region channel.
AudioEngine & engine()
Definition: session.h:546
void read(Sample const *&data, framecnt_t frames) const
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
ExportChannelPtr create(uint32_t channel)
PBD::ScopedConnection export_connection