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