For 'Route::send_pan_azi_controllable()' (when building non-Mixbus) I'm assuming...
[ardour.git] / libs / ardour / audio_track.cc
1 /*
2     Copyright (C) 2002 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <boost/scoped_array.hpp>
21
22 #include "pbd/enumwriter.h"
23 #include "pbd/error.h"
24
25 #include "evoral/Curve.hpp"
26
27 #include "ardour/amp.h"
28 #include "ardour/audio_buffer.h"
29 #include "ardour/audio_track.h"
30 #include "ardour/audioplaylist.h"
31 #include "ardour/boost_debug.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/delivery.h"
34 #include "ardour/disk_reader.h"
35 #include "ardour/disk_writer.h"
36 #include "ardour/meter.h"
37 #include "ardour/monitor_control.h"
38 #include "ardour/playlist_factory.h"
39 #include "ardour/processor.h"
40 #include "ardour/profile.h"
41 #include "ardour/region.h"
42 #include "ardour/region_factory.h"
43 #include "ardour/session.h"
44 #include "ardour/session_playlists.h"
45 #include "ardour/source.h"
46 #include "ardour/types_convert.h"
47 #include "ardour/utils.h"
48
49 #include "pbd/i18n.h"
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54
55 AudioTrack::AudioTrack (Session& sess, string name, TrackMode mode)
56         : Track (sess, name, PresentationInfo::AudioTrack, mode)
57 {
58 }
59
60 AudioTrack::~AudioTrack ()
61 {
62         if (_freeze_record.playlist && !_session.deletion_in_progress()) {
63                 _freeze_record.playlist->release();
64         }
65 }
66
67 int
68 AudioTrack::set_state (const XMLNode& node, int version)
69 {
70         if (!node.get_property (X_("mode"), _mode)) {
71                 _mode = Normal;
72         }
73
74         if (Profile->get_trx() && _mode == Destructive) {
75                 /* Tracks does not support destructive tracks and trying to
76                    handle it as a normal track would be wrong.
77                 */
78                 error << string_compose (_("%1: this session uses destructive tracks, which are not supported"), PROGRAM_NAME) << endmsg;
79                 return -1;
80         }
81
82         if (Track::set_state (node, version)) {
83                 return -1;
84         }
85
86         pending_state = const_cast<XMLNode*> (&node);
87
88         if (_session.state_of_the_state() & Session::Loading) {
89                 _session.StateReady.connect_same_thread (*this, boost::bind (&AudioTrack::set_state_part_two, this));
90         } else {
91                 set_state_part_two ();
92         }
93
94         return 0;
95 }
96
97 XMLNode&
98 AudioTrack::state (bool save_template)
99 {
100         XMLNode& root (Track::state (save_template));
101         XMLNode* freeze_node;
102
103         if (_freeze_record.playlist) {
104                 XMLNode* inode;
105
106                 freeze_node = new XMLNode (X_("freeze-info"));
107                 freeze_node->set_property ("playlist", _freeze_record.playlist->name());
108                 freeze_node->set_property ("state", _freeze_record.state);
109
110                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
111                         inode = new XMLNode (X_("processor"));
112                         inode->set_property (X_ ("id"), (*i)->id.to_s ());
113                         inode->add_child_copy ((*i)->state);
114
115                         freeze_node->add_child_nocopy (*inode);
116                 }
117
118                 root.add_child_nocopy (*freeze_node);
119         }
120
121         root.set_property (X_("mode"), _mode);
122
123         return root;
124 }
125
126 void
127 AudioTrack::set_state_part_two ()
128 {
129         XMLNode* fnode;
130         XMLProperty const * prop;
131
132         /* This is called after all session state has been restored but before
133            have been made ports and connections are established.
134         */
135
136         if (pending_state == 0) {
137                 return;
138         }
139
140         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
141
142                 _freeze_record.state = Frozen;
143
144                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
145                         delete *i;
146                 }
147                 _freeze_record.processor_info.clear ();
148
149                 if ((prop = fnode->property (X_("playlist"))) != 0) {
150                         boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
151                         if (pl) {
152                                 _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
153                                 _freeze_record.playlist->use();
154                         } else {
155                                 _freeze_record.playlist.reset ();
156                                 _freeze_record.state = NoFreeze;
157                         return;
158                         }
159                 }
160
161                 fnode->get_property (X_("state"), _freeze_record.state);
162
163                 XMLNodeConstIterator citer;
164                 XMLNodeList clist = fnode->children();
165
166                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
167                         if ((*citer)->name() != X_("processor")) {
168                                 continue;
169                         }
170
171                         if ((prop = (*citer)->property (X_("id"))) == 0) {
172                                 continue;
173                         }
174
175                         FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
176                                                                                    boost::shared_ptr<Processor>());
177                         frii->id = prop->value ();
178                         _freeze_record.processor_info.push_back (frii);
179                 }
180         }
181 }
182
183 int
184 AudioTrack::export_stuff (BufferSet& buffers, samplepos_t start, samplecnt_t nframes,
185                           boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export, bool for_freeze)
186 {
187         boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]);
188         boost::scoped_array<Sample> mix_buffer (new Sample[nframes]);
189
190         Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
191
192         boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(playlist());
193
194         assert(apl);
195         assert(buffers.count().n_audio() >= 1);
196         assert ((samplecnt_t) buffers.get_audio(0).capacity() >= nframes);
197
198         if (apl->read (buffers.get_audio(0).data(), mix_buffer.get(), gain_buffer.get(), start, nframes) != nframes) {
199                 return -1;
200         }
201
202         uint32_t n=1;
203         Sample* b = buffers.get_audio(0).data();
204         BufferSet::audio_iterator bi = buffers.audio_begin();
205         ++bi;
206         for ( ; bi != buffers.audio_end(); ++bi, ++n) {
207                 if (n < _disk_reader->output_streams().n_audio()) {
208                         if (apl->read (bi->data(), mix_buffer.get(), gain_buffer.get(), start, nframes, n) != nframes) {
209                                 return -1;
210                         }
211                         b = bi->data();
212                 } else {
213                         /* duplicate last across remaining buffers */
214                         memcpy (bi->data(), b, sizeof (Sample) * nframes);
215                 }
216         }
217
218         bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
219
220         return 0;
221 }
222
223 bool
224 AudioTrack::bounceable (boost::shared_ptr<Processor> endpoint, bool include_endpoint) const
225 {
226         if (!endpoint && !include_endpoint) {
227                 /* no processing - just read from the playlist and create new
228                    files: always possible.
229                 */
230                 return true;
231         }
232
233         Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
234         uint32_t naudio = n_inputs().n_audio();
235
236         for (ProcessorList::const_iterator r = _processors.begin(); r != _processors.end(); ++r) {
237
238                 /* if we're not including the endpoint, potentially stop
239                    right here before we test matching i/o valences.
240                 */
241
242                 if (!include_endpoint && (*r) == endpoint) {
243                         return true;
244                 }
245
246                 /* ignore any processors that do routing, because we will not
247                  * use them during a bounce/freeze/export operation.
248                  */
249
250                 if ((*r)->does_routing()) {
251                         continue;
252                 }
253
254                 /* does the output from the last considered processor match the
255                  * input to this one?
256                  */
257
258                 if (naudio != (*r)->input_streams().n_audio()) {
259                         return false;
260                 }
261
262                 /* we're including the endpoint - if we just hit it,
263                    then stop.
264                 */
265
266                 if ((*r) == endpoint) {
267                         return true;
268                 }
269
270                 /* save outputs of this processor to test against inputs
271                    of the next one.
272                 */
273
274                 naudio = (*r)->output_streams().n_audio();
275         }
276
277         return true;
278 }
279
280 boost::shared_ptr<Region>
281 AudioTrack::bounce (InterThreadInfo& itt)
282 {
283         return bounce_range (_session.current_start_sample(), _session.current_end_sample(), itt, main_outs(), false);
284 }
285
286 boost::shared_ptr<Region>
287 AudioTrack::bounce_range (samplepos_t start, samplepos_t end, InterThreadInfo& itt,
288                           boost::shared_ptr<Processor> endpoint, bool include_endpoint)
289 {
290         vector<boost::shared_ptr<Source> > srcs;
291         return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
292 }
293
294 void
295 AudioTrack::freeze_me (InterThreadInfo& itt)
296 {
297         vector<boost::shared_ptr<Source> > srcs;
298         string new_playlist_name;
299         boost::shared_ptr<Playlist> new_playlist;
300         string dir;
301         string region_name;
302
303         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(playlist())) == 0) {
304                 return;
305         }
306
307         uint32_t n = 1;
308
309         while (n < (UINT_MAX-1)) {
310
311                 string candidate;
312
313                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
314
315                 if (_session.playlists->by_name (candidate) == 0) {
316                         new_playlist_name = candidate;
317                         break;
318                 }
319
320                 ++n;
321
322         }
323
324         if (n == (UINT_MAX-1)) {
325           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
326                             " to create another one"), _freeze_record.playlist->name())
327                << endmsg;
328                 return;
329         }
330
331         boost::shared_ptr<Region> res;
332
333         if ((res = _session.write_one_track (*this, _session.current_start_sample(), _session.current_end_sample(),
334                                         true, srcs, itt, main_outs(), false, false, true)) == 0) {
335                 return;
336         }
337
338         _freeze_record.processor_info.clear ();
339
340         {
341                 Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
342
343                 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
344
345                         if ((*r)->does_routing() && (*r)->active()) {
346                                 break;
347                         }
348                         if (!boost::dynamic_pointer_cast<PeakMeter>(*r)) {
349
350                                 FreezeRecordProcessorInfo* frii  = new FreezeRecordProcessorInfo ((*r)->get_state(), (*r));
351
352                                 frii->id = (*r)->id();
353
354                                 _freeze_record.processor_info.push_back (frii);
355
356                                 /* now deactivate the processor, */
357                                 if (!boost::dynamic_pointer_cast<Amp>(*r)) {
358                                         (*r)->deactivate ();
359                                 }
360                         }
361
362                         _session.set_dirty ();
363                 }
364         }
365
366         new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false);
367
368         /* XXX need main outs automation state _freeze_record.pan_automation_state = _mainpanner->automation_state(); */
369
370         region_name = new_playlist_name;
371
372         /* create a new region from all filesources, keep it private */
373
374         PropertyList plist;
375
376         plist.add (Properties::start, 0);
377         plist.add (Properties::length, srcs[0]->length(srcs[0]->timeline_position()));
378         plist.add (Properties::name, region_name);
379         plist.add (Properties::whole_file, true);
380
381         boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
382
383         new_playlist->set_orig_track_id (id());
384         new_playlist->add_region (region, _session.current_start_sample());
385         new_playlist->set_frozen (true);
386         region->set_locked (true);
387
388         use_playlist (DataType::AUDIO, boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
389         _disk_writer->set_record_enabled (false);
390
391         _freeze_record.playlist->use(); // prevent deletion
392
393         /* reset stuff that has already been accounted for in the freeze process */
394
395         gain_control()->set_value (GAIN_COEFF_UNITY, Controllable::NoGroup);
396         gain_control()->set_automation_state (Off);
397
398         /* XXX need to use _main_outs _panner->set_automation_state (Off); */
399
400         _freeze_record.state = Frozen;
401         FreezeChange(); /* EMIT SIGNAL */
402 }
403
404 void
405 AudioTrack::unfreeze ()
406 {
407         if (_freeze_record.playlist) {
408                 _freeze_record.playlist->release();
409                 use_playlist (DataType::AUDIO, _freeze_record.playlist);
410
411                 {
412                         Glib::Threads::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc
413                         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
414                                 for (vector<FreezeRecordProcessorInfo*>::iterator ii = _freeze_record.processor_info.begin(); ii != _freeze_record.processor_info.end(); ++ii) {
415                                         if ((*ii)->id == (*i)->id()) {
416                                                 (*i)->set_state (((*ii)->state), Stateful::current_state_version);
417                                                 break;
418                                         }
419                                 }
420                         }
421                 }
422
423                 _freeze_record.playlist.reset ();
424                 /* XXX need to use _main_outs _panner->set_automation_state (_freeze_record.pan_automation_state); */
425         }
426
427         _freeze_record.state = UnFrozen;
428         FreezeChange (); /* EMIT SIGNAL */
429 }
430
431 boost::shared_ptr<AudioFileSource>
432 AudioTrack::write_source (uint32_t n)
433 {
434         assert (_disk_writer);
435         return _disk_writer->audio_write_source (n);
436 }