Code used to just push back new markers to the end of the relevant list, and
this would then the new marker to be deleted soon thereafter. Instead pass
an interator indicating where to place the marker in the list.
Note that we rely on the use of std::list<T> here to keep the iterator to the
existing marker valid.
This used to be a distinct kind of drag, but ended up being refactored into
something that happens during a regular drag. Has not been used in quite some time.
We need to delete all existing region views before we redisplay the track. This
was removed as part of an "experimental performance optimization" in 4f7a4cd233
but playlist switching is a rare and non-performance limited operation
Note position in samples must be calculated using absolute position
on the timeline. Otherwise the tempo-map is not applied correctly.
Previously this caused issues since the position was first
offset back by _region->position() - time relative to region left
edge - and then the tempo-map was applied.
Another solution identically would be:
(note_start + session_source_start).samples() - _region->position().samples()
Since we're reconnecting visible marker objects with a new map, there's a good
chance that the map will contain map points that don't correspond to the map
points currently referenced by those markers. Thus, tests for address
equivalence will often fail.
Instead, repeat what has been done elsewhere and use the heuristic that we only
allow one point of a given type at the same superclock position.
UIConfig insert-at-position saves/restores the enum as integer.
This is used directly as parameter for insert_at_combo.set_active().
For this to work, the enum needs to match the order of elements
in the dropdown.
It would be preferable to register the enum, and map the
dropdown entries, but for now this does the trick, without
breaking existing UIConfigs.
PresentationInfo::Change (Properties::selected) is emitted and
handled before Mixer_UI::add_routes() is called. At that point
in time the MixerStrip(s) to be selected may not exist.
Visual selection state was lost.
Furthermore move_stripable_into_view() calling translate_coordinates()
only works after GTK has completed the resize operation.
This lead to the mixer scrolling back to the left edge when creating
new tracks.
Also each selection change caused all tracks to be re-packed.
Now redisplay_track_list() is only called if visibility or order
changes. This signficanly improves performance with large sessions.
fix bindings to shifted symbols (see below)
add shortcuts to recorder, virtual midi keyboard
change shortcut (secondary+c) from Big Clock to Cue page
(*) shifted symbols like '+' are accessed in a very specific way, like:
<@TERTIARY@>plus
and
<@SECONDARY@><@TERTIARY@>plus
RegionView::make_name already adds the prefix, AudioRegionView
does not need to add it again.
Also the font used on macOS (Lucia Grande) has a rather limited
UTF-8 charset and does not support:
\u20F0 (COMBINING ENCLOSING CIRCLE BACKSLASH)
\U0001F507 (SPEAKER WITH CANCELLATION STROKE)
so for now we keep using "!" on macOS.
* expand/shrink track height
* stem-export selected tracks
* create a range from selected regions
* consolidate range
* add a single Range marker for selected region(s)
* unlink (fork) midi region from linked regions
* toggle plugin manager window
* fixed shortcut for Crop
* moved "audio patchbay" from Alt-P to Alt-Shift-A,
making it more consistent with Alt-Shift-M: MIDI patchbay
See also 89a85da52c
* Fix deflection when using percent (use sqrt/pow2)
* Simplify linear deflection when using semitones
* Allow deflection of > 200% when using semitones
The AudioClock uses samples. Duration calculation is
done using the current clock pos. The returned distance is
using Beats, can be directly used for all notes regardless of their
position.
Now that this works correctly the dialog can also be made available
for multiple-selection.
Better version of 817fccb3e5, the visibility should not depend
on the number of items in the dialog, but its requested height
vs screen height.
The main use-case is to not show the scroll-bar if the dialog has only
a few rows. Then again if the scrollbar is visible, the dialog
should not shrink below a reasonable min. height.
Mixer-scenes are session objects, and the signal must not be
connected across session instances.
This fixes a read-lock after write-lock when switching snapshots:
Session::set_state -> MixerScene::set_state ->
MixerScene::set_name -> Change(); /* emit signal */
... -> Mixer_UI::update_scene_buttons -> Session::nth_mixer_scene
The design ignored the ratio computed by the drag interaction, and relied on getting the stretch
ratio from the dialog. This truncated the actual ratio, leading to (relatively) small errors
in the length of the generated region.
Now, if the ratio provided by the drag is not (1/1) (i.e. a single click while in timefx mode)
then the percentage stretch spinner is marked insensitive and the stretch ratio is taken from
the given ratio. For single clicks, the user can still adjust the percentage as they wish
Disable the "More" button when search parameters change. The button is
supposed to continue the current search, but if any of the search
parameters (tags, sort, or licence) have changed, that doesn't really
make sense. Just disable it if the user changes any of them.
Make sure that filenames in the freesound results list are escaped
properly for the tooltip, and append the full licence URL returned to the
tooltip too.
Make the filename column Gtk::TREE_VIEW_COLUMN_FIXED, so that it doesn't
expand to the width of the longest filename in the results and push the
columns to the right out of view. Resizing the import dialogue larger
still allows longer file names to be seen, and it's still possible to
manually resize the filename column as well.
Only show the hours & minutes in the duration column if they're non-zero,
and justify them right.
Add a drop-down list to the freesound import tab, to optionally restrict
search results to "CC-BY", "CC-BY-NC", or "PD" only licensed sound
files. Defaults to "Any", which will return sounds with any licence.
* keep shuttle and mouse position in sync when dragging
* do not show speed options above max-transport-speed
* use quadratic deflection with speed percentage
* reduce knob width since the slider is rather narrow these days
```
#3 in __assert_fail
#4 in Temporal::TempoMap::use
#5 in Temporal::timepos_t::_superclocks
#6 in Temporal::timepos_t::superclocks
#7 in Temporal::timepos_t::samples
#8 in ARDOUR::Region::position_sample
#9 in ARDOUR::RBEffect::run
#10 in Editor::do_timefx
#11 in Editor::timefx_thread
```
This also invalidates any prior libardour rc-config
(which was not previously exposed as config).
Note: old existing cache is not moved or invalidated
when the path changes.
Ardour's "pbd/i18n.h" needs to be included last,
after all template specialization, otherwise there will be
an ambiguity:
```
boost/function_types/detail/class_transform.hpp:23:26:
error: ‘boost::mpl::placeholders::_’ has not been declared
using mpl::placeholders::_;
```
Add a new client id & token for Ardour 7, and update to Freesound's API
v2.
Implement OAuth authentication for Freesound downloads, as described at:
https://freesound.org/docs/api/authentication.html#oauth-authentication
Open the Freesound login page in the default browser, so that the user
can log in and get an authorization code, to copy-&-paste from the
browser. Exchange this authorization code for an access token, and use
it in a custom 'Authorization: Bearer $TOKEN' http header.
If logging in to Freesound to download a file fails or is cancelled,
clear the 'downloading' flag for that file in the list so that a
subsequent click on it will try to log in again.
Show login progress in download progress bar, and disable preview if
file hasn't yet been downloaded.
If a download fails for any reason (except the user cancelling it),
report an error in the Log window.
Use curl_free() for pointers returned by curl_easy_escape(), as per the
curl documentation, rather than plain free().
Also, don't use the www. sub-domain of freesound.org: although it
appears to work for most things, it returns an empty document from
https://freesound.org/apiv2/oauth2/access_token/
Remove default empty token value from Mootcher constructor, to make it
explicit when we construct a Mootcher that doesn't require
authorisation, by requiring an empty token parameter in that case.
The RecoderUI can show device input meters as long as a backend is
running regardless of a session. I/O Plugins are however
part of a specific session.
* control points that were already closer than one_tick_in_pixels
were able to move beyond adjacent points, resulting in out-of-order lines
* prior code was using 'one tick' as the smallest spacing between two
CPs, but that is larger than the default 'guard point' spacing. this
resulted in odd behavior because of the dxt calculation when you moved
a point that was created as a 'guard point'
For now, use the same 64 samples we use for 'guard points'. And change
the 'dxt' calculation logic to more aggressively limit the points from
overlapping.
TODO: we might decide that 'one tick' should be the minimum automation
period throughout ardour. In that case we should change guard-points.
* in the case where there are no existing automation points, then
initiating an automation range drag (select range, switch to Draw)
should initialize the line at the current knob position
Stem-export defaults to use selected tracks. This retains
the selection, so focus remains. Repeat stem export will use
previously exported tracks if the selection is empty, or the
current selection (again).
citations are needed to explain when&how this is useful
the definition of Ripple is "accommodate cut/insert/moves by moving all
regions to the 'right' (later) of the operation by the same amount".
moving markers to the 'left' of the grabbed_region explicitly breaks the
definition of ripple. it makes documentation hard.
furthermore, in a more complicated session with multiple tracks, this behavior
ignores the regions on other tracks and the markers that still might be
associated with them (consider the case where you move the first region
on track A but there are many prior regions on track B with markers over
them)
The state was inconsistent after using the "All" buttons, causing
confusing behaviour. Most visibly, the message "No timespan has been
selected!" message and the disabling of the "Export" button were not
cleared.
Fixed by making
ExportTimespanSelector::set_selection_state_of_all_timespans call
update_timespans and CriticalSelectionChanged , like for example
ExportTimespanSelector::update_range_name and
ExportTimespanSelectorMultiple::update_selection do.
this prevents the case where have enabled snap, and you add a note that
appears to be on a bar line. but actually it is {some Grid value} off,
it just looks right because of pixel rounding.
This fixes the issue where you click to create a note, but move the mouse
just a little, resulting in a note of invisibly small length
Do the calculation in ::motion so it displays the final
size while you are dragging. "what you see is what you will get"
* move abort_reversible_command into the correct bracketed location
* check for missing _session at top of function to avoid unnecessary nesting
* this fixes an undo 'assert' when an action like "clear xrun markers" has no effect
* this was likely a copy+paste thinko since they are adjacent in the code
these functions operate on the _note_diff_command,
which is explicitly a NoteDiff, not a generic DiffCommand
also fix a few thinkos where the ambiguous naming led to errors
This splits apart the actual signal handler from the work that needs to be done
to update the GUI in response to a tempo map change. This allows us to do the
visual update when we are manipulating the thread-local write copy of the map
during e.g. a drag operation.
This is in preparation to always show a line, which show
the current value in case there are no automation points yet.
It also unconditionally snapshots the current value without
changing automation modes to touch/write first.
The virtual keyboard sends all events with the same timestamp.
When playing fast (mouse-sweep) note-on and note-off will have
the same timestamp.
Since dbd8089fb8, a393f75694 concurrent MIDI are sorted with note-off
first. This correctly handles events when played from the timeline:
note-on .. note-off|note-on ... note-off
But in case of a MIDI keyboard a note-off event must be send after
the note-on.
The ::start_drag() implementation now defers add/extend selection logic to
MidiRegionView::note_selected(), and drops the original limitation that we did
not do extend-selection on button press, only button release.