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