updated .po files (*not* translations, just .po files)
[ardour.git] / libs / ardour / session_process.cc
index 329bb62174f30592be99ca6fe3b0537e73a52d58..b18e00f9fd7f1271805428f44c857bfd0b68dfd8 100644 (file)
 #include <glibmm/thread.h>
 
 #include "ardour/ardour.h"
-#include "ardour/audio_diskstream.h"
 #include "ardour/audioengine.h"
 #include "ardour/auditioner.h"
 #include "ardour/butler.h"
 #include "ardour/debug.h"
+#include "ardour/process_thread.h"
 #include "ardour/session.h"
 #include "ardour/slave.h"
 #include "ardour/timestamps.h"
+#include "ardour/graph.h"
+#include "ardour/audio_port.h"
 
 #include "midi++/manager.h"
+#include "midi++/mmc.h"
 
 #include "i18n.h"
 
@@ -51,10 +54,6 @@ using namespace std;
 void
 Session::process (nframes_t nframes)
 {
-       // This is no more the appropriate place to call cycle
-       // start. cycle_start needs to be called at the Route::roll()
-       // where the signals which we want to mixdown have been calculated.
-       //
        MIDI::Manager::instance()->cycle_start(nframes);
 
        _silent = false;
@@ -70,8 +69,12 @@ Session::process (nframes_t nframes)
                }
        }
 
+        _engine.main_thread()->get_buffers ();
+
        (this->*process_function) (nframes);
 
+        _engine.main_thread()->drop_buffers ();
+
        // the ticker is for sending time information like MidiClock
        nframes_t transport_frames = transport_frame();
        BBT_Time  transport_bbt;
@@ -85,15 +88,6 @@ Session::process (nframes_t nframes)
        MIDI::Manager::instance()->cycle_end();
 }
 
-void
-Session::prepare_diskstreams ()
-{
-       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-               (*i)->prepare ();
-       }
-}
-
 int
 Session::fail_roll (nframes_t nframes)
 {
@@ -112,6 +106,8 @@ Session::no_roll (nframes_t nframes)
                _click_io->silence (nframes);
        }
 
+       route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
+        /*
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
                if ((*i)->is_hidden()) {
@@ -127,12 +123,13 @@ Session::no_roll (nframes_t nframes)
                        break;
                }
        }
+        */
 
        return ret;
 }
 
 int
-Session::process_routes (nframes_t nframes)
+Session::process_routes (nframes_t nframes, bool& need_butler)
 {
        bool record_active;
        int  declick = get_transport_declick_required();
@@ -149,6 +146,8 @@ Session::process_routes (nframes_t nframes)
        const nframes_t start_frame = _transport_frame;
        const nframes_t end_frame = _transport_frame + (nframes_t)floor(nframes * _transport_speed);
 
+       route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
+/*
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
                int ret;
@@ -159,28 +158,17 @@ Session::process_routes (nframes_t nframes)
 
                (*i)->set_pending_declick (declick);
 
-               if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors)) < 0) {
-
-                       /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
-                          and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
-                          call path, so make sure we release any outstanding locks here before we return failure.
-                       */
-
-                       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-                       for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
-                               (*ids)->recover ();
-                       }
-
+               if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
                        stop_transport ();
                        return -1;
                }
        }
-
+*/
        return 0;
 }
 
 int
-Session::silent_process_routes (nframes_t nframes)
+Session::silent_process_routes (nframes_t nframes, bool& need_butler)
 {
        bool record_active = actively_recording();
        int  declick = get_transport_declick_required();
@@ -195,6 +183,8 @@ Session::silent_process_routes (nframes_t nframes)
        const nframes_t start_frame = _transport_frame;
        const nframes_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
 
+       route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
+/*
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
                int ret;
@@ -203,68 +193,36 @@ Session::silent_process_routes (nframes_t nframes)
                        continue;
                }
 
-               if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors)) < 0) {
-
-                       /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
-                          and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
-                          call path, so make sure we release any outstanding locks here before we return failure.
-                       */
-
-                       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-                       for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
-                               (*ids)->recover ();
-                       }
-
+               if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
                        stop_transport ();
                        return -1;
                }
        }
-
+*/
        return 0;
 }
 
 void
-Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
+Session::get_track_statistics ()
 {
-       int dret;
        float pworst = 1.0f;
        float cworst = 1.0f;
 
-       boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-
-               if ((*i)->hidden()) {
-                       continue;
-               }
-
-               /* force all diskstreams not handled by a Route to call do their stuff.
-                  Note: the diskstreams that were handled by a route will just return zero
-                  from this call, because they know they were processed. So in fact, this
-                  also runs commit() for every diskstream.
-                */
+       boost::shared_ptr<RouteList> rl = routes.reader();
+       for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
 
-               if ((dret = (*i)->process (_transport_frame, nframes, actively_recording(), get_rec_monitors_input())) == 0) {
-                       if ((*i)->commit (nframes)) {
-                               needs_butler = true;
-                       }
+               boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
 
-               } else if (dret < 0) {
-                       (*i)->recover();
+               if (!tr || tr->hidden()) {
+                       continue;
                }
 
-               pworst = min (pworst, (*i)->playback_buffer_load());
-               cworst = min (cworst, (*i)->capture_buffer_load());
+               pworst = min (pworst, tr->playback_buffer_load());
+               cworst = min (cworst, tr->capture_buffer_load());
        }
 
-       uint32_t pmin = g_atomic_int_get (&_playback_load);
-       uint32_t pminold = g_atomic_int_get (&_playback_load_min);
-       uint32_t cmin = g_atomic_int_get (&_capture_load);
-       uint32_t cminold = g_atomic_int_get (&_capture_load_min);
-
        g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
        g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
-       g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
-       g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
 
        if (actively_recording()) {
                set_dirty();
@@ -275,12 +233,12 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
 void
 Session::process_with_events (nframes_t nframes)
 {
-       SessionEvent*         ev;
+       SessionEvent*  ev;
        nframes_t      this_nframes;
-       nframes_t      end_frame;
+       framepos_t     end_frame;
        bool           session_needs_butler = false;
-       nframes_t      stop_limit;
-       long           frames_moved;
+       framepos_t     stop_limit;
+       framecnt_t     frames_moved;
 
        /* make sure the auditioner is silent */
 
@@ -310,8 +268,7 @@ Session::process_with_events (nframes_t nframes)
         * on locates (and allow slow slaves to position and prepare for rolling)
         */
        if (_send_timecode_update) {
-               send_full_time_code(nframes);
-               deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
+               send_full_time_code (_transport_frame);
        }
 
        if (!process_can_proceed()) {
@@ -325,11 +282,11 @@ Session::process_with_events (nframes_t nframes)
        }
 
        if (_transport_speed == 1.0) {
-               frames_moved = (long) nframes;
+               frames_moved = (framecnt_t) nframes;
        } else {
                interpolation.set_target_speed (fabs(_target_transport_speed));
                interpolation.set_speed (fabs(_transport_speed));
-               frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
+               frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
        }
 
        end_frame = _transport_frame + (nframes_t)frames_moved;
@@ -354,18 +311,18 @@ Session::process_with_events (nframes_t nframes)
                        return;
                }
 
-               if (!_exporting) {
+               if (!_exporting && !timecode_transmission_suspended()) {
                        send_midi_time_code_for_cycle (nframes);
                }
 
                if (actively_recording()) {
-                       stop_limit = max_frames;
+                       stop_limit = max_framepos;
                } else {
 
                        if (Config->get_stop_at_session_end()) {
                                stop_limit = current_end_frame();
                        } else {
-                               stop_limit = max_frames;
+                               stop_limit = max_framepos;
                        }
                }
 
@@ -385,12 +342,12 @@ Session::process_with_events (nframes_t nframes)
                while (nframes) {
 
                        this_nframes = nframes; /* real (jack) time relative */
-                       frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */
+                       frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
 
                        /* running an event, position transport precisely to its time */
                        if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
                                /* this isn't quite right for reverse play */
-                               frames_moved = (long) (this_event->action_frame - _transport_frame);
+                               frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
                                this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) );
                        }
 
@@ -398,15 +355,12 @@ Session::process_with_events (nframes_t nframes)
 
                                click (_transport_frame, this_nframes);
 
-                               /* now process frames between now and the first event in this block */
-                               prepare_diskstreams ();
-
-                               if (process_routes (this_nframes)) {
+                               if (process_routes (this_nframes, session_needs_butler)) {
                                        fail_roll (nframes);
                                        return;
                                }
 
-                               commit_diskstreams (this_nframes, session_needs_butler);
+                               get_track_statistics ();
 
                                nframes -= this_nframes;
 
@@ -481,7 +435,7 @@ bool
 Session::follow_slave (nframes_t nframes)
 {
        double slave_speed;
-       nframes64_t slave_transport_frame;
+       framepos_t slave_transport_frame;
        nframes_t this_delta;
        int dir;
 
@@ -572,6 +526,7 @@ Session::follow_slave (nframes_t nframes)
                        
                        if (_slave->give_slave_full_control_over_transport_speed()) {
                                set_transport_speed (slave_speed, false, false);
+                               //std::cout << "set speed = " << slave_speed << "\n";
                        } else {
                                float adjusted_speed = slave_speed + (1.5 * (delta /  float(_current_frame_rate)));
                                request_transport_speed (adjusted_speed);
@@ -580,10 +535,12 @@ Session::follow_slave (nframes_t nframes)
                                                                           slave_speed));
                        }
                        
-                       if (abs(average_slave_delta) > _slave->resolution()) {
+#if 1
+                       if ((nframes_t) abs(average_slave_delta) > _slave->resolution()) {
                                cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
                                goto silent_motion;
                        }
+#endif
                }
        }
 
@@ -613,7 +570,7 @@ Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
        }
 
        if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
-               delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta);
+               delta_accumulator[delta_accumulator_cnt++] = (nframes_t) dir *  (nframes_t) this_delta;
        }
 
        if (have_first_delta_accumulator) {
@@ -621,7 +578,7 @@ Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
                for (int i = 0; i < delta_accumulator_size; ++i) {
                        average_slave_delta += delta_accumulator[i];
                }
-               average_slave_delta /= long(delta_accumulator_size);
+               average_slave_delta /= (int32_t) delta_accumulator_size;
                if (average_slave_delta < 0L) {
                        average_dir = -1;
                        average_slave_delta = abs(average_slave_delta);
@@ -651,7 +608,7 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
 
                                _slave_state = Running;
 
-                               Location* al = _locations.auto_loop_location();
+                               Location* al = _locations->auto_loop_location();
 
                                if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
                                        // cancel looping
@@ -687,18 +644,21 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
                                bool ok = true;
                                nframes_t frame_delta = slave_transport_frame - _transport_frame;
 
-                               boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
-
-                               for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-                                       if (!(*i)->can_internal_playback_seek (frame_delta)) {
+                               boost::shared_ptr<RouteList> rl = routes.reader();
+                               for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+                                       boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+                                       if (tr && !tr->can_internal_playback_seek (frame_delta)) {
                                                ok = false;
                                                break;
                                        }
                                }
 
                                if (ok) {
-                                       for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-                                               (*i)->internal_playback_seek (frame_delta);
+                                       for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+                                               boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
+                                               if (tr) {
+                                                       tr->internal_playback_seek (frame_delta);
+                                               }
                                        }
                                        _transport_frame += frame_delta;
 
@@ -707,7 +667,7 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
                                        /* XXX what? */
                                }
 
-                               memset (delta_accumulator, 0, sizeof (long) * delta_accumulator_size);
+                               memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
                                average_slave_delta = 0L;
                                this_delta = 0;
                        }
@@ -747,9 +707,9 @@ Session::follow_slave_silently (nframes_t nframes, float slave_speed)
 
                bool need_butler;
 
-               prepare_diskstreams ();
-               silent_process_routes (nframes);
-               commit_diskstreams (nframes, need_butler);
+               silent_process_routes (nframes, need_butler);
+
+               get_track_statistics ();
 
                if (need_butler) {
                        _butler->summon ();
@@ -762,16 +722,16 @@ Session::follow_slave_silently (nframes_t nframes, float slave_speed)
                } else {
                        increment_transport_position (frames_moved);
                }
-
-               nframes_t stop_limit;
+                
+               framepos_t stop_limit;
 
                if (actively_recording()) {
-                       stop_limit = max_frames;
+                       stop_limit = max_framepos;
                } else {
                        if (Config->get_stop_at_session_end()) {
                                stop_limit = current_end_frame();
                        } else {
-                               stop_limit = max_frames;
+                               stop_limit = max_framepos;
                        }
                }
 
@@ -783,8 +743,8 @@ void
 Session::process_without_events (nframes_t nframes)
 {
        bool session_needs_butler = false;
-       nframes_t stop_limit;
-       long frames_moved;
+       framepos_t stop_limit;
+       framecnt_t frames_moved;
 
        if (!process_can_proceed()) {
                _silent = true;
@@ -802,17 +762,17 @@ Session::process_without_events (nframes_t nframes)
                return;
        }
 
-       if (!_exporting) {
+       if (!_exporting && !timecode_transmission_suspended()) {
                send_midi_time_code_for_cycle (nframes);
        }
 
        if (actively_recording()) {
-               stop_limit = max_frames;
+               stop_limit = max_framepos;
        } else {
                if (Config->get_stop_at_session_end()) {
                        stop_limit = current_end_frame();
                } else {
-                       stop_limit = max_frames;
+                       stop_limit = max_framepos;
                }
        }
 
@@ -827,22 +787,20 @@ Session::process_without_events (nframes_t nframes)
 
        click (_transport_frame, nframes);
 
-       prepare_diskstreams ();
-
        if (_transport_speed == 1.0) {
-               frames_moved = (long) nframes;
+               frames_moved = (framecnt_t) nframes;
        } else {
                interpolation.set_target_speed (fabs(_target_transport_speed));
                interpolation.set_speed (fabs(_transport_speed));
-               frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
+               frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
        }
 
-       if (process_routes (nframes)) {
+       if (process_routes (nframes, session_needs_butler)) {
                fail_roll (nframes);
                return;
        }
 
-       commit_diskstreams (nframes, session_needs_butler);
+       get_track_statistics ();
 
        if (frames_moved < 0) {
                decrement_transport_position (-frames_moved);
@@ -879,6 +837,12 @@ Session::process_audition (nframes_t nframes)
                _butler->summon ();
        }
 
+        /* if using a monitor section, run it because otherwise we don't hear anything */
+
+        if (auditioner->needs_monitor()) {
+                _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
+        }
+        
        /* handle pending events */
 
        while (pending_events.read (&ev, 1) == 1) {
@@ -896,7 +860,7 @@ Session::process_audition (nframes_t nframes)
                process_event (ev);
        }
 
-       if (!auditioner->active()) {
+       if (!auditioner->auditioning()) {
                /* auditioner no longer active, so go back to the normal process callback */
                process_function = &Session::process_with_events;
        }
@@ -920,7 +884,7 @@ Session::maybe_sync_start (nframes_t& nframes)
 
                no_roll (sync_offset);
                nframes -= sync_offset;
-               Port::increment_port_offset (sync_offset);
+               AudioPort::increment_port_offset (sync_offset);
                waiting_for_sync_offset = false;
 
                if (nframes == 0) {
@@ -983,18 +947,6 @@ Session::set_next_event ()
        }
 }
 
-void
-Session::cleanup_event (SessionEvent* ev, int status)
-{
-       switch (ev->type) {
-       case SessionEvent::SetRecordEnable:
-               delete ev->routes;
-               break;
-       default:
-               break;
-       }
-}
-
 void
 Session::process_event (SessionEvent* ev)
 {
@@ -1108,11 +1060,11 @@ Session::process_event (SessionEvent* ev)
                break;
 
        case SessionEvent::Overwrite:
-               overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
+               overwrite_some_buffers (static_cast<Track*>(ev->ptr));
                break;
 
-       case SessionEvent::SetDiskstreamSpeed:
-               set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
+       case SessionEvent::SetTrackSpeed:
+               set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
                break;
 
        case SessionEvent::SetSyncSource:
@@ -1134,8 +1086,21 @@ Session::process_event (SessionEvent* ev)
                set_play_range (ev->audio_range, (ev->speed == 1.0f));
                break;
 
-       case SessionEvent::SetRecordEnable:
-               do_record_enable_change_all (ev->routes, ev->yes_or_no);
+       case SessionEvent::RealTimeOperation:
+               process_rtop (ev);
+               del = false; // other side of RT request needs to clean up
+               break;
+
+        case SessionEvent::AdjustPlaybackBuffering:
+                schedule_playback_buffering_adjustment ();
+                break;
+
+        case SessionEvent::AdjustCaptureBuffering:
+                schedule_capture_buffering_adjustment ();
+                break;
+
+       case SessionEvent::SetTimecodeTransmission:
+               g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
                break;
 
        default:
@@ -1148,9 +1113,8 @@ Session::process_event (SessionEvent* ev)
                del = del && !_remove_event (ev);
        }
 
-       ev->Complete (ev, 0); /* EMIT SIGNAL */
-
        if (del) {
                delete ev;
        }
 }
+