Remove not implemented API
[ardour.git] / libs / ardour / track.cc
1 /*
2     Copyright (C) 2006 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 #include "pbd/error.h"
19
20 #include "ardour/amp.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/audiofilesource.h"
23 #include "ardour/audioplaylist.h"
24 #include "ardour/audioregion.h"
25 #include "ardour/debug.h"
26 #include "ardour/delivery.h"
27 #include "ardour/disk_reader.h"
28 #include "ardour/disk_writer.h"
29 #include "ardour/event_type_map.h"
30 #include "ardour/io_processor.h"
31 #include "ardour/meter.h"
32 #include "ardour/midi_playlist.h"
33 #include "ardour/midi_region.h"
34 #include "ardour/monitor_control.h"
35 #include "ardour/playlist.h"
36 #include "ardour/playlist_factory.h"
37 #include "ardour/port.h"
38 #include "ardour/processor.h"
39 #include "ardour/profile.h"
40 #include "ardour/region_factory.h"
41 #include "ardour/record_enable_control.h"
42 #include "ardour/record_safe_control.h"
43 #include "ardour/route_group_specialized.h"
44 #include "ardour/session.h"
45 #include "ardour/session_playlists.h"
46 #include "ardour/smf_source.h"
47 #include "ardour/track.h"
48 #include "ardour/types_convert.h"
49 #include "ardour/utils.h"
50
51 #include "pbd/i18n.h"
52
53 using namespace std;
54 using namespace ARDOUR;
55 using namespace PBD;
56
57 Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
58         : Route (sess, name, flag, default_type)
59         , _saved_meter_point (_meter_point)
60         , _mode (mode)
61         , _alignment_choice (Automatic)
62 {
63         _freeze_record.state = NoFreeze;
64         _declickable = true;
65
66 }
67
68 Track::~Track ()
69 {
70         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
71
72         if (_disk_reader) {
73                 _disk_reader->set_route (boost::shared_ptr<Route>());
74                 _disk_reader.reset ();
75         }
76
77         if (_disk_writer) {
78                 _disk_writer->set_route (boost::shared_ptr<Route>());
79                 _disk_writer.reset ();
80         }
81 }
82
83 int
84 Track::init ()
85 {
86         if (Route::init ()) {
87                 return -1;
88         }
89
90         DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
91
92         if (_mode == Destructive && !Profile->get_trx()) {
93                 dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
94         }
95
96         _disk_reader.reset (new DiskReader (_session, name(), dflags));
97         _disk_reader->set_block_size (_session.get_block_size ());
98         _disk_reader->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
99         _disk_reader->set_owner (this);
100
101         _disk_writer.reset (new DiskWriter (_session, name(), dflags));
102         _disk_writer->set_block_size (_session.get_block_size ());
103         _disk_writer->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
104         _disk_writer->set_owner (this);
105
106         set_align_choice_from_io ();
107
108         use_new_playlist (data_type());
109
110         boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
111         boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
112
113         _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
114         add_control (_record_enable_control);
115
116         _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
117         add_control (_record_safe_control);
118
119         _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
120         add_control (_monitoring_control);
121
122         _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
123
124         _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
125         _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
126         _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
127
128         _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this));
129
130         return 0;
131 }
132
133 void
134 Track::input_changed ()
135 {
136         if (_disk_writer && _alignment_choice == Automatic) {
137                 set_align_choice_from_io ();
138         }
139 }
140
141 XMLNode&
142 Track::state (bool save_template)
143 {
144         XMLNode& root (Route::state (save_template));
145
146         if (_playlists[DataType::AUDIO]) {
147                 root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
148         }
149
150         if (_playlists[DataType::MIDI]) {
151                 root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
152         }
153
154         root.add_child_nocopy (_monitoring_control->get_state ());
155         root.add_child_nocopy (_record_safe_control->get_state ());
156         root.add_child_nocopy (_record_enable_control->get_state ());
157
158         root.set_property (X_("saved-meter-point"), _saved_meter_point);
159         root.set_property (X_("alignment-choice"), _alignment_choice);
160
161         return root;
162 }
163
164 int
165 Track::set_state (const XMLNode& node, int version)
166 {
167         if (Route::set_state (node, version)) {
168                 return -1;
169         }
170
171         if (version >= 3000 && version < 6000) {
172                 if (XMLNode* ds_node = find_named_node (node, "Diskstream")) {
173                         std::string name;
174                         if (ds_node->get_property ("name", name)) {
175
176                                 ds_node->set_property ("active", true);
177
178                                 _disk_writer->set_state (*ds_node, version);
179                                 _disk_reader->set_state (*ds_node, version);
180
181                                 AlignChoice ac;
182                                 if (ds_node->get_property (X_("capture-alignment"), ac)) {
183                                         set_align_choice (ac, true);
184                                 }
185
186                                 if (boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists->by_name (name))) {
187                                         use_playlist (DataType::AUDIO, pl);
188                                 }
189
190                                 if (boost::shared_ptr<MidiPlaylist> pl = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) {
191                                         use_playlist (DataType::MIDI, pl);
192                                 }
193                         }
194                 }
195         }
196
197         XMLNode* child;
198         std::string playlist_id;
199
200         if (node.get_property (X_("audio-playlist"), playlist_id)) {
201                 find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
202         }
203
204         if (node.get_property (X_("midi-playlist"), playlist_id)) {
205                 find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
206         }
207
208         XMLNodeList nlist = node.children();
209         for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
210                 child = *niter;
211
212                 if (child->name() == Controllable::xml_node_name) {
213                         std::string name;
214                         if (!child->get_property ("name", name)) {
215                                 continue;
216                         }
217
218                         if (name == _record_enable_control->name()) {
219                                 _record_enable_control->set_state (*child, version);
220                         } else if (name == _record_safe_control->name()) {
221                                 _record_safe_control->set_state (*child, version);
222                         } else if (name == _monitoring_control->name()) {
223                                 _monitoring_control->set_state (*child, version);
224                         }
225                 }
226         }
227
228         if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
229                 _saved_meter_point = _meter_point;
230         }
231
232
233         AlignChoice ac;
234
235         if (node.get_property (X_("alignment-choice"), ac)) {
236                 set_align_choice (ac, true);
237         }
238
239         return 0;
240 }
241
242 Track::FreezeRecord::~FreezeRecord ()
243 {
244         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
245                 delete *i;
246         }
247 }
248
249 Track::FreezeState
250 Track::freeze_state() const
251 {
252         return _freeze_record.state;
253 }
254
255 bool
256 Track::can_record()
257 {
258         bool will_record = true;
259         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
260                 if (!i->connected())
261                         will_record = false;
262         }
263
264         return will_record;
265 }
266
267 int
268 Track::prep_record_enabled (bool yn)
269 {
270         if (yn && _record_safe_control->get_value()) {
271                 return -1;
272         }
273
274         if (!can_be_record_enabled()) {
275                 return -1;
276         }
277
278         /* keep track of the meter point as it was before we rec-enabled */
279         if (!_disk_writer->record_enabled()) {
280                 _saved_meter_point = _meter_point;
281         }
282
283         bool will_follow;
284
285         if (yn) {
286                 will_follow = _disk_writer->prep_record_enable ();
287         } else {
288                 will_follow = _disk_writer->prep_record_disable ();
289         }
290
291         if (will_follow) {
292                 if (yn) {
293                         if (_meter_point != MeterCustom) {
294                                 set_meter_point (MeterInput);
295                         }
296                 } else {
297                         set_meter_point (_saved_meter_point);
298                 }
299         }
300
301         return 0;
302 }
303
304 void
305 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
306 {
307         _disk_writer->set_record_enabled (_record_enable_control->get_value());
308 }
309
310 void
311 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
312 {
313         _disk_writer->set_record_safe (_record_safe_control->get_value());
314 }
315
316 bool
317 Track::can_be_record_safe ()
318 {
319         return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
320 }
321
322 bool
323 Track::can_be_record_enabled ()
324 {
325         return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
326 }
327
328 void
329 Track::parameter_changed (string const & p)
330 {
331         if (p == "track-name-number") {
332                 resync_track_name ();
333         }
334         else if (p == "track-name-take") {
335                 resync_track_name ();
336         }
337         else if (p == "take-name") {
338                 if (_session.config.get_track_name_take()) {
339                         resync_track_name ();
340                 }
341         }
342 }
343
344 void
345 Track::resync_track_name ()
346 {
347         set_name(name());
348 }
349
350 bool
351 Track::set_name (const string& str)
352 {
353         bool ret;
354
355         if (str.empty ()) {
356                 return false;
357         }
358
359         if (_record_enable_control->get_value()) {
360                 /* when re-arm'ed the file (named after the track) is already ready to rolll */
361                 return false;
362         }
363
364         string diskstream_name = "";
365         if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
366                 // Note: any text is fine, legalize_for_path() fixes this later
367                 diskstream_name += _session.config.get_take_name ();
368                 diskstream_name += "_";
369         }
370         const int64_t tracknumber = track_number();
371         if (tracknumber > 0 && _session.config.get_track_name_number()) {
372                 char num[64], fmt[10];
373                 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
374                 snprintf(num, sizeof(num), fmt, tracknumber);
375                 diskstream_name += num;
376                 diskstream_name += "_";
377         }
378         diskstream_name += str;
379
380         if (diskstream_name == _diskstream_name) {
381                 return true;
382         }
383         _diskstream_name = diskstream_name;
384
385         _disk_writer->set_write_source_name (diskstream_name);
386
387         boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
388
389         if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
390                 /* Only rename the diskstream (and therefore the playlist) if
391                    a) the playlist has never had a region added to it and
392                    b) there is only one playlist for this track.
393
394                    If (a) is not followed, people can get confused if, say,
395                    they have notes about a playlist with a given name and then
396                    it changes (see mantis #4759).
397
398                    If (b) is not followed, we rename the current playlist and not
399                    the other ones, which is a bit confusing (see mantis #4977).
400                 */
401                 _disk_reader->set_name (str);
402                 _disk_writer->set_name (str);
403         }
404
405         for (uint32_t n = 0; n < DataType::num_types; ++n) {
406                 if (_playlists[n]) {
407                         _playlists[n]->set_name (str);
408                 }
409         }
410
411         /* save state so that the statefile fully reflects any filename changes */
412
413         if ((ret = Route::set_name (str)) == 0) {
414                 _session.save_state ("");
415         }
416
417         return ret;
418 }
419
420 boost::shared_ptr<Playlist>
421 Track::playlist ()
422 {
423         return _playlists[data_type()];
424 }
425
426 void
427 Track::request_input_monitoring (bool m)
428 {
429         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
430                 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
431         }
432 }
433
434 void
435 Track::ensure_input_monitoring (bool m)
436 {
437         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
438                 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
439         }
440 }
441
442 bool
443 Track::destructive () const
444 {
445         return _disk_writer->destructive ();
446 }
447
448 list<boost::shared_ptr<Source> > &
449 Track::last_capture_sources ()
450 {
451         return _disk_writer->last_capture_sources ();
452 }
453
454 std::string
455 Track::steal_write_source_name()
456 {
457         return _disk_writer->steal_write_source_name ();
458 }
459
460 void
461 Track::reset_write_sources (bool r, bool force)
462 {
463         _disk_writer->reset_write_sources (r, force);
464 }
465
466 float
467 Track::playback_buffer_load () const
468 {
469         return _disk_reader->buffer_load ();
470 }
471
472 float
473 Track::capture_buffer_load () const
474 {
475         return _disk_writer->buffer_load ();
476 }
477
478 int
479 Track::do_refill ()
480 {
481         return _disk_reader->do_refill ();
482 }
483
484 int
485 Track::do_flush (RunContext c, bool force)
486 {
487         return _disk_writer->do_flush (c, force);
488 }
489
490 void
491 Track::set_pending_overwrite (bool o)
492 {
493         _disk_reader->set_pending_overwrite (o);
494 }
495
496 int
497 Track::seek (samplepos_t p, bool complete_refill)
498 {
499         if (_disk_reader->seek (p, complete_refill)) {
500                 return -1;
501         }
502         return _disk_writer->seek (p, complete_refill);
503 }
504
505 int
506 Track::can_internal_playback_seek (samplecnt_t p)
507 {
508         return _disk_reader->can_internal_playback_seek (p);
509 }
510
511 int
512 Track::internal_playback_seek (samplecnt_t p)
513 {
514         return _disk_reader->internal_playback_seek (p);
515 }
516
517 void
518 Track::non_realtime_locate (samplepos_t p)
519 {
520         Route::non_realtime_locate (p);
521
522         if (!is_private_route()) {
523                 /* don't waste i/o cycles and butler calls
524                    for private tracks (e.g.auditioner)
525                 */
526                 _disk_reader->non_realtime_locate (p);
527                 _disk_writer->non_realtime_locate (p);
528         }
529 }
530
531 void
532 Track::non_realtime_speed_change ()
533 {
534         _disk_reader->non_realtime_speed_change ();
535 }
536
537 int
538 Track::overwrite_existing_buffers ()
539 {
540         return _disk_reader->overwrite_existing_buffers ();
541 }
542
543 samplecnt_t
544 Track::get_captured_samples (uint32_t n) const
545 {
546         return _disk_writer->get_captured_samples (n);
547 }
548
549 int
550 Track::set_loop (Location* l)
551 {
552         if (_disk_reader->set_loop (l)) {
553                 return -1;
554         }
555         return _disk_writer->set_loop (l);
556 }
557
558 void
559 Track::transport_looped (samplepos_t p)
560 {
561         return _disk_writer->transport_looped (p);
562 }
563
564 void
565 Track::realtime_handle_transport_stopped ()
566 {
567         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
568
569         if (!lm.locked ()) {
570                 return;
571         }
572
573         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
574                 (*i)->realtime_handle_transport_stopped ();
575         }
576 }
577
578 void
579 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
580 {
581         _disk_writer->transport_stopped_wallclock (n, t, g);
582 }
583
584 bool
585 Track::pending_overwrite () const
586 {
587         return _disk_reader->pending_overwrite ();
588 }
589
590 void
591 Track::set_slaved (bool s)
592 {
593         _disk_reader->set_slaved (s);
594         _disk_writer->set_slaved (s);
595 }
596
597 ChanCount
598 Track::n_channels ()
599 {
600         return _disk_reader->output_streams();
601 }
602
603 samplepos_t
604 Track::get_capture_start_sample (uint32_t n) const
605 {
606         return _disk_writer->get_capture_start_sample (n);
607 }
608
609 AlignStyle
610 Track::alignment_style () const
611 {
612         return _disk_writer->alignment_style ();
613 }
614
615 AlignChoice
616 Track::alignment_choice () const
617 {
618         return _alignment_choice;
619 }
620
621 samplepos_t
622 Track::current_capture_start () const
623 {
624         return _disk_writer->current_capture_start ();
625 }
626
627 samplepos_t
628 Track::current_capture_end () const
629 {
630         return _disk_writer->current_capture_end ();
631 }
632
633 void
634 Track::playlist_modified ()
635 {
636         _disk_reader->playlist_modified ();
637 }
638
639 int
640 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
641 {
642         boost::shared_ptr<Playlist> playlist;
643
644         if ((playlist = _session.playlists->by_id (id)) == 0) {
645                 return -1;
646         }
647
648         if (!playlist) {
649                 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
650                 return -1;
651         }
652
653         return use_playlist (dt, playlist);
654 }
655
656 int
657 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
658 {
659         int ret;
660
661         if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
662                 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
663                         p->set_orig_track_id (id());
664                 }
665         }
666
667         if (ret == 0) {
668                 _playlists[dt] = p;
669         }
670
671         _session.set_dirty ();
672         PlaylistChanged (); /* EMIT SIGNAL */
673
674         return ret;
675 }
676
677 int
678 Track::use_copy_playlist ()
679 {
680         assert (_playlists[data_type()]);
681
682         if (_playlists[data_type()] == 0) {
683                 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
684                 return -1;
685         }
686
687         string newname;
688         boost::shared_ptr<Playlist> playlist;
689
690         newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
691
692         if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
693                 return -1;
694         }
695
696         playlist->reset_shares();
697
698         return use_playlist (data_type(), playlist);
699 }
700
701 int
702 Track::use_new_playlist (DataType dt)
703 {
704         string newname;
705         boost::shared_ptr<Playlist> playlist = _playlists[dt];
706
707         if (playlist) {
708                 newname = Playlist::bump_name (playlist->name(), _session);
709         } else {
710                 newname = Playlist::bump_name (_name, _session);
711         }
712
713         playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
714
715         if (!playlist) {
716                 return -1;
717         }
718
719         return use_playlist (dt, playlist);
720 }
721
722 void
723 Track::set_align_choice (AlignChoice ac, bool force)
724 {
725         _alignment_choice = ac;
726         switch (ac) {
727                 case Automatic:
728                         set_align_choice_from_io ();
729                         break;
730                 case UseCaptureTime:
731                         _disk_writer->set_align_style (CaptureTime, force);
732                         break;
733                 case UseExistingMaterial:
734                         _disk_writer->set_align_style (ExistingMaterial, force);
735                         break;
736         }
737 }
738
739 void
740 Track::set_align_style (AlignStyle s, bool force)
741 {
742         _disk_writer->set_align_style (s, force);
743 }
744
745 void
746 Track::set_align_choice_from_io ()
747 {
748         bool have_physical = false;
749
750         if (_input) {
751                 uint32_t n = 0;
752                 vector<string> connections;
753                 boost::shared_ptr<Port> p;
754
755                 while (true) {
756
757                         p = _input->nth (n++);
758
759                         if (!p) {
760                                 break;
761                         }
762
763                         if (p->get_connections (connections) != 0) {
764                                 if (AudioEngine::instance()->port_is_physical (connections[0])) {
765                                         have_physical = true;
766                                         break;
767                                 }
768                         }
769
770                         connections.clear ();
771                 }
772         }
773
774 #ifdef MIXBUS
775         // compensate for latency when bouncing from master or mixbus.
776         // we need to use "ExistingMaterial" to pick up the master bus' latency
777         // see also Route::direct_feeds_according_to_reality
778         IOVector ios;
779         ios.push_back (_input);
780         if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
781                 have_physical = true;
782         }
783         for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
784                 if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
785                         have_physical = true;
786                 }
787         }
788 #endif
789
790         if (have_physical) {
791                 _disk_writer->set_align_style (ExistingMaterial);
792         } else {
793                 _disk_writer->set_align_style (CaptureTime);
794         }
795 }
796
797 void
798 Track::set_block_size (pframes_t n)
799 {
800         Route::set_block_size (n);
801         _disk_reader->set_block_size (n);
802         _disk_writer->set_block_size (n);
803 }
804
805 void
806 Track::adjust_playback_buffering ()
807 {
808         if (_disk_reader) {
809                 _disk_reader->adjust_buffering ();
810         }
811 }
812
813 void
814 Track::adjust_capture_buffering ()
815 {
816         if (_disk_writer) {
817                 _disk_writer->adjust_buffering ();
818         }
819 }
820
821
822 void
823 Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)
824 {
825         /* never declick if there is an internal generator - we just want it to
826            keep generating sound without interruption.
827
828            ditto if we are monitoring inputs.
829         */
830
831         if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
832                 return;
833         }
834
835         if (!declick) {
836                 declick = _pending_declick;
837         }
838
839         if (declick != 0) {
840                 Amp::declick (bufs, nframes, declick);
841         }
842 }
843
844 void
845 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
846 {
847         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
848                 (*i)->monitoring_changed ();
849         }
850 }
851
852 MeterState
853 Track::metering_state () const
854 {
855         bool rv;
856         if (_session.transport_rolling ()) {
857                 // audio_track.cc || midi_track.cc roll() runs meter IFF:
858                 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
859         } else {
860                 // track no_roll() always metering if
861                 rv = _meter_point == MeterInput;
862         }
863         return rv ? MeteringInput : MeteringRoute;
864 }
865
866 bool
867 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
868 {
869         if (Route::set_processor_state (node, prop, new_order, must_configure)) {
870                 return true;
871         }
872
873         cerr << name() << " looking for state for track procs, DR = " << _disk_reader << endl;
874
875         if (prop->value() == "diskreader") {
876                 if (_disk_reader) {
877                         _disk_reader->set_state (node, Stateful::current_state_version);
878                         new_order.push_back (_disk_reader);
879                         return true;
880                 }
881         } else if (prop->value() == "diskwriter") {
882                 if (_disk_writer) {
883                         _disk_writer->set_state (node, Stateful::current_state_version);
884                         new_order.push_back (_disk_writer);
885                         return true;
886                 }
887         }
888
889         error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
890         return false;
891 }
892
893 void
894 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
895 {
896         if (srcs.empty()) {
897                 return;
898         }
899
900         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
901         boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
902
903         if (afs) {
904                 use_captured_audio_sources (srcs, capture_info);
905         }
906
907         if (mfs) {
908                 use_captured_midi_sources (srcs, capture_info);
909         }
910 }
911
912 void
913 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
914 {
915         if (srcs.empty() || data_type() != DataType::MIDI) {
916                 return;
917         }
918
919         boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
920         boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
921         boost::shared_ptr<MidiRegion> midi_region;
922         CaptureInfos::const_iterator ci;
923
924         if (!mfs || !pl) {
925                 return;
926         }
927
928         samplecnt_t total_capture = 0;
929
930         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
931                 total_capture += (*ci)->samples;
932         }
933
934         /* we will want to be able to keep (over)writing the source
935            but we don't want it to be removable. this also differs
936            from the audio situation, where the source at this point
937            must be considered immutable. luckily, we can rely on
938            MidiSource::mark_streaming_write_completed() to have
939            already done the necessary work for that.
940         */
941
942         string whole_file_region_name;
943         whole_file_region_name = region_name_from_path (mfs->name(), true);
944
945         /* Register a new region with the Session that
946            describes the entire source. Do this first
947            so that any sub-regions will obviously be
948            children of this one (later!)
949         */
950
951         try {
952                 PropertyList plist;
953
954                 plist.add (Properties::name, whole_file_region_name);
955                 plist.add (Properties::whole_file, true);
956                 plist.add (Properties::automatic, true);
957                 plist.add (Properties::start, 0);
958                 plist.add (Properties::length, total_capture);
959                 plist.add (Properties::layer, 0);
960
961                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
962
963                 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
964                 midi_region->special_set_position (capture_info.front()->start);
965         }
966
967         catch (failed_constructor& err) {
968                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
969                 /* XXX what now? */
970         }
971
972         pl->clear_changes ();
973         pl->freeze ();
974
975         /* Session sample time of the initial capture in this pass, which is where the source starts */
976         samplepos_t initial_capture = 0;
977         if (!capture_info.empty()) {
978                 initial_capture = capture_info.front()->start;
979         }
980
981         BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
982         const samplepos_t preroll_off = _session.preroll_record_trim_len ();
983
984         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
985
986                 string region_name;
987
988                 RegionFactory::region_name (region_name, mfs->name(), false);
989
990                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
991                                                                       _name, (*ci)->start, (*ci)->samples, region_name));
992
993
994                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " add a region\n";
995
996                 try {
997                         PropertyList plist;
998
999                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1000                         plist.add (Properties::start, (*ci)->start - initial_capture);
1001                         plist.add (Properties::length, (*ci)->samples);
1002                         plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double());
1003                         plist.add (Properties::name, region_name);
1004
1005                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1006                         midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1007                         if (preroll_off > 0) {
1008                                 midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
1009                         }
1010                 }
1011
1012                 catch (failed_constructor& err) {
1013                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1014                         continue; /* XXX is this OK? */
1015                 }
1016
1017                 cerr << "add new region, len = " << (*ci)->samples << " @ " << (*ci)->start << endl;
1018
1019                 pl->add_region (midi_region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode ());
1020         }
1021
1022         pl->thaw ();
1023         _session.add_command (new StatefulDiffCommand (pl));
1024 }
1025
1026 void
1027 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1028 {
1029         if (srcs.empty() || data_type() != DataType::AUDIO) {
1030                 return;
1031         }
1032
1033         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1034         boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1035         boost::shared_ptr<AudioRegion> region;
1036
1037         if (!afs || !pl) {
1038                 return;
1039         }
1040
1041         /* destructive tracks have a single, never changing region */
1042
1043         if (destructive()) {
1044
1045                 /* send a signal that any UI can pick up to do the right thing. there is
1046                    a small problem here in that a UI may need the peak data to be ready
1047                    for the data that was recorded and this isn't interlocked with that
1048                    process. this problem is deferred to the UI.
1049                  */
1050
1051                 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1052                 return;
1053         }
1054
1055         string whole_file_region_name;
1056         whole_file_region_name = region_name_from_path (afs->name(), true);
1057
1058         /* Register a new region with the Session that
1059            describes the entire source. Do this first
1060            so that any sub-regions will obviously be
1061            children of this one (later!)
1062         */
1063
1064         try {
1065                 PropertyList plist;
1066
1067                 plist.add (Properties::start, afs->last_capture_start_sample());
1068                 plist.add (Properties::length, afs->length(0));
1069                 plist.add (Properties::name, whole_file_region_name);
1070                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1071                 rx->set_automatic (true);
1072                 rx->set_whole_file (true);
1073
1074                 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1075                 region->special_set_position (afs->natural_position());
1076         }
1077
1078
1079         catch (failed_constructor& err) {
1080                 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1081                 /* XXX what now? */
1082         }
1083
1084         pl->clear_changes ();
1085         pl->set_capture_insertion_in_progress (true);
1086         pl->freeze ();
1087
1088         const samplepos_t preroll_off = _session.preroll_record_trim_len ();
1089         samplecnt_t buffer_position = afs->last_capture_start_sample ();
1090         CaptureInfos::const_iterator ci;
1091
1092         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1093
1094                 string region_name;
1095
1096                 RegionFactory::region_name (region_name, whole_file_region_name, false);
1097
1098                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1099                                                                       _name, (*ci)->start, (*ci)->samples, region_name, buffer_position));
1100
1101                 try {
1102
1103                         PropertyList plist;
1104
1105                         plist.add (Properties::start, buffer_position);
1106                         plist.add (Properties::length, (*ci)->samples);
1107                         plist.add (Properties::name, region_name);
1108
1109                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1110                         region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1111                         if (preroll_off > 0) {
1112                                 region->trim_front (buffer_position + preroll_off);
1113                         }
1114                 }
1115
1116                 catch (failed_constructor& err) {
1117                         error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1118                         continue; /* XXX is this OK? */
1119                 }
1120
1121                 pl->add_region (region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode());
1122                 pl->set_layer (region, DBL_MAX);
1123
1124                 buffer_position += (*ci)->samples;
1125         }
1126
1127         pl->thaw ();
1128         pl->set_capture_insertion_in_progress (false);
1129         _session.add_command (new StatefulDiffCommand (pl));
1130 }
1131
1132