13
0
Commit Graph

771 Commits

Author SHA1 Message Date
610b5dddbf ControlList: GUARD_POINT_DELTA needs to take time domain into account 2022-08-11 15:26:42 -06:00
5f5f4599f2
Fix MIDISource event-interpolation state save
The actual goal here is to use direct InterpolationStyle serialization
in MidiSource (identical to AutomationList). enum_2_string()
does not work for Evoral types.

As side-effect virtual base-classes have been changed to pass
Parameters as const references
2022-07-22 03:38:41 +02:00
0d70be3a05 miscellaneous fixes for warnings from -Wconversion 2022-07-04 22:01:48 -06:00
ca49bc00f0
Remove old "user" API, use consistent get/set_double() 2022-06-29 01:39:02 +02:00
3623b39168
Replace ::user_double() with ::get_double() 1/2 2022-06-29 01:39:02 +02:00
a4a241c738
Prepare replacing ::user_double() with ::get_double()
Automation Controls (and controls in general) are now
only updated in realtime context. Either via automation-playback,
or via SessioEvent. This directly sets the Control:_user_value
(before emitting the Changed signal).

The GUI does not need to evaluate the control at a given point
in time, so the API call can be removed and unified.

This commit first removes all calls to "get_double" to ensure
that no special cases exist.
2022-06-29 01:39:02 +02:00
0d9656ef82 use new macros to cleanup #ifndef NDEBUG as much as possible (libs edition) 2022-06-22 13:31:08 -06:00
9b80d6558a fix optimized unused variable warning 2022-06-22 13:31:08 -06:00
ad8e1c1cfd fix optimized unused variable warnings 2022-06-22 13:31:08 -06:00
ac18b84351 remove always-true-condition from if() to avoid compiler warning 2022-06-21 17:34:09 -06:00
c8feef51ab convert use of operator* for tim::line types with ::scale(ratio_t) 2022-05-27 12:47:44 -06:00
60e5b84d78 temporal: alternative solution to overflow in timeline operator*()
This uses boost::multiprecision::int512_t when multiplying and dividing by the numerator
and denominator of a ratio_t. 128 bits would be sufficient but for some reason, the boost
docs show the 512 bit variant being very slightly faster.

This is a better solution than using a double, which although it will prevent overflow
has fairly limited resolution.
2022-05-24 21:46:10 -06:00
Mads Kiilerich
c1c95f538f evoral: fix ControlList::_x_scale to avoid ratio overflow when adjusting fade length
Region fades would sometimes get in a mode with weird behaviour. They
would be drawn in 2d with crossing lines, mainly moving back and forth
horizontally - not as a function of time. It would sound as it looked.
The fade would sometimes jump around when resizing. It could be worked
around by resetting the fade shape. It turned out the problem could be
reproduced by making minute long fades.

This change fixes or works around the problem.

Back story:

timepos_t (in temporal/timeline.h) uses 62 bit for integer value and the
max value is thus 4611686018427387904 ~ 5e18. timepos_t counts
superclocks, where superclock_ticks_per_second is 56448000 ~ 6e7. It can
thus store up to 8e10 seconds - thousands of years.

ratio_t (in temporal/types.h) can represent fractions as 64 bit (signed)
numerator and denominator. timepos_t avoids floating point operations,
but has operator* with ratio_t. To avoid crazy loss of precision it will
multiply the superclock count with the numerator before dividing with
the denominator.

Audio region fade in and out uses a number of increasing timepos_t
values (in a ControlList) up to the length of fade. When dragging to
resize, these values are (in_x_scale) multiplied with the ratio_t of the
new and old fade length. The problem is that the 62 bits will overflow
if using fades more than sqrt(5e18) ~ 2e9 superclock ticks ~ 38 seconds.
It will overflow into the "beat" flag and (at 58 seconds) into the sign
bit. The timepos_t values in the fade will thus jump and can be negative
or change to count beats.

To work around that problem, this changeset just use floating point
values for scaling the timepos_t values. All scaled values are stored as
integer anyway, so it should not make any actual difference for this use
case. There might however be other uses of ControlList where it matters.

As an implementation detail of this "workaround" of using double, it
could perhaps also be nice to implement timepos_t operator* (or
operator*=) for double. But I'm not sure we want floating point support
in timepos_t.

An alternative (and better) solution would be to convince the fraction
multiplication to use 128 bits. It is essential to avoid overflow -
mainly in static analysis, alternatively as runtime checks or asserts.
2022-05-24 17:15:37 -06:00
cd332a2af0 when pasting a Range of automation, first add guard points,
so the automation data before and after this range is retained
2022-05-16 07:16:25 -05:00
3a174ff914 add support for 'positive' guard points in ControlList 2022-05-16 07:16:25 -05:00
c98561e95c when cutting or clearing an automation range, always add boundary points
* these guard points are necessary to retain the automation that existed
 before and after the selected range is removed
2022-05-16 07:16:24 -05:00
2b8b9a3a2f const for const-sake 2022-05-01 18:01:35 -06:00
d218dcb21b evoral: when adding points to a ControlList, coerce the time domain of the new point to the list time domain
This may not be the ideal solution, but for now it appears to be the best approach to preventing
points with different time domains with the same list
2022-05-01 17:50:51 -06:00
3454353aa3 remove concept of "note-mode" from Evoral::Sequence (and thus ARDOUR::MidiModel)
This note-mode had no effect on anything at all, at least as far back
as 5.12. There is a note-mode in the GUI which affects the duration of notes
added using the GUI, and that remains in place. It is not clear
if the _percussive member of Evoral::Sequence ever had any effect on
the actual MIDI event stream the Sequence could generate.
2022-04-05 20:52:09 -06:00
8657eba4c5 evoral: NOOP reorder and edit comments 2022-04-05 20:52:09 -06:00
8c3fad0133 evoral: fix implementation of rt_safe_earliest_event_linear_unlocked
Code within the method was using @param start_time rather than start, which is a modified
value required to generate the correct results.

This comment also contains some logical reordering, optimization and commenting
on this rather complex method.
2022-04-05 20:52:09 -06:00
256e6f97a2 evoral: change how we specify a zero min_x_delta to rt_safe_earliest_event_linear_unlocked
See comment in the code for more details.
2022-04-05 20:52:09 -06:00
5fbc390821 evoral: NOOP whitespace adjustment 2022-04-05 20:52:09 -06:00
83dc2fe407 evoral: change interpolation distance to match 6.x
Note that the value is still defined in Beats (ticks) rather than seconds
which means that the interpolation density is tempo-dependent. This
should still likely change one day.
2022-04-05 20:52:09 -06:00
176c41a485
Fix region-gain when region-start is trimmed
Region-gain (unlike other automation) is specific to the
region and independent of the source. Region::start() offset
does not apply. When region-start is trimmed the region's
envelope is modified (not just offset). The event-list is truncated.

Any audio-region envelope does (and must) have a point exactly
at the start and end of the region.

truncate_start() can thus calculate the earliest position of
valid events with the new length relative to the last event.

The mathematical operator for that is subtraction, not distance.
2022-03-17 23:46:55 +01:00
eced764480 smf_source: implement SMF::UsedChannels as a bitset; move midi screening into load_model()
we screen midi files for some aggregate info:
 used channels, used patches, and note-count

you can't do this from open() because there are cases (after importing)
 when the source exists but it is not yet written to disk
2022-03-01 10:11:14 -06:00
b96b97c439 PatchChange: fix set_channel() 2022-03-01 10:11:14 -06:00
fc3abecca0 PatchChange: yet more checks to keep patch state in sync (is_set())
* fix the case for creating an empty, unset patch
* fix is_set() for bank changes: 2nd byte is the one that gets 'set'
2022-03-01 10:11:14 -06:00
f9dbe34900
Add missing include 2022-02-08 21:24:54 +01:00
cd53301d06
Significantly speed up loading SMF tempo-maps
Files that have many tracks, each with tempo information
were near impossible to load (30+ mins on modern 4.2Ghz CPU!),
because tempo is parsed incrementally:

```
For each new track:
  for each new tempo-event:
    rewind()
    for each loaded track so far:
      for each event on this track so far
```

This reduces the complexity from O(tracks^2 * tempos^2)
to O(tracks * tempos).

"Come Thou Fount Tempo Map.mid" has 238 Tracks and 56168 total
Tempo Changes (236 per track). This now requires only 56168 iterations
in smf_create_tempo_map_and_compute_seconds, rather than 1.64e+9
iterations
2022-02-05 17:33:21 +01:00
207ad2d369
Add API to query SMF note-count and pgm-changes
This information is useful for trigger-clips, in particular
if the file can change synth-settings via patch-changes.
2022-02-05 17:33:21 +01:00
12e8235193
Add API to query set of used MIDI channels in a SMF 2022-02-05 00:13:27 +01:00
374faa0d5c PatchChange: use correct hwx constants to detect/set "unset" byte values 2022-02-02 15:06:11 -07:00
31f4d8a2ca PatchChange: fix operator=() implementation which failed to manage event buffer ownership correctly 2022-02-02 15:06:11 -07:00
603d1f1f57 evoral: some changes/extensions to Evoral::PatchChange to make it more useful
The concept of an "unset" PatchChange now exists, and thus a default constructor that constructs
such a thing
2022-02-02 15:06:11 -07:00
2eadb75bd1 move static scale_midi_velocity() function from Amp to Evoral::Event 2022-02-02 09:58:57 -07:00
Mads Kiilerich
8bb91099c5 wscript: drop configure statements already present in the top level wscript
Avoid repeated pointless configure messages like:
Checking for 'g++' (C++ compiler!)                   : /usr/lib64/ccache/g++
Checking for 'gcc' (C compiler)                      : /usr/lib64/ccache/gcc
2022-01-22 22:19:03 +01:00
16511974e2
Fix class/struct mismatch C++ ABI [-Wmismatched-tags] 2022-01-10 00:06:24 +01:00
e295e1c8d7
Disable evoral unit-tests -- nutempo update is needed 2022-01-03 01:11:54 +01:00
60be0c27a1
Use updated temporal API 1/2 2021-12-11 14:42:36 +01:00
0733b2d9e2 SMF: Often files don't have Track+Instr names. Make something up to avoid file collisions. 2021-11-13 15:54:11 -06:00
35312dc85c SMF: API change: report format (0,1 or2) and total channels used 2021-11-13 15:54:11 -06:00
c74f80caa4
NO-OP: clean up maths, remove extra brackets
This may also help due to huge xdelta numbers.
2021-09-02 20:45:30 +02:00
940f3022c1 prevent addition of events to a ControlList whose time-domain does not match the ControlList's own time-domain 2021-08-30 15:15:14 -06:00
4fb3e24bd6 evoral: tentative fix for problems with Curve::multipoint_eval()
Now that we use superclock_t for audio time, it is possible for the square of an audio time value to overflow int64_t quite easily.
This change fixes that (and cleans up other code a little), but probably a different solution would be a good idea
2021-08-30 14:29:11 -06:00
0699449f29 evoral: debugging curve errors 2021-08-30 09:04:27 -06:00
4cef8c681c evoral: fix for Curve coefficient computation 2021-08-30 09:04:27 -06:00
9a53ef4020 libevoral: fix some existing or potential issues with time domains 2021-08-13 12:51:34 -06:00
e11ecd56a9 libevoral: avoid use of std::numeric_limits<timepos_t> which does not (or should not) exist 2021-08-13 12:51:34 -06:00
87e56f28e9 libevoral: remove semi-shadow local variable 2021-08-13 12:51:34 -06:00
6d154c14b4 libevoral: add a new method to set the time domain that can be used from ::set_state(), when the event list is not (yet) empty 2021-08-13 12:51:34 -06:00
1a41e98c1c improve comment for future readers 2021-08-13 12:51:33 -06:00
068cc4135f remove another NUTEMPO #warning (see comment) 2021-08-13 12:51:33 -06:00
7c10cf1d54 Automatable now requires (and owns) a time domain to be used by automation data 2021-08-13 12:51:32 -06:00
1a5e2aacff remove another NUTEMPO warning 2021-08-13 12:51:32 -06:00
7c61fe405c Evoral: cleanup for explicit Beats::operator bool() 2021-08-13 12:51:31 -06:00
779a04b0ce Evoral: alter ControlList::paste() to internally change time domain of pasted events 2021-08-13 12:51:31 -06:00
bed76798f3 manual fixups after rebase against master (general libs edition) 2021-08-13 12:51:31 -06:00
18fea5c7a9 changes required by fixing ambiguities in timepos_t/timecnt_t API (evoral edition) 2021-08-13 12:51:31 -06:00
def35cf043 mark BBT_Offset (double) constructor explicit to avoid implicit conversion in timeline expressions.
Also clean up the mess this had caused.
2021-08-13 12:51:30 -06:00
ebd8704f9d libevoral: tweaks related to timeline types based on libardour conversion 2021-08-13 12:51:29 -06:00
6b09642406 changes to compile against libtemporal and use of timepos_t/timecnt_t 2021-08-13 12:51:28 -06:00
f4490f54c5 change Timecode::BBT_Time to use Temporal namespace, plus a couple of other minor changes to enable compilation
This still uses the tempo map object in libs/ardour, not the new one in libs/temporal, and isn't likely to be functional
(though it could be)
2021-08-13 12:51:28 -06:00
d58e7c7ee4 Revert "fix handling of SMF files with consecutive noteOn events"
This breaks MIDI files that have events ordered On,On,Off,Off, and only fixes
the "malformed" On,On,Off. Correct fix requires collecting all events occuring
yat one time, sorting into Off,On and then merging.

This reverts commit 5c3e5f9afb.
2021-06-29 17:29:29 -06:00
5c3e5f9afb fix handling of SMF files with consecutive noteOn events
We no longer store nascent notes when noteOn is received, but wait till noteOff arrives. We also
ignore all other noteOn events between the earliest received and the noteOff.

Potentially we may want to use the _overlap_pitch_resolution member at some point
to offer control of this behavior.
2021-06-28 08:30:38 -06:00
336319a1df SMF meta-events do not set running status while parsing the file 2021-06-22 14:18:03 -06:00
c45be2266e support SMF markers without labels 2021-05-09 17:52:29 -06:00
f689e9ecab Evoral: add methods to SMF to load and access markers/cues in SMF files 2021-05-07 14:58:16 -06:00
cc7b8b1bc5
gcc-11 compat, volatile atomic variables (1/2)
"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
2021-03-22 15:30:07 +01:00
7e1ce160e9
ARM 32bit enum alignment (used in MIDIBuffer)
Evoral::EventType is written directly into a uint8_t buffer
by dereferncing a pointer-type:
*(reinterpret_cast<Evoral::EventType*>((uintptr_t)...)
2020-09-28 01:21:43 +02:00
472fe2b556
Prepare for distinct live-midi event type
The motivation for this is to determine if a given event
originates from a user-controlled live input controller or
from playback from disk or a MIDI file.

This distinction is required for VST3 MIDI learn.
2020-09-20 17:16:53 +02:00
b9cfb31205
Fix control-list editing (#8384)
This fixes segfaults as well as corrupt listes when copy/pasting
due to invalid iterators.

::mark_dirty() must be called with WriterLock, and
::rt_safe_earliest_event_linear_unlocked() must not be called
while _events is being modified. The Sequence iterator
(only user of that function) does not ensure this. Only the
sequence read-lock is taken.
2020-08-31 07:39:45 +02:00
65ecc1b40e
Do not interpolate away explicit MIDI automation points #8362 2020-08-15 01:57:01 +02:00
e4c56a0371
Remove unused API
These are longer be used since Seuqnce has a "force_discrete"
boolen that needs to be taken into account in addition to
user-configurable ControlList _interpolation mode.
2020-08-15 01:56:42 +02:00
c6b87972b1
Remove unused libsmf seconds/time API
This significantly speeds up parsing MIDI files with complex
tempo-maps. e.g. "Black MIDI Trilogy_2.mid" has 24134 Tempo
changes. Prior to this commit parsing that file took over 5 minutes.
now it loads in under one seconds (libsmf only; libardour still
add overhead, and now needs about 30-40 seconds, previously
it took about 10 mins).

The problem was that every call to `smf_track_add_event_pulses()`
calls `seconds_from_pulses()` which calls `smf_get_tempo_by_seconds()`
which iterates over the tempo-map:

  for every midi-event { for ever tempo until that midi-event {..} }

This does not scale to 3.5M events and 24k tempo-changes.
2020-07-16 18:38:03 +02:00
ba7db8759b
SMF: remove unused variable (from 803dab7d87) 2020-07-16 18:35:43 +02:00
803dab7d87
SMF: various backports from libsmf PR7
see also https://github.com/stump/libsmf/pull/7

* Fix validity checks of escaped data
* Handle non-EOT-terminated tracks.
* Fix buffer overflow on tempo change event
* Fix memory leaks in case loading fails
* Fix a logic errors in extract_escaped_event()
* Fix the assertion problem `is_sysex_byte(status)`
* Make libsmf more tolerant to malformed MIDI files.
  (fixes import of files generated by NoteEdit)
2020-07-16 18:00:40 +02:00
23e6dd5f6b
NO-OP: backport some libsmf doc and warnings 2020-07-16 17:58:04 +02:00
43158047ed
SMF: use glib macros for endian conversion 2020-07-16 17:57:59 +02:00
650fd31332
Improve debug message 2020-06-12 05:08:40 +02:00
Daniel Appelt
522d6d769c
Add ControlList docs that are relevant for Lua 2020-05-28 18:52:02 +02:00
44bca6cc8f
Fix memory leak when reading MIDI files 2020-05-22 01:29:25 +02:00
447b473a1d slight better warning/debug message for a stuck note to-be-deleted 2020-05-04 18:48:17 -06:00
c264ab6c95
Remove debug output 2020-04-23 02:29:45 +02:00
9a93583ef7 fully initialize SMF tempo information to default (4/4, 120bpm)
Leaving CPC and 32nd-per-quarter at -1 causes arithmetic errors later if the SMF
file doesn't contain an explicit time signature meta-event
2020-04-21 21:17:14 -06:00
5c789547cb
Fix building unit-tests 2020-01-27 17:43:37 +01:00
3b65b430aa
Remove midi-event by iterator, not key -- #7885
With concurrent events removing by key, allowed for invalid
iterators.
2020-01-25 22:15:37 +01:00
06b2eb1c27
Explicitly use OSX
Previously this was inherited via PBD.

On MacOS/X,  this adds
  "-undefined dynamic_lookup -flat_namespace"
and various "-framework .." options to linkflags

Without this flag, .dylibs fail to link usually because
of missing `-lintl` (Undefined symbols: "_libintl_dgettext")

On other systems this is a NO-OP:
CFLAGS_OSX, CXXFLAGS_OSX and LINKFLAGS_OSX
are only set on the darwin platform.
2020-01-25 04:07:41 +01:00
Nikolaus Gullotta
4b355868cc Fix test breakage from a855119bdd 2020-01-16 14:01:18 -06:00
d79e869da8 use "extends to numeric_limits<Beats>::max()" rather than "zero length" for nascent (incoming) notes 2020-01-11 10:57:21 -07:00
8547a23e9c removal incorrect/unnecessary forward decl 2020-01-11 10:57:21 -07:00
39bdde4250 Use labs() for long instead of abs() 2019-12-09 23:25:51 +01:00
7d90ad4023
Fix bool-automation anchor
Typo sneaked in from ff2f93497...cc7de475f2
2019-11-13 16:53:46 +01:00
John Emmas
c7bdc38c95 Accommodate some recently moved/renamed folders and source files (libevoral) 2019-11-03 13:46:29 +00:00
eaae38ba84 move evoral/src/* to evoral/ 2019-11-02 16:32:18 -06:00
a855119bdd rename all Evoral source from .(hpp|cpp)$ to .(h|cc) 2019-11-02 16:32:18 -06:00
88f9aaff7d
Add API to safely query timestamp of first/last control event
Direct calls to back()->when or front()->when are not safe
when the list is concurrently modified, or empty.
2019-10-18 01:37:56 +02:00
e0d5c1426c
NO-OP: fix some Wimplicit-fallthrough
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
2019-09-18 17:37:54 +02:00
cb3afb6981 Remove a (no longer needed) source file from our MSVC project (evoral) 2019-09-18 15:05:16 +01:00
60bce78c7e
Fix Wdeprecated, dynamic exception
Dynamic exception specifications are deprecated in C++11,
and were removed in C++17.
2019-09-18 04:43:09 +02:00