X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_transport.cc;h=0e808accb76a0da7f1f52269f16abcb6bb72d853;hb=7d96960b162d25da87c388a3083775e8770bba56;hp=69de9ead2efa836303a0cfb769c2210c8de41e94;hpb=fddc11f556061d0ffa9a173a3652aa34c20bac3b;p=ardour.git diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 69de9ead2e..0e808accb7 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -21,8 +21,6 @@ #include #include -#include -#include #include "pbd/undo.h" #include "pbd/error.h" @@ -47,7 +45,6 @@ using namespace std; using namespace ARDOUR; -using namespace sigc; using namespace PBD; void @@ -73,20 +70,20 @@ void Session::request_input_change_handling () { if (!(_state_of_the_state & (InitialConnecting|Deletion))) { - Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0); + SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0); queue_event (ev); } } void -Session::request_sync_source (SyncSource src) +Session::request_sync_source (Slave* new_slave) { - Event* ev = new Event (Event::SetSyncSource, Event::Add, Event::Immediate, 0, 0.0); + SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0); bool seamless; seamless = Config->get_seamless_loop (); - if (src == JACK) { + if (dynamic_cast(new_slave)) { /* JACK cannot support seamless looping at present */ Config->set_seamless_loop (false); } else { @@ -97,14 +94,14 @@ Session::request_sync_source (SyncSource src) /* save value of seamless from before the switch */ _was_seamless = seamless; - ev->sync_source = src; + ev->slave = new_slave; queue_event (ev); } void Session::request_transport_speed (double speed) { - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed); + SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed); DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed)); queue_event (ev); } @@ -112,7 +109,7 @@ Session::request_transport_speed (double speed) void Session::request_diskstream_speed (Diskstream& ds, double speed) { - Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed); + SessionEvent* ev = new SessionEvent (SessionEvent::SetDiskstreamSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed); ev->set_ptr (&ds); queue_event (ev); } @@ -120,7 +117,7 @@ Session::request_diskstream_speed (Diskstream& ds, double speed) void Session::request_stop (bool abort, bool clear_state) { - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort, clear_state); + SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state); DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state)); queue_event (ev); } @@ -128,7 +125,7 @@ Session::request_stop (bool abort, bool clear_state) void Session::request_locate (nframes_t target_frame, bool with_roll) { - Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false); + SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false); DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame)); queue_event (ev); } @@ -136,7 +133,7 @@ Session::request_locate (nframes_t target_frame, bool with_roll) void Session::force_locate (nframes64_t target_frame, bool with_roll) { - Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true); + SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true); DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame)); queue_event (ev); } @@ -144,7 +141,7 @@ Session::force_locate (nframes64_t target_frame, bool with_roll) void Session::request_play_loop (bool yn, bool leave_rolling) { - Event* ev; + SessionEvent* ev; Location *location = _locations.auto_loop_location(); if (location == 0 && yn) { @@ -153,7 +150,7 @@ Session::request_play_loop (bool yn, bool leave_rolling) return; } - ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); + ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn); DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling)); queue_event (ev); @@ -167,7 +164,7 @@ Session::request_play_loop (bool yn, bool leave_rolling) void Session::request_play_range (list* range, bool leave_rolling) { - Event* ev = new Event (Event::SetPlayAudioRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0)); + SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0)); if (range) { ev->audio_range = *range; } else { @@ -222,9 +219,9 @@ Session::realtime_stop (bool abort, bool clear_state) add_post_transport_work (todo); } - _clear_event_type (Event::StopOnce); - _clear_event_type (Event::RangeStop); - _clear_event_type (Event::RangeLocate); + _clear_event_type (SessionEvent::StopOnce); + _clear_event_type (SessionEvent::RangeStop); + _clear_event_type (SessionEvent::RangeLocate); disable_record (true); @@ -576,7 +573,9 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) play_loop = false; } - PositionChanged ((nframes64_t) _transport_frame); /* EMIT SIGNAL */ + // can't cast away volatile so copy and emit that + nframes64_t tframe = _transport_frame; + PositionChanged (tframe); /* EMIT SIGNAL */ TransportStateChange (); /* EMIT SIGNAL */ /* and start it up again if relevant */ @@ -615,7 +614,7 @@ void Session::unset_play_loop () { play_loop = false; - clear_events (Event::AutoLoop); + clear_events (SessionEvent::AutoLoop); // set all diskstreams to NOT use internal looping boost::shared_ptr dsl = diskstreams.reader(); @@ -676,7 +675,7 @@ Session::set_play_loop (bool yn) /* put the loop event into the event list */ - Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f); + SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f); merge_event (event); /* locate to start of loop and roll. If doing seamless loop, force a @@ -1033,7 +1032,7 @@ Session::stop_transport (bool abort, bool clear_state) and then we'll really be stopped. */ - Event *ev = new Event (Event::StopOnce, Event::Replace, + SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace, _transport_frame + _worst_output_latency - current_block_size, 0, 0, abort); @@ -1156,17 +1155,16 @@ Session::reset_rf_scale (nframes_t motion) } void -Session::drop_sync_source () +Session::use_sync_source (Slave* new_slave) { + /* Runs in process() context */ + bool non_rt_required = false; - if (_transport_speed) { - error << _("please stop the transport before adjusting slave settings") << endmsg; - return; - } + /* XXX this deletion is problematic because we're in RT context */ delete _slave; - _slave = 0; + _slave = new_slave; boost::shared_ptr dsl = diskstreams.reader(); for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { @@ -1174,7 +1172,7 @@ Session::drop_sync_source () if ((*i)->realtime_set_speed ((*i)->speed(), true)) { non_rt_required = true; } - (*i)->set_slaved (0); + (*i)->set_slaved (_slave != 0); } } @@ -1187,24 +1185,27 @@ Session::drop_sync_source () } void -Session::use_sync_source (SyncSource src) +Session::drop_sync_source () { - bool reverse = false; - bool non_rt_required = false; + request_sync_source (0); +} - if (_transport_speed) { - error << _("please stop the transport before adjusting slave settings") << endmsg; - return; - } +void +Session::switch_to_sync_source (SyncSource src) +{ + Slave* new_slave; - delete _slave; - _slave = 0; + DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src))); switch (src) { case MTC: + if (_slave && dynamic_cast(_slave)) { + return; + } + if (_mtc_port) { try { - _slave = new MTC_Slave (*this, *_mtc_port); + new_slave = new MTC_Slave (*this, *_mtc_port); } catch (failed_constructor& err) { @@ -1218,9 +1219,13 @@ Session::use_sync_source (SyncSource src) break; case MIDIClock: + if (_slave && dynamic_cast(_slave)) { + return; + } + if (_midi_clock_port) { try { - _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24); + new_slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24); } catch (failed_constructor& err) { @@ -1234,31 +1239,19 @@ Session::use_sync_source (SyncSource src) break; case JACK: - _slave = new JACK_Slave (_engine.jack()); - break; - - }; - - boost::shared_ptr dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - if ((*i)->realtime_set_speed ((*i)->speed(), true)) { - non_rt_required = true; - } - (*i)->set_slaved (_slave); + if (_slave && dynamic_cast(_slave)) { + return; } - } - - if (reverse) { - reverse_diskstream_buffers (); - } - if (non_rt_required) { - add_post_transport_work (PostTransportSpeed); - _butler->schedule_transport_work (); - } + new_slave = new JACK_Slave (_engine.jack()); + break; + + default: + new_slave = 0; + break; + }; - set_dirty(); + request_sync_source (new_slave); } void @@ -1282,14 +1275,14 @@ void Session::unset_play_range () { _play_range = false; - _clear_event_type (Event::RangeStop); - _clear_event_type (Event::RangeLocate); + _clear_event_type (SessionEvent::RangeStop); + _clear_event_type (SessionEvent::RangeLocate); } void Session::set_play_range (list& range, bool leave_rolling) { - Event* ev; + SessionEvent* ev; /* Called from event-processing context */ @@ -1300,7 +1293,7 @@ Session::set_play_range (list& range, bool leave_rolling) */ if (!leave_rolling) { /* stop transport */ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); + SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false); merge_event (ev); } return; @@ -1335,9 +1328,9 @@ Session::set_play_range (list& range, bool leave_rolling) } if (next == range.end()) { - ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f); + ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f); } else { - ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f); + ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f); } merge_event (ev); @@ -1347,7 +1340,7 @@ Session::set_play_range (list& range, bool leave_rolling) } else if (sz == 1) { - ev = new Event (Event::RangeStop, Event::Add, range.front().end, 0, 0.0f); + ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f); merge_event (ev); } @@ -1358,7 +1351,7 @@ Session::set_play_range (list& range, bool leave_rolling) /* now start rolling at the right place */ - ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, range.front().start, 0.0f, false); + ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false); merge_event (ev); TransportStateChange (); @@ -1376,7 +1369,7 @@ Session::request_bounded_roll (nframes_t start, nframes_t end) void Session::request_roll_at_and_return (nframes_t start, nframes_t return_to) { - Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0); + SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0); ev->target2_frame = start; queue_event (ev); } @@ -1408,7 +1401,9 @@ Session::engine_halted () void Session::xrun_recovery () { - Xrun ((nframes64_t)_transport_frame); //EMIT SIGNAL + // can't cast away volatile so copy and emit that + nframes64_t tframe = _transport_frame; + Xrun (tframe); //EMIT SIGNAL if (Config->get_stop_recording_on_xrun() && actively_recording()) {