2 Copyright (C) 2002 Paul Davis
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.
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.
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.
21 #include "pbd/error.h"
22 #include "pbd/enumwriter.h"
23 #include "pbd/boost_debug.h"
25 #include "evoral/Curve.hpp"
27 #include "ardour/amp.h"
28 #include "ardour/audio_buffer.h"
29 #include "ardour/audio_diskstream.h"
30 #include "ardour/audio_track.h"
31 #include "ardour/audioplaylist.h"
32 #include "ardour/audioregion.h"
33 #include "ardour/audiosource.h"
34 #include "ardour/buffer_set.h"
35 #include "ardour/io_processor.h"
36 #include "ardour/panner.h"
37 #include "ardour/meter.h"
38 #include "ardour/playlist_factory.h"
39 #include "ardour/plugin_insert.h"
40 #include "ardour/processor.h"
41 #include "ardour/region_factory.h"
42 #include "ardour/route_group_specialized.h"
43 #include "ardour/session.h"
44 #include "ardour/utils.h"
45 #include "ardour/session_playlists.h"
49 using namespace ARDOUR
;
52 AudioTrack::AudioTrack (Session
& sess
, string name
, Route::Flag flag
, TrackMode mode
)
53 : Track (sess
, name
, flag
, mode
)
57 AudioTrack::~AudioTrack ()
62 AudioTrack::use_new_diskstream ()
64 AudioDiskstream::Flag dflags
= AudioDiskstream::Flag (0);
66 if (_flags
& Hidden
) {
67 dflags
= AudioDiskstream::Flag (dflags
| AudioDiskstream::Hidden
);
69 dflags
= AudioDiskstream::Flag (dflags
| AudioDiskstream::Recordable
);
72 if (_mode
== Destructive
) {
73 dflags
= AudioDiskstream::Flag (dflags
| AudioDiskstream::Destructive
);
74 } else if (_mode
== NonLayered
){
75 dflags
= AudioDiskstream::Flag(dflags
| AudioDiskstream::NonLayered
);
78 AudioDiskstream
* dsp (new AudioDiskstream (_session
, name(), dflags
));
79 boost::shared_ptr
<AudioDiskstream
> ds (dsp
);
81 _session
.add_diskstream (ds
);
87 AudioTrack::set_diskstream (boost::shared_ptr
<Diskstream
> ds
)
90 _diskstream
->set_route (*this);
91 _diskstream
->set_destructive (_mode
== Destructive
);
92 _diskstream
->set_non_layered (_mode
== NonLayered
);
94 if (audio_diskstream()->deprecated_io_node
) {
96 if (!IO::connecting_legal
) {
97 IO::ConnectingLegal
.connect_same_thread (*this, boost::bind (&AudioTrack::deprecated_use_diskstream_connections
, this));
99 deprecated_use_diskstream_connections ();
103 _diskstream
->set_record_enabled (false);
104 _diskstream
->monitor_input (false);
106 DiskstreamChanged (); /* EMIT SIGNAL */
109 boost::shared_ptr
<AudioDiskstream
>
110 AudioTrack::audio_diskstream() const
112 return boost::dynamic_pointer_cast
<AudioDiskstream
>(_diskstream
);
116 AudioTrack::set_mode (TrackMode m
)
120 if (_diskstream
->set_destructive (m
== Destructive
)) {
124 _diskstream
->set_non_layered (m
== NonLayered
);
127 TrackModeChanged (); /* EMIT SIGNAL */
134 AudioTrack::can_use_mode (TrackMode m
, bool& bounce_required
)
139 bounce_required
= false;
144 return _diskstream
->can_become_destructive (bounce_required
);
149 AudioTrack::deprecated_use_diskstream_connections ()
151 boost::shared_ptr
<AudioDiskstream
> diskstream
= audio_diskstream();
153 if (diskstream
->deprecated_io_node
== 0) {
157 const XMLProperty
* prop
;
158 XMLNode
& node (*diskstream
->deprecated_io_node
);
160 /* don't do this more than once. */
162 diskstream
->deprecated_io_node
= 0;
164 if ((prop
= node
.property ("gain")) != 0) {
165 _amp
->set_gain (atof (prop
->value().c_str()), this);
168 if ((prop
= node
.property ("input-connection")) != 0) {
169 boost::shared_ptr
<Bundle
> c
= _session
.bundle_by_name (prop
->value());
172 error
<< string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop
->value(), _name
) << endmsg
;
174 if ((c
= _session
.bundle_by_name (_("in 1"))) == 0) {
175 error
<< _("No input bundles available as a replacement")
179 info
<< string_compose (_("Bundle %1 was not available - \"in 1\" used instead"), prop
->value())
184 _input
->connect_ports_to_bundle (c
, this);
186 } else if ((prop
= node
.property ("inputs")) != 0) {
187 if (_input
->set_ports (prop
->value())) {
188 error
<< string_compose(_("improper input channel list in XML node (%1)"), prop
->value()) << endmsg
;
197 AudioTrack::set_state (const XMLNode
& node
, int version
)
199 return _set_state (node
, version
, true);
203 AudioTrack::_set_state (const XMLNode
& node
, int version
, bool call_base
)
205 const XMLProperty
*prop
;
206 XMLNodeConstIterator iter
;
209 if (Route::_set_state (node
, version
, call_base
)) {
214 if ((prop
= node
.property (X_("mode"))) != 0) {
215 _mode
= TrackMode (string_2_enum (prop
->value(), _mode
));
221 XMLNodeConstIterator niter
;
224 nlist
= node
.children();
225 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
){
228 if (child
->name() == X_("recenable")) {
229 _rec_enable_control
->set_state (*child
, version
);
230 _session
.add_controllable (_rec_enable_control
);
234 pending_state
= const_cast<XMLNode
*> (&node
);
236 if (_session
.state_of_the_state() & Session::Loading
) {
237 _session
.StateReady
.connect_same_thread (*this, boost::bind (&AudioTrack::set_state_part_two
, this));
239 set_state_part_two ();
246 AudioTrack::state(bool full_state
)
248 XMLNode
& root (Route::state(full_state
));
249 XMLNode
* freeze_node
;
252 if (_freeze_record
.playlist
) {
255 freeze_node
= new XMLNode (X_("freeze-info"));
256 freeze_node
->add_property ("playlist", _freeze_record
.playlist
->name());
257 freeze_node
->add_property ("state", enum_2_string (_freeze_record
.state
));
259 for (vector
<FreezeRecordProcessorInfo
*>::iterator i
= _freeze_record
.processor_info
.begin(); i
!= _freeze_record
.processor_info
.end(); ++i
) {
260 inode
= new XMLNode (X_("processor"));
261 (*i
)->id
.print (buf
, sizeof (buf
));
262 inode
->add_property (X_("id"), buf
);
263 inode
->add_child_copy ((*i
)->state
);
265 freeze_node
->add_child_nocopy (*inode
);
268 root
.add_child_nocopy (*freeze_node
);
271 /* Alignment: act as a proxy for the diskstream */
273 XMLNode
* align_node
= new XMLNode (X_("Alignment"));
274 AlignStyle as
= _diskstream
->alignment_style ();
275 align_node
->add_property (X_("style"), enum_2_string (as
));
276 root
.add_child_nocopy (*align_node
);
278 root
.add_property (X_("mode"), enum_2_string (_mode
));
280 /* we don't return diskstream state because we don't
281 own the diskstream exclusively. control of the diskstream
282 state is ceded to the Session, even if we create the
286 _diskstream
->id().print (buf
, sizeof (buf
));
287 root
.add_property ("diskstream-id", buf
);
289 root
.add_child_nocopy (_rec_enable_control
->get_state());
295 AudioTrack::set_state_part_two ()
299 LocaleGuard
lg (X_("POSIX"));
301 /* This is called after all session state has been restored but before
302 have been made ports and connections are established.
305 if (pending_state
== 0) {
309 if ((fnode
= find_named_node (*pending_state
, X_("freeze-info"))) != 0) {
311 _freeze_record
.state
= Frozen
;
313 for (vector
<FreezeRecordProcessorInfo
*>::iterator i
= _freeze_record
.processor_info
.begin(); i
!= _freeze_record
.processor_info
.end(); ++i
) {
316 _freeze_record
.processor_info
.clear ();
318 if ((prop
= fnode
->property (X_("playlist"))) != 0) {
319 boost::shared_ptr
<Playlist
> pl
= _session
.playlists
->by_name (prop
->value());
321 _freeze_record
.playlist
= boost::dynamic_pointer_cast
<AudioPlaylist
> (pl
);
323 _freeze_record
.playlist
.reset ();
324 _freeze_record
.state
= NoFreeze
;
329 if ((prop
= fnode
->property (X_("state"))) != 0) {
330 _freeze_record
.state
= FreezeState (string_2_enum (prop
->value(), _freeze_record
.state
));
333 XMLNodeConstIterator citer
;
334 XMLNodeList clist
= fnode
->children();
336 for (citer
= clist
.begin(); citer
!= clist
.end(); ++citer
) {
337 if ((*citer
)->name() != X_("processor")) {
341 if ((prop
= (*citer
)->property (X_("id"))) == 0) {
345 FreezeRecordProcessorInfo
* frii
= new FreezeRecordProcessorInfo (*((*citer
)->children().front()),
346 boost::shared_ptr
<Processor
>());
347 frii
->id
= prop
->value ();
348 _freeze_record
.processor_info
.push_back (frii
);
352 /* Alignment: act as a proxy for the diskstream */
354 if ((fnode
= find_named_node (*pending_state
, X_("Alignment"))) != 0) {
356 if ((prop
= fnode
->property (X_("style"))) != 0) {
358 /* fix for older sessions from before EnumWriter */
362 if (prop
->value() == "capture") {
363 pstr
= "CaptureTime";
364 } else if (prop
->value() == "existing") {
365 pstr
= "ExistingMaterial";
367 pstr
= prop
->value();
370 AlignStyle as
= AlignStyle (string_2_enum (pstr
, as
));
371 _diskstream
->set_persistent_align_style (as
);
378 AudioTrack::roll (nframes_t nframes
, sframes_t start_frame
, sframes_t end_frame
, int declick
,
379 bool can_record
, bool rec_monitors_input
, bool& need_butler
)
384 nframes_t transport_frame
;
385 boost::shared_ptr
<AudioDiskstream
> diskstream
= audio_diskstream();
388 Glib::RWLock::ReaderLock
lm (_processor_lock
, Glib::TRY_LOCK
);
390 // automation snapshot can also be called from the non-rt context
391 // and it uses the redirect list, so we take the lock out here
392 automation_snapshot (start_frame
, false);
396 if (n_outputs().n_total() == 0 && _processors
.empty()) {
405 transport_frame
= _session
.transport_frame();
407 if ((nframes
= check_initial_delay (nframes
, transport_frame
)) == 0) {
409 /* need to do this so that the diskstream sets its
410 playback distance to zero, thus causing diskstream::commit
413 return diskstream
->process (transport_frame
, 0, can_record
, rec_monitors_input
, need_butler
);
417 _amp
->apply_gain_automation(false);
419 if ((dret
= diskstream
->process (transport_frame
, nframes
, can_record
, rec_monitors_input
, need_butler
)) != 0) {
424 /* special condition applies */
426 if (_meter_point
== MeterInput
) {
427 _input
->process_input (_meter
, start_frame
, end_frame
, nframes
);
430 if (diskstream
->record_enabled() && !can_record
&& !_session
.config
.get_auto_input()) {
432 /* not actually recording, but we want to hear the input material anyway,
433 at least potentially (depending on monitoring options)
436 passthru (start_frame
, end_frame
, nframes
, false);
438 } else if ((b
= diskstream
->playback_buffer(0)) != 0) {
441 XXX is it true that the earlier test on n_outputs()
442 means that we can avoid checking it again here? i think
443 so, because changing the i/o configuration of an IO
444 requires holding the AudioEngine lock, which we hold
445 while in the process() tree.
449 /* copy the diskstream data to all output buffers */
451 size_t limit
= input_streams ().n_audio();
452 BufferSet
& bufs
= _session
.get_scratch_buffers ();
453 const size_t blimit
= bufs
.count().n_audio();
458 if (limit
> blimit
) {
460 /* example case: auditioner configured for stereo output,
461 but loaded with an 8 channel file. there are only
462 2 passthrough buffers, but n_process_buffers() will
465 arbitrary decision: map all channels in the diskstream
466 to the outputs available.
469 float scaling
= limit
/blimit
;
471 for (i
= 0, n
= 1; i
< blimit
; ++i
, ++n
) {
473 /* first time through just copy a channel into
477 Sample
* bb
= bufs
.get_audio (i
).data();
479 for (nframes_t xx
= 0; xx
< nframes
; ++xx
) {
480 bb
[xx
] = b
[xx
] * scaling
;
483 if (n
< diskstream
->n_channels().n_audio()) {
484 tmpb
= diskstream
->playback_buffer(n
);
491 for (;i
< limit
; ++i
, ++n
) {
493 /* for all remaining channels, sum with existing
494 data in the output buffers
497 bufs
.get_audio (i
%blimit
).accumulate_with_gain_from (b
, nframes
, 0, scaling
);
499 if (n
< diskstream
->n_channels().n_audio()) {
500 tmpb
= diskstream
->playback_buffer(n
);
511 for (i
= 0, n
= 1; i
< limit
; ++i
, ++n
) {
512 memcpy (bufs
.get_audio (i
).data(), b
, sizeof (Sample
) * nframes
);
513 if (n
< diskstream
->n_channels().n_audio()) {
514 tmpb
= diskstream
->playback_buffer(n
);
521 /* try to leave any MIDI buffers alone */
524 chn
.set_audio (limit
);
525 chn
.set_midi (_input
->n_ports().n_midi());
526 bufs
.set_count (chn
);
529 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
531 if (!diskstream
->record_enabled() && _session
.transport_rolling()) {
532 #ifdef XXX_MOVE_THIS_TO_AMP
533 Glib::Mutex::Lock
am (data().control_lock(), Glib::TRY_LOCK
);
535 if (am
.locked() && gain_control()->automation_playback()) {
536 _amp
->apply_gain_automation(
537 gain_control()->list()->curve().rt_safe_get_vector (
538 start_frame
, end_frame
, _session
.gain_automation_buffer(), nframes
));
543 process_output_buffers (bufs
, start_frame
, end_frame
, nframes
, (!_session
.get_record_enabled() || !Config
->get_do_not_record_plugins()), declick
);
546 /* problem with the diskstream; just be quiet for a bit */
554 AudioTrack::export_stuff (BufferSet
& buffers
, sframes_t start
, nframes_t nframes
, bool enable_processing
)
556 gain_t gain_buffer
[nframes
];
557 float mix_buffer
[nframes
];
558 ProcessorList::iterator i
;
559 boost::shared_ptr
<AudioDiskstream
> diskstream
= audio_diskstream();
561 Glib::RWLock::ReaderLock
rlock (_processor_lock
);
563 boost::shared_ptr
<AudioPlaylist
> apl
= boost::dynamic_pointer_cast
<AudioPlaylist
>(diskstream
->playlist());
566 assert(buffers
.get_audio(0).capacity() >= nframes
);
568 if (apl
->read (buffers
.get_audio(0).data(), mix_buffer
, gain_buffer
, start
, nframes
) != nframes
) {
572 assert(buffers
.count().n_audio() >= 1);
574 Sample
* b
= buffers
.get_audio(0).data();
575 BufferSet::audio_iterator bi
= buffers
.audio_begin();
577 for ( ; bi
!= buffers
.audio_end(); ++bi
, ++n
) {
578 if (n
< diskstream
->n_channels().n_audio()) {
579 if (apl
->read (bi
->data(), mix_buffer
, gain_buffer
, start
, nframes
, n
) != nframes
) {
585 /* duplicate last across remaining buffers */
586 memcpy (bi
->data(), b
, sizeof (Sample
) * nframes
);
590 // If no processing is required, there's no need to go any further.
591 if (!enable_processing
) {
595 /* note: only run processors during export. other layers in the machinery
596 will already have checked that there are no external port processors.
599 for (i
= _processors
.begin(); i
!= _processors
.end(); ++i
) {
600 boost::shared_ptr
<Processor
> processor
;
601 if ((processor
= boost::dynamic_pointer_cast
<Processor
>(*i
)) != 0) {
602 processor
->run (buffers
, start
, start
+nframes
, nframes
, true);
609 boost::shared_ptr
<Region
>
610 AudioTrack::bounce (InterThreadInfo
& itt
)
612 vector
<boost::shared_ptr
<Source
> > srcs
;
613 return _session
.write_one_track (*this, _session
.current_start_frame(), _session
.current_end_frame(), false, srcs
, itt
);
616 boost::shared_ptr
<Region
>
617 AudioTrack::bounce_range (nframes_t start
, nframes_t end
, InterThreadInfo
& itt
, bool enable_processing
)
619 vector
<boost::shared_ptr
<Source
> > srcs
;
620 return _session
.write_one_track (*this, start
, end
, false, srcs
, itt
, enable_processing
);
624 AudioTrack::freeze_me (InterThreadInfo
& itt
)
626 vector
<boost::shared_ptr
<Source
> > srcs
;
627 string new_playlist_name
;
628 boost::shared_ptr
<Playlist
> new_playlist
;
631 boost::shared_ptr
<AudioDiskstream
> diskstream
= audio_diskstream();
633 if ((_freeze_record
.playlist
= boost::dynamic_pointer_cast
<AudioPlaylist
>(diskstream
->playlist())) == 0) {
639 while (n
< (UINT_MAX
-1)) {
643 candidate
= string_compose ("<F%2>%1", _freeze_record
.playlist
->name(), n
);
645 if (_session
.playlists
->by_name (candidate
) == 0) {
646 new_playlist_name
= candidate
;
654 if (n
== (UINT_MAX
-1)) {
655 error
<< string_compose (X_("There are too many frozen versions of playlist \"%1\""
656 " to create another one"), _freeze_record
.playlist
->name())
661 boost::shared_ptr
<Region
> res
;
663 if ((res
= _session
.write_one_track (*this, _session
.current_start_frame(), _session
.current_end_frame(), true, srcs
, itt
)) == 0) {
667 _freeze_record
.processor_info
.clear ();
670 Glib::RWLock::ReaderLock
lm (_processor_lock
);
672 for (ProcessorList::iterator r
= _processors
.begin(); r
!= _processors
.end(); ++r
) {
674 boost::shared_ptr
<Processor
> processor
;
676 if ((processor
= boost::dynamic_pointer_cast
<Processor
>(*r
)) != 0) {
678 FreezeRecordProcessorInfo
* frii
= new FreezeRecordProcessorInfo ((*r
)->get_state(), processor
);
680 frii
->id
= processor
->id();
682 _freeze_record
.processor_info
.push_back (frii
);
684 /* now deactivate the processor */
686 processor
->deactivate ();
687 _session
.set_dirty ();
692 new_playlist
= PlaylistFactory::create (DataType::AUDIO
, _session
, new_playlist_name
, false);
694 _freeze_record
.gain
= _amp
->gain();
695 _freeze_record
.gain_automation_state
= _amp
->gain_control()->automation_state();
696 /* XXX need main outs automation state _freeze_record.pan_automation_state = _mainpanner->automation_state(); */
698 region_name
= new_playlist_name
;
700 /* create a new region from all filesources, keep it private */
704 plist
.add (Properties::start
, 0);
705 plist
.add (Properties::length
, srcs
[0]->length(srcs
[0]->timeline_position()));
706 plist
.add (Properties::name
, region_name
);
707 plist
.add (Properties::whole_file
, true);
709 boost::shared_ptr
<Region
> region (RegionFactory::create (srcs
, plist
, false));
711 new_playlist
->set_orig_diskstream_id (diskstream
->id());
712 new_playlist
->add_region (region
, _session
.current_start_frame());
713 new_playlist
->set_frozen (true);
714 region
->set_locked (true);
716 diskstream
->use_playlist (boost::dynamic_pointer_cast
<AudioPlaylist
>(new_playlist
));
717 diskstream
->set_record_enabled (false);
719 /* reset stuff that has already been accounted for in the freeze process */
721 set_gain (1.0, this);
722 _amp
->gain_control()->set_automation_state (Off
);
723 /* XXX need to use _main_outs _panner->set_automation_state (Off); */
725 _freeze_record
.state
= Frozen
;
726 FreezeChange(); /* EMIT SIGNAL */
730 AudioTrack::unfreeze ()
732 if (_freeze_record
.playlist
) {
733 audio_diskstream()->use_playlist (_freeze_record
.playlist
);
736 Glib::RWLock::ReaderLock
lm (_processor_lock
); // should this be a write lock? jlc
737 for (ProcessorList::iterator i
= _processors
.begin(); i
!= _processors
.end(); ++i
) {
738 for (vector
<FreezeRecordProcessorInfo
*>::iterator ii
= _freeze_record
.processor_info
.begin(); ii
!= _freeze_record
.processor_info
.end(); ++ii
) {
739 if ((*ii
)->id
== (*i
)->id()) {
740 (*i
)->set_state (((*ii
)->state
), Stateful::current_state_version
);
747 _freeze_record
.playlist
.reset ();
748 set_gain (_freeze_record
.gain
, this);
749 _amp
->gain_control()->set_automation_state (_freeze_record
.gain_automation_state
);
750 /* XXX need to use _main_outs _panner->set_automation_state (_freeze_record.pan_automation_state); */
753 _freeze_record
.state
= UnFrozen
;
754 FreezeChange (); /* EMIT SIGNAL */