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