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.
lili93's session (#ardour) triggered this w/jackd 512fpp:
Drag/Drop copy a latent plugin from one track to another while rolling.
The GUI-thread as well as the auto-connect thread concurrently call
jack_recompute_total_latencies(). The auto-connect thread holds
a process lock while doing so. The GUI does not use any mutexes.
This randomly deadlocks in libjack.
backtrace: https://pastebin.com/6m3KGhWS
This also removes enums introduced to describe well-known parameters for Mixbus. Lookup now involves string
parsing every time, but this is not likely to be a notable cost.
Previously Ardour used a /local/ per track vari-speed mechanism.
Now that the disk-reader is a latency-compensated processor, the speed
of each disk-reader would need to be maintained locally, offset by each
disk-reader's output latency. Furthermore each disk-reader may
produce a different number of samples, depending on its global alignment.
This commit introduces port-data resampling directly at the engine-level:
Up/down-sample all input ports at the beginning, and down/up-sample output
port-data using the inverse ratio at the end of the session's process
cycle.
The session itself is unaware of the speed-change, and only needs to
handle transport speeds {-1, 0, +1}.
This also allows for aligned cue-monitoring and vari-speed recording,
and also pitch-shifts synthesized MIDI along.
* prevent duplicate names when pulling-in external sources
* drop "origin" after including external sources
* don't include unused playlists
(they may reference sources that are not included)
* likewise exclude unused regions
* Processor implement get_state(), classes derived from Processor
implement protected ::state() -- as documented in processor.h
* likewise for Route, Track: make ::state() a protected interface
* removal of "full_state", use explicit "template_save"
* use RAII/Unwind to skip saving automation-state
The general goal is to align transport-sample to be the audible frame
and use that as "anchor" for all processing.
transport_sample cannot become negative (00:00:00:00 is the first audible
frame).
Internally transport pre-rolls (read-ahead) before the transport starts
to move. This allows inputs and disk to prefill the pipeline.
When starting to roll, the session counts down a global "remaning preroll"
counter, which is the worst-latency from in-to-out.
Each route in turn will start processing at its own output-latency.
Route::process_output_buffers() - which does the actual processing
incl disk i/o - begins by offsetting the "current sample" by the
route's process-latency and decrements the offset for each latent
processor. At the end of the function the output will be aligned
and match transport-sample - downstream-playback-latency (if any).
PS. This commit is a first step only: transport looping & vari-speed have
not yet been implemented/updated.
* centralize signal_latency_at_***_position to processors
* update initial-delay/roll-delay when processor order changes
* consolidate signal-latency calculation: use the same method
for processor-changes and session's post_playback_latency.
* include relative output-delay in roll-delay
* fix capture processor position & optimize stem-export latency
(roll-delay fixes pending Route:roll() update)
Generated by tools/f2s. Some hand-editing will be required in a few places to fix up comments related to timecode
and video in order to keep the legible
Remove various checks, add assert() for now (perhaps some old sessions?)
This fixes an off-by one issue when adding tracks (presentation
info order in add_routes_inner)
Fixed a crash if an x-run or graph-reorder happens after the LTC encoder
has been destroyed (possible at session-close or after disabling
the encoder). This also fixes duplicate callbacks in case the
encoder was re-enabled times in an active session.
Useful as temporary buffer: This allows a controllable to
get a master's automation-curve and combine it with its own
(gain, trim, send) automation buffer.
A transport-speed-change is no reason to skip processing.
Prior to this change cannot_process() silently skipped in the process
cycle of the speed-change (which may have been every process-cycle),
without moving the transport or doing any processing.
eg. at the end of a loop, the session may already be playing the
beginning of the loop. The TransportLooped signal was emitted.
Yet due to playback latency, the audible frame is still at the end of
the loop.
To interpolate the playhead position the UI needs to be able to know:
Relying on the TransportLooped signal is not sufficient because it
does not take playback latency into account.
By setting strict-io on the Instrument plugin early during track
creation, adding the plugin will trigger a PluginSetup Dialog for
multi-out instruments in a strict i/o track.
shared_ptr<Port> now uses a deleter functor which pushes Port* to a lock-free FIFO so that the Port is
always deleted (and thus unregistered with the PortEngine/backend) in a safe context w.r.t. various
callbacks in the host. Currently the auto_connect_thread in Session has been tasked with doing these
deletions.
* add a threaded TmpFile Writer
* update API calls to that process_export_fw() can be used as
process_function
The idea is to re-use export infrastructure from normalization:
export to a tmp-file and then encode target formats after that.
Pass current (latency compensated) cycle times to plugin.
This fixes time-reporting to plugins and also fixes automation
and when bouncing (the session->transport* is not valid) etc.
Route now calls back into Session when solo/mute/listen state changes. All other interested
parties must use the Route::{solo,mute,...}_control()->Changed() to be notified of changes.
The Session requires more information than the Changed signal can provide, in order to
propagate solo/mute changes across the entire Session correctly.
Note that this uses an experimental use of CRTP to isolate a public API within Session