From 9686f8097d45c306168d1a5220d9c8bf225edb8c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 7 Dec 2009 21:37:35 +0000 Subject: first pass at end-to-end RT operation request (GUI->session->RT thread->GUI), just for rec-enable git-svn-id: svn://localhost/ardour2/branches/3.0@6324 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/route_ui.cc | 29 +++++++++++++++++++++-------- gtk2_ardour/route_ui.h | 4 ++++ libs/ardour/ardour/session.h | 16 +++++++++++++--- libs/ardour/ardour/session_event.h | 6 ++++-- libs/ardour/session.cc | 20 ++++++++++++-------- libs/ardour/session_events.cc | 7 ------- libs/ardour/session_process.cc | 24 ++++++++++++++++++++++-- libs/ardour/session_state.cc | 17 +++++++++++++++++ libs/surfaces/control_protocol/basic_ui.cc | 4 ++-- 9 files changed, 95 insertions(+), 32 deletions(-) diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index fe2adff449..a8e97f081f 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -452,6 +452,22 @@ RouteUI::solo_release(GdkEventButton*) return true; } +void +RouteUI::post_rec_cleanup (SessionEvent* ev, UndoTransaction* undo, Session::GlobalRecordEnableStateCommand* cmd) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &RouteUI::post_rec_cleanup), ev, undo, cmd)); + + delete ev->routes; + delete ev; + + check_rec_enable_sensitivity (); + + cmd->mark(); + undo->add_command(cmd); + + _session.finish_reversible_command (*undo); +} + bool RouteUI::rec_enable_press(GdkEventButton* ev) { @@ -474,20 +490,17 @@ RouteUI::rec_enable_press(GdkEventButton* ev) } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) { - _session.begin_reversible_command (_("rec-enable change")); + UndoTransaction* undo = _session.start_reversible_command (_("rec-enable change")); Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this); + sigc::slot callback = bind (sigc::mem_fun (*this, &RouteUI::post_rec_cleanup), undo, cmd); + if (rec_enable_button->get_active()) { - _session.record_disenable_all (); + _session.record_disenable_all (callback); } else { - _session.record_enable_all (); - check_rec_enable_sensitivity (); + _session.record_enable_all (callback); } - cmd->mark(); - _session.add_command(cmd); - _session.commit_reversible_command (); - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { /* Primary-button1 applies change to the mix group. diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index b62b146735..e71864ab20 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -25,6 +25,8 @@ #include "pbd/xml++.h" #include "ardour/ardour.h" #include "ardour/mute_master.h" +#include "ardour/session_event.h" +#include "ardour/session.h" #include "ardour/route.h" #include "ardour/track.h" @@ -209,6 +211,8 @@ class RouteUI : public virtual AxisView void check_rec_enable_sensitivity (); void parameter_changed (std::string const &); void relabel_solo_button (); + + void post_rec_cleanup (ARDOUR::SessionEvent* ev, UndoTransaction* undo, ARDOUR::Session::GlobalRecordEnableStateCommand*); }; #endif /* __ardour_route_ui__ */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index c9b2ba11a3..18af14a313 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -330,6 +330,12 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu int remove_region_from_region_list (boost::shared_ptr); + /* ask the session to do realtime things, in RT context, then get back to us via a callback (which must be + cross-thread or RT safe, since it too is called from RT context) + */ + + void request_real_time_operation (sigc::slot rt_op, sigc::slot callback); + nframes_t get_maximum_extent () const; nframes_t current_end_frame() const { return end_location->start(); } nframes_t current_start_frame() const { return start_location->start(); } @@ -621,8 +627,8 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu sigc::signal SoloActive; sigc::signal SoloChanged; - void record_disenable_all (); - void record_enable_all (); + void record_disenable_all (sigc::slot); + void record_enable_all (sigc::slot); /* control/master out */ @@ -719,6 +725,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu void begin_reversible_command (const std::string& cmd_name); void commit_reversible_command (Command* cmd = 0); + UndoTransaction* start_reversible_command (const std::string& cmd_name); + void finish_reversible_command (UndoTransaction&); + void add_command (Command *const cmd) { assert(!_current_trans.empty ()); _current_trans.top()->add_command (cmd); @@ -1466,8 +1475,9 @@ class Session : public PBD::StatefulDestructible, public SessionEventManager, pu void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int); int jack_sync_callback (jack_transport_state_t, jack_position_t*); void reset_jack_connection (jack_client_t* jack); - void record_enable_change_all (bool yn); + void record_enable_change_all (bool yn, sigc::slot); void do_record_enable_change_all (RouteList*, bool); + void process_rtop (SessionEvent*); XMLNode& state(bool); diff --git a/libs/ardour/ardour/session_event.h b/libs/ardour/ardour/session_event.h index 07c795257f..a903e3cd4f 100644 --- a/libs/ardour/ardour/session_event.h +++ b/libs/ardour/ardour/session_event.h @@ -33,6 +33,7 @@ struct SessionEvent { InputConfigurationChange, SetPlayAudioRange, SetRecordEnable, + RealTimeOperation, /* only one of each of these events can be queued at any one time */ @@ -66,13 +67,14 @@ struct SessionEvent { RouteList* routes; }; + sigc::slot rt_slot; /* what to call in RT context */ + sigc::slot rt_return; /* called after rt_slot, with this event as an argument */ + std::list audio_range; std::list music_range; boost::shared_ptr region; - sigc::signal Complete; - SessionEvent (Type t, Action a, nframes_t when, nframes_t where, double spd, bool yn = false, bool yn2 = false) : type (t) , action (a) diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index f113bf4ebc..5c8c2254f9 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3605,27 +3605,27 @@ Session::graph_reordered () } void -Session::record_disenable_all () +Session::record_disenable_all (sigc::slot callback) { if (!writable()) { return; } - record_enable_change_all (false); + record_enable_change_all (false, callback); } void -Session::record_enable_all () +Session::record_enable_all (sigc::slot callback) { if (!writable()) { return; } - record_enable_change_all (true); + record_enable_change_all (true, callback); } void -Session::record_enable_change_all (bool yn) +Session::record_enable_change_all (bool yn, sigc::slot callback) { shared_ptr r = routes.reader (); RouteList* tracks = new RouteList; @@ -3637,11 +3637,15 @@ Session::record_enable_change_all (bool yn) tracks->push_back (*i); } } + + sigc::slot rt_op = bind (sigc::mem_fun (*this, &Session::do_record_enable_change_all), tracks, yn); + + SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0); - SessionEvent* ev = new SessionEvent (SessionEvent::SetRecordEnable, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, yn); + ev->routes = tracks; // set here so that callback can delete it + ev->rt_slot = rt_op; + ev->rt_return = callback; - ev->routes = tracks; - ev->Complete.connect (mem_fun (*this, &Session::cleanup_event)); queue_event (ev); } diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index 7b24b1abef..170a1c0c4c 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -278,10 +278,3 @@ SessionEventManager::_clear_event_type (SessionEvent::Type type) set_next_event (); } -#if 0 -void -Session::process_rtop (SessionEvent* ev) -{ - ev->rt_return (ev->rt_slot ()); -} -#endif diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 329bb62174..22c6abfc73 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -1138,6 +1138,11 @@ Session::process_event (SessionEvent* ev) do_record_enable_change_all (ev->routes, ev->yes_or_no); break; + case SessionEvent::RealTimeOperation: + process_rtop (ev); + del = false; // other side of RT request needs to clean up + break; + default: fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg; /*NOTREACHED*/ @@ -1148,9 +1153,24 @@ Session::process_event (SessionEvent* ev) del = del && !_remove_event (ev); } - ev->Complete (ev, 0); /* EMIT SIGNAL */ - if (del) { delete ev; } } + + +void +Session::request_real_time_operation (sigc::slot rt_op, sigc::slot callback) +{ + SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0); + ev->rt_slot = rt_op; + ev->rt_return = callback; + queue_event (ev); +} + +void +Session::process_rtop (SessionEvent* ev) +{ + ev->rt_slot (); + ev->rt_return (ev); +} diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 7b8f49e128..3aaa3dbf22 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2125,6 +2125,23 @@ Session::route_group_by_name (string name) return 0; } +UndoTransaction* +Session::start_reversible_command (const string& name) +{ + UndoTransaction* trans = new UndoTransaction(); + trans->set_name(name); + return trans; +} + +void +Session::finish_reversible_command (UndoTransaction& ut) +{ + struct timeval now; + gettimeofday(&now, 0); + ut.set_timestamp(now); + _history.add (&ut); +} + void Session::begin_reversible_command(const string& name) { diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc index 3d336adb47..3ae5455a8c 100644 --- a/libs/surfaces/control_protocol/basic_ui.cc +++ b/libs/surfaces/control_protocol/basic_ui.cc @@ -215,9 +215,9 @@ void BasicUI::toggle_all_rec_enables () { if (session->get_record_enabled()) { - session->record_disenable_all (); + // session->record_disenable_all (); } else { - session->record_enable_all (); + // session->record_enable_all (); } } -- cgit v1.2.3