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