gcc can recognize various regexps in comments. Since C++17 provides
[[fallthrough]], using /* fallthrough */ consistently seems
appropriate until we switch to C++17.
see also https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
A "fall through" comment is most portable way to indicate
"no break, fallthru" cases.
* __attribute__ ((fallthrough)) // is not portable
* [[fallthrough]]; // is C++17
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.
smf_delete() does not handle NULL, and segfaults instead.
This only crashes with optimized builds.
libsmf will call g_critical() earlier and in that case debug-builds
call UI::handle_fatal() and ask the user to "click to exit".
This is mostly to see if there'll be any problems when merging these changes into Mixbus. I'm guessing there'll be some conflicts in these projects (and a lot more to follow...)
* lock list when editing (prevent concurrent modification of insert
iterator
* don't add a guard-point if an event is already present between the
target and guard-point-position
* remove existing automation-events (old guard points) when
touching automation w/o change
* don't unset "new write pass" when not rolling
(fixes issues when not rolling but locating with write-enabled)
AudioRegion::set_fade_in() freezes the original ControlList, then
assigns a new one and thaws that.
Frozen state needs to be retained during assignment.
Related: The overloaded assignment operator in AutomationList
performed duplicate signal emission and didn't freeze the list.
Ardour may have ignored log-scale for parameters 0..N and allowed
writing '0'. Force those values into the valid range on session load.
Also mark the list as "needs sorting" which removes potential duplicates.
The Control and ControlList uses the raw value (eg. coefficient for gain,
Hz for frequencies) and those Lists are stored in existing sessions.
In the vast majority of cases interpolating automation values using exp/log
scale for dB, freq makes more sense -- it's also what the fader does.
Adding additional interpolation methods is future proof (we might at allow
to even add different methods per automation point (to the next) like other
DAWs do.
Currently it's mainly used in preparation for consistent GUI automation-
lanes. Between 2 points there's always a visual straight line.
This allows complete mathematical description of a given parameter
and parameter values.
Semantic type abstraction is reserved for Ardour::ParameterDescriptor.
This fixes copy/paste of MIDI automation (time-unit: beat) from/to
Parameter automation (time-unit: samples).
It also fixes repeatedly pasting with tempo-ramps: pre-multiply length
before converting to samples.
Just an update to slightly rotten wscripts, shouldn't be any changes during an
ardour build. Motivation being a short development cycle for working on evoral
and/or its test suite.
Note the old Note::operator= was unsafe, since it made shallow copies of the on
and off events, which results in a double delete of events when the notes are
destructed.
I'm not sure if this is really the best way to do event types (should it
just be a completely static enum in evoral, or completely dynamic and
provided by the type map, or a mix like currently?), but previously the
event type was frequently set to either total garbage, or parameter
types, which are a different thing.
This fixes all those cases, and makes Evoral::EventType an enum so the
compiler will warn about implicit conversions from int.
It is slightly questionable whether type specific methods like
velocity() belong on Event at all, these may be better off as free
functions. However the code currently uses them as methods in many
places, and it seems like a step in the right direction, since, for
example, we might some day have events that have a velocity but aren't
stored as MIDI messages (e.g. if Ardour uses an internal musical model
that is more expressive).
In any case, the former inheritance and plethora of sloppy casts is
definitely not the right thing.
eg. import a .mid that has a CC later in the file.
Arodur wrongly added an initial point, effectively moving the event
backwards to "0" (no virgin territory)
uselib is no longer implicit (inherited by .use). This is still incomplete,
some uselibs for non-linux variants may be missing.
bld.is_defined("HAVE_XXX") also no longer works and will have to be
changed (I think to bld.env["HAVE_XXX"]) in countless places.
libevoral itself doesn't seem to need libpthread - but by some mechanism it #includes <pbd/event_loop.h> (which now does #include <pthread.h>). So let's make sure it can be found.
- disallow simultaneous events via ControlList::editor_add ()
- clicking on an automation line selects the points that define it.
- don't 'flash' a region selection when using mousedraw mode.
- cp click selection resembles region selection.
- region gain points respect snap modifier (a la automation points).
PluginInsert::automation_run() subdivides plugin-run on every
control-port automation event (without splitting the process cycle).
libevoral has no automation-control context, hence this function
must be implemented by Automatable.
Iterating over a const Midi-Sequence calls Evoral::Sequence::set_event(),
which in turn used Evoral::Event::operator=() which always created
a new event-ID (create copy of the event).
Issues fixed:
- Saving *unmodified* MIDI produced new event-IDs on every save;
files changed with every save. - greetings to Deva.
- all [GUI] operations that use IDs to refer to notes e.g. undo.
invalid undo-history.
Also clarify assignment operator name. Prefer explicit assign() over =.
Evoral::Beats::operator>() rounds to (1.0 / PPQN), hardcoded 1/1920.0.
If the time difference between two events is smaller than 1/PPQN,
Beats::operator>() and Beats::operator<() produce ambiguous results.
The same pair of values is both "less than" and "greater than" depending
which operator is used.
While it's fine for some cases to ignore the order of nearly concurent
events, the std::priority_queue must be strictly ordered.
- don't keep setting/unsetting write pass when transport frame
remains the same (think larger jack buffer sizes)
- insert guards are now 64 frames after when.
- refactor previous approach.
- clearing automation points sets control to "off" rather than touch.
- multiple touches on the same pass acts consistently (no more
fader jumps on mouse button press
- use actual value for initial point rather than some arbitrary
default. clarify new semantics of add () (with_default->with_initial).
- clean some whitespace
- add guard points as needed in stop.
- catch grab broken signal (i can't trigger it, but the docs seem
to think it is essential).
- probably fixes a lot of cases where note ids are assumed to be
unique (they weren't for copies and some others).
- wrong branch, but it needs testing.
towards fixing #6238 and #6096.
GUI thread:
#2 Glib::Threads::Mutex::Lock::Lock
#3 Evoral::ControlList::eval
#4 Evoral::Control::get_double
#5 ARDOUR::AutomationControl::get_value
#6 ProcessorEntry::Control::control_changed
..
#15 PBD::Timer::timeout_handler
at the same time: Audio Thread (try-lock, fails)
#0 Evoral::Curve::rt_safe_get_vector
#1 ARDOUR::Amp::setup_gain_automation
#2 ARDOUR::Route::process_output_buffers
Due to the failed try-lock.. AMP::_apply_gain_automation
is false. and Amp::run() uses a different gain factor.
-> click.
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.
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.
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.