Large nasty commit in the form of a 5000 line patch chock-full of completely
[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     $Id$
19 */
20 #include <pbd/error.h>
21 #include <sigc++/retype.h>
22 #include <sigc++/retype_return.h>
23 #include <sigc++/bind.h>
24
25 #include <ardour/audio_track.h>
26 #include <ardour/audio_diskstream.h>
27 #include <ardour/session.h>
28 #include <ardour/redirect.h>
29 #include <ardour/audioregion.h>
30 #include <ardour/audiosource.h>
31 #include <ardour/route_group_specialized.h>
32 #include <ardour/insert.h>
33 #include <ardour/audioplaylist.h>
34 #include <ardour/panner.h>
35 #include <ardour/utils.h>
36
37 #include "i18n.h"
38
39 using namespace std;
40 using namespace ARDOUR;
41 using namespace PBD;
42
43 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
44         : Route (sess, name, 1, -1, -1, -1, flag),
45           _diskstream (0),
46           _midi_rec_enable_control (*this, _session.midi_port())
47 {
48         AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
49
50         if (_flags & Hidden) {
51                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
52         } else {
53                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
54         }
55
56         if (mode == Destructive) {
57                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
58         }
59
60         AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
61         
62         _declickable = true;
63         _freeze_record.state = NoFreeze;
64         _saved_meter_point = _meter_point;
65         _mode = mode;
66
67         set_diskstream (*ds, this);
68
69         // session.SMPTEOffsetChanged.connect (mem_fun (*this, &AudioTrack::handle_smpte_offset_change));
70
71         // we do this even though Route already did it in it's init
72         reset_midi_control (_session.midi_port(), _session.get_midi_control());
73         
74 }
75
76 AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
77         : Route (sess, "to be renamed", 0, 0, -1, -1),
78           _diskstream (0),
79           _midi_rec_enable_control (*this, _session.midi_port())
80 {
81         _freeze_record.state = NoFreeze;
82         set_state (node);
83         _declickable = true;
84         _saved_meter_point = _meter_point;
85
86         // we do this even though Route already did it in it's init
87         reset_midi_control (_session.midi_port(), _session.get_midi_control());
88 }
89
90 AudioTrack::~AudioTrack ()
91 {
92         if (_diskstream) {
93                 _diskstream->unref();
94         }
95 }
96
97 #if 0
98 void
99 AudioTrack::handle_smpte_offset_change ()
100 {
101         diskstream
102 }
103 #endif
104
105 int
106 AudioTrack::deprecated_use_diskstream_connections ()
107 {
108         if (_diskstream->deprecated_io_node == 0) {
109                 return 0;
110         }
111
112         const XMLProperty* prop;
113         XMLNode& node (*_diskstream->deprecated_io_node);
114
115         /* don't do this more than once. */
116
117         _diskstream->deprecated_io_node = 0;
118
119         set_input_minimum (-1);
120         set_input_maximum (-1);
121         set_output_minimum (-1);
122         set_output_maximum (-1);
123         
124         if ((prop = node.property ("gain")) != 0) {
125                 set_gain (atof (prop->value().c_str()), this);
126                 _gain = _desired_gain;
127         }
128
129         if ((prop = node.property ("input-connection")) != 0) {
130                 Connection* c = _session.connection_by_name (prop->value());
131                 
132                 if (c == 0) {
133                         error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
134                         
135                         if ((c = _session.connection_by_name (_("in 1"))) == 0) {
136                                 error << _("No input connections available as a replacement")
137                                 << endmsg;
138                                 return -1;
139                         } else {
140                                 info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
141                                << endmsg;
142                         }
143                 }
144
145                 use_input_connection (*c, this);
146
147         } else if ((prop = node.property ("inputs")) != 0) {
148                 if (set_inputs (prop->value())) {
149                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
150                         return -1;
151                 }
152         }
153         
154         return 0;
155 }
156
157 int
158 AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
159 {
160         if (_diskstream) {
161                 _diskstream->unref();
162         }
163
164         _diskstream = &ds.ref();
165         _diskstream->set_io (*this);
166         _diskstream->set_destructive (_mode == Destructive);
167
168         if (_diskstream->deprecated_io_node) {
169
170                 if (!connecting_legal) {
171                         ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
172                 } else {
173                         deprecated_use_diskstream_connections ();
174                 }
175         }
176
177         _diskstream->set_record_enabled (false, this);
178         _diskstream->monitor_input (false);
179
180         ic_connection.disconnect();
181         ic_connection = input_changed.connect (mem_fun (*_diskstream, &AudioDiskstream::handle_input_change));
182
183         diskstream_changed (src); /* EMIT SIGNAL */
184
185         return 0;
186 }       
187
188 int 
189 AudioTrack::use_diskstream (string name)
190 {
191         AudioDiskstream *dstream;
192
193         if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_name (name))) == 0) {
194           error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
195                 return -1;
196         }
197         
198         return set_diskstream (*dstream, this);
199 }
200
201 int 
202 AudioTrack::use_diskstream (id_t id)
203 {
204         AudioDiskstream *dstream;
205
206         if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_id (id))) == 0) {
207                 error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
208                 return -1;
209         }
210         
211         return set_diskstream (*dstream, this);
212 }
213
214 bool
215 AudioTrack::record_enabled () const
216 {
217         return _diskstream->record_enabled ();
218 }
219
220 void
221 AudioTrack::set_record_enable (bool yn, void *src)
222 {
223         if (_freeze_record.state == Frozen) {
224                 return;
225         }
226
227         if (_mix_group && src != _mix_group && _mix_group->is_active()) {
228                 _mix_group->apply (&AudioTrack::set_record_enable, yn, _mix_group);
229                 return;
230         }
231
232         /* keep track of the meter point as it was before we rec-enabled */
233
234         if (!_diskstream->record_enabled()) {
235                 _saved_meter_point = _meter_point;
236         }
237         
238         _diskstream->set_record_enabled (yn, src);
239
240         if (_diskstream->record_enabled()) {
241                 set_meter_point (MeterInput, this);
242         } else {
243                 set_meter_point (_saved_meter_point, this);
244         }
245
246         if (_session.get_midi_feedback()) {
247                 _midi_rec_enable_control.send_feedback (record_enabled());
248         }
249
250 }
251
252 void
253 AudioTrack::set_meter_point (MeterPoint p, void *src)
254 {
255         Route::set_meter_point (p, src);
256 }
257
258 int
259 AudioTrack::set_state (const XMLNode& node)
260 {
261         const XMLProperty *prop;
262         XMLNodeConstIterator iter;
263         XMLNodeList midi_kids;
264
265         if (Route::set_state (node)) {
266                 return -1;
267         }
268
269         if ((prop = node.property (X_("mode"))) != 0) {
270                 if (prop->value() == X_("normal")) {
271                         _mode = Normal;
272                 } else if (prop->value() == X_("destructive")) {
273                         _mode = Destructive;
274                 } else {
275                         warning << string_compose ("unknown audio track mode \"%1\" seen and ignored", prop->value()) << endmsg;
276                         _mode = Normal;
277                 }
278         } else {
279                 _mode = Normal;
280         }
281
282         midi_kids = node.children ("MIDI");
283         
284         for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
285         
286                 XMLNodeList kids;
287                 XMLNodeConstIterator miter;
288                 XMLNode*    child;
289
290                 kids = (*iter)->children ();
291
292                 for (miter = kids.begin(); miter != kids.end(); ++miter) {
293
294                         child =* miter;
295
296                         if (child->name() == "rec_enable") {
297                         
298                                 MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
299                                 MIDI::byte additional = 0;  /* ditto */
300                                 MIDI::channel_t chn = 0;    /* ditto */
301
302                                 if (get_midi_node_info (child, ev, chn, additional)) {
303                                         _midi_rec_enable_control.set_control_type (chn, ev, additional);
304                                 } else {
305                                   error << string_compose(_("MIDI rec_enable control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
306                                 }
307                         }
308                 }
309         }
310
311         
312         if ((prop = node.property ("diskstream-id")) == 0) {
313                 
314                 /* some old sessions use the diskstream name rather than the ID */
315
316                 if ((prop = node.property ("diskstream")) == 0) {
317                         fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg;
318                         /*NOTREACHED*/
319                         return -1;
320                 }
321
322                 if (use_diskstream (prop->value())) {
323                         return -1;
324                 }
325
326         } else {
327                 
328                 id_t id = strtoull (prop->value().c_str(), 0, 10);
329                 
330                 if (use_diskstream (id)) {
331                         return -1;
332                 }
333         }
334
335
336         XMLNodeList nlist;
337         XMLNodeConstIterator niter;
338         XMLNode *child;
339
340         nlist = node.children();
341         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
342                 child = *niter;
343
344                 if (child->name() == X_("remote_control")) {
345                         if ((prop = child->property (X_("id"))) != 0) {
346                                 int32_t x;
347                                 sscanf (prop->value().c_str(), "%d", &x);
348                                 set_remote_control_id (x);
349                         }
350                 }
351         }
352
353         pending_state = const_cast<XMLNode*> (&node);
354
355         _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
356
357         return 0;
358 }
359
360 XMLNode&
361 AudioTrack::get_template ()
362 {
363         return state (false);
364 }
365
366 XMLNode&
367 AudioTrack::get_state ()
368 {
369         return state (true);
370 }
371
372 XMLNode& 
373 AudioTrack::state(bool full_state)
374 {
375         XMLNode& root (Route::state(full_state));
376         XMLNode* freeze_node;
377         char buf[32];
378
379         if (_freeze_record.playlist) {
380                 XMLNode* inode;
381
382                 freeze_node = new XMLNode (X_("freeze-info"));
383                 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
384                 snprintf (buf, sizeof (buf), "%d", (int) _freeze_record.state);
385                 freeze_node->add_property ("state", buf);
386
387                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
388                         inode = new XMLNode (X_("insert"));
389                         snprintf (buf, sizeof (buf), "%" PRIu64, (*i)->id);
390                         inode->add_property (X_("id"), buf);
391                         inode->add_child_copy ((*i)->state);
392                 
393                         freeze_node->add_child_nocopy (*inode);
394                 }
395
396                 root.add_child_nocopy (*freeze_node);
397         }
398
399         /* Alignment: act as a proxy for the diskstream */
400         
401         XMLNode* align_node = new XMLNode (X_("alignment"));
402         switch (_diskstream->alignment_style()) {
403         case ExistingMaterial:
404                 snprintf (buf, sizeof (buf), X_("existing"));
405                 break;
406         case CaptureTime:
407                 snprintf (buf, sizeof (buf), X_("capture"));
408                 break;
409         }
410         align_node->add_property (X_("style"), buf);
411         root.add_child_nocopy (*align_node);
412
413         /* MIDI control */
414
415         MIDI::channel_t chn;
416         MIDI::eventType ev;
417         MIDI::byte      additional;
418         XMLNode*        midi_node = 0;
419         XMLNode*        child;
420         XMLNodeList     midikids;
421
422         midikids = root.children ("MIDI");
423         if (!midikids.empty()) {
424                 midi_node = midikids.front();
425         }
426         else {
427                 midi_node = root.add_child ("MIDI");
428         }
429                 
430         if (_midi_rec_enable_control.get_control_info (chn, ev, additional) && midi_node) {
431
432                 child = midi_node->add_child ("rec_enable");
433                 set_midi_node_info (child, ev, chn, additional);
434         }
435
436         XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
437         snprintf (buf, sizeof (buf), "%d", _remote_control_id);
438         remote_control_node->add_property (X_("id"), buf);
439         root.add_child_nocopy (*remote_control_node);
440
441         switch (_mode) {
442         case Normal:
443                 root.add_property (X_("mode"), X_("normal"));
444                 break;
445         case Destructive:
446                 root.add_property (X_("mode"), X_("destructive"));
447                 break;
448         }
449
450         /* we don't return diskstream state because we don't
451            own the diskstream exclusively. control of the diskstream
452            state is ceded to the Session, even if we create the
453            diskstream.
454         */
455
456         snprintf (buf, sizeof (buf), "%" PRIu64, _diskstream->id());
457         root.add_property ("diskstream-id", buf);
458
459         return root;
460 }
461
462 void
463 AudioTrack::set_state_part_two ()
464 {
465         XMLNode* fnode;
466         XMLProperty* prop;
467         LocaleGuard lg (X_("POSIX"));
468
469         /* This is called after all session state has been restored but before
470            have been made ports and connections are established.
471         */
472
473         if (pending_state == 0) {
474                 return;
475         }
476
477         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
478
479                 
480                 _freeze_record.have_mementos = false;
481                 _freeze_record.state = Frozen;
482                 
483                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
484                         delete *i;
485                 }
486                 _freeze_record.insert_info.clear ();
487                 
488                 if ((prop = fnode->property (X_("playlist"))) != 0) {
489                         Playlist* pl = _session.playlist_by_name (prop->value());
490                         if (pl) {
491                                 _freeze_record.playlist = dynamic_cast<AudioPlaylist*> (pl);
492                         } else {
493                                 _freeze_record.playlist = 0;
494                                 _freeze_record.state = NoFreeze;
495                         return;
496                         }
497                 }
498                 
499                 if ((prop = fnode->property (X_("state"))) != 0) {
500                         _freeze_record.state = (FreezeState) atoi (prop->value().c_str());
501                 }
502                 
503                 XMLNodeConstIterator citer;
504                 XMLNodeList clist = fnode->children();
505                 
506                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
507                         if ((*citer)->name() != X_("insert")) {
508                                 continue;
509                         }
510                         
511                         if ((prop = (*citer)->property (X_("id"))) == 0) {
512                                 continue;
513                         }
514                         
515                         FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()));
516                         frii->insert = 0;
517                         sscanf (prop->value().c_str(), "%" PRIu64, &frii->id);
518                         _freeze_record.insert_info.push_back (frii);
519                 }
520         }
521
522         /* Alignment: act as a proxy for the diskstream */
523
524         if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
525
526                 if ((prop = fnode->property (X_("style"))) != 0) {
527                         if (prop->value() == "existing") {
528                                 _diskstream->set_persistent_align_style (ExistingMaterial);
529                         } else if (prop->value() == "capture") {
530                                 _diskstream->set_persistent_align_style (CaptureTime);
531                         }
532                 }
533         }
534         return;
535 }       
536
537 uint32_t
538 AudioTrack::n_process_buffers ()
539 {
540         return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
541 }
542
543 void
544 AudioTrack::passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter)
545 {
546         uint32_t nbufs = n_process_buffers ();
547         process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, offset, true, declick, meter);
548 }
549
550 int 
551 AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, 
552                      bool session_state_changing, bool can_record, bool rec_monitors_input)
553 {
554         if (n_outputs() == 0) {
555                 return 0;
556         }
557
558         if (!_active) {
559                 silence (nframes, offset);
560                 return 0;
561         }
562
563         if (session_state_changing) {
564
565                 /* XXX is this safe to do against transport state changes? */
566
567                 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
568                 return 0;
569         }
570
571         _diskstream->check_record_status (start_frame, nframes, can_record);
572
573         bool send_silence;
574         
575         if (_have_internal_generator) {
576                 /* since the instrument has no input streams,
577                    there is no reason to send any signal
578                    into the route.
579                 */
580                 send_silence = true;
581         } else {
582
583                 if (_session.get_auto_input()) {
584                         if (Config->get_use_sw_monitoring()) {
585                                 send_silence = false;
586                         } else {
587                                 send_silence = true;
588                         }
589                 } else {
590                         if (_diskstream->record_enabled()) {
591                                 if (Config->get_use_sw_monitoring()) {
592                                         send_silence = false;
593                                 } else {
594                                         send_silence = true;
595                                 }
596                         } else {
597                                 send_silence = true;
598                         }
599                 }
600         }
601
602         apply_gain_automation = false;
603
604         if (send_silence) {
605                 
606                 /* if we're sending silence, but we want the meters to show levels for the signal,
607                    meter right here.
608                 */
609                 
610                 if (_have_internal_generator) {
611                         passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
612                 } else {
613                         if (_meter_point == MeterInput) {
614                                 just_meter_input (start_frame, end_frame, nframes, offset);
615                         }
616                         passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
617                 }
618
619         } else {
620         
621                 /* we're sending signal, but we may still want to meter the input. 
622                  */
623
624                 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
625         }
626
627         return 0;
628 }
629
630 int
631 AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
632                   bool can_record, bool rec_monitors_input)
633 {
634         int dret;
635         Sample* b;
636         Sample* tmpb;
637         jack_nframes_t transport_frame;
638
639         {
640                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
641                 if (lm.locked()) {
642                         // automation snapshot can also be called from the non-rt context
643                         // and it uses the redirect list, so we take the lock out here
644                         automation_snapshot (start_frame);
645                 }
646         }
647         
648         if (n_outputs() == 0 && _redirects.empty()) {
649                 return 0;
650         }
651
652         if (!_active) {
653                 silence (nframes, offset);
654                 return 0;
655         }
656
657         transport_frame = _session.transport_frame();
658
659         if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
660                 /* need to do this so that the diskstream sets its
661                    playback distance to zero, thus causing diskstream::commit
662                    to do nothing.
663                 */
664                 return _diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
665         } 
666
667         _silent = false;
668         apply_gain_automation = false;
669
670         if ((dret = _diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
671                 
672                 silence (nframes, offset);
673
674                 return dret;
675         }
676
677         /* special condition applies */
678         
679         if (_meter_point == MeterInput) {
680                 just_meter_input (start_frame, end_frame, nframes, offset);
681         }
682
683         if (_diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
684
685                 /* not actually recording, but we want to hear the input material anyway,
686                    at least potentially (depending on monitoring options)
687                  */
688
689                 passthru (start_frame, end_frame, nframes, offset, 0, true);
690
691         } else if ((b = _diskstream->playback_buffer(0)) != 0) {
692
693                 /*
694                   XXX is it true that the earlier test on n_outputs()
695                   means that we can avoid checking it again here? i think
696                   so, because changing the i/o configuration of an IO
697                   requires holding the AudioEngine lock, which we hold
698                   while in the process() tree.
699                 */
700
701                 
702                 /* copy the diskstream data to all output buffers */
703                 
704                 vector<Sample*>& bufs = _session.get_passthru_buffers ();
705                 uint32_t limit = n_process_buffers ();
706                 
707                 uint32_t n;
708                 uint32_t i;
709
710
711                 for (i = 0, n = 1; i < limit; ++i, ++n) {
712                         memcpy (bufs[i], b, sizeof (Sample) * nframes); 
713                         if (n < _diskstream->n_channels()) {
714                                 tmpb = _diskstream->playback_buffer(n);
715                                 if (tmpb!=0) {
716                                         b = tmpb;
717                                 }
718                         }
719                 }
720
721                 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
722
723                 if (!_diskstream->record_enabled() && _session.transport_rolling()) {
724                         Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
725                         
726                         if (am.locked() && gain_automation_playback()) {
727                                 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
728                         }
729                 }
730
731                 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
732                 
733         } else {
734                 /* problem with the diskstream; just be quiet for a bit */
735                 silence (nframes, offset);
736         }
737
738         return 0;
739 }
740
741 int
742 AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, 
743                          bool can_record, bool rec_monitors_input)
744 {
745         if (n_outputs() == 0 && _redirects.empty()) {
746                 return 0;
747         }
748
749         if (!_active) {
750                 silence (nframes, offset);
751                 return 0;
752         }
753
754         _silent = true;
755         apply_gain_automation = false;
756
757         silence (nframes, offset);
758
759         return _diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
760 }
761
762 void
763 AudioTrack::toggle_monitor_input ()
764 {
765         for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
766                 (*i)->request_monitor_input(!(*i)->monitoring_input());
767         }
768 }
769
770 int
771 AudioTrack::set_name (string str, void *src)
772 {
773         int ret;
774
775         if (record_enabled() && _session.actively_recording()) {
776                 /* this messes things up if done while recording */
777                 return -1;
778         }
779
780         if (_diskstream->set_name (str, src)) {
781                 return -1;
782         }
783
784         /* save state so that the statefile fully reflects any filename changes */
785
786         if ((ret = IO::set_name (str, src)) == 0) {
787                 _session.save_state ("");
788         }
789         return ret;
790 }
791
792 int
793 AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes)
794 {
795         gain_t  gain_automation[nframes];
796         gain_t  gain_buffer[nframes];
797         float   mix_buffer[nframes];
798         RedirectList::iterator i;
799         bool post_fader_work = false;
800         gain_t this_gain = _gain;
801         vector<Sample*>::iterator bi;
802         Sample * b;
803         
804         Glib::RWLock::ReaderLock rlock (redirect_lock);
805
806         // FIXME
807         AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
808         assert(apl);
809
810         if (apl->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
811                 return -1;
812         }
813
814         uint32_t n=1;
815         bi = buffers.begin();
816         b = buffers[0];
817         ++bi;
818         for (; bi != buffers.end(); ++bi, ++n) {
819                 if (n < _diskstream->n_channels()) {
820                         if (apl->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
821                                 return -1;
822                         }
823                         b = (*bi);
824                 }
825                 else {
826                         /* duplicate last across remaining buffers */
827                         memcpy ((*bi), b, sizeof (Sample) * nframes); 
828                 }
829         }
830
831
832         /* note: only run inserts during export. other layers in the machinery
833            will already have checked that there are no external port inserts.
834         */
835         
836         for (i = _redirects.begin(); i != _redirects.end(); ++i) {
837                 Insert *insert;
838                 
839                 if ((insert = dynamic_cast<Insert*>(*i)) != 0) {
840                         switch (insert->placement()) {
841                         case PreFader:
842                                 insert->run (buffers, nbufs, nframes, 0);
843                                 break;
844                         case PostFader:
845                                 post_fader_work = true;
846                                 break;
847                         }
848                 }
849         }
850         
851         if (_gain_automation_curve.automation_state() == Play) {
852                 
853                 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
854
855                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
856                         Sample *b = *bi;
857                         for (jack_nframes_t n = 0; n < nframes; ++n) {
858                                 b[n] *= gain_automation[n];
859                         }
860                 }
861
862         } else {
863
864                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
865                         Sample *b = *bi;
866                         for (jack_nframes_t n = 0; n < nframes; ++n) {
867                                 b[n] *= this_gain;
868                         }
869                 }
870         }
871
872         if (post_fader_work) {
873
874                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
875                         PluginInsert *insert;
876                         
877                         if ((insert = dynamic_cast<PluginInsert*>(*i)) != 0) {
878                                 switch ((*i)->placement()) {
879                                 case PreFader:
880                                         break;
881                                 case PostFader:
882                                         insert->run (buffers, nbufs, nframes, 0);
883                                         break;
884                                 }
885                         }
886                 }
887         } 
888
889         return 0;
890 }
891
892 void
893 AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency)
894 {
895         Route::set_latency_delay (longest_session_latency);
896         _diskstream->set_roll_delay (_roll_delay);
897 }
898
899 jack_nframes_t
900 AudioTrack::update_total_latency ()
901 {
902         _own_latency = 0;
903
904         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
905                 if ((*i)->active ()) {
906                         _own_latency += (*i)->latency ();
907                 }
908         }
909
910         set_port_latency (_own_latency);
911
912         return _own_latency;
913 }
914
915 void
916 AudioTrack::bounce (InterThreadInfo& itt)
917 {
918         vector<AudioSource*> srcs;
919         _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
920 }
921
922
923 void
924 AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
925 {
926         vector<AudioSource*> srcs;
927         _session.write_one_audio_track (*this, start, end, false, srcs, itt);
928 }
929
930 void
931 AudioTrack::freeze (InterThreadInfo& itt)
932 {
933         Insert* insert;
934         vector<AudioSource*> srcs;
935         string new_playlist_name;
936         Playlist* new_playlist;
937         string dir;
938         AudioRegion* region;
939         string region_name;
940         
941         if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(_diskstream->playlist())) == 0) {
942                 return;
943         }
944
945         uint32_t n = 1;
946
947         while (n < (UINT_MAX-1)) {
948          
949                 string candidate;
950                 
951                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
952
953                 if (_session.playlist_by_name (candidate) == 0) {
954                         new_playlist_name = candidate;
955                         break;
956                 }
957
958                 ++n;
959
960         } 
961
962         if (n == (UINT_MAX-1)) {
963           error << string_compose (X_("There Are too many frozen versions of playlist \"%1\""
964                             " to create another one"), _freeze_record.playlist->name())
965                << endmsg;
966                 return;
967         }
968
969         if (_session.write_one_audio_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) {
970                 return;
971         }
972
973         _freeze_record.insert_info.clear ();
974         _freeze_record.have_mementos = true;
975
976         {
977                 Glib::RWLock::ReaderLock lm (redirect_lock);
978                 
979                 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
980                         
981                         if ((insert = dynamic_cast<Insert*>(*r)) != 0) {
982                                 
983                                 FreezeRecordInsertInfo* frii  = new FreezeRecordInsertInfo ((*r)->get_state());
984                                 
985                                 frii->insert = insert;
986                                 frii->id = insert->id();
987                                 frii->memento = (*r)->get_memento();
988                                 
989                                 _freeze_record.insert_info.push_back (frii);
990                                 
991                                 /* now deactivate the insert */
992                                 
993                                 insert->set_active (false, this);
994                         }
995                 }
996         }
997
998         new_playlist = new AudioPlaylist (_session, new_playlist_name, false);
999         region_name = new_playlist_name;
1000
1001         /* create a new region from all filesources, keep it private */
1002
1003         region = new AudioRegion (srcs, 0, srcs[0]->length(), 
1004                                   region_name, 0, 
1005                                   (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
1006                                   false);
1007
1008         new_playlist->set_orig_diskstream_id (_diskstream->id());
1009         new_playlist->add_region (*region, 0);
1010         new_playlist->set_frozen (true);
1011         region->set_locked (true);
1012
1013         _diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
1014         _diskstream->set_record_enabled (false, this);
1015
1016         _freeze_record.state = Frozen;
1017         FreezeChange(); /* EMIT SIGNAL */
1018 }
1019
1020 void
1021 AudioTrack::unfreeze ()
1022 {
1023         if (_freeze_record.playlist) {
1024                 _diskstream->use_playlist (_freeze_record.playlist);
1025
1026                 if (_freeze_record.have_mementos) {
1027
1028                         for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
1029                                 (*i)->memento ();
1030                         }
1031
1032                 } else {
1033
1034                         Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
1035                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
1036                                 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
1037                                         if ((*ii)->id == (*i)->id()) {
1038                                                 (*i)->set_state (((*ii)->state));
1039                                                 break;
1040                                         }
1041                                 }
1042                         }
1043                 }
1044                 
1045                 _freeze_record.playlist = 0;
1046         }
1047
1048         _freeze_record.state = UnFrozen;
1049         FreezeChange (); /* EMIT SIGNAL */
1050 }
1051
1052 AudioTrack::FreezeRecord::~FreezeRecord ()
1053 {
1054         for (vector<FreezeRecordInsertInfo*>::iterator i = insert_info.begin(); i != insert_info.end(); ++i) {
1055                 delete *i;
1056         }
1057 }
1058
1059 AudioTrack::FreezeState
1060 AudioTrack::freeze_state() const
1061 {
1062         return _freeze_record.state;
1063 }
1064
1065
1066 void
1067 AudioTrack::reset_midi_control (MIDI::Port* port, bool on)
1068 {
1069         MIDI::channel_t chn;
1070         MIDI::eventType ev;
1071         MIDI::byte extra;
1072
1073         Route::reset_midi_control (port, on);
1074         
1075         _midi_rec_enable_control.get_control_info (chn, ev, extra);
1076         if (!on) {
1077                 chn = -1;
1078         }
1079         _midi_rec_enable_control.midi_rebind (port, chn);
1080 }
1081
1082 void
1083 AudioTrack::send_all_midi_feedback ()
1084 {
1085         if (_session.get_midi_feedback()) {
1086
1087                 Route::send_all_midi_feedback();
1088
1089                 _midi_rec_enable_control.send_feedback (record_enabled());
1090         }
1091 }
1092
1093
1094 AudioTrack::MIDIRecEnableControl::MIDIRecEnableControl (AudioTrack& s,  MIDI::Port* port)
1095         : MIDI::Controllable (port, 0), track (s), setting(false)
1096 {
1097         last_written = false; /* XXX need a good out of bound value */
1098 }
1099
1100 void
1101 AudioTrack::MIDIRecEnableControl::set_value (float val)
1102 {
1103         bool bval = ((val >= 0.5f) ? true: false);
1104         
1105         setting = true;
1106         track.set_record_enable (bval, this);
1107         setting = false;
1108 }
1109
1110 void
1111 AudioTrack::MIDIRecEnableControl::send_feedback (bool value)
1112 {
1113
1114         if (!setting && get_midi_feedback()) {
1115                 MIDI::byte val = (MIDI::byte) (value ? 127: 0);
1116                 MIDI::channel_t ch = 0;
1117                 MIDI::eventType ev = MIDI::none;
1118                 MIDI::byte additional = 0;
1119                 MIDI::EventTwoBytes data;
1120             
1121                 if (get_control_info (ch, ev, additional)) {
1122                         data.controller_number = additional;
1123                         data.value = val;
1124
1125                         track._session.send_midi_message (get_port(), ev, ch, data);
1126                 }
1127         }
1128         
1129 }
1130
1131 MIDI::byte*
1132 AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force)
1133 {
1134         if (get_midi_feedback()) {
1135
1136                 MIDI::channel_t ch = 0;
1137                 MIDI::eventType ev = MIDI::none;
1138                 MIDI::byte additional = 0;
1139
1140                 if (get_control_info (ch, ev, additional)) {
1141                         if (val != last_written || force) {
1142                                 *buf++ = ev & ch;
1143                                 *buf++ = additional; /* controller number */
1144                                 *buf++ = (MIDI::byte) (val ? 127: 0);
1145                                 last_written = val;
1146                                 bufsize -= 3;
1147                         }
1148                 }
1149         }
1150
1151         return buf;
1152 }
1153
1154 void
1155 AudioTrack::set_mode (TrackMode m)
1156 {
1157         if (_diskstream) {
1158                 if (_mode != m) {
1159                         _mode = m;
1160                         _diskstream->set_destructive (m == Destructive);
1161                         ModeChanged();
1162                 }
1163         }
1164 }