Big Thanks to Steve for finding this and writing clear steps to reproduce when logging this bug in Bugzilla. Also thanks to Peter for confirming the same bug is present on Windows, i.e. is all platforms, not just Linux.
This is a minimal fix for this bug, and can be improved on in time. There is almost no error checking in the file read and write, so if you use a bad presets file, you won't be told (yet).
It does provide import and export for all effects that have presets.
Problem:
Validation of the length fails, because what should be the min and max are in fact the max and min.
Introduced by commit 1d32824, which got the min and max the wrong way round.
Nyquist has a limit (less than 2000) for the number of arguments
which may be exceeded when creating the *track* clips property.
In the event that there are more than 1000 clips in a track,
Audacity will now only add the first 1000 clips to the *track* property
and add NIL as the 1001th.
... removing link dependencies on them from src/menus, so they are now suitable
for moving out into modules.
They are:
Mixer Board
Karaoke (also called Lyrics)
History
Contrast
Plot Spectrum
Their header files are now no longer included anywhere but in their own
implementation files!
These are ancient and "configunix.h" was being pulled in
via Types.h. Nothing major, but they were generated for
a 32-bit system and "may" cause problems when used on
64-bit systems.
(That's unlikely though since they haven't all this time.)
... Problem with static initialization order of ReservedCommandFlags, caused
wrong enablement of menu items (at least on Mac), such as Plot Spectrum or
Contrast enabled when there was no selection
* Calculate loudness for short or silent selections as well.
In case of selections shorter than 400ms (one momentary loudness block),
take what we have got and divide only be the actual length.
Abort loudness normalization silently if the selected audio is all
silent.
* Fix loudness effect bug when selection includes a gap.
If the selected audio in a track contained a gap between two clips,
an incorrect amount of samples was processed.
... consistently with the drop-down menu, and now the Tracks Preferences too.
Only distinguish Waveform and Spectrogram and nil.
See also commit e3d9fd9.
... you use the prompt, and you enter a complete script with control comments
that are reinterpreted to put up a second dialog.
This simplifies Effect::Delegate() and avoids mutual recursion of ShowInterface
with DoEffect.
... and Track::GetOwner() is publicized, so that now you can find the
the AudacityProject, if any, that owns a given Track; this will help eliminate
some uses of GetActiveProject
... This changes visible behavior.
If a realtime effect was open (say, AUGraphicEQ on Mac), and there were multiple
projects, then the window was associated with one of the projects.
But the "Apply" button could apply the effect to the active project, even if
that was not the associated one. But the associated project was queried for
the existence of a selection.
Now, EffectUIHost::OnApply consistently examines and changes only the associated
project, even if it is not active.
You have to close the window and reopen it with the other project if you really
want to change the other.
You can't have two realtime effects open at once, even if for different
projects. To overcome that limitation, we would have to make
RealtimeEffectsManager store state per-project, not globally.
... by passing parent as reference, not pointer, and testing in the dialog
factory function.
This is important so that we know the lifetime of an effect dialog, even when
it is non-modal, is bounded by the lifetime of the associated project.
... We need to un-correct the smart quote characters back to dumb quotes
before passing the input to the Lisp interpreter.
The smart quote correction is a consequence of the move to the MacOS 10.9 SDK.
Stopping the correction at the source would require objective-C hacks in a
custom build of wxWidgets, and just not worth the effort.
This fix only corrects the text input at one wxTextCtrl. Should we reexamine
other uses of that class?
... When locale is not English (and translation is complete enough, as in
French) then the switching from Generic to Full interface in Options... did not
work.
(Locales lacking translations of the strings "Full" and "Generic" didn't have
this problem.)
(AudioUnit effects still don't implement a "Basic" interface distinct from
"Generic" regardless of locale. That's another matter.)
... in cases of "TranslatableString" that are not really translated.
This makes it easier to scan the code for such unusual constructions of
TranslatableString, distinct from mere mentions of the TranslatableString type.
... Format arguments are substituted into the translation of the msgid, which
may not be known at the time the format arguments are captured (because locale
may change). This allows TranslatableString with arguments to be constructed
at static initialization time.
There is also a special "verbatim" or null context which makes no translations
of msgids.
There is not yet any use of other contexts besides default or null.
... include it in the msgid intead, to get appropriate translations. For
instance some locales use the same character but prefer to insert a space
before it.
... And corrected improper connections in HistoryWindow and ContrastDialog,
improper because they got called with the wrong this pointer, to
the control instead of the dialog. But that was harmless anyway because the
handlers did not use this.
... Trying to reduce that just to chained calls on S, or conditional and looping
logic for variations in layout.
Lift some declarations to higher scope; or use expressions that avoid local
variables; or even use lambdas for more complicated computation of arguments
for the member functions of S.
Problem:
Currently calling Track::EnsureVisible() also sets the track as focus.
In Audacity 2.3.3 the timing of the code to set the focus was changed. Rather than a direct call, an event is queued, and then the focus is set. This has changed the timing of the focus event which is sent with respect to other focus and name change events. In particular in the case of toggling the selectness of the focused track, this moved the focus event to be after the name change event.
These changes only had an effect on NVDA - Jaws and Narrator were unaffected.
The introduction of this bug has highlighted an existing problem.
1. There are a small number of existing cases where a track needs to be visible, but where it is already the focus, and so setting the focus is unnecessary. For example, pressing Enter to toggle whether a track is selected.
2. Some of the Audacity code which calls EnsureVisible() is written with the assumption that EnsureVisible() doesn't set the focus, and so there are unnecessary focus events. Whilst other code which calls EnsureVisible() assumes that it also sets the focus. Confusion.
The Fix:
Remove the setting of focus from within Track::EnsureVisible(), and so remove the unnecessary focus events.
Calls to set the focus were added before calls to EnsureVisible where the code was relying on EnsureVisible to set the focus. In TrackPanel::ProcessUIHandleResult, and TrackPanel::OnMouseEvent, I wasn't sure if the focus needed to be set, so called it anyway to ensure that the behaviour did not change.
So I would like to remove the setting of focus from within Track::EnsureVisible(), and add explicit calls to set the focus where necessary.
I think this would make the code clearer, remove unnecessary calls to set the focus, and make it easier to keep NVDA happy.
The Calf plugin suite exposes Event ports which is currently not supported or defined in `liblilv`, so instead of flat rejecting the filter, test the port name for `Events` and allow them to load.
This avoids catastrophic rounding errors which can even lead to filter
instability in some cases. This is a real problem in the coming IIR envelope
detector.
This is based on my old loudness effect prototype which was included
in the Normalize effect.
Create all source files and add them to all build systems.
Currently, the effect only consists of a GUI mockup.
Create Octave+mod-script-pipe based dummy unit-test as well.
This change reduces the risk of LADSPA plugins referencing
Audacity symbols by using the RTLD_DEEPBIND flag when loading
the plugins.
It also addresses an issue specific to the "blop" plugins where
they load their own libraries (without RTLD_DEEPBIND).
A much better solution would be to change Audacity's default
symbol visibility to "hidden" which would expose ONLY symbols
specificially marked as visible.
Also abolished use of nPoints, making parameters easier to set up.
This also fixes an issue where more points than are there could be read, if cfg file bad.
Drag to enlarge the window, and the length of the graphic sliders.
This was part of splitting EQ. The split effect would look strange if we did not do this.
Graphic EQ sliders are now in a sizer, and so we no longer lay them out 'by hand' in the way we previously did.
This is part of the work of fixing Equalization by splitting it into two effects.
The Graphic EQ effect now does not show the curve or 'grid on/off' checkbox.
Screenshot Commands now include Graphic EQ and Filter Curve in the captures (and not EQ anymore).
Menu items now have a space in them.
... It was introduced at 2e11844f6a, so since
2.3.1
A null check on inputTracks() was needed.
This appears to be the only effect where inputTracks() was called while
populating its dialog, so there should not be any similar crashes with other
effects.
... Let the window respond to an undo manager event instead, whenever there
is a push or modify
Maybe this makes a few unnecessary redraws that did not happen before. If
that is important, then we should figure out how to put the logic for eliding
the redraw into ProjectWindow, and the extra information needed for the
decision into the events, but not make intrusions in other code all over the
place.
... not the best thing for the long term, but hidden dependencies on
TransportMenus.cpp are eliminated
Tying CommonCommandFlags again into the big component, which is now 26
... and simplify, using a std::atomic instead of a critical section.
(But did this before, and does this now, correctly synchronize across threads?
I defer that question.)
... though in a small cycle with each other, by moving RealtimeEffectManager to
new files, which remain in the big component.
Net loss of 1, the big component now has 27 files
... Breaking up an s.c.c. of 6 into 3 components:
ODManager, ODTask, ODWaveTrackTaskQueue
UndoManager
WaveClip, WaveTrack
Rewrite the OD tasks and queues to hold weak pointers to tracks, so the
track destructor need not notify them.
... Mostly into CommonCommandFlags.cpp, but some elsewhere, to avoid giving
that new file problematic dependencies on LabelTrack, ControlToolBar, and
EffectManager.
Note that CutCopyAvailableFlag is critically ordered, for message purposes,
only with AudioIONotAvailableFlag, the only flag with a message that it combines
with in menu item definitions.
The dependency on LabelTrack.cpp might not be a bad one later, if the track and
its view can be separated, and that would allow CutCopyAvailableFlag to be
put with the others. But much other work on LabelTrack must happen first.
... New files, but (almost) empty; don't use the global variable gAudioIO,
but use one of two accessor function names (which are the same function for
now).
AudioIOBase will have fewer dependencies than AudioIO -- in particular, no
dependency on tracks.
It won't include StartStream. It will contain functions to query the
present state of streams, and device capabilities.
Mac and Linux (correctly) allow files to be saved with an arbitrary
file extension, or no file extension at all. For the exported file
to be visible in the export dialog, the dialog must include an optional
wildcard for "All files".
... that is, a factory function, open, close, import, undo/redo/rollback.
Also the callbacks from AudioIO, which need to invoke undo history push when
recording stops.
It is meant as a high-level class using several of the other things attached
to the project, while AudacityProject will be a low level class acting mostly
as just the container of the attached structures.
... as a preparation for splitting up class AudacityProject.
Use ProjectWindow as an alias for AudacityProject, and fetch it from the
project with a static member function, where certain of its services are used;
pretending they are not the same class.
Use global accessor functions to get wxFrame from the project where only
wxFrame's member functions are needed, so there will be less dependency on
ProjectWindow when it becomes a distinct class.