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