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