summaryrefslogtreecommitdiff
path: root/libs/ardour/session_process.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-12-04 02:15:12 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-12-04 02:15:12 +0000
commit9ad2875905c611b33fc9114101da224c878ca9cd (patch)
tree8e37e2a765ea68eea29c42a6f0cdc13b05180bbe /libs/ardour/session_process.cc
parent1ef43ec89c1073a370450b9756fca361b1c0f69d (diff)
move Session::Event into SessionEvent class; add SessionEventManager (Session IS-A SessionEventManager); make session ops to toggle all track rec-enable be atomic with respect to process()
git-svn-id: svn://localhost/ardour2/branches/3.0@6273 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/session_process.cc')
-rw-r--r--libs/ardour/session_process.cc217
1 files changed, 212 insertions, 5 deletions
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index d7a92de3b2..329bb62174 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -23,6 +23,7 @@
#include <unistd.h>
#include "pbd/error.h"
+#include "pbd/enumwriter.h"
#include <glibmm/thread.h>
@@ -274,7 +275,7 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
void
Session::process_with_events (nframes_t nframes)
{
- Event* ev;
+ SessionEvent* ev;
nframes_t this_nframes;
nframes_t end_frame;
bool session_needs_butler = false;
@@ -299,7 +300,7 @@ Session::process_with_events (nframes_t nframes)
*/
while (!non_realtime_work_pending() && !immediate_events.empty()) {
- Event *ev = immediate_events.front ();
+ SessionEvent *ev = immediate_events.front ();
immediate_events.pop_front ();
process_event (ev);
}
@@ -334,7 +335,7 @@ Session::process_with_events (nframes_t nframes)
end_frame = _transport_frame + (nframes_t)frames_moved;
{
- Event* this_event;
+ SessionEvent* this_event;
Events::iterator the_next_one;
if (!process_can_proceed()) {
@@ -863,7 +864,7 @@ Session::process_without_events (nframes_t nframes)
void
Session::process_audition (nframes_t nframes)
{
- Event* ev;
+ SessionEvent* ev;
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -890,7 +891,7 @@ Session::process_audition (nframes_t nframes)
*/
while (!non_realtime_work_pending() && !immediate_events.empty()) {
- Event *ev = immediate_events.front ();
+ SessionEvent *ev = immediate_events.front ();
immediate_events.pop_front ();
process_event (ev);
}
@@ -947,3 +948,209 @@ Session::maybe_sync_start (nframes_t& nframes)
return false;
}
+void
+Session::queue_event (SessionEvent* ev)
+{
+ if (_state_of_the_state & Deletion) {
+ return;
+ } else if (_state_of_the_state & Loading) {
+ merge_event (ev);
+ } else {
+ pending_events.write (&ev, 1);
+ }
+}
+
+void
+Session::set_next_event ()
+{
+ if (events.empty()) {
+ next_event = events.end();
+ return;
+ }
+
+ if (next_event == events.end()) {
+ next_event = events.begin();
+ }
+
+ if ((*next_event)->action_frame > _transport_frame) {
+ next_event = events.begin();
+ }
+
+ for (; next_event != events.end(); ++next_event) {
+ if ((*next_event)->action_frame >= _transport_frame) {
+ break;
+ }
+ }
+}
+
+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)
+{
+ bool remove = true;
+ bool del = true;
+
+ /* if we're in the middle of a state change (i.e. waiting
+ for the butler thread to complete the non-realtime
+ part of the change), we'll just have to queue this
+ event for a time when the change is complete.
+ */
+
+ if (non_realtime_work_pending()) {
+
+ /* except locates, which we have the capability to handle */
+
+ if (ev->type != SessionEvent::Locate) {
+ immediate_events.insert (immediate_events.end(), ev);
+ _remove_event (ev);
+ return;
+ }
+ }
+
+ DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
+
+ switch (ev->type) {
+ case SessionEvent::SetLoop:
+ set_play_loop (ev->yes_or_no);
+ break;
+
+ case SessionEvent::AutoLoop:
+ if (play_loop) {
+ start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
+ }
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::Locate:
+ if (ev->yes_or_no) {
+ // cerr << "forced locate to " << ev->target_frame << endl;
+ locate (ev->target_frame, false, true, false);
+ } else {
+ // cerr << "soft locate to " << ev->target_frame << endl;
+ start_locate (ev->target_frame, false, true, false);
+ }
+ _send_timecode_update = true;
+ break;
+
+ case SessionEvent::LocateRoll:
+ if (ev->yes_or_no) {
+ // cerr << "forced locate to+roll " << ev->target_frame << endl;
+ locate (ev->target_frame, true, true, false);
+ } else {
+ // cerr << "soft locate to+roll " << ev->target_frame << endl;
+ start_locate (ev->target_frame, true, true, false);
+ }
+ _send_timecode_update = true;
+ break;
+
+ case SessionEvent::LocateRollLocate:
+ // locate is handled by ::request_roll_at_and_return()
+ _requested_return_frame = ev->target_frame;
+ request_locate (ev->target2_frame, true);
+ break;
+
+
+ case SessionEvent::SetTransportSpeed:
+ set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
+ break;
+
+ case SessionEvent::PunchIn:
+ // cerr << "PunchIN at " << transport_frame() << endl;
+ if (config.get_punch_in() && record_status() == Enabled) {
+ enable_record ();
+ }
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::PunchOut:
+ // cerr << "PunchOUT at " << transport_frame() << endl;
+ if (config.get_punch_out()) {
+ step_back_from_record ();
+ }
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::StopOnce:
+ if (!non_realtime_work_pending()) {
+ stop_transport (ev->yes_or_no);
+ _clear_event_type (SessionEvent::StopOnce);
+ }
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::RangeStop:
+ if (!non_realtime_work_pending()) {
+ stop_transport (ev->yes_or_no);
+ }
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::RangeLocate:
+ start_locate (ev->target_frame, true, true, false);
+ remove = false;
+ del = false;
+ break;
+
+ case SessionEvent::Overwrite:
+ overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
+ break;
+
+ case SessionEvent::SetDiskstreamSpeed:
+ set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
+ break;
+
+ case SessionEvent::SetSyncSource:
+ use_sync_source (ev->slave);
+ break;
+
+ case SessionEvent::Audition:
+ set_audition (ev->region);
+ // drop reference to region
+ ev->region.reset ();
+ break;
+
+ case SessionEvent::InputConfigurationChange:
+ add_post_transport_work (PostTransportInputChange);
+ _butler->schedule_transport_work ();
+ break;
+
+ case SessionEvent::SetPlayAudioRange:
+ 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);
+ break;
+
+ default:
+ fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
+ /*NOTREACHED*/
+ break;
+ };
+
+ if (remove) {
+ del = del && !_remove_event (ev);
+ }
+
+ ev->Complete (ev, 0); /* EMIT SIGNAL */
+
+ if (del) {
+ delete ev;
+ }
+}