diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-10-30 18:14:25 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-10-30 18:14:25 +0000 |
commit | e98b3c1ec65f173f357f9b6747d11174e2743cd6 (patch) | |
tree | 43e209e88951691811a3371091950952d4ecbaf7 | |
parent | c83e48e07a0b4790512c6251d8ad8f941c881021 (diff) |
make 3.0 catch up with transport and other changes in 2.X (hand applied, not merged)
git-svn-id: svn://localhost/ardour2/branches/3.0@5989 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | ardour.rc.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour.menus.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 162 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui2.cc | 60 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_dialogs.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_options.cc | 16 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 32 | ||||
-rw-r--r-- | gtk2_ardour/engine_dialog.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/public_editor.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 18 | ||||
-rw-r--r-- | libs/ardour/diskstream.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session.cc | 5 | ||||
-rw-r--r-- | libs/ardour/session_events.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 3 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 143 |
18 files changed, 247 insertions, 222 deletions
diff --git a/ardour.rc.in b/ardour.rc.in index 61090589e8..ffee881be5 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -40,6 +40,7 @@ <Option name="default-narrow_ms" value="0"/> <Option name="timecode-format" value="timecode_30"/> <Option name="font-scale" value="102400"/> + <Option name="seamless-loop" value="1"/> </Config> <extra> <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/> diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index afbbf196f9..bd2c4dda62 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -43,6 +43,7 @@ <menu action="PlayMenu"> <menuitem action='play-selected-regions'/> <menuitem action='play-edit-range'/> + <menuitem action='PlaySelection'/> <menuitem action='play-from-edit-point-and-return'/> <menuitem action='Loop'/> </menu> diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 30a9d59312..8dc5680a1e 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1462,10 +1462,6 @@ ARDOUR_UI::transport_stop () return; } - if (session->get_play_loop ()) { - session->request_play_loop (false); - } - session->request_stop (); } @@ -1517,35 +1513,91 @@ ARDOUR_UI::transport_record (bool roll) //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl; } -void +void ARDOUR_UI::transport_roll () { - bool rolling; - if (!session) { return; } - rolling = session->transport_rolling (); + if (session->is_auditioning()) { + return; + } + + switch (Config->get_slave_source()) { + case None: + case JACK: + break; + default: + /* transport controlled by the master */ + return; + } - //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl; + bool rolling = session->transport_rolling(); if (session->get_play_loop()) { - session->request_play_loop (false); - auto_loop_button.set_visual_state (1); - roll_button.set_visual_state (1); + session->request_play_loop (false, true); } else if (session->get_play_range ()) { - session->request_play_range (false); - play_selection_button.set_visual_state (0); - } else if (rolling) { - session->request_locate (session->last_transport_start(), true); + session->request_play_range (false, true); + } + + if (!rolling) { + session->request_transport_speed (1.0f); } - session->request_transport_speed (1.0f); + map_transport_state (); } void -ARDOUR_UI::transport_loop() +ARDOUR_UI::toggle_roll (bool with_abort) +{ + + if (!session) { + return; + } + + if (session->is_auditioning()) { + session->cancel_audition (); + return; + } + + switch (Config->get_slave_source()) { + case None: + case JACK: + break; + default: + /* transport controlled by the master */ + return; + } + + bool rolling = session->transport_rolling(); + bool affect_transport = true; + + if (rolling) { + /* drop out of loop/range playback but leave transport rolling */ + if (session->get_play_loop()) { + affect_transport = false; + session->request_play_loop (false, true); + } else if (session->get_play_range ()) { + affect_transport = false; + session->request_play_range (false, true); + } + } + + if (affect_transport) { + + if (rolling) { + session->request_stop (with_abort); + } else { + session->request_transport_speed (1.0f); + } + } + + map_transport_state (); +} + +void +ARDOUR_UI::toggle_session_auto_loop () { if (session) { if (session->get_play_loop()) { @@ -1554,10 +1606,14 @@ ARDOUR_UI::transport_loop() if (looploc) { session->request_locate (looploc->start(), true); } + } else { + session->request_play_loop (false); + } + } else { + Location * looploc = session->locations()->auto_loop_location(); + if (looploc) { + session->request_play_loop (true); } - } - else { - session->request_play_loop (true); } } } @@ -1569,10 +1625,6 @@ ARDOUR_UI::transport_play_selection () return; } - if (!session->get_play_range()) { - session->request_stop (); - } - editor->play_selection (); } @@ -1627,6 +1679,7 @@ ARDOUR_UI::transport_forward (int option) /* speed up */ session->request_transport_speed (current_transport_speed * 1.5f); } + } } @@ -1653,25 +1706,60 @@ ARDOUR_UI::toggle_record_enable (uint32_t dstream) } void -ARDOUR_UI::queue_transport_change () -{ - Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state)); -} - -void ARDOUR_UI::map_transport_state () { + ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state)); + + if (!session) { + auto_loop_button.set_visual_state (0); + play_selection_button.set_visual_state (0); + roll_button.set_visual_state (0); + stop_button.set_visual_state (1); + return; + } + float sp = session->transport_speed(); if (sp == 1.0f) { - transport_rolling (); - } else if (sp < 0.0f) { - transport_rewinding (); - } else if (sp > 0.0f) { - transport_forwarding (); + shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ + shuttle_box.queue_draw (); + } else if (sp == 0.0f) { + shuttle_fract = 0; + shuttle_box.queue_draw (); + update_disk_space (); + } + + if (sp != 0.0) { + + if (session->get_play_range()) { + + play_selection_button.set_visual_state (1); + roll_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); + + } else if (session->get_play_loop ()) { + + auto_loop_button.set_visual_state (1); + play_selection_button.set_visual_state (0); + roll_button.set_visual_state (0); + + } else { + + roll_button.set_visual_state (1); + play_selection_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); + } + + stop_button.set_visual_state (0); + } else { - transport_stopped (); + + stop_button.set_visual_state (1); + roll_button.set_visual_state (0); + play_selection_button.set_visual_state (0); + auto_loop_button.set_visual_state (0); } + } void diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 7253f58031..0ec3069217 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -282,7 +282,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI void update_autosave(); sigc::connection _autosave_connection; - void queue_transport_change (); void map_transport_state (); int32_t do_engine_start (); @@ -548,11 +547,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI void transport_forward (int option); void transport_rewind (int option); void transport_loop (); - - void transport_rolling (); - void transport_rewinding (); - void transport_forwarding (); - void transport_stopped (); + void toggle_roll (bool with_abort); bool _session_is_new; void connect_to_session (ARDOUR::Session *); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index 57c3df4cdf..e2f4db7e5a 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -128,66 +128,6 @@ ARDOUR_UI::display_message (const char *prefix, gint prefix_len, RefPtr<TextBuff } void -ARDOUR_UI::transport_stopped () -{ - stop_button.set_visual_state (1); - - roll_button.set_visual_state (0); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - - shuttle_fract = 0; - shuttle_box.queue_draw (); - - update_disk_space (); -} - -void -ARDOUR_UI::transport_rolling () -{ - stop_button.set_visual_state (0); - if (session->get_play_range()) { - play_selection_button.set_visual_state (1); - roll_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - - } else if (session->get_play_loop ()) { - auto_loop_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - roll_button.set_visual_state (0); - - } else { - - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); - } - - /* reset shuttle controller */ - - shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ - shuttle_box.queue_draw (); -} - -void -ARDOUR_UI::transport_rewinding () -{ - stop_button.set_visual_state (0); - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); -} - -void -ARDOUR_UI::transport_forwarding () -{ - stop_button.set_visual_state (0); - roll_button.set_visual_state (1); - play_selection_button.set_visual_state (0); - auto_loop_button.set_visual_state (0); -} - -void ARDOUR_UI::setup_transport () { transport_tearoff = manage (new TearOff (transport_tearoff_hbox)); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 486c60dbe4..cfb3d6574e 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -111,7 +111,7 @@ ARDOUR_UI::connect_to_session (Session *s) do any GUI work, just queue it for handling by the GUI thread. */ - session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change)); + session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::map_transport_state)); /* alert the user to these things happening */ @@ -149,7 +149,7 @@ ARDOUR_UI::connect_to_session (Session *s) start_clocking (); start_blinking (); - transport_stopped (); + map_transport_state (); second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000); point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index c1ffb11dc3..21a4fb5c44 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -251,10 +251,10 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - ActionManager::register_action (transport_actions, X_("ToggleRoll"), _("Start/Stop"), bind (mem_fun (*editor, &PublicEditor::toggle_playback), false)); + ActionManager::register_action (transport_actions, X_("ToggleRoll"), _("Start/Stop"), bind (mem_fun (*this, &ARDOUR_UI::toggle_roll), false)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - ActionManager::register_action (transport_actions, X_("ToggleRollForgetCapture"), _("Stop and Forget Capture"), bind (mem_fun(*editor, &PublicEditor::toggle_playback), true)); + ActionManager::register_action (transport_actions, X_("ToggleRollForgetCapture"), _("Stop and Forget Capture"), bind (mem_fun(*this, &ARDOUR_UI::toggle_roll), true)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 9370315a8f..663bb8eaff 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -108,22 +108,6 @@ ARDOUR_UI::toggle_click () } void -ARDOUR_UI::toggle_session_auto_loop () -{ - if (session) { - if (session->get_play_loop()) { - if (session->transport_rolling()) { - transport_roll(); - } else { - session->request_play_loop (false); - } - } else { - session->request_play_loop (true); - } - } -} - -void ARDOUR_UI::unset_dual_punch () { Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch"); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 609a0ef6ed..8376b8cedf 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -229,7 +229,6 @@ class Editor : public PublicEditor void separate_region_from_punch (); void separate_region_from_loop (); void separate_regions_using_location (ARDOUR::Location&); - void toggle_playback (bool with_abort); void transition_to_rolling (bool forward); /* undo related */ diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 9de3d0138f..8c6da6c1de 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2368,37 +2368,6 @@ Editor::transition_to_rolling (bool fwd) } void -Editor::toggle_playback (bool with_abort) -{ - if (!session) { - return; - } - - switch (Config->get_slave_source()) { - case None: - case JACK: - break; - default: - /* transport controlled by the master */ - return; - } - - if (session->is_auditioning()) { - session->cancel_audition (); - return; - } - - if (session->transport_rolling()) { - session->request_stop (with_abort); - if (session->get_play_loop()) { - session->request_play_loop (false); - } - } else { - session->request_transport_speed (1.0f); - } -} - -void Editor::play_from_start () { session->request_locate (session->current_start_frame(), true); @@ -2638,7 +2607,6 @@ Editor::play_selected_region () } } - session->request_stop (); session->request_bounded_roll (start, end); } diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 3dbc5b5eea..05d953aeab 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -1180,8 +1180,7 @@ EngineControl::set_state (const XMLNode& root) clist = root.children(); for (citer = clist.begin(); citer != clist.end(); ++citer) { - if ( prop && (prop->value() == "FFADO" )) - continue; + child = *citer; prop = child->property ("val"); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 035d05c1af..3540af927f 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -186,7 +186,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void new_region_from_selection () = 0; virtual void separate_region_from_selection () = 0; - virtual void toggle_playback (bool with_abort) = 0; virtual void transition_to_rolling (bool fwd) = 0; virtual nframes64_t unit_to_frame (double unit) const = 0; // XXX remove me when libardour goes nframes64_t diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 8dfcf228b9..3a980982c3 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -391,7 +391,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable void request_stop (bool abort = false); void request_locate (nframes_t frame, bool with_roll = false); - void request_play_loop (bool yn); + void request_play_loop (bool yn, bool leave_rolling = false); bool get_play_loop () const { return play_loop; } nframes_t last_transport_start() const { return _last_roll_location; } @@ -917,7 +917,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable void set_audio_range (std::list<AudioRange>&); void set_music_range (std::list<MusicRange>&); - void request_play_range (bool yn); + void request_play_range (bool yn, bool leave_rolling = false); bool get_play_range () const { return _play_range; } /* buffers for gain and pan */ @@ -1117,15 +1117,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable } } - bool maybe_stop (nframes_t limit) { - if ( (_transport_speed > 0.0f && _transport_frame >= limit) - || (_transport_speed < 0.0f && _transport_frame == 0) ) { - stop_transport (); - return true; - } - return false; - } - + bool maybe_stop (nframes_t limit); bool maybe_sync_start (nframes_t&); void check_declick_out (); @@ -1369,7 +1361,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable void change_midi_ports (); int use_config_midi_ports (); - void set_play_loop (bool yn); + void set_play_loop (bool yn, bool leave_rolling); void overwrite_some_buffers (Diskstream*); void flush_all_inserts (); int micro_locate (nframes_t distance); @@ -1627,7 +1619,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable std::list<AudioRange> current_audio_range; bool _play_range; - void set_play_range (bool yn); + void set_play_range (bool yn, bool leave_rolling); void setup_auto_play (); /* main outs */ diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index aaeb15a995..0d27cb508a 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -584,6 +584,8 @@ Diskstream::check_record_status (nframes_t transport_frame, nframes_t /*nframes* } else { last_recordable_frame += _roll_delay; } + + first_recordable_frame = max_frames; } last_possibly_recording = possibly_recording; @@ -597,7 +599,7 @@ Diskstream::route_going_away () void Diskstream::calculate_record_range(OverlapType ot, sframes_t transport_frame, nframes_t nframes, - nframes_t& rec_nframes, nframes_t& rec_offset) + nframes_t& rec_nframes, nframes_t& rec_offset) { switch (ot) { case OverlapNone: diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 564031fc75..031c2aa58a 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -958,9 +958,10 @@ Session::auto_loop_changed (Location* location) if (transport_rolling() && play_loop) { - //if (_transport_frame < location->start() || _transport_frame > location->end()) { - if (_transport_frame > location->end()) { + // if (_transport_frame > location->end()) { + + if (_transport_frame < location->start() || _transport_frame > location->end()) { // relocate to beginning of loop clear_events (Event::LocateRoll); diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index b795d3fb59..65635b773f 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -321,7 +321,7 @@ Session::process_event (Event* ev) switch (ev->type) { case Event::SetLoop: - set_play_loop (ev->yes_or_no); + set_play_loop (ev->yes_or_no, (ev->speed == 1.0f)); break; case Event::AutoLoop: @@ -435,7 +435,7 @@ Session::process_event (Event* ev) break; case Event::SetPlayRange: - set_play_range (ev->yes_or_no); + set_play_range (ev->yes_or_no, (ev->speed == 1.0f)); break; default: diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 8b8e2ba8ff..f60cf8e85f 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -174,6 +174,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) auto_play_legal = false; transport_sub_state = 0; _transport_frame = 0; + _requested_return_frame = -1; end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd))); start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart))); g_atomic_int_set (&_record_status, Disabled); @@ -194,7 +195,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) _have_captured = false; _worst_output_latency = 0; _worst_input_latency = 0; - _worst_track_latency = 0; + _worst_track_latency = 0; _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading); _slave = 0; diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index e53aa4d5d3..8ab2523119 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -67,9 +67,8 @@ Session::request_slave_source (SlaveSource src) if (src == JACK) { /* could set_seamless_loop() be disposed of entirely?*/ Config->set_seamless_loop (false); - } else { - Config->set_seamless_loop (true); } + ev->slave = src; queue_event (ev); } @@ -111,7 +110,7 @@ Session::force_locate (nframes_t target_frame, bool with_roll) } void -Session::request_play_loop (bool yn) +Session::request_play_loop (bool yn, bool leave_rolling) { Event* ev; Location *location = _locations.auto_loop_location(); @@ -122,10 +121,10 @@ Session::request_play_loop (bool yn) return; } - ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn); + ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); queue_event (ev); - if (!yn && Config->get_seamless_loop() && transport_rolling()) { + if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) { // request an immediate locate to refresh the diskstreams // after disabling looping request_locate (_transport_frame-1, false); @@ -402,28 +401,69 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) && !(post_transport_work & PostTransportLocate)) { + /* no explicit locate queued */ + bool do_locate = false; if (_requested_return_frame >= 0) { + + /* 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; - _requested_return_frame = -1; do_locate = true; + } else { - _transport_frame = _last_roll_location; - } + if (config.get_auto_return()) { - if (synced_to_jack() && !play_loop) { - do_locate = true; + if (play_loop) { + + /* don't try to handle loop play when synced to JACK */ + + if (!synced_to_jack()) { + + Location *location = _locations.auto_loop_location(); + + if (location != 0) { + _transport_frame = location->start(); + } else { + _transport_frame = _last_roll_location; + } + do_locate = true; + } + + } else if (_play_range) { + + /* return to start of range */ + + if (!current_audio_range.empty()) { + _transport_frame = current_audio_range.front().start; + do_locate = true; + } + + } else { + + /* regular auto-return */ + + _transport_frame = _last_roll_location; + do_locate = true; + } + } } + _requested_return_frame = -1; + if (do_locate) { - // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl; _engine.transport_locate (_transport_frame); } - } + } } + /* 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()) { (*i)->non_realtime_locate (_transport_frame); @@ -480,9 +520,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if (post_transport_work & PostTransportStop) { _play_range = false; - - /* do not turn off autoloop on stop */ - + play_loop = false; } nframes_t tf = _transport_frame; @@ -523,11 +561,17 @@ Session::check_declick_out () } void -Session::set_play_loop (bool yn) +Session::set_play_loop (bool yn, bool leave_rolling) { /* Called from event-handling context */ - if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) { + Location *loc; + + if (yn == play_loop) { + return; + } + + if ((actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) { return; } @@ -543,10 +587,9 @@ Session::set_play_loop (bool yn) if ((play_loop = yn)) { - Location *loc; - + if (loc) { - if ((loc = _locations.auto_loop_location()) != 0) { + set_play_range (false, true); if (Config->get_seamless_loop()) { // set all diskstreams to use internal looping @@ -572,20 +615,13 @@ 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 if current pos is outside of the loop range */ - if (_transport_frame < loc->start() || _transport_frame > loc->end()) { - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack()); - merge_event (event); - } - else { - // locate to current position (+ 1 to force reload) - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack()); - 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); } - } else { clear_events (Event::AutoLoop); @@ -598,6 +634,7 @@ Session::set_play_loop (bool yn) } } + TransportStateChange (); /* EMIT SIGNAL */ } void @@ -755,7 +792,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { // cancel looping directly, this is called from event handling context - set_play_loop (false); + set_play_loop (false, false); } else if (al && _transport_frame == al->start()) { if (with_loop) { @@ -1157,27 +1194,32 @@ Session::set_audio_range (list<AudioRange>& range) } void -Session::request_play_range (bool yn) +Session::request_play_range (bool yn, bool leave_rolling) { - Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn); + Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0f : 0.0f), yn); queue_event (ev); } void -Session::set_play_range (bool yn) +Session::set_play_range (bool yn, bool leave_rolling) { /* Called from event-processing context */ - if (_play_range != yn) { - _play_range = yn; - setup_auto_play (); + if (yn) { + /* cancel loop play */ + set_play_range (false, true); + } - if (!_play_range) { - /* stop transport */ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); - merge_event (ev); - } + _play_range = yn; + setup_auto_play (); + + + if (!_play_range && !leave_rolling) { + /* stop transport */ + Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); + merge_event (ev); } + TransportStateChange (); /* EMIT SIGNAL */ } void @@ -1252,7 +1294,6 @@ Session::request_roll_at_and_return (nframes_t start, nframes_t return_to) void Session::request_bounded_roll (nframes_t start, nframes_t end) { - request_stop (); Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0); queue_event (ev); request_locate (start, true); @@ -1375,3 +1416,17 @@ Session::reset_jack_connection (jack_client_t* jack) js->reset_client (jack); } } + +bool +Session::maybe_stop (nframes_t limit) +{ + if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) { + if (synced_to_jack () && Config->get_jack_time_master ()) { + _engine.transport_stop (); + } else if (!synced_to_jack ()) { + stop_transport (); + } + return true; + } + return false; +} |