RCU-ification of AudioEngine port list, and DiskStreams. not well tested, but basical...
[ardour.git] / libs / ardour / session_process.cc
1 /*
2     Copyright (C) 1999-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
21 #include <cmath>
22 #include <cerrno>
23 #include <algorithm>
24 #include <unistd.h>
25
26 #include <pbd/error.h>
27  
28 #include <glibmm/thread.h>
29
30 #include <ardour/ardour.h>
31 #include <ardour/session.h>
32 #include <ardour/timestamps.h>
33 #include <ardour/audio_diskstream.h>
34 #include <ardour/audioengine.h>
35 #include <ardour/slave.h>
36 #include <ardour/auditioner.h>
37 #include <ardour/cycles.h>
38 #include <ardour/cycle_timer.h>
39
40 #include "i18n.h"
41
42 using namespace ARDOUR;
43 using namespace PBD;
44 using namespace std;
45
46 void
47 Session::process (jack_nframes_t nframes)
48 {
49         if (synced_to_jack() && waiting_to_start) {
50                 if ( _engine.transport_state() == AudioEngine::TransportRolling) {
51                         actually_start_transport ();
52                 }
53         }
54
55         if (non_realtime_work_pending()) {
56                 if (g_atomic_int_get (&butler_should_do_transport_work) == 0) {
57                         post_transport ();
58                 } 
59         } 
60         
61         (this->*process_function) (nframes);
62
63         SendFeedback (); /* EMIT SIGNAL */
64 }
65
66 void
67 Session::prepare_diskstreams ()
68 {
69         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
70         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
71                 (*i)->prepare ();
72         }
73 }
74
75 int
76 Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
77 {
78         jack_nframes_t end_frame = _transport_frame + nframes;
79         int ret = 0;
80         bool declick = get_transport_declick_required();
81         boost::shared_ptr<RouteList> r = routes.reader ();
82
83         if (_click_io) {
84                 _click_io->silence (nframes, offset);
85         }
86
87         if (g_atomic_int_get (&processing_prohibited)) {
88                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
89                         (*i)->silence (nframes, offset);
90                 }
91                 return 0;
92         }
93
94         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
95                 
96                 if ((*i)->hidden()) {
97                         continue;
98                 }
99                 
100                 (*i)->set_pending_declick (declick);
101                 
102                 if ((*i)->no_roll (nframes, _transport_frame, end_frame, offset, non_realtime_work_pending(), 
103                                    actively_recording(), declick)) {
104                         error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
105                         ret = -1;
106                         break;
107                 }
108         }
109
110         return ret;
111 }
112
113 int
114 Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
115 {
116         bool record_active;
117         int  declick = get_transport_declick_required();
118         bool rec_monitors = get_rec_monitors_input();
119         boost::shared_ptr<RouteList> r = routes.reader ();
120
121         if (transport_sub_state & StopPendingCapture) {
122                 /* force a declick out */
123                 declick = -1;
124         }
125
126         record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
127
128         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
129
130                 int ret;
131
132                 if ((*i)->hidden()) {
133                         continue;
134                 }
135
136                 (*i)->set_pending_declick (declick);
137
138                 if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
139
140                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
141                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
142                            call path, so make sure we release any outstanding locks here before we return failure.
143                         */
144
145                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
146                         for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
147                                 (*ids)->recover ();
148                         }
149
150                         stop_transport ();
151                         return -1;
152                 } 
153         }
154
155         return 0;
156 }
157
158 int
159 Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
160 {
161         bool record_active = actively_recording();
162         int  declick = get_transport_declick_required();
163         bool rec_monitors = get_rec_monitors_input();
164         boost::shared_ptr<RouteList> r = routes.reader ();
165
166         if (transport_sub_state & StopPendingCapture) {
167                 /* force a declick out */
168                 declick = -1;
169         }
170
171         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
172
173                 int ret;
174
175                 if ((*i)->hidden()) {
176                         continue;
177                 }
178
179                 if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
180                         
181                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
182                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
183                            call path, so make sure we release any outstanding locks here before we return failure.
184                         */
185
186                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
187                         for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
188                                 (*ids)->recover ();
189                         }
190
191                         stop_transport ();
192                         return -1;
193                 } 
194         }
195
196         return 0;
197 }
198
199 void
200 Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
201 {
202         int dret;
203         float pworst = 1.0f;
204         float cworst = 1.0f;
205
206         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
207         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
208
209                 if ((*i)->hidden()) {
210                         continue;
211                 }
212                 
213                 /* force all diskstreams not handled by a Route to call do their stuff.
214                  */
215
216                 if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {
217                         if ((*i)->commit (nframes)) {
218                                 needs_butler = true;
219                         }
220
221                 } else if (dret < 0) {
222                         (*i)->recover();
223                 }
224                 
225                 pworst = min (pworst, (*i)->playback_buffer_load());
226                 cworst = min (cworst, (*i)->capture_buffer_load());
227         }
228
229         uint32_t pmin = g_atomic_int_get (&_playback_load);
230         uint32_t pminold = g_atomic_int_get (&_playback_load_min);
231         uint32_t cmin = g_atomic_int_get (&_capture_load);
232         uint32_t cminold = g_atomic_int_get (&_capture_load_min);
233
234         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
235         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
236         g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
237         g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
238
239         if (actively_recording()) {
240                 set_dirty();
241         }
242 }
243
244 void
245 Session::process_with_events (jack_nframes_t nframes)
246 {
247         Event* ev;
248         jack_nframes_t this_nframes;
249         jack_nframes_t end_frame;
250         jack_nframes_t offset;
251         bool session_needs_butler = false;
252         jack_nframes_t stop_limit;
253         long           frames_moved;
254
255         /* make sure the auditioner is silent */
256
257         if (auditioner) {
258                 auditioner->silence (nframes, 0);
259         }
260
261         /* handle any pending events */
262
263         while (pending_events.read (&ev, 1) == 1) {
264                 merge_event (ev);
265         }
266
267         /* if we are not in the middle of a state change,
268            and there are immediate events queued up,
269            process them. 
270         */
271
272         while (!non_realtime_work_pending() && !immediate_events.empty()) {
273                 Event *ev = immediate_events.front ();
274                 immediate_events.pop_front ();
275                 process_event (ev);
276         }
277
278         if (!process_can_proceed()) {
279                 no_roll (nframes, 0);
280                 return;
281         }
282                 
283         if (events.empty() || next_event == events.end()) {
284                 process_without_events (nframes);
285                 return;
286         }
287
288         end_frame = _transport_frame + nframes;
289
290         {
291                 Event* this_event;
292                 Events::iterator the_next_one;
293                 
294                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
295                         no_roll (nframes, 0);
296                         return;
297                 }
298                 
299                 if (!_exporting && _slave) {
300                         if (!follow_slave (nframes, 0)) {
301                                 return;
302                         }
303                 } 
304
305                 if (_transport_speed == 0) {
306                         no_roll (nframes, 0);
307                         return;
308                 }
309
310                 if (actively_recording()) {
311                         stop_limit = max_frames;
312                 } else {
313
314                         if (Config->get_stop_at_session_end()) {
315                                 stop_limit = current_end_frame();
316                         } else {
317                                 stop_limit = max_frames;
318                         }
319                 }
320
321                 if (maybe_stop (stop_limit)) {
322                         no_roll (nframes, 0);
323                         return;
324                 } 
325
326                 this_event = *next_event;
327                 the_next_one = next_event;
328                 ++the_next_one;
329
330                 offset = 0;
331
332                 while (nframes) {
333
334                         if (this_event == 0 || this_event->action_frame > end_frame || this_event->action_frame < _transport_frame) {
335
336                                 this_nframes = nframes;
337                                 
338                         } else {
339                                 
340                                 /* compute nframes to next event */
341
342                                 if (this_event->action_frame < end_frame) {
343                                         this_nframes = nframes - (end_frame - this_event->action_frame);
344                                 } else {
345                                         this_nframes = nframes;
346                                 }
347                         }
348
349                         if (this_nframes) {
350                                 
351                                 click (_transport_frame, nframes, offset);
352                                 
353                                 /* now process frames between now and the first event in this block */
354                                 prepare_diskstreams ();
355
356                                 if (process_routes (this_nframes, offset)) {
357                                         no_roll (nframes, 0);
358                                         return;
359                                 }
360                                 
361                                 commit_diskstreams (this_nframes, session_needs_butler);
362
363                                 nframes -= this_nframes;
364                                 offset += this_nframes;
365                                 
366                                 frames_moved = (jack_nframes_t) floor (_transport_speed * this_nframes);
367                         
368                                 if (frames_moved < 0) {
369                                         decrement_transport_position (-frames_moved);
370                                 } else {
371                                         increment_transport_position (frames_moved);
372                                 }
373
374                                 maybe_stop (stop_limit);
375                                 check_declick_out ();
376                         }
377
378                         /* now handle this event and all others scheduled for the same time */
379                         
380                         while (this_event && this_event->action_frame == _transport_frame) {
381                                 process_event (this_event);
382
383                                 if (the_next_one == events.end()) {
384                                         this_event = 0;
385                                 } else {
386                                         this_event = *the_next_one;
387                                         ++the_next_one;
388                                 }
389                         } 
390
391                         /* if an event left our state changing, do the right thing */
392
393                         if (non_realtime_work_pending()) {
394                                 no_roll (nframes, offset);
395                                 break;
396                         }
397
398                         /* this is necessary to handle the case of seamless looping */
399                         /* not sure if it will work in conjuction with varispeed */
400                         end_frame = _transport_frame + nframes;
401                         
402                 }
403
404                 set_next_event ();
405
406         } /* implicit release of route lock */
407
408
409         if (session_needs_butler) {
410                 summon_butler ();
411         } 
412         
413         if (!_engine.freewheeling() && send_mtc) {
414                 send_midi_time_code_in_another_thread ();
415         }
416
417         return;
418 }               
419
420 void
421 Session::reset_slave_state ()
422 {
423         average_slave_delta = 1800;
424         delta_accumulator_cnt = 0;
425         have_first_delta_accumulator = false;
426         slave_state = Stopped;
427 }
428
429 bool
430 Session::transport_locked () const
431 {
432         Slave* sl = _slave;
433
434         if (!locate_pending() && ((_slave_type == None) || (sl && sl->ok() && sl->locked()))) {
435                 return true;
436         }
437
438         return false;
439 }
440
441 bool
442 Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
443 {
444         float slave_speed;
445         jack_nframes_t slave_transport_frame;
446         jack_nframes_t this_delta;
447         int dir;
448         bool starting;
449
450         if (!_slave->ok()) {
451                 stop_transport ();
452                 set_slave_source (None, 0);
453                 goto noroll;
454         }
455         
456         _slave->speed_and_position (slave_speed, slave_transport_frame);
457
458         if (!_slave->locked()) {
459                 goto noroll;
460         }
461
462         if (slave_transport_frame > _transport_frame) {
463                 this_delta = slave_transport_frame - _transport_frame;
464                 dir = 1;
465         } else {
466                 this_delta = _transport_frame - slave_transport_frame;
467                 dir = -1;
468         }
469
470         if ((starting = _slave->starting())) {
471                 slave_speed = 0.0f;
472         }
473
474 #if 0
475         cerr << "delta = " << (int) (dir * this_delta)
476              << " speed = " << slave_speed 
477              << " ts = " << _transport_speed 
478              << " M@"<< slave_transport_frame << " S@" << _transport_frame 
479              << " avgdelta = " << average_slave_delta 
480              << endl;
481 #endif  
482
483         if (Config->get_timecode_source_is_synced()) {
484
485                 /* if the TC source is synced, then we assume that its 
486                    speed is binary: 0.0 or 1.0
487                 */
488
489                 if (slave_speed != 0.0f) {
490                         slave_speed = 1.0f;
491                 } 
492
493         } else {
494
495                 /* TC source is able to drift relative to us (slave)
496                    so we need to keep track of the drift and adjust
497                    our speed to remain locked.
498                 */
499
500                 if (delta_accumulator_cnt >= delta_accumulator_size) {
501                         have_first_delta_accumulator = true;
502                         delta_accumulator_cnt = 0;
503                 }
504
505                 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
506                         delta_accumulator[delta_accumulator_cnt++] = dir*this_delta;
507                 }
508                 
509                 if (have_first_delta_accumulator) {
510                         average_slave_delta = 0;
511                         for (int i = 0; i < delta_accumulator_size; ++i) {
512                                 average_slave_delta += delta_accumulator[i];
513                         }
514                         average_slave_delta /= delta_accumulator_size;
515                         if (average_slave_delta < 0) {
516                                 average_dir = -1;
517                                 average_slave_delta = -average_slave_delta;
518                         } else {
519                                 average_dir = 1;
520                         }
521                         // cerr << "avgdelta = " << average_slave_delta*average_dir << endl;
522                 }
523         }
524
525         if (slave_speed != 0.0f) {
526
527                 /* slave is running */
528
529                 switch (slave_state) {
530                 case Stopped:
531                         if (_slave->requires_seekahead()) {
532                                 slave_wait_end = slave_transport_frame + _current_frame_rate;
533                                 locate (slave_wait_end, false, false);
534                                 slave_state = Waiting;
535                                 starting = true;
536
537                         } else {
538
539                                 slave_state = Running;
540
541                                 Location* al = _locations.auto_loop_location();
542
543                                 if (al && auto_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
544                                         // cancel looping
545                                         request_auto_loop(false);
546                                 }
547
548                                 if (slave_transport_frame != _transport_frame) {
549                                         locate (slave_transport_frame, false, false);
550                                 }
551                         }
552                         break;
553
554                 case Waiting:
555                         break;
556
557                 default:
558                         break;
559
560                 }
561
562                 if (slave_state == Waiting) {
563
564                         // cerr << "waiting at " << slave_transport_frame << endl;
565                         
566                         if (slave_transport_frame >= slave_wait_end) {
567                                 // cerr << "\tstart at " << _transport_frame << endl;
568
569                                 slave_state = Running;
570
571                                 bool ok = true;
572                                 jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
573
574                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
575                                 
576                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
577                                         if (!(*i)->can_internal_playback_seek (frame_delta)) {
578                                                 ok = false;
579                                                 break;
580                                         }
581                                 }
582
583                                 if (ok) {
584                                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
585                                                 (*i)->internal_playback_seek (frame_delta);
586                                         }
587                                         _transport_frame += frame_delta;
588                                        
589                                 } else {
590                                         // cerr << "cannot micro-seek\n";
591                                         /* XXX what? */
592                                 }
593
594                                 memset (delta_accumulator, 0, sizeof (jack_nframes_t) * delta_accumulator_size);
595                                 average_slave_delta = 0;
596                                 this_delta = 0;
597                         }
598                 }
599                 
600                 if (slave_state == Running && _transport_speed == 0.0f) {
601                         
602                         // cerr << "slave starts transport\n";
603                         
604                         start_transport ();
605                 } 
606
607         } else {
608
609                 /* slave has stopped */
610
611                 if (_transport_speed != 0.0f) {
612
613                         // cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame 
614                         // << " tf = " << _transport_frame
615                         // << endl;
616                         
617                         if (_slave_type == JACK) {
618                                 last_stop_frame = _transport_frame;
619                         }
620
621                         stop_transport();
622                 }
623
624                 if (slave_transport_frame != _transport_frame) {
625                         // cerr << "slave stopped, move to " << slave_transport_frame << endl;
626                         force_locate (slave_transport_frame, false);
627                 }
628
629                 slave_state = Stopped;
630         }
631
632         if (slave_state == Running && !Config->get_timecode_source_is_synced()) {
633
634
635                 if (_transport_speed != 0.0f) {
636                         
637                         /* 
638                            note that average_dir is +1 or -1 
639                         */
640                         
641                         const float adjust_seconds = 1.0f;
642                         float delta;
643
644                         //if (average_slave_delta == 0) {
645                                 delta = this_delta;
646                                 delta *= dir;
647 //                      } else {
648 //                              delta = average_slave_delta;
649 //                              delta *= average_dir;
650 //                      }
651
652                         float adjusted_speed = slave_speed +
653                                 (delta / (adjust_seconds * _current_frame_rate));
654                         
655                         // cerr << "adjust using " << delta
656                         // << " towards " << adjusted_speed
657                         // << " ratio = " << adjusted_speed / slave_speed
658                         // << " current = " << _transport_speed
659                         // << " slave @ " << slave_speed
660                         // << endl;
661                         
662                         request_transport_speed (adjusted_speed);
663                         
664 #if 1
665                         if ((jack_nframes_t) average_slave_delta > _slave->resolution()) {
666                                 // cerr << "not locked\n";
667                                 goto silent_motion;
668                         }
669 #endif
670                 }
671         } 
672
673         if (!starting && !non_realtime_work_pending()) {
674                 /* speed is set, we're locked, and good to go */
675                 return true;
676         }
677
678   silent_motion:
679
680         if (slave_speed && _transport_speed) {
681
682                 /* something isn't right, but we should move with the master
683                    for now.
684                 */
685
686                 bool need_butler;
687                 
688                 prepare_diskstreams ();
689                 silent_process_routes (nframes, offset);
690                 commit_diskstreams (nframes, need_butler);
691
692                 if (need_butler) {
693                         summon_butler ();
694                 }
695                 
696                 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
697                 
698                 if (frames_moved < 0) {
699                         decrement_transport_position (-frames_moved);
700                 } else {
701                         increment_transport_position (frames_moved);
702                 }
703                 
704                 jack_nframes_t stop_limit;
705                 
706                 if (actively_recording()) {
707                         stop_limit = max_frames;
708                 } else {
709                         if (Config->get_stop_at_session_end()) {
710                                 stop_limit = current_end_frame();
711                         } else {
712                                 stop_limit = max_frames;
713                         }
714                 }
715
716                 maybe_stop (stop_limit);
717         }
718
719   noroll:
720         /* don't move at all */
721         no_roll (nframes, 0);
722         return false;
723 }
724
725 void
726 Session::process_without_events (jack_nframes_t nframes)
727 {
728         bool session_needs_butler = false;
729         jack_nframes_t stop_limit;
730         long frames_moved;
731         
732         {
733                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
734                         no_roll (nframes, 0);
735                         return;
736                 }
737
738                 if (!_exporting && _slave) {
739                         if (!follow_slave (nframes, 0)) {
740                                 return;
741                         }
742                 } 
743
744                 if (_transport_speed == 0) {
745                         no_roll (nframes, 0);
746                         return;
747                 }
748                 
749                 if (actively_recording()) {
750                         stop_limit = max_frames;
751                 } else {
752                         if (Config->get_stop_at_session_end()) {
753                                 stop_limit = current_end_frame();
754                         } else {
755                                 stop_limit = max_frames;
756                         }
757                 }
758                 
759                 if (maybe_stop (stop_limit)) {
760                         no_roll (nframes, 0);
761                         return;
762                 } 
763
764                 click (_transport_frame, nframes, 0);
765
766                 prepare_diskstreams ();
767         
768                 frames_moved = (long) floor (_transport_speed * nframes);
769
770                 if (process_routes (nframes, 0)) {
771                         no_roll (nframes, 0);
772                         return;
773                 }
774
775                 commit_diskstreams (nframes, session_needs_butler);
776
777                 if (frames_moved < 0) {
778                         decrement_transport_position (-frames_moved);
779                 } else {
780                         increment_transport_position (frames_moved);
781                 }
782                 
783                 maybe_stop (stop_limit);
784                 check_declick_out ();
785
786         } /* implicit release of route lock */
787
788         if (session_needs_butler) {
789                 summon_butler ();
790         } 
791         
792         if (!_engine.freewheeling() && send_mtc) {
793                 send_midi_time_code_in_another_thread ();
794         }
795
796         return;
797 }               
798
799 void
800 Session::process_audition (jack_nframes_t nframes)
801 {
802         Event* ev;
803         boost::shared_ptr<RouteList> r = routes.reader ();
804
805         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
806                 if (!(*i)->hidden()) {
807                         (*i)->silence (nframes, 0);
808                 }
809         }
810
811         /* run the auditioner, and if it says we need butler service, ask for it */
812         
813         if (auditioner->play_audition (nframes) > 0) {
814                 summon_butler ();
815         } 
816
817         /* handle pending events */
818
819         while (pending_events.read (&ev, 1) == 1) {
820                 merge_event (ev);
821         }
822
823         /* if we are not in the middle of a state change,
824            and there are immediate events queued up,
825            process them. 
826         */
827
828         while (!non_realtime_work_pending() && !immediate_events.empty()) {
829                 Event *ev = immediate_events.front ();
830                 immediate_events.pop_front ();
831                 process_event (ev);
832         }
833
834         if (!auditioner->active()) {
835                 process_function = &Session::process_with_events;
836         }
837 }
838