The issue is that when ExportDialog is destroyed
ExportFileNotebook::FilePage::on_hide is called which in turn calls
ExportProfileManager::save_format_to_disk() in order to save changes to the
analysis and soundcloud upload checkboxes. This then causes the
ExportProfileManager::FormatListChanged signal to be emitted, which in all
other cases is emitted when the format list is modified so that the GUI can
rebuild the format selector menu in ExportFormatSelector::update_format_list
when a format is added or removed.
The problem when doing this in the destructor is that some of the widgets have
already been destroyed, specifically the issue was in
ExportFileNotebook::update_soundcloud_upload trying to access the
soundcloud_selector member that had already had its destructor called.
As it is not necessary to call this signal in the first place and it just
causes unnecessary GUI updates remove the signal emission.
let the user/developer know if this does occur rather than just silently
skipping the file.
Fix some whitespace issues while we are changing indentation.
The paths are in UTF-8 encoding and ::rename expects paths in the system
codepage encoding so ::rename will fail for any paths that contain characters
that aren't in the system codepage.
This fixes Flush Wastebasket on Windows where paths contain characters that
aren't in the system codepage(usually most non-ascii characters).
The path is in UTF-8 encoding so use Glib functions to properly support paths
containing characters that aren't in the system codepage.
This fixes Clean-up Unused Sources on Windows where paths contain characters
that aren't in the system codepage(usually most non-ascii characters).
Some Mixbus users (on Windows) have reported seeing ludicrously high figures for the amount of disk space that'll be recovered if they choose to clean up unused sources. I can't see anything obviously wrong in Ardour's code - except for one situation where we don't check a return value after calling 'g_stat()'.
On Windows, the relevant path should be (hopefully!) in UTF8 format and the first thing that g_stat() does is to convert it to UTF16. If that conversion fails for some reason, g_stat() will return an error status and statbuf will be uninitialized - but at the moment, we're not checking this. As an experiment, let's check the returned value and find out if these user reports go away.
Unfortunately, if it does fix the problem then we've got an even bigger problem - because somehow, a Windows user can create source files with invalid names which can't be later deleted!!
Clearing location markers is a frequent task and should be automizable. For
example it is handy to clear all the markers when restarting the recording
from scratch after a failed recording.
If a Session is saved and then the start or end session markers are moved,
closing the Session will not result in "Unsaved Session" dialog being presented
even though the Session has been modified. This change sets the Session as
modified when either the Session start or end markers are modified.
- after reports that a tempo with non-4.0 note type
would produce a ramp in the preceding section, an incorrect
assumption was made leading to a bogus 'fix' that redefined
Tempo's pulses_per_minute().
the real fix was simple:
the ramp's function constant was calculated using the note type
of the proceding tempo rather than the current one.
- this patch reverts e82482e8e9 and a4d67279e0
and maintains the old definition of Tempo::pulses_per_minute()
This [hopefully] fixes jack1 zombification on session-load with large
plugin-states. Previously it was possible to block
Route::process_output_buffers().
and also allow immediate work during use latency-compute runs.
At session load, Ardour calls a plugins "set default" state (GUI thread).
Some plugins may schedule work during state-restore. Ardour immediately
proceeded to restore the actual session plugin state without processing
the already scheduled work and without calling run() for a plugin
to apply state synchronously.
The code computing the position of the popup menu used to compare the
given string to each MenuItem::get_label() result, but that method
actually replaces the content (child) of the MenuItem if that child is
not already a Gtk::Label. In particular, this breaks menu separators.
Avoid the issue by checking by hand if the only child of the MenuItem is
a Label, and directly compare the label text.
Because all uses of the function positioning menus anchored to a widget
were as callback argument to Gtk::Menu::popup() where the caller needed
to correctly bind arguments, this led to repeated and a bit obscure code.
Wrap the logic into an helper function that takes care of all that, and
update the callers.
This mostly fixes an issue with notifying plugins about tempo-ramps
and BPM changes.
remaining to be fixed (in tempo.h):
```
_session.tempo_map().metric_at(frame_position).tempo().beats_per_minute()
```
currently returns the most recent *fixed* tempo at or before
`frame_position`. All other Plugin types are affected by this as well.
- don't alter region frame length on tempo change or position change.
- set region _start correctly (see comments) on tempo map change.
- ensure audio-locked region's beat is set on tempo map change
- audio-locked midi regions can be start-trimmed properly
when close to 1|1|0
- a midi region placed before the first meter
will continue the tempo curve and first meter.
Only a couple of callers require change, as bbt_at_beat() already
deals with this.
- TempoMap initially contains a tempo and meter.
using add_tempo/meter() using the position of an
existing section does the right thing, but prints a warning.
Use replace_tempo/meter().
Jack2 calls back from a notification thread and the callback (PortManager::connect_callback())
could end up holding the final reference on 1 or more ports. The ports would then be
unregistered as we leave the callback scope, which is illegal (no server calls from
a notification thread)
If the script doesn't provide a dsp_ioconfig() function, or if it does
not return a table of tables, provide an empty table of table as
default, which means a single configuration with default values.
Demote configurations if they have mismatched midi in or out with the
same mechanism as for audio, but with lower coefficients so that
mismatched midi has less influence than mismatched audio in selecting
the best configuration.
POLICY CHANGE.
Just refuse configurations without any output at all, and let the
remaining logic take care of selecting configurations with no audio
output if they make sense and there are no better configurations.
POLICY CHANGE: configurations with no output might now be considered
even if they have audio inputs (e.g. a pure pitch detector without audio
passthrough), whereas they were skipped before.
Instead of uniformly demote configurations with a non-matching audio
input count (using a penalty offset of 1000), also grade the
impreciseness of the configuration so that those with the nearest input
count are preferred. As for outputs, give a slightly higher handicap to
configuration with too many inputs with regard to the actual audio
inputs that can be fed to the plugin.
POLICY CHANGE: when only imprecise configurations are found the actually
selected one can be different (better) than before this commit.
Just make the code responsible for possible_in > 0 also handle
possible_in == 0 since it nearly does the same thing.
The only difference is that the possible_in == 0 case didn't check at
all for audio_in, essentially acting as if possible_in was audio_in.
There is thus a small POLICY CHANGE, but the selected configuration will
stay the same unless a better matching configuration is available.
Still no policy change, since when a configuration is chosen that would
have belonged to the second pass, then its penalty will be increased by
1000 and it will be selected only as last recourse.
This doesn't change the policy since configurations are given an
additional 1000 penalty if audio_in != possible_in, and will thus be
trumped by any "precise" configuration (unless the latter has 1000
excess or missing outputs which should be less than likely).
Instead of setting \imprecise at the end of the loop if a configuration
was found (which clobbered valuable information, see dae2406187), set it
each time a new configuration is chosen.
In the second loop that tries harder, resetting \imprecise also avoids a
previous "imprecise->set(AUDIO, 0)" to last even if another
configuration is chosen later.
Last but not least, it will enable correctly setting the midi input
count hoped for by the configuration.
Merge the cases in == -1 and in == -2 since those are both wildcards,
almost symmetric in the AU spec, and handled completely symmetrically by
the code here considering it accepts invalid or unspecified demands.
Also merge the cases in > 0 and in < -2 since they are handled exactly
the same as far as outputs are concerned.
That code modifies \imprecise if it is not NULL, but
- if a configuration is found, \imprecise will be set to in, clobbering
the tentative changes done here;
- if a configuration is not found, a last-resort loop will be run that
will set the same member of \imprecise, also clobbering our changes.
Remove it since it does nothing that is looked at before being
forgotten. A way to get the intended outcome will be introduced later.
...to later enable that condition truthiness to depend on the
loop iteration. The goal here is to prepare for the upcoming rewrite,
without introducing any policy change for now.
There is no behavior change because if all loop iterations are skipped,
then \found will be false, and with \imprecise being null the last
attempt will be skipped and we will return false.
Instead of doing an initial loop for detection of exact matches, then
letting the following loop set \audio_out yet ignore its value, merge
the two loops but give exact matches a negative penalty so that the
\audio_out value they set won't change afterwards.
No policy change.
Since can_replicate is true at loop start, and in the loop body there is
a break; after every can_replicate=false, there's no point to test its
value in the loop condition.
There is no code that read the set value in between the removed line and
its exact counterpart below. There is no similar duplicate in the
AudioUnit code due to the way AudioUnit handles midi.
The original LV2 state extension required that run() is suspended during
restore(). Ardour violates this rule, which can lead to crashes and
other issues.
The state extension has been updated to allow restoring state in a
thread-safe way by using the worker to enqueue state changes. This
commit supports that new specification, i.e. supports dropout-free state
restoration properly.
However, the bug with old plugins that do not use this facility is still
not fixed.