Auto-connect outputs that appear as a result of e.g. instruments being added to MIDI...
[ardour.git] / libs / ardour / diskstream.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <fstream>
21 #include <cassert>
22 #include <cstdio>
23 #include <unistd.h>
24 #include <cmath>
25 #include <cerrno>
26 #include <string>
27 #include <climits>
28 #include <fcntl.h>
29 #include <cstdlib>
30 #include <ctime>
31 #include <sys/stat.h>
32 #include <sys/mman.h>
33
34
35 #include "pbd/error.h"
36 #include "pbd/basename.h"
37 #include <glibmm/thread.h>
38 #include "pbd/xml++.h"
39 #include "pbd/memento_command.h"
40
41 #include "ardour/ardour.h"
42 #include "ardour/audioengine.h"
43 #include "ardour/debug.h"
44 #include "ardour/diskstream.h"
45 #include "ardour/utils.h"
46 #include "ardour/configuration.h"
47 #include "ardour/audiofilesource.h"
48 #include "ardour/send.h"
49 #include "ardour/playlist.h"
50 #include "ardour/cycle_timer.h"
51 #include "ardour/region.h"
52 #include "ardour/panner.h"
53 #include "ardour/session.h"
54 #include "ardour/io.h"
55 #include "ardour/track.h"
56
57 #include "i18n.h"
58 #include <locale.h>
59
60 using namespace std;
61 using namespace ARDOUR;
62 using namespace PBD;
63
64 /* XXX This goes uninitialized when there is no ~/.config/ardour3 directory.
65  * I can't figure out why, so this will do for now (just stole the
66  * default from configuration_vars.h).  0 is not a good value for
67  * allocating buffer sizes..
68  */
69 ARDOUR::nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
70
71 PBD::Signal0<void>                Diskstream::DiskOverrun;
72 PBD::Signal0<void>                Diskstream::DiskUnderrun;
73
74 Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
75         : SessionObject(sess, name)
76         , i_am_the_modifier (0)
77         , _track (0)
78         , _record_enabled (0)
79         , _visible_speed (1.0f)
80         , _actual_speed (1.0f)
81         , _buffer_reallocation_required (false)
82         , _seek_required (false)
83         , force_refill (false)
84         , capture_start_frame (0)
85         , capture_captured (0)
86         , was_recording (false)
87         , adjust_capture_position (0)
88         , _capture_offset (0)
89         , _roll_delay (0)
90         , first_recordable_frame (max_frames)
91         , last_recordable_frame (max_frames)
92         , last_possibly_recording (0)
93         , _alignment_style (ExistingMaterial)
94         , _scrubbing (false)
95         , _slaved (false)
96         , loop_location (0)
97         , overwrite_frame (0)
98         , overwrite_offset (0)
99         , _pending_overwrite (false)
100         , overwrite_queued (false)
101         , wrap_buffer_size (0)
102         , speed_buffer_size (0)
103         , _speed (1.0)
104         , _target_speed (_speed)
105         , file_frame (0)
106         , playback_sample (0)
107         , playback_distance (0)
108         , _read_data_count (0)
109         , _write_data_count (0)
110         , in_set_state (false)
111         , _persistent_alignment_style (ExistingMaterial)
112         , first_input_change (true)
113         , scrub_start (0)
114         , scrub_buffer_size (0)
115         , scrub_offset (0)
116         , _flags (flag)
117
118 {
119 }
120
121 Diskstream::Diskstream (Session& sess, const XMLNode& /*node*/)
122         : SessionObject(sess, "unnamed diskstream")
123         , i_am_the_modifier (0)
124         , _track (0)
125         , _record_enabled (0)
126         , _visible_speed (1.0f)
127         , _actual_speed (1.0f)
128         , _buffer_reallocation_required (false)
129         , _seek_required (false)
130         , force_refill (false)
131         , capture_start_frame (0)
132         , capture_captured (0)
133         , was_recording (false)
134         , adjust_capture_position (0)
135         , _capture_offset (0)
136         , _roll_delay (0)
137         , first_recordable_frame (max_frames)
138         , last_recordable_frame (max_frames)
139         , last_possibly_recording (0)
140         , _alignment_style (ExistingMaterial)
141         , _scrubbing (false)
142         , _slaved (false)
143         , loop_location (0)
144         , overwrite_frame (0)
145         , overwrite_offset (0)
146         , _pending_overwrite (false)
147         , overwrite_queued (false)
148         , wrap_buffer_size (0)
149         , speed_buffer_size (0)
150         , _speed (1.0)
151         , _target_speed (_speed)
152         , file_frame (0)
153         , playback_sample (0)
154         , playback_distance (0)
155         , _read_data_count (0)
156         , _write_data_count (0)
157         , in_set_state (false)
158         , _persistent_alignment_style (ExistingMaterial)
159         , first_input_change (true)
160         , scrub_start (0)
161         , scrub_buffer_size (0)
162         , scrub_offset (0)
163         , _flags (Recordable)
164 {
165 }
166
167 Diskstream::~Diskstream ()
168 {
169         DEBUG_TRACE (DEBUG::Destruction, string_compose ("Diskstream %1 deleted\n", _name));
170
171         if (_playlist) {
172                 _playlist->release ();
173         }
174 }
175
176 void
177 Diskstream::set_track (Track* t)
178 {
179         _track = t;
180         _io = _track->input();
181
182         ic_connection.disconnect();
183         _io->changed.connect_same_thread (ic_connection, boost::bind (&Diskstream::handle_input_change, this, _1, _2));
184
185         input_change_pending = IOChange::ConfigurationChanged;
186         non_realtime_input_change ();
187         set_align_style_from_io ();
188
189         _track->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this));
190 }
191
192 void
193 Diskstream::handle_input_change (IOChange change, void * /*src*/)
194 {
195         Glib::Mutex::Lock lm (state_lock);
196
197         if (!(input_change_pending.type & change.type)) {
198                 input_change_pending.type = IOChange::Type (input_change_pending.type | change.type);
199                 _session.request_input_change_handling ();
200         }
201 }
202
203 void
204 Diskstream::non_realtime_set_speed ()
205 {
206         if (_buffer_reallocation_required)
207         {
208                 Glib::Mutex::Lock lm (state_lock);
209                 allocate_temporary_buffers ();
210
211                 _buffer_reallocation_required = false;
212         }
213
214         if (_seek_required) {
215                 if (speed() != 1.0f || speed() != -1.0f) {
216                         seek ((nframes_t) (_session.transport_frame() * (double) speed()), true);
217                 }
218                 else {
219                         seek (_session.transport_frame(), true);
220                 }
221
222                 _seek_required = false;
223         }
224 }
225
226 bool
227 Diskstream::realtime_set_speed (double sp, bool global)
228 {
229         bool changed = false;
230         double new_speed = sp * _session.transport_speed();
231
232         if (_visible_speed != sp) {
233                 _visible_speed = sp;
234                 changed = true;
235         }
236
237         if (new_speed != _actual_speed) {
238
239                 nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() *
240                                                                             fabs (new_speed)) + 1;
241
242                 if (required_wrap_size > wrap_buffer_size) {
243                         _buffer_reallocation_required = true;
244                 }
245
246                 _actual_speed = new_speed;
247                 _target_speed = fabs(_actual_speed);
248         }
249
250         if (changed) {
251                 if (!global) {
252                         _seek_required = true;
253                 }
254                 SpeedChanged (); /* EMIT SIGNAL */
255         }
256
257         return _buffer_reallocation_required || _seek_required;
258 }
259
260 void
261 Diskstream::set_capture_offset ()
262 {
263         if (_io == 0) {
264                 /* can't capture, so forget it */
265                 return;
266         }
267
268         _capture_offset = _io->latency();
269 }
270
271 void
272 Diskstream::set_align_style (AlignStyle a)
273 {
274         if (record_enabled() && _session.actively_recording()) {
275                 return;
276         }
277
278         if (a != _alignment_style) {
279                 _alignment_style = a;
280                 AlignmentStyleChanged ();
281         }
282 }
283
284 int
285 Diskstream::set_loop (Location *location)
286 {
287         if (location) {
288                 if (location->start() >= location->end()) {
289                         error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
290                         return -1;
291                 }
292         }
293
294         loop_location = location;
295
296          LoopSet (location); /* EMIT SIGNAL */
297         return 0;
298 }
299
300 ARDOUR::nframes_t
301 Diskstream::get_capture_start_frame (uint32_t n)
302 {
303         Glib::Mutex::Lock lm (capture_info_lock);
304
305         if (capture_info.size() > n) {
306                 return capture_info[n]->start;
307         }
308         else {
309                 return capture_start_frame;
310         }
311 }
312
313 ARDOUR::nframes_t
314 Diskstream::get_captured_frames (uint32_t n)
315 {
316         Glib::Mutex::Lock lm (capture_info_lock);
317
318         if (capture_info.size() > n) {
319                 return capture_info[n]->frames;
320         }
321         else {  
322                 return capture_captured;
323         }
324 }
325
326 void
327 Diskstream::set_roll_delay (ARDOUR::nframes_t nframes)
328 {
329         _roll_delay = nframes;
330 }
331
332 int
333 Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
334 {
335         if (!playlist) {
336                 return 0;
337         }
338
339         bool prior_playlist = false;
340
341         {
342                 Glib::Mutex::Lock lm (state_lock);
343
344                 if (playlist == _playlist) {
345                         return 0;
346                 }
347
348                 playlist_connections.drop_connections ();
349
350                 if (_playlist) {
351                         _playlist->release();
352                         prior_playlist = true;
353                 }
354
355                 _playlist = playlist;
356                 _playlist->use();
357
358                 if (!in_set_state && recordable()) {
359                         reset_write_sources (false);
360                 }
361
362                 _playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this));
363                 _playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist)));
364                 _playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_ranges_moved, this, _1, _2));
365         }
366
367         /* don't do this if we've already asked for it *or* if we are setting up
368            the diskstream for the very first time - the input changed handling will
369            take care of the buffer refill.
370         */
371
372         if (!overwrite_queued && prior_playlist) {
373                 _session.request_overwrite_buffer (_track);
374                 overwrite_queued = true;
375         }
376
377         PlaylistChanged (); /* EMIT SIGNAL */
378         _session.set_dirty ();
379
380         return 0;
381 }
382
383 void
384 Diskstream::playlist_changed (const PropertyChange&)
385 {
386         playlist_modified ();
387 }
388
389 void
390 Diskstream::playlist_modified ()
391 {
392         if (!i_am_the_modifier && !overwrite_queued) {
393                 _session.request_overwrite_buffer (_track);
394                 overwrite_queued = true;
395         }
396 }
397
398 void
399 Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl)
400 {
401         boost::shared_ptr<Playlist> pl (wpl.lock());
402
403         if (pl == _playlist) {
404
405                 /* this catches an ordering issue with session destruction. playlists
406                    are destroyed before diskstreams. we have to invalidate any handles
407                    we have to the playlist.
408                 */
409
410                 if (_playlist) {
411                         _playlist.reset ();
412                 }
413         }
414 }
415
416 bool
417 Diskstream::set_name (const string& str)
418 {
419         if (_name != str) {
420                 assert(playlist());
421                 playlist()->set_name (str);
422
423                 SessionObject::set_name(str);
424
425                 if (!in_set_state && recordable()) {
426                         /* rename existing capture files so that they have the correct name */
427                         return rename_write_sources ();
428                 } else {
429                         return false;
430                 }
431         }
432
433         return true;
434 }
435
436 void
437 Diskstream::playlist_ranges_moved (list< Evoral::RangeMove<framepos_t> > const & movements_frames, bool from_undo)
438 {
439         /* If we're coming from an undo, it will have handled
440            automation undo (it must, since automation-follows-regions
441            can lose automation data).  Hence we can do nothing here.
442         */
443         
444         if (from_undo) {
445                 return;
446         }
447         
448         if (!_track || Config->get_automation_follows_regions () == false) {
449                 return;
450         }
451
452         list< Evoral::RangeMove<double> > movements;
453
454         for (list< Evoral::RangeMove<framepos_t> >::const_iterator i = movements_frames.begin();
455              i != movements_frames.end();
456              ++i) {
457
458                 movements.push_back(Evoral::RangeMove<double>(i->from, i->length, i->to));
459         }
460
461         /* move panner automation */
462         boost::shared_ptr<Panner> p = _track->main_outs()->panner ();
463         if (p) {
464                 for (uint32_t i = 0; i < p->npanners (); ++i) {
465                         boost::shared_ptr<AutomationList> pan_alist = p->streampanner(i).pan_control()->alist();
466                         XMLNode & before = pan_alist->get_state ();
467                         bool const things_moved = pan_alist->move_ranges (movements);
468                         if (things_moved) {
469                                 _session.add_command (new MementoCommand<AutomationList> (
470                                                               *pan_alist.get(), &before, &pan_alist->get_state ()));
471                         }
472                 }
473         }
474
475         /* move processor automation */
476         _track->foreach_processor (boost::bind (&Diskstream::move_processor_automation, this, _1, movements_frames));
477 }
478
479 void
480 Diskstream::move_processor_automation (boost::weak_ptr<Processor> p, list< Evoral::RangeMove<framepos_t> > const & movements_frames)
481 {
482         boost::shared_ptr<Processor> processor (p.lock ());
483         if (!processor) {
484                 return;
485         }
486
487         list< Evoral::RangeMove<double> > movements;
488         for (list< Evoral::RangeMove<framepos_t> >::const_iterator i = movements_frames.begin(); i != movements_frames.end(); ++i) {
489                 movements.push_back(Evoral::RangeMove<double>(i->from, i->length, i->to));
490         }
491
492         set<Evoral::Parameter> const a = processor->what_can_be_automated ();
493
494         for (set<Evoral::Parameter>::iterator i = a.begin (); i != a.end (); ++i) {
495                 boost::shared_ptr<AutomationList> al = processor->automation_control(*i)->alist();
496                 XMLNode & before = al->get_state ();
497                 bool const things_moved = al->move_ranges (movements);
498                 if (things_moved) {
499                         _session.add_command (
500                                 new MementoCommand<AutomationList> (
501                                         *al.get(), &before, &al->get_state ()
502                                         )
503                                 );
504                 }
505         }
506 }
507
508 void
509 Diskstream::check_record_status (nframes_t transport_frame, nframes_t /*nframes*/, bool can_record)
510 {
511         int possibly_recording;
512         int rolling;
513         int change;
514         const int transport_rolling = 0x4;
515         const int track_rec_enabled = 0x2;
516         const int global_rec_enabled = 0x1;
517         const int fully_rec_enabled = (transport_rolling|track_rec_enabled|global_rec_enabled);
518
519         /* merge together the 3 factors that affect record status, and compute
520            what has changed.
521         */
522
523         rolling = _session.transport_speed() != 0.0f;
524         possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
525         change = possibly_recording ^ last_possibly_recording;
526
527         if (possibly_recording == last_possibly_recording) {
528                 return;
529         }
530         if (possibly_recording == fully_rec_enabled) {
531
532                 if (last_possibly_recording == fully_rec_enabled) {
533                         return;
534                 }
535
536                 /* we transitioned to recording. lets see if its transport based or a punch */
537                 
538                 first_recordable_frame = transport_frame + _capture_offset;
539                 last_recordable_frame = max_frames;
540                 capture_start_frame = transport_frame;
541
542                 if (change & transport_rolling) {
543
544                         /* transport-change (started rolling) */
545                         
546                         if (_alignment_style == ExistingMaterial) {
547                                 
548                                 /* there are two delays happening:
549                                    
550                                    1) inbound, represented by _capture_offset
551                                    2) outbound, represented by _session.worst_output_latency()
552
553                                    the first sample to record occurs when the larger of these
554                                    two has elapsed, since they occur in parallel.
555
556                                    since we've already added _capture_offset, just add the
557                                    difference if _session.worst_output_latency() is larger.
558                                 */
559
560                                 if (_capture_offset < _session.worst_output_latency()) {
561                                         first_recordable_frame += (_session.worst_output_latency() - _capture_offset);
562                                 } 
563                         } else {
564                                 first_recordable_frame += _roll_delay;
565                         }
566                         
567                 } else {
568
569                         /* punch in */
570
571                         if (_alignment_style == ExistingMaterial) {
572
573                                 /* There are two kinds of punch:
574                                    
575                                    manual punch in happens at the correct transport frame
576                                    because the user hit a button. but to get alignment correct 
577                                    we have to back up the position of the new region to the 
578                                    appropriate spot given the roll delay.
579
580                                    autopunch toggles recording at the precise
581                                    transport frame, and then the DS waits
582                                    to start recording for a time that depends
583                                    on the output latency.
584
585                                    XXX: BUT THIS CODE DOESN'T DIFFERENTIATE !!!
586
587                                 */
588
589                                 if (_capture_offset < _session.worst_output_latency()) {
590                                         /* see comment in ExistingMaterial block above */
591                                         first_recordable_frame += (_session.worst_output_latency() - _capture_offset);
592                                 }
593
594                         } else {
595                                 capture_start_frame -= _roll_delay;
596                         }
597                 }
598                 
599                 prepare_record_status (capture_start_frame);
600
601         } else {
602
603                 if (last_possibly_recording == fully_rec_enabled) {
604
605                         /* we were recording last time */
606                         
607                         if (change & transport_rolling) {
608                                 /* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop() */
609                                 
610                         } else {
611                                 /* punch out */
612                                 
613                                 last_recordable_frame = transport_frame + _capture_offset;
614                                 
615                                 if (_alignment_style == ExistingMaterial) {
616                                         if (_session.worst_output_latency() > _capture_offset) {
617                                                 last_recordable_frame += (_session.worst_output_latency() - _capture_offset);
618                                         }
619                                 } else {
620                                         last_recordable_frame += _roll_delay;
621                                 }
622                         }
623                 }
624         }
625
626         last_possibly_recording = possibly_recording;
627 }
628
629 void
630 Diskstream::route_going_away ()
631 {
632         _io.reset ();
633 }
634
635 void
636 Diskstream::calculate_record_range(OverlapType ot, sframes_t transport_frame, nframes_t nframes,
637                                    nframes_t& rec_nframes, nframes_t& rec_offset)
638 {
639         switch (ot) {
640         case OverlapNone:
641                 rec_nframes = 0;
642                 break;
643
644         case OverlapInternal:
645                 /*     ----------    recrange
646                          |---|       transrange
647                 */
648                 rec_nframes = nframes;
649                 rec_offset = 0;
650                 break;
651
652         case OverlapStart:
653                 /*    |--------|    recrange
654                 -----|          transrange
655                 */
656                 rec_nframes = transport_frame + nframes - first_recordable_frame;
657                 if (rec_nframes) {
658                         rec_offset = first_recordable_frame - transport_frame;
659                 }
660                 break;
661
662         case OverlapEnd:
663                 /*    |--------|    recrange
664                          |--------  transrange
665                 */
666                 rec_nframes = last_recordable_frame - transport_frame;
667                 rec_offset = 0;
668                 break;
669
670         case OverlapExternal:
671                 /*    |--------|    recrange
672                     --------------  transrange
673                 */
674                 rec_nframes = last_recordable_frame - first_recordable_frame;
675                 rec_offset = first_recordable_frame - transport_frame;
676                 break;
677         }
678 }
679
680 void
681 Diskstream::prepare_to_stop (framepos_t pos)
682 {
683         last_recordable_frame = pos + _capture_offset;
684 }