*/
-#include <cmath>
-#include <cerrno>
-#include <unistd.h>
-
#ifdef WAF_BUILD
#include "libardour-config.h"
#endif
+#include <cmath>
+#include <cerrno>
+#include <unistd.h>
#include "pbd/undo.h"
#include "pbd/error.h"
#include "midi++/port.h"
#include "midi++/manager.h"
-#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
#include "ardour/butler.h"
auditioner->cancel_audition ();
}
- clear_clicks();
cumulative_rf_motion = 0;
reset_rf_scale (0);
}
+ clear_clicks();
+
/* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
*/
have_looped = false;
- send_full_time_code (_transport_frame);
-
- if (!dynamic_cast<MTC_Slave*>(_slave)) {
- MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
- send_mmc_locate (_transport_frame);
+ if (!_engine.freewheeling()) {
+ send_full_time_code (_transport_frame);
+
+ if (!dynamic_cast<MTC_Slave*>(_slave)) {
+ MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
+ send_mmc_locate (_transport_frame);
+ }
}
if ((ptw & PostTransportLocate) && get_record_enabled()) {
/* this is called after a process() iteration. if PendingDeclickOut was set,
it means that we were waiting to declick the output (which has just been
- done) before doing something else. this is where we do that "something else".
+ done) before maybe doing something else. this is where we do that "something else".
note: called from the audio thread.
*/
stop_transport (pending_abort);
transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
}
+
+ } else if (transport_sub_state & PendingLoopDeclickOut) {
+ /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
+ transport_sub_state &= ~PendingLoopDeclickOut;
}
}
{
play_loop = false;
clear_events (SessionEvent::AutoLoop);
+ clear_events (SessionEvent::AutoLoopDeclick);
// set all tracks to NOT use internal looping
boost::shared_ptr<RouteList> rl = routes.reader ();
}
}
- /* put the loop event into the event list */
+ /* Put the delick and loop events in into the event list. The declick event will
+ cause a de-clicking fade-out just before the end of the loop, and it will also result
+ in a fade-in when the loop restarts. The AutoLoop event will peform the actual loop.
+ */
- SessionEvent* event = new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f);
- merge_event (event);
+ framepos_t dcp;
+ framecnt_t dcl;
+ auto_loop_declick_range (loc, dcp, dcl);
+ merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
+ merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
/* locate to start of loop and roll. If doing seamless loop, force a
locate+buffer refill even if we are positioned there already.
return;
}
- if (_transport_speed) {
- /* schedule a declick. we'll be called again when its done */
+ if (_transport_speed && !with_loop) {
+ /* Schedule a declick. We'll be called again when its done.
+ We only do it this way for ordinary locates, not those
+ due to loops.
+ */
if (!(transport_sub_state & PendingDeclickOut)) {
transport_sub_state |= (PendingDeclickOut|PendingLocate);
(*i)->automation_snapshot (_transport_frame, true);
}
- Timecode::Time time;
- timecode_time_subframes (_transport_frame, time);
- if (!dynamic_cast<MTC_Slave*>(_slave)) {
- MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
+ if (!_engine.freewheeling()) {
+ Timecode::Time time;
+ timecode_time_subframes (_transport_frame, time);
+ if (!dynamic_cast<MTC_Slave*>(_slave)) {
+ MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
+ }
}
TransportStateChange (); /* EMIT SIGNAL */
request_sync_source (new_slave);
}
-void
-Session::reverse_track_buffers ()
-{
- add_post_transport_work (PostTransportReverse);
- _butler->schedule_transport_work ();
-}
-
void
Session::set_track_speed (Track* track, double speed)
{
the picture.
*/
- g_atomic_int_set (&_butler->should_do_transport_work, 0);
- set_post_transport_work (PostTransportWork (0));
- _butler->stop ();
+ if (_butler) {
+ g_atomic_int_set (&_butler->should_do_transport_work, 0);
+ set_post_transport_work (PostTransportWork (0));
+ _butler->stop ();
+ }
realtime_stop (false, true);
non_realtime_stop (false, 0, ignored);
void
Session::route_processors_changed (RouteProcessorChange c)
{
+ if (ignore_route_processor_changes) {
+ return;
+ }
+
if (c.type == RouteProcessorChange::MeterPointChange) {
return;
}
void
Session::send_mmc_locate (framepos_t t)
{
- Timecode::Time time;
- timecode_time_subframes (t, time);
- MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
+ if (!_engine.freewheeling()) {
+ Timecode::Time time;
+ timecode_time_subframes (t, time);
+ MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
+ }
}
/** Ask the transport to not send timecode until further notice. The suspension