various "deep" fixes related to looping, particularly seamless, and transport state
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 4 Nov 2009 21:18:37 +0000 (21:18 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 4 Nov 2009 21:18:37 +0000 (21:18 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@6013 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour_ui.cc
libs/ardour/ardour/session.h
libs/ardour/audio_diskstream.cc
libs/ardour/session_events.cc
libs/ardour/session_transport.cc

index e56e4ebd691f3cb6a2e0a2384b04a142a4988fd3..4bbd7c54293d112244acf5d207820970962755dc 100644 (file)
@@ -1472,7 +1472,14 @@ ARDOUR_UI::transport_roll ()
        bool rolling = session->transport_rolling();
 
        if (session->get_play_loop()) {
-               session->request_play_loop (false, true);
+               /* XXX it is not possible to just leave seamless loop and keep
+                  playing at present (nov 4th 2009
+               */
+               if (!Config->get_seamless_loop()) {
+                       session->request_play_loop (false, true);
+               } else {
+                       return;
+               }
        } else if (session->get_play_range ()) {
                session->request_play_range (false, true);
        } 
index f1ba58dfe28b7e195e5e65d49dee09af53d7e8c1..2b44eb5ac241cd6c9663dee0173ab48fced3a5b3 100644 (file)
@@ -1452,8 +1452,8 @@ class Session : public PBD::StatefulDestructible
        void overwrite_some_buffers (Diskstream*);
        void flush_all_redirects ();
        int  micro_locate (nframes_t distance);
-       void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
-       void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
+       void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
+       void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
        void force_locate (nframes_t frame, bool with_roll = false);
        void set_diskstream_speed (Diskstream*, float speed);
        void set_transport_speed (float speed, bool abort = false);
index 494f95b1744156abf57be1e5a6032380b588fc08..0f8df820bf897018228549d042903fd8cf88c550 100644 (file)
@@ -985,7 +985,7 @@ AudioDiskstream::seek (nframes_t frame, bool complete_refill)
                (*chan)->playback_buf->reset ();
                (*chan)->capture_buf->reset ();
        }
-       
+
        /* can't rec-enable in destructive mode if transport is before start */
        
        if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
@@ -994,7 +994,7 @@ AudioDiskstream::seek (nframes_t frame, bool complete_refill)
        
        playback_sample = frame;
        file_frame = frame;
-       
+
        if (complete_refill) {
                while ((ret = do_refill_with_alloc ()) > 0) ;
        } else {
index d818b0b2548631756eaf3c977b4ac4692c844ce8..14d53fe4ad36eebeabc3dc59a4d09a499d71ae8f 100644 (file)
@@ -322,7 +322,7 @@ Session::process_event (Event* ev)
 
        case Event::AutoLoop:
                if (play_loop) {
-                       start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
+                       start_locate (ev->target_frame, true, false, true);
                }
                remove = false;
                del = false;
index aa4db0a7b282a8da223794f5f72cccd7f4a47744..37c60b810594d7a10c0d8d5bd9b69b978f1508c5 100644 (file)
@@ -392,8 +392,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
                                /* explicit return request pre-queued in event list. overrides everything else */
                                
-                               cerr << "explicit auto-return to " << _requested_return_frame << endl;
-
                                _transport_frame = _requested_return_frame;
                                do_locate = true;
 
@@ -455,7 +453,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
        /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
 
-
        for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
                if (!(*i)->hidden()) {
                        if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
@@ -623,13 +620,15 @@ Session::set_play_loop (bool yn)
                        Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
                        merge_event (event);
 
-                       /* locate to start of loop and roll */
-                       event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
-                       merge_event (event);
-               }
+                       /* locate to start of loop and roll. If doing seamless loop, force a 
+                          locate+buffer refill even if we are positioned there already.
+                       */
 
+                       start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
+               }
 
        } else {
+
                unset_play_loop ();
        }
 
@@ -647,7 +646,7 @@ Session::flush_all_redirects ()
 }
 
 void
-Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
+Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
 {
        if (synced_to_jack()) {
 
@@ -672,7 +671,7 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
 
        } else {
 
-               locate (target_frame, with_roll, with_flush, with_loop);
+               locate (target_frame, with_roll, with_flush, with_loop, force);
        }
 }
 
@@ -696,13 +695,13 @@ Session::micro_locate (nframes_t distance)
 }
 
 void
-Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
+Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
 {
        if (actively_recording() && !with_loop) {
                return;
        }
 
-       if (_transport_frame == target_frame && !loop_changing && !with_loop) {
+       if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
                if (with_roll) {
                        set_transport_speed (1.0, false);
                }
@@ -724,12 +723,16 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
                } 
        }
 
+       /* stop if we are rolling and we're not doing autoplay and we don't plan to roll when done and we not looping while synced to
+          jack
+       */
+
        if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
                realtime_stop (false);
        } 
 
-       if ( !with_loop || loop_changing) {
-               
+       if (force || !with_loop || loop_changing) {
+
                post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
                
                if (with_roll) {