There is no event processing after the locate, and so the event that is (was)
queued at the loop start will not be processed, and each time we reach the
loop end, we will try (and fail) to queue an identical event (fail because
duplicate events are not allowed). We don't need this event (or signal) at
all, because locates (and then ::start_transport() while looping do not
represent a state change that any UI needs to know about.
* remove unused variables in session.h
* move default play speed (varispeed(sic)) into fsm
* request_transport_speed should -never- set the default_play_speed
* remove unused variables in session.h
* move default play speed (varispeed(sic)) into fsm
* request_transport_speed should -never- set the default_play_speed
The TransportFSM is now responsible for deciding what to do at all transport state transitions. The Session (via the TransportAPI) merely
provides mechanism (locate, start, stop, set_speed). Default and most recent speed requests are managed by the TransportFSM too
"While 'atomic' has a volatile qualifier, this is a historical
artifact and the pointer passed to it should not be volatile."
Furthermore "It is very important that all accesses to a
particular integer or pointer be performed using only this API"
(from https://developer.gnome.org/glib/2.68/glib-Atomic-Operations.html)
Hence initialization of atomic variables is changed to also use
this API, instead of directly initializing the value.
This also fixes a few cases where atomic variables were
accessed directly.
see also libs/pbd/pbd/g_atomic_compat.h
This is is useful to determine if an undoable action was
performed before adding additional information (e.g. selection
changes) to the undo transaction.
The JACK API doesn't allow server calls from inside a server callback, even though JACK2 doesn't enforce this.
It would be nice to find a way to NOT call Session::setup_bundles() from every port registration callback, too.
Retain engine speed across stop/start/locate, so that it is
possible to run a loop at non-unity speed. User must
explicitly reset to 1.0 if default speeds are set to !1.0
When using the export-tool, the very first callback may already be
freewheeling. In this case the first call to the butler also happens
directly from the freewheel process-callback and initial session events
are handled there. Setting PostTransportAdjustPlaybackBuffering
took the process-lock, which caused a deadlock:
Glib::Threads::Mutex::Lock::Lock(Glib::Threads::Mutex&) at /usr/include/glibmm-2.4/glibmm/threads.h:687
ARDOUR::Session::butler_transport_work() at ../libs/ardour/session_transport.cc:1157
ARDOUR::Session::process_export_fw(unsigned int) at ../libs/ardour/session_export.cc:303
ARDOUR::AudioEngine::process_callback(unsigned int) at ../libs/ardour/audioengine.cc:486
ARDOUR::DummyAudioBackend::main_process_thread() at ../libs/backends/dummy/dummy_audiobackend.cc:951
* replace signal-emission with direct calls to CoreSelecton
using BaseUI's session pointer
* remove unused leftmost strip API
* use CoreSelection for first-selected strip
* Accessing CoreSelection does not modify the session
(allow access from const callbacks)
* replace static calls in P2 surface
This removes indirection and dependency on the GUI for
managing strip selection.
Previously when locating process_can_proceed() was set to true,
and routes were not processed while transport states are cleared.
As a result live input was also not processed.
This is no longer needed because the DiskReader handles seeking
directly.
At present only audio data from disk readers is declicked. MIDI tracks with audio output should
likely also be declicked, at which time Session::need_declick_before_locate() will require
amending
This consolidates instrument creation for midi tracks & routes.
If an instrument is added, output auto-connect is postponed until
after the instrument plugin is added. Also when a multi-channel
instrument is fanned-out, the track outputs are not auto-connected.
This also subscribes MIDI-Busses to auto-connect when an instrument
is loaded or replaced at a later time.
Also remove redundant double call to Track::set_block_size(). This dates back to 2010
when there used be an additional traversal of the Diskstream RCU-managed list, before
they became owned by Tracks
Port and connection changes always imply a latency_callback from
the engine. Worst I/O latency is updated directly in
Session::update_latency() which is called from
AudioEngine::latency_callback.
Explicit subscriptions to route->output()->changed() is not needed
to update the worst I/O latency.
Only set_block_size() needs to to update the I/O latency when
the buffer-size changes.
Auto-connect is handled in a background thread, so newly created
tracks are not immediately connected.
This causes a race-condition when fan-out directly disconnects
and re-connects ports after track/bus creation.
When we create a new session and are using a template from an old version of
Ardour, we should not issue the VersionMismatch dialog and not make a copy of
the session file for the old version.
We need to extend the signature of Session::load_state() to tell it if we are
creating a session from a template. Session::_is_new cannot be used for it
because it has a the semantics if to auto connect the the master bus.
Note that this is done at the GUI level, might need to double check if there are
other paths into a "save" that should be covered. Control surfaces use the action, but
Lua comes to mind
Substantive comments associated with code in Session::plan_master_strategy.
Known not to work for reverse TC. Also, the JACK related code has not yet been tested
This was a leftover from changes made for Tracks Live, related to
the concept of an auto-return preference. We don't use this anywhere in Ardour
or Mixbus, and the concept should eventually be removed entirely.
This fixes a crash: missing playlist due to missing .mid,
and retains regions for missing MIDI files.
As opposed to missing Audio, we cannot use a SilentFileSource,
because MIDI files are destructive.
This also adds an API to query missing files that have been replaced
with silence to report them to the user.
This is in preparation for saving state while the session is
record-arm'ed. Most notably config changes and undo/redo.
In case both normal and pending save happens, pending must be
last and is required to recover from crashes during recording.
set_session_extents had a bug; it wasn't calling locations->add()
on the newly created location.
The correct implementation was in set_session_range_location,
but this was only called from one place.
This function was removed, and set_session_extents will be used in its place.
set_session_extents will create a session location if one no longer exists,
so there is no need for set_session_range_location.
Session::TransportStateChanged notifies about transport stop before the stop is complete (i.e. at the start of the declick).
Various other objects (notably control surfaces) connect to this signal and use it to modify their displayed state.
We need a method that can tell them we are stopped (or stopping) even though we are not "fully" stopped yet. This is
that method
This might fix a "SessionHandleRef exists across session deletion",
when the shared_ptr was be pushed onto a x-thread pool, and not
invalidated in time before the session was closed.
destroy_sources () is only called from Session::remove_last_capture ().
The list of sources to be destroyed is the local scope of that method
and will hold a reference to the object.
copy-construct the list and removing elements one by one from the
copy is only unnecessary overhead.
When looping, we do not want to resolve notes at the end of the loop via ::realtime_locate() -
::get_midi_playback() has already taken care of this. But when not looping, we need this. So,
add an argument to tell all interested parties whether the locate is for a loop end or not
Remove need for explicit `initialize_latencies` call that used
to be called from GUI-thread post_engine_init(), as well as
Session::engine_running().
Further reduce calls, `graph_reordered` implies a latency-update
and fix ordering issue. update_latency_compensation() must be called
*after* resort_routes().
There are still over a hundred left, but this addresses many already.
In particular @param references to undocumented parameters.
Most notably in audio_backend.h
Session::Controllables is a shared_ptr<> list. As long
as the session exists the Controllables will be around. Destroyed(*)
can only be called after the session is destroyed and releases the
shared_ptr<>
NB. this code had a nice hack to construct a "shared_from_this"
workaround. For future reference:
struct null_deleter { void operator()(void const *) const {} };
boost::shared_ptr<Controllable>(c, null_deleter())
This partially reverts 639dff3a7c. When loading a session,
the monitor-bus that was saved with the session is used.
This changes semantics of the monitor-section/config.
Config::set_use_monitor_bus(bool) is used to initiate a change!
Notification about the change is sent asynchronously by
Session::MonitorBusAddedOrRemoved
It is no longer possible to directly call add/remove_monitor_section()
and leave the session + config in an inconsistent state.