Remove MMC thread protection which is pointless now that only JACK MIDI ports are...
[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 */
19
20 #include <cmath>
21 #include <cerrno>
22 #include <algorithm>
23 #include <unistd.h>
24
25 #include "pbd/error.h"
26 #include "pbd/enumwriter.h"
27
28 #include <glibmm/thread.h>
29
30 #include "ardour/ardour.h"
31 #include "ardour/audioengine.h"
32 #include "ardour/auditioner.h"
33 #include "ardour/butler.h"
34 #include "ardour/debug.h"
35 #include "ardour/process_thread.h"
36 #include "ardour/session.h"
37 #include "ardour/slave.h"
38 #include "ardour/timestamps.h"
39 #include "ardour/graph.h"
40 #include "ardour/port.h"
41
42 #include "midi++/manager.h"
43 #include "midi++/mmc.h"
44
45 #include "i18n.h"
46
47 using namespace ARDOUR;
48 using namespace PBD;
49 using namespace std;
50
51 /** Called by the audio engine when there is work to be done with JACK.
52  * @param nframes Number of frames to process.
53  */
54 void
55 Session::process (nframes_t nframes)
56 {
57         MIDI::Manager::instance()->cycle_start(nframes);
58
59         _silent = false;
60
61         if (processing_blocked()) {
62                 _silent = true;
63                 return;
64         }
65
66         if (non_realtime_work_pending()) {
67                 if (!_butler->transport_work_requested ()) {
68                         post_transport ();
69                 }
70         }
71
72         _engine.main_thread()->get_buffers ();
73
74         (this->*process_function) (nframes);
75
76         _engine.main_thread()->drop_buffers ();
77
78         // the ticker is for sending time information like MidiClock
79         nframes_t transport_frames = transport_frame();
80         BBT_Time  transport_bbt;
81         bbt_time(transport_frames, transport_bbt);
82         Timecode::Time transport_timecode;
83         timecode_time(transport_frames, transport_timecode);
84         tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */
85
86         SendFeedback (); /* EMIT SIGNAL */
87
88         MIDI::Manager::instance()->cycle_end();
89 }
90
91 int
92 Session::fail_roll (nframes_t nframes)
93 {
94         return no_roll (nframes);
95 }
96
97 int
98 Session::no_roll (nframes_t nframes)
99 {
100         nframes_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
101         int ret = 0;
102         bool declick = get_transport_declick_required();
103         boost::shared_ptr<RouteList> r = routes.reader ();
104
105         if (_click_io) {
106                 _click_io->silence (nframes);
107         }
108
109         route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
110         /*
111         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
112
113                 if ((*i)->is_hidden()) {
114                         continue;
115                 }
116
117                 (*i)->set_pending_declick (declick);
118
119                 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
120                                    actively_recording(), declick)) {
121                         error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
122                         ret = -1;
123                         break;
124                 }
125         }
126         */
127
128         return ret;
129 }
130
131 int
132 Session::process_routes (nframes_t nframes, bool& need_butler)
133 {
134         bool record_active;
135         int  declick = get_transport_declick_required();
136         bool rec_monitors = get_rec_monitors_input();
137         boost::shared_ptr<RouteList> r = routes.reader ();
138
139         if (transport_sub_state & StopPendingCapture) {
140                 /* force a declick out */
141                 declick = -1;
142         }
143
144         record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
145
146         const nframes_t start_frame = _transport_frame;
147         const nframes_t end_frame = _transport_frame + (nframes_t)floor(nframes * _transport_speed);
148
149         route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
150 /*
151         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
152
153                 int ret;
154
155                 if ((*i)->is_hidden()) {
156                         continue;
157                 }
158
159                 (*i)->set_pending_declick (declick);
160
161                 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
162                         stop_transport ();
163                         return -1;
164                 }
165         }
166 */
167         return 0;
168 }
169
170 int
171 Session::silent_process_routes (nframes_t nframes, bool& need_butler)
172 {
173         bool record_active = actively_recording();
174         int  declick = get_transport_declick_required();
175         bool rec_monitors = get_rec_monitors_input();
176         boost::shared_ptr<RouteList> r = routes.reader ();
177
178         if (transport_sub_state & StopPendingCapture) {
179                 /* force a declick out */
180                 declick = -1;
181         }
182
183         const nframes_t start_frame = _transport_frame;
184         const nframes_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
185
186         route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
187 /*
188         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
189
190                 int ret;
191
192                 if ((*i)->is_hidden()) {
193                         continue;
194                 }
195
196                 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
197                         stop_transport ();
198                         return -1;
199                 }
200         }
201 */
202         return 0;
203 }
204
205 void
206 Session::get_track_statistics ()
207 {
208         float pworst = 1.0f;
209         float cworst = 1.0f;
210
211         boost::shared_ptr<RouteList> rl = routes.reader();
212         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
213
214                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
215
216                 if (!tr || tr->hidden()) {
217                         continue;
218                 }
219
220                 pworst = min (pworst, tr->playback_buffer_load());
221                 cworst = min (cworst, tr->capture_buffer_load());
222         }
223
224         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
225         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
226
227         if (actively_recording()) {
228                 set_dirty();
229         }
230 }
231
232 /** Process callback used when the auditioner is not active */
233 void
234 Session::process_with_events (nframes_t nframes)
235 {
236         SessionEvent*         ev;
237         nframes_t      this_nframes;
238         nframes_t      end_frame;
239         bool           session_needs_butler = false;
240         nframes_t      stop_limit;
241         long           frames_moved;
242
243         /* make sure the auditioner is silent */
244
245         if (auditioner) {
246                 auditioner->silence (nframes);
247         }
248
249         /* handle any pending events */
250
251         while (pending_events.read (&ev, 1) == 1) {
252                 merge_event (ev);
253         }
254
255         /* if we are not in the middle of a state change,
256            and there are immediate events queued up,
257            process them.
258         */
259
260         while (!non_realtime_work_pending() && !immediate_events.empty()) {
261                 SessionEvent *ev = immediate_events.front ();
262                 immediate_events.pop_front ();
263                 process_event (ev);
264         }
265
266         /* Events caused a transport change, send an MTC Full Frame (Timecode) message.
267          * This is sent whether rolling or not, to give slaves an idea of ardour time
268          * on locates (and allow slow slaves to position and prepare for rolling)
269          */
270         if (_send_timecode_update) {
271                 send_full_time_code(nframes);
272         }
273
274         if (!process_can_proceed()) {
275                 _silent = true;
276                 return;
277         }
278
279         if (events.empty() || next_event == events.end()) {
280                 process_without_events (nframes);
281                 return;
282         }
283
284         if (_transport_speed == 1.0) {
285                 frames_moved = (long) nframes;
286         } else {
287                 interpolation.set_target_speed (fabs(_target_transport_speed));
288                 interpolation.set_speed (fabs(_transport_speed));
289                 frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
290         }
291
292         end_frame = _transport_frame + (nframes_t)frames_moved;
293
294         {
295                 SessionEvent* this_event;
296                 Events::iterator the_next_one;
297
298                 if (!process_can_proceed()) {
299                         _silent = true;
300                         return;
301                 }
302
303                 if (!_exporting && _slave) {
304                         if (!follow_slave (nframes)) {
305                                 return;
306                         }
307                 }
308
309                 if (_transport_speed == 0) {
310                         no_roll (nframes);
311                         return;
312                 }
313
314                 if (!_exporting) {
315                         send_midi_time_code_for_cycle (nframes);
316                 }
317
318                 if (actively_recording()) {
319                         stop_limit = max_frames;
320                 } else {
321
322                         if (Config->get_stop_at_session_end()) {
323                                 stop_limit = current_end_frame();
324                         } else {
325                                 stop_limit = max_frames;
326                         }
327                 }
328
329                 if (maybe_stop (stop_limit)) {
330                         no_roll (nframes);
331                         return;
332                 }
333
334                 this_event = *next_event;
335                 the_next_one = next_event;
336                 ++the_next_one;
337
338                 /* yes folks, here it is, the actual loop where we really truly
339                    process some audio
340                 */
341
342                 while (nframes) {
343
344                         this_nframes = nframes; /* real (jack) time relative */
345                         frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */
346
347                         /* running an event, position transport precisely to its time */
348                         if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
349                                 /* this isn't quite right for reverse play */
350                                 frames_moved = (long) (this_event->action_frame - _transport_frame);
351                                 this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) );
352                         }
353
354                         if (this_nframes) {
355
356                                 click (_transport_frame, this_nframes);
357
358                                 if (process_routes (this_nframes, session_needs_butler)) {
359                                         fail_roll (nframes);
360                                         return;
361                                 }
362
363                                 get_track_statistics ();
364
365                                 nframes -= this_nframes;
366
367                                 if (frames_moved < 0) {
368                                         decrement_transport_position (-frames_moved);
369                                 } else {
370                                         increment_transport_position (frames_moved);
371                                 }
372
373                                 maybe_stop (stop_limit);
374                                 check_declick_out ();
375                         }
376
377                         _engine.split_cycle (this_nframes);
378
379                         /* now handle this event and all others scheduled for the same time */
380
381                         while (this_event && this_event->action_frame == _transport_frame) {
382                                 process_event (this_event);
383
384                                 if (the_next_one == events.end()) {
385                                         this_event = 0;
386                                 } else {
387                                         this_event = *the_next_one;
388                                         ++the_next_one;
389                                 }
390                         }
391
392                         /* if an event left our state changing, do the right thing */
393
394                         if (nframes && non_realtime_work_pending()) {
395                                 no_roll (nframes);
396                                 break;
397                         }
398
399                         /* this is necessary to handle the case of seamless looping */
400                         end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed);
401
402                 }
403
404                 set_next_event ();
405
406         } /* implicit release of route lock */
407
408         if (session_needs_butler) {
409                 _butler->summon ();
410         }
411 }
412
413 void
414 Session::reset_slave_state ()
415 {
416         average_slave_delta = 1800;
417         delta_accumulator_cnt = 0;
418         have_first_delta_accumulator = false;
419         _slave_state = Stopped;
420 }
421
422 bool
423 Session::transport_locked () const
424 {
425         Slave* sl = _slave;
426
427         if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
428                 return true;
429         }
430
431         return false;
432 }
433
434 bool
435 Session::follow_slave (nframes_t nframes)
436 {
437         double slave_speed;
438         nframes64_t slave_transport_frame;
439         nframes_t this_delta;
440         int dir;
441
442         if (!_slave->ok()) {
443                 stop_transport ();
444                 config.set_external_sync (false);
445                 goto noroll;
446         }
447
448         _slave->speed_and_position (slave_speed, slave_transport_frame);
449
450         DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
451
452         if (!_slave->locked()) {
453                 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
454                 goto noroll;
455         }
456
457         if (slave_transport_frame > _transport_frame) {
458                 this_delta = slave_transport_frame - _transport_frame;
459                 dir = 1;
460         } else {
461                 this_delta = _transport_frame - slave_transport_frame;
462                 dir = -1;
463         }
464
465         if (_slave->starting()) {
466                 slave_speed = 0.0f;
467         }
468
469         if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
470
471                 /* if the TC source is synced, then we assume that its
472                    speed is binary: 0.0 or 1.0
473                 */
474
475                 if (slave_speed != 0.0f) {
476                         slave_speed = 1.0f;
477                 }
478
479         } else {
480
481                 /* if we are chasing and the average delta between us and the
482                    master gets too big, we want to switch to silent
483                    motion. so keep track of that here.
484                 */
485
486                 if (_slave_state == Running) {
487                         calculate_moving_average_of_slave_delta(dir, this_delta);
488                 }
489         }
490
491         track_slave_state (slave_speed, slave_transport_frame, this_delta);
492
493         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
494                                                    _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
495                      
496
497         if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
498
499                 if (_transport_speed != 0.0f) {
500
501                         /*
502                            note that average_dir is +1 or -1
503                         */
504
505                         float delta;
506
507                         if (average_slave_delta == 0) {
508                                 delta = this_delta;
509                                 delta *= dir;
510                         } else {
511                                 delta = average_slave_delta;
512                                 delta *= average_dir;
513                         }
514
515 #ifndef NDEBUG
516                         if (slave_speed != 0.0) {
517                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
518                                                                            (int) (dir * this_delta),
519                                                                            slave_speed,
520                                                                            _transport_speed,
521                                                                            _transport_frame,
522                                                                            slave_transport_frame, 
523                                                                            average_slave_delta));
524                         }
525 #endif
526                         
527                         if (_slave->give_slave_full_control_over_transport_speed()) {
528                                 set_transport_speed (slave_speed, false, false);
529                                 //std::cout << "set speed = " << slave_speed << "\n";
530                         } else {
531                                 float adjusted_speed = slave_speed + (1.5 * (delta /  float(_current_frame_rate)));
532                                 request_transport_speed (adjusted_speed);
533                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
534                                                                            delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
535                                                                            slave_speed));
536                         }
537                         
538 #if 1
539                         if ((nframes_t) abs(average_slave_delta) > _slave->resolution()) {
540                                 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
541                                 goto silent_motion;
542                         }
543 #endif
544                 }
545         }
546
547
548         if (_slave_state == Running && !non_realtime_work_pending()) {
549                 /* speed is set, we're locked, and good to go */
550                 return true;
551         }
552
553   silent_motion:
554         DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
555         follow_slave_silently (nframes, slave_speed);
556
557   noroll:
558         /* don't move at all */
559         DEBUG_TRACE (DEBUG::Slave, "no roll\n")
560         no_roll (nframes);
561         return false;
562 }
563
564 void
565 Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
566 {
567         if (delta_accumulator_cnt >= delta_accumulator_size) {
568                 have_first_delta_accumulator = true;
569                 delta_accumulator_cnt = 0;
570         }
571
572         if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
573                 delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta);
574         }
575
576         if (have_first_delta_accumulator) {
577                 average_slave_delta = 0L;
578                 for (int i = 0; i < delta_accumulator_size; ++i) {
579                         average_slave_delta += delta_accumulator[i];
580                 }
581                 average_slave_delta /= long(delta_accumulator_size);
582                 if (average_slave_delta < 0L) {
583                         average_dir = -1;
584                         average_slave_delta = abs(average_slave_delta);
585                 } else {
586                         average_dir = 1;
587                 }
588         }
589 }
590
591 void
592 Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame, nframes_t this_delta)
593 {
594         if (slave_speed != 0.0f) {
595
596                 /* slave is running */
597
598                 switch (_slave_state) {
599                 case Stopped:
600                         if (_slave->requires_seekahead()) {
601                                 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
602                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
603                                 /* we can call locate() here because we are in process context */
604                                 locate (slave_wait_end, false, false);
605                                 _slave_state = Waiting;
606
607                         } else {
608
609                                 _slave_state = Running;
610
611                                 Location* al = _locations.auto_loop_location();
612
613                                 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
614                                         // cancel looping
615                                         request_play_loop(false);
616                                 }
617
618                                 if (slave_transport_frame != _transport_frame) {
619                                         locate (slave_transport_frame, false, false);
620                                 }
621                         }
622                         break;
623
624                 case Waiting:
625                 default:
626                         break;
627                 }
628
629                 if (_slave_state == Waiting) {
630
631                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
632
633                         if (slave_transport_frame >= slave_wait_end) {
634
635                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
636
637                                 _slave_state = Running;
638
639                                 /* now perform a "micro-seek" within the disk buffers to realign ourselves
640                                    precisely with the master.
641                                 */
642
643
644                                 bool ok = true;
645                                 nframes_t frame_delta = slave_transport_frame - _transport_frame;
646
647                                 boost::shared_ptr<RouteList> rl = routes.reader();
648                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
649                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
650                                         if (tr && !tr->can_internal_playback_seek (frame_delta)) {
651                                                 ok = false;
652                                                 break;
653                                         }
654                                 }
655
656                                 if (ok) {
657                                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
658                                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
659                                                 if (tr) {
660                                                         tr->internal_playback_seek (frame_delta);
661                                                 }
662                                         }
663                                         _transport_frame += frame_delta;
664
665                                 } else {
666                                         cerr << "cannot micro-seek\n";
667                                         /* XXX what? */
668                                 }
669
670                                 memset (delta_accumulator, 0, sizeof (long) * delta_accumulator_size);
671                                 average_slave_delta = 0L;
672                                 this_delta = 0;
673                         }
674                 }
675
676                 if (_slave_state == Running && _transport_speed == 0.0f) {
677                         DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
678                         start_transport ();
679                 }
680
681         } else { // slave_speed is 0
682
683                 /* slave has stopped */
684
685                 if (_transport_speed != 0.0f) {
686                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
687                         stop_transport();
688                 }
689
690                 if (slave_transport_frame != _transport_frame) {
691                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
692                         force_locate (slave_transport_frame, false);
693                 }
694
695                 _slave_state = Stopped;
696         }
697 }
698
699 void
700 Session::follow_slave_silently (nframes_t nframes, float slave_speed)
701 {
702         if (slave_speed && _transport_speed) {
703
704                 /* something isn't right, but we should move with the master
705                    for now.
706                 */
707
708                 bool need_butler;
709
710                 silent_process_routes (nframes, need_butler);
711
712                 get_track_statistics ();
713
714                 if (need_butler) {
715                         _butler->summon ();
716                 }
717
718                 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
719
720                 if (frames_moved < 0) {
721                         decrement_transport_position (-frames_moved);
722                 } else {
723                         increment_transport_position (frames_moved);
724                 }
725
726                 nframes_t stop_limit;
727
728                 if (actively_recording()) {
729                         stop_limit = max_frames;
730                 } else {
731                         if (Config->get_stop_at_session_end()) {
732                                 stop_limit = current_end_frame();
733                         } else {
734                                 stop_limit = max_frames;
735                         }
736                 }
737
738                 maybe_stop (stop_limit);
739         }
740 }
741
742 void
743 Session::process_without_events (nframes_t nframes)
744 {
745         bool session_needs_butler = false;
746         nframes_t stop_limit;
747         long frames_moved;
748
749         if (!process_can_proceed()) {
750                 _silent = true;
751                 return;
752         }
753
754         if (!_exporting && _slave) {
755                 if (!follow_slave (nframes)) {
756                         return;
757                 }
758         }
759
760         if (_transport_speed == 0) {
761                 fail_roll (nframes);
762                 return;
763         }
764
765         if (!_exporting) {
766                 send_midi_time_code_for_cycle (nframes);
767         }
768
769         if (actively_recording()) {
770                 stop_limit = max_frames;
771         } else {
772                 if (Config->get_stop_at_session_end()) {
773                         stop_limit = current_end_frame();
774                 } else {
775                         stop_limit = max_frames;
776                 }
777         }
778
779         if (maybe_stop (stop_limit)) {
780                 fail_roll (nframes);
781                 return;
782         }
783
784         if (maybe_sync_start (nframes)) {
785                 return;
786         }
787
788         click (_transport_frame, nframes);
789
790         if (_transport_speed == 1.0) {
791                 frames_moved = (long) nframes;
792         } else {
793                 interpolation.set_target_speed (fabs(_target_transport_speed));
794                 interpolation.set_speed (fabs(_transport_speed));
795                 frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
796         }
797
798         if (process_routes (nframes, session_needs_butler)) {
799                 fail_roll (nframes);
800                 return;
801         }
802
803         get_track_statistics ();
804
805         if (frames_moved < 0) {
806                 decrement_transport_position (-frames_moved);
807         } else {
808                 increment_transport_position (frames_moved);
809         }
810
811         maybe_stop (stop_limit);
812         check_declick_out ();
813
814         if (session_needs_butler) {
815                 _butler->summon ();
816         }
817 }
818
819 /** Process callback used when the auditioner is active.
820  * @param nframes number of frames to process.
821  */
822 void
823 Session::process_audition (nframes_t nframes)
824 {
825         SessionEvent* ev;
826         boost::shared_ptr<RouteList> r = routes.reader ();
827
828         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
829                 if (!(*i)->is_hidden()) {
830                         (*i)->silence (nframes);
831                 }
832         }
833
834         /* run the auditioner, and if it says we need butler service, ask for it */
835
836         if (auditioner->play_audition (nframes) > 0) {
837                 _butler->summon ();
838         }
839
840         /* if using a monitor section, run it because otherwise we don't hear anything */
841
842         if (auditioner->needs_monitor()) {
843                 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
844         }
845         
846         /* handle pending events */
847
848         while (pending_events.read (&ev, 1) == 1) {
849                 merge_event (ev);
850         }
851
852         /* if we are not in the middle of a state change,
853            and there are immediate events queued up,
854            process them.
855         */
856
857         while (!non_realtime_work_pending() && !immediate_events.empty()) {
858                 SessionEvent *ev = immediate_events.front ();
859                 immediate_events.pop_front ();
860                 process_event (ev);
861         }
862
863         if (!auditioner->auditioning()) {
864                 /* auditioner no longer active, so go back to the normal process callback */
865                 process_function = &Session::process_with_events;
866         }
867 }
868
869 bool
870 Session::maybe_sync_start (nframes_t& nframes)
871 {
872         nframes_t sync_offset;
873
874         if (!waiting_for_sync_offset) {
875                 return false;
876         }
877
878         if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
879
880                 /* generate silence up to the sync point, then
881                    adjust nframes + offset to reflect whatever
882                    is left to do.
883                 */
884
885                 no_roll (sync_offset);
886                 nframes -= sync_offset;
887                 Port::increment_port_offset (sync_offset);
888                 waiting_for_sync_offset = false;
889
890                 if (nframes == 0) {
891                         return true; // done, nothing left to process
892                 }
893
894         } else {
895
896                 /* sync offset point is not within this process()
897                    cycle, so just generate silence. and don't bother
898                    with any fancy stuff here, just the minimal silence.
899                 */
900
901                 _silent = true;
902
903                 if (Config->get_locate_while_waiting_for_sync()) {
904                         if (micro_locate (nframes)) {
905                                 /* XXX ERROR !!! XXX */
906                         }
907                 }
908
909                 return true; // done, nothing left to process
910         }
911
912         return false;
913 }
914
915 void
916 Session::queue_event (SessionEvent* ev)
917 {
918         if (_state_of_the_state & Deletion) {
919                 return;
920         } else if (_state_of_the_state & Loading) {
921                 merge_event (ev);
922         } else {
923                 pending_events.write (&ev, 1);
924         }
925 }
926
927 void
928 Session::set_next_event ()
929 {
930         if (events.empty()) {
931                 next_event = events.end();
932                 return;
933         }
934
935         if (next_event == events.end()) {
936                 next_event = events.begin();
937         }
938
939         if ((*next_event)->action_frame > _transport_frame) {
940                 next_event = events.begin();
941         }
942
943         for (; next_event != events.end(); ++next_event) {
944                 if ((*next_event)->action_frame >= _transport_frame) {
945                         break;
946                 }
947         }
948 }
949
950 void
951 Session::process_event (SessionEvent* ev)
952 {
953         bool remove = true;
954         bool del = true;
955
956         /* if we're in the middle of a state change (i.e. waiting
957            for the butler thread to complete the non-realtime
958            part of the change), we'll just have to queue this
959            event for a time when the change is complete.
960         */
961
962         if (non_realtime_work_pending()) {
963
964                 /* except locates, which we have the capability to handle */
965
966                 if (ev->type != SessionEvent::Locate) {
967                         immediate_events.insert (immediate_events.end(), ev);
968                         _remove_event (ev);
969                         return;
970                 }
971         }
972
973         DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
974
975         switch (ev->type) {
976         case SessionEvent::SetLoop:
977                 set_play_loop (ev->yes_or_no);
978                 break;
979
980         case SessionEvent::AutoLoop:
981                 if (play_loop) {
982                         start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
983                 }
984                 remove = false;
985                 del = false;
986                 break;
987
988         case SessionEvent::Locate:
989                 if (ev->yes_or_no) {
990                         // cerr << "forced locate to " << ev->target_frame << endl;
991                         locate (ev->target_frame, false, true, false);
992                 } else {
993                         // cerr << "soft locate to " << ev->target_frame << endl;
994                         start_locate (ev->target_frame, false, true, false);
995                 }
996                 _send_timecode_update = true;
997                 break;
998
999         case SessionEvent::LocateRoll:
1000                 if (ev->yes_or_no) {
1001                         // cerr << "forced locate to+roll " << ev->target_frame << endl;
1002                         locate (ev->target_frame, true, true, false);
1003                 } else {
1004                         // cerr << "soft locate to+roll " << ev->target_frame << endl;
1005                         start_locate (ev->target_frame, true, true, false);
1006                 }
1007                 _send_timecode_update = true;
1008                 break;
1009
1010         case SessionEvent::LocateRollLocate:
1011                 // locate is handled by ::request_roll_at_and_return()
1012                 _requested_return_frame = ev->target_frame;
1013                 request_locate (ev->target2_frame, true);
1014                 break;
1015
1016
1017         case SessionEvent::SetTransportSpeed:
1018                 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1019                 break;
1020
1021         case SessionEvent::PunchIn:
1022                 // cerr << "PunchIN at " << transport_frame() << endl;
1023                 if (config.get_punch_in() && record_status() == Enabled) {
1024                         enable_record ();
1025                 }
1026                 remove = false;
1027                 del = false;
1028                 break;
1029
1030         case SessionEvent::PunchOut:
1031                 // cerr << "PunchOUT at " << transport_frame() << endl;
1032                 if (config.get_punch_out()) {
1033                         step_back_from_record ();
1034                 }
1035                 remove = false;
1036                 del = false;
1037                 break;
1038
1039         case SessionEvent::StopOnce:
1040                 if (!non_realtime_work_pending()) {
1041                         stop_transport (ev->yes_or_no);
1042                         _clear_event_type (SessionEvent::StopOnce);
1043                 }
1044                 remove = false;
1045                 del = false;
1046                 break;
1047
1048         case SessionEvent::RangeStop:
1049                 if (!non_realtime_work_pending()) {
1050                         stop_transport (ev->yes_or_no);
1051                 }
1052                 remove = false;
1053                 del = false;
1054                 break;
1055
1056         case SessionEvent::RangeLocate:
1057                 start_locate (ev->target_frame, true, true, false);
1058                 remove = false;
1059                 del = false;
1060                 break;
1061
1062         case SessionEvent::Overwrite:
1063                 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1064                 break;
1065
1066         case SessionEvent::SetTrackSpeed:
1067                 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1068                 break;
1069
1070         case SessionEvent::SetSyncSource:
1071                 use_sync_source (ev->slave);
1072                 break;
1073
1074         case SessionEvent::Audition:
1075                 set_audition (ev->region);
1076                 // drop reference to region
1077                 ev->region.reset ();
1078                 break;
1079
1080         case SessionEvent::InputConfigurationChange:
1081                 add_post_transport_work (PostTransportInputChange);
1082                 _butler->schedule_transport_work ();
1083                 break;
1084
1085         case SessionEvent::SetPlayAudioRange:
1086                 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1087                 break;
1088
1089         case SessionEvent::RealTimeOperation:
1090                 process_rtop (ev);
1091                 del = false; // other side of RT request needs to clean up
1092                 break;
1093
1094         case SessionEvent::AdjustPlaybackBuffering:
1095                 schedule_playback_buffering_adjustment ();
1096                 break;
1097
1098         case SessionEvent::AdjustCaptureBuffering:
1099                 schedule_capture_buffering_adjustment ();
1100                 break;
1101
1102         default:
1103           fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1104                 /*NOTREACHED*/
1105                 break;
1106         };
1107
1108         if (remove) {
1109                 del = del && !_remove_event (ev);
1110         }
1111
1112         if (del) {
1113                 delete ev;
1114         }
1115 }
1116