Across the entire audio system, audio now works in 0-1 terms instead of
0-100 as before. Therefore, volume is now a double instead of an int.
The master volume of the AudioServer changes smoothly through a
FadingProperty, preventing clicks. Finally, volume computations are done
with logarithmic scaling, which is more natural for the human ear.
Note that this could be 4-5 different commits, but as they change each
other's code all the time, it makes no sense to split them up.
freq_bin was converted to double after it was calculated, so there was
a much higher probability it could be 0 instead of some comma number,
which meant that the bars always stayed on top.
The freq_bin in bins_per_group was multiplied only to be divided later,
which could even result in a crash if you set higher buffer size
(like 1000ms) in PlaybackManager, due to rounding errors I presume.
Prior this change, opening a playlist always spawned a new widget.
This could end up with having a few the same widgets, which you couldn't
even close (besides the last one).
Removed the old custom checkbox selection code in the Visualization
menu and replaced them with GUI::ActionGroup with set_exclusive
enabled instead :^)
1) The Sound Player visualizer couldn't deal with small sample buffers,
which occur on low sample rates. Now, it simply doesn't update its
buffer, meaning the display is broken on low sample rates. I'm not too
familiar with the visualizer to figure out a proper fix for now, but
this mitigates the issue (and "normal" sample rates still work).
2) Piano wouldn't buffer enough samples for small sample rates, so the
sample count per buffer is now increased to 2^12, introducing minor
amounts of (acceptable) lag.
All audio applications (aplay, Piano, Sound Player) respect the ability
of the system to have theoretically any sample rate. Therefore, they
resample their own audio into the system sample rate.
LibAudio previously had its loaders resample their own audio, even
though they expose their sample rate. This is now changed. The loaders
output audio data in their file's sample rate, which the user has to
query and resample appropriately. Resampling code from Buffer, WavLoader
and FlacLoader is removed.
Note that these applications only check the sample rate at startup,
which is reasonable (the user has to restart applications when changing
the sample rate). Fully dynamic adaptation could both lead to errors and
will require another IPC interface. This seems to be enough for now.
Most of the models were just calling did_update anyway, which is
pointless since it can be unified to the base Model class. Instead, code
calling update() will now call invalidate(), which functions identically
and is more obvious in what it does.
Additionally, a default implementation is provided, which removes the
need to add empty implementations of update() for each model subclass.
Co-Authored-By: Ali Mohammad Pur <ali.mpfard@gmail.com>
Applications previously had to create a GUI::Menubar object, add menus
to it, and then call GUI::Window::set_menubar().
This patch introduces GUI::Window::add_menu() which creates the menubar
automatically and adds items to it. Application code becomes slightly
simpler as a result. :^)
AK's version should see better inlining behaviors, than the LibM one.
We avoid mixed usage for now though.
Also clean up some stale math includes and improper floatingpoint usage.
This removes StringView::find_first_of(char) and find_last_of(char) and
replaces all its usages with find and find_last respectively. This is
because those two methods are functionally equivalent.
find_{first,last}_of should only be used if searching for multiple
different characters, which is never the case with the char argument.
This also adds the [[nodiscard]] to the remaining find_{first,last}_of
methods.
The LexicalPath instance methods dirname(), basename(), title() and
extension() will be changed to return StringView const& in a further
commit. Due to this, users creating temporary LexicalPath objects just
to call one of those getters will recieve a StringView const& pointing
to a possible freed buffer.
To avoid this, static methods for those APIs have been added, which will
return a String by value to avoid those problems. All cases where
temporary LexicalPath objects have been used as described above haven
been changed to use the static APIs.
This commit addresses two issues:
1. If you play a 96 KHz Wave file, the slider position is incorrect,
because it is assumed all files are 44.1 KHz.
2. For high-bitrate files, there are audio dropouts due to not
buffering enough audio data.
Issue 1 is addressed by scaling the number of played samples by the
ratio between the source and destination sample rates.
Issue 2 is addressed by buffering a certain number of milliseconds
worth of audio data (instead of a fixed number of bytes).
This makes the the buffer size independent of the source sample rate.
Some of the code is redesigned to be simpler. The code that did the
book-keeping of which buffers need to be loaded and which have been
already played has been removed. Instead, we enqueue a new buffer based
on a low watermark of samples remaining in the audio server queue.
Other small fixes include:
1. Disable the stop button when playback is finished.
2. Remove hard-coded instances of 44100.
3. Update the GUI every 50 ms (was 100), which improves visualizations.
Previously, if you play a file, then stop, then play again, the stop
button will be permanently disabled until you open a file again.
The stop button should be enabled whenever a file is loaded.
This commit fixes the GUI bug by enabling the stop button whenever the
play button is clicked (if a file is currently loaded).
When the cursor is clicked outside of the slider knob,
the current behavior is that it will step up or down by the
Slider page step amount.
This commit adds an option to jump the slider knob
directly to the where the mouse cursor is on mouse down events.
This behavior is disabled by default. It must be enabled with
`Slider::set_jump_to_cursor()`.
Jump to cursor is enabled in SoundPlayer since most music players
have this behavior.
This changes (context) menus across the system to conform to titlecase
capitalization and to not underline the same character twice (for
accessing actions with Alt).
Since applications using Core::EventLoop no longer need to create a
socket in /tmp/rpc/, and also don't need to listen for incoming
connections on this socket, we can remove a whole bunch of pledges!
Not sure why some menus did have one and others didn't, even in the
same application - now they all do. :^)
I added character shortcuts to some menu actions as well.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
This flag warns on classes which have `virtual` functions but do not
have a `virtual` destructor.
This patch adds both the flag and missing destructors. The access level
of the destructors was determined by a two rules of thumb:
1. A destructor should have a similar or lower access level to that of a
constructor.
2. Having a `private` destructor implicitly deletes the default
constructor, which is probably undesirable for "interface" types
(classes with only virtual functions and no data).
In short, most of the added destructors are `protected`, unless the
compiler complained about access.
I hereby declare these to be full nouns that we don't split,
neither by space, nor by underscore:
- Breadcrumbbar
- Coolbar
- Menubar
- Progressbar
- Scrollbar
- Statusbar
- Taskbar
- Toolbar
This patch makes everything consistent by replacing every other variant
of these with the proper one. :^)