Lock was not held across a replace_{tempo,meter}() operation because of re-use
of {remove,add}_{tempo,meter}. Moved functional code into _locked variants so
that replace operation can hold lock across its entire active lifetime.
Made correct error handling for cases we didn't see before.
Removed redundant and experimental code I forgot to remove months ago.
Added debug output which will help in future testing
Conflicts:
libs/ardour/ardour/audioengine.h
libs/ardour/engine_state_controller.cc
libs/backends/wavesaudio/waves_midi_device.cc
This works around a bug in OnsetDetector.
It requests a buffer of 1114 samples but later FFT
bails out if the buffer size is not a power-of-two.
Also large buffersizes fail.
Work-around: use ADAPT_ALL_SAFE (no buffersize
adapter), use a reasonably small buffersize.
The current settings work, even though it produces
the following warnings (vamp-plugins/OnsetDetect.cpp)
WARNING: OnsetDetector::initialise: Possibly sub-optimal step size for this sample rate: 512 (wanted 557)
WARNING: OnsetDetector::initialise: Possibly sub-optimal block size for this sample rate: 1024 (wanted 1114)
This commit should be reverted once VAMP/QM/aubio
is updated/fixed.
Technically it doesn't make much difference but from what I can tell, the only files which #include 'gtk2_ardour/gui_thread.h' are the source files from gtk2_ardour itself. The support libraries always #include 'gtkmm2ext/gui_thread.h' directly (which seems sensible). So for consistency's sake, let's keep it the same for libcanvas.
This moves MIDI channel filtering into a reusable class and moves filtering to
the source, rather than modifying the buffer afterwards. This is necessary so
that the playlist trackers reflect the emitted notes (and thus are able to stop
them in situations like mute).
As a perk, this is also faster because events are just dropped on read, rather
than pushed into a buffer then later removed (which is very slow).
Really hammering on mute or solo still seems to produce stuck notes
occasionally (perhaps related to multiple-on warnings). I am not yet sure why,
but occasional beats always.
Add "PERFORMER" to the exported .toc & .cue files based on the value of the
"album_artist" metadata field, and also use the value of the "album" field
for the TITLE if is set, falling back to the session or range name if it is
blank.
Invalidate all source entries from the image cache when we get our
region's DropReferences signal, while ignoring any subsequent regions with
no source.
Fixes bug #6166 (except record).
This attempts to follow the "current" control value somewhat aggressively:
* On locate, slider is set to the value from the top region at the new
transport position.
* Playback or MIDI input is followed "live".
* Whenever the slider is moved (including automatically), that value is emitted
as an immediate event to keep external gear in sync.
General idea is that the Ardour slider should act as a mirror of an external
hardware knob, and both should be synced to whatever the control is at the
current transport position. Since we lack real playback/touch/etc modes for
these for now, we must choose one behaviour, and this seems like the most
reasonable one.
Follow is handled in the audio thread, which is probably not ideal, but since
these controls have no lists and do not record, should be fine. Probably.
<oofus> rgareus: pre fader sends are not really used
for FX sends, they would either be sending to other
busses or to something like headphone/cue feeds.
You don't want those mixes having stuff muted in
them as you are muting you main mix.
ignore non-plugin processors for OSC
/ardour/routes/plugin/parameter
fixes issue with hidden internal processors. (rec-en
track adds a hidden [meter] processor at the top,
internal returns on busses have returns etc.)
Add an option to insert new routes at the top of the list ("First").
Reorder/rename the entries in the dialog.
Session's _order_hint is now the signed int it always wanted to be.
Fixes bug #6179. Top vs. bottom seems pretty arbitrary to me, and this solves
the obscuring issue (which is quite common since there are often PC events at
the start of MIDI files), so bottom it is.
When building with MSVC, some libraries had PROGRAM_NAME set to "Mixbus" and PROGRAM_VERSION set to "3". Whereas other libraries had PROGRAM_NAME set to "Mixbus3" while PROGRAM_VERSION was an empty string.
I've a horrible feeling there must have been a reason for this but I can't quite think what it was. Hopefully though, this change will standardize everything.
this is not a fix yet, just some comments and
code cleanup done while reading/investigating:
* limit reads to available write-space
* skip inactive tracks
* handle potential unsigned + negative value.
This breaks the build for windows builds that don't use the pthreads_win32
library. Using the opaque pthread_t type like this is probably not a great
idea. Using PBD::pthread_name is another option that I've used elsewhere
that seems more useful.
For some backends the process thread can change (e.g.
switch coreaudio headphone + internal speakers)
If there are existing x-thread event calls this can lead to
the following situation:
1) SessionEvent::operator new
2) audioengine process thread change
3) SessionEvent::operator delete -> crash, wrong thread
SessionEvent::operator delete can safely push the event back to
the pool for later cleanup..
Summary:
* use mmap() for the whole peakfile instead of lots of small seek/reads
* cache the computed peaks
* where possible, open files with O_NOATIME.
In summary:
* no antialiasing of waveviews
* no diagonal lines
* simplify clip detection
* don't use LINE_CAP_ROUND for outline
* use the wave colour when drawing outline only
Add a function TempoMap::meter_section_at(), similar to
TempoMap::tempo_section_at() but returning the meter section at the given
position, and use this to make editing meter changes from the main clock
work on the meter that's in effect at the current position.
The only user (matrix) does not care which bundles are added/removed.
This simplification will make it a lot easier to keep bundles
in sync with actual hardware ports.
Before this, LV2 preset deletion in Ardour was doubly broken: the wrong file
was being removed, and removing the correct file would only result in a broken
preset. This change uses a new version of Lilv which has a more sophisticated
mechanism for preset deletion.
Also, fix "clashing" presets saved with the same name for different plugins, by
prefixing the plugin name to the bundle (this is now a recommendation in the
LV2 preset specification).
* allow to change buffersizes
* subscribe to buffersize & samplerate changes
* add support for half-duplex devices.
* aggregate Devices (not yet used) code from JACK2
* unify deprecated API wrappers
* properly keep track of MIDI ports
* disable MidiI/O during freewheeling
* various small fixes & cleanup
This avoids stuck notes if active notes are edited, but without stopping all
active notes in the region on any edit as before.
This implementation injects note ons in places that aren't actually note
starts. Depending on how percussive the instrument is, this may not be
desired. In the future, an option for this would be an improvement, but there
are other places where "start notes in the middle" is a reasonable option. I
think that should be handled universally if we're to do it at all, so not
considering it a part of this fix for now.
Towards putting more advanced logic here, where two copies of everything will
get even more hairy.
The two cases of reading from one or many regions are not very different in the
read phase, the only difference is the target. So, point a reference to the
appropriate target, use the same read code in either case, then sort/etc
afterwards only if necessary.
(hopefully) fixes export randomly stalling on windows:
dequeue_request() was a single request (no queue) on Windows.
Butler::queue_request() is called
-> Butler goes to work..
-> while working, another request is queued
-> butler never sees this
-> deadlock
during Freewheeling/Export wait_until_finished()
waits for the 2nd request to be handled, and never returns.
MidiPort::cycle_end() was never called, hence after the
first cycle all midi buffers were assumed to be
“mixed down” already.
this fixes
Midi-track 1 -[midi]-> Midi-track2 synth -[audio]-> out
on export.
Ardour calls input_streams(), output_streams() to determine
if the plugin is about to be re-configured (old stream I/O count
!= new I/O count) and emit PluginIoReConfigure() if that’s true.
If the plugin has not been initialized (no format set), we can
safely assume that it will need to be reconfigured.
Forcing Audio=Midi=0 will do so.
The only time where the format is not yet set and hence the actual
channel count is still unknown) is during the first call to
PluginInsert::configure_io().
At the time of writing, this all is a NOOP anyway! The only user
of the PluginIoReConfigure() signal is the GUI to update connection
lines… and since the first PluginInsert::configure_io() happens
during insertion before the plugin is painted and subscribed to
PluginIoReConfigure(), this function could return any value.
Still 0,0 is just more appropriate than assuming mono audio in/out
and no midi.
It is less likely that these would cause issues because the
variables involved define the size of the data read, which
is almost certainly less than the 32 bit limit (i.e. they are
not positional). But to keep things clean and to keep questions
at bay, make them 64 bit values.
Best to just do this as early as possible to avoid having to deal with this
situation all over the code.
Also fixes violation of LV2 MIDI specification, which requires no such events
are delivered to plugins.
Silly to make a junk Note just to pass to append_note_off_unlocked, which just
uses the fields that are on the MIDIEvent anyway then throws it away.
Also explicitly dispatch to append_note_off_unlocked in the caller for note ons
with velocity 0 rather than make append_note_on_unlocked deal with it.
Session::unset_play_loop() needed to be a no-op if play loop was
already false, and this was exacerbated now that it potentially
schedules butler transport work.
Try to make sure that we appropriately reset and refill track
buffers whenever we enter/leave loop playback,and whenever
we locate. In addition, if we start playing somewhere other
than the loop range while loop is enabled, then the first
time we hit the loop end, set up the track buffers.
Conflicts:
libs/ardour/session_transport.cc
Those objects do not have a versioned API by themselves.
This fixes issues with duplicate deployment (OSX, Linux bundles: cp) and
ardour listing control-surfaces multiple times (file index plugin dir).
Add a test, based on the worked example in www.korf.co.uk/spline.pdf, for
the constrained cubic spline interpolation.
The delta values for the float comparisons are rather arbitrary, I'm sorry
to say: they're basically chosen so that everything passes.
Gtk coalesces multiple exposes into a single combined rect.
If _single_exposure is disabled, we break apart the individual expose rects for the canvas rendering.
undo (n) where n > 1
redo (m) where m < n
new transaction.
Previously the redo list was left untouched.
This would lead to utter nonsense in the redo list.
AFAICT this never worked.
clear_events() must run in realtime context, which is likely to be asynchronous
with respect to the thread that calls it. So allow caller to pass in a functor
that will be executed (also in realtime context) after the clear is done.
Additionally, allow for a cross-thread callback to the event loop/thread which
initiated/allocated the clear event request so that it can flush its own pending
loop. This part probably isn't necessary but doesn't hurt and is a useful model.
The event would be placed back in the free list at the next event allocation
by the calling thread anyway.
Expanded API splits apart some CrossThreadPool functionality, and provides
access to current pool status information (available(), total(), used(), pending_size())
The region is the un-coalesced set of rectangles that were requested for redraw. The area
is the coalesced single rectangle. In the worst cases, the coalesced rectangle could span
the entire window even though just two pixels in opposite corners were to be redrawn.
There is a problem with the verbose cursor as it is dragged across MIDI tracks. TO BE
FIXED.
The infinite loop would happen if the 2 supplied paths were on different Windows drives - for example if one was on drive C:\ and the other on drive E:\
I don't think this new test will be detrimental to the other platforms but if it is, we could easily separate it out with a '#ifdef PLATFORM_WINDOWS' directive.
This gets us around a problem when converting a session from the old (Ardour2) format - where the Session Range (start) value was getting incorrectly set if we hadn't already set the end value.
at the time the graph gets around to takes down
client threads, the jack-backend’s jack_client has been reset.
But never mind: libjack does not care about it, anyway.
Don’t statically initiate the lv2 world, use explicit call after
scanning bundles.
lilv_world_load_specifications() and lilv_world_load_plugin_classes()
are only ever called after lilv_world_load_all(), so we postpone
the call to it.
Don’t call ::output() [here: SilenceTrimmer::process()]
with no data to process.
If (position + N * period-size) % chunksize == 0;
frames_left == 0 before the last call to ::output().
chunker.h:60 keeps the ProcessContext<T>::EndOfInput
flag and the SilenceTrimmer will already have done ‘in_end’ processing.