summaryrefslogtreecommitdiff
path: root/Userland/Applications/SoundPlayer
AgeCommit message (Collapse)Author
2022-01-04Userland: Resolve -Woverloaded-virtual in LibGUI and SoundPlayerAndrew Kaster
Enable the warning project-wide. It catches when a non-virtual method creates an overload set with a virtual method. This might cause surprising overload resolution depending on how the method is invoked.
2022-01-02SoundPlayer: Don't enqueue samples depending on the GUI loopkleines Filmröllchen
Previously, SoundPlayer would read and enqueue samples in the GUI loop (through a Timer). Apart from general problems with doing audio on the GUI thread, this is particularly bad as the audio would lag or drop out when the GUI lags (e.g. window resizes and moves, changing the visualizer). As Piano does, now SoundPlayer enqueues more audio once the audio server signals that a buffer has finished playing. The GUI- dependent decoding is still kept as a "backup" and to start the entire cycle, but it's not solely depended on. A queue of buffer IDs is used to keep track of playing buffers and how many there are. The buffer overhead, i.e. how many buffers "too many" currently exist, is currently set to its absolute minimum of 2.
2022-01-02SoundPlayer: Remove resolved FIXMEkleines Filmröllchen
I already resolved this some time ago but apparently forgot about it :^)
2021-12-30LibGUI+SoundPlayer: Use 'decrease_slider_by_page_steps()' methodElyse
This method allow us to avoid repeating the pattern 'set_value(value() - page_step() * page_number)'.
2021-12-30LibGUI+SoundPlayer: Use 'increase_slider_by_page_steps()'Elyse
This method allow us to avoid repeating the pattern 'set_value(value() + page_step() * page_number)'.
2021-12-24SoundPlayer: Add a keyboard shortcut 'M' to mute the playerElyse
This shortcut let us mute/unmute the player, but it still doesn't update the volume slider because the actual volume widget can't display a muted state.
2021-12-24SoundPlayer: Add 'mute' methods to PlayerElyse
These methods allow us to mute/unmute the player without needing to modify the volume level that it has.
2021-12-24SoundPlayer: Sync startup loop and show playlist settings in GUIMax Trussell
This fix syncs up the AudioPlayer's internal state for showing playlist information with the AudioPlayer's GUI. Before, if the AudioPlayer was opened with a playlist file (.m3u or .m3u8) it would automatically show the playlist information in the GUI and set the loop mode to playlist, but the menu options would be unchecked. In order to hide the playlist information, the menu option would then have to be toggled twice -- once on and again off.
2021-12-04SoundPlayer: Port to LibMain :^)Elyse
2021-11-28LibAudio: New error propagation API in Loader and Bufferkleines Filmröllchen
Previously, a libc-like out-of-line error information was used in the loader and its plugins. Now, all functions that may fail to do their job return some sort of Result. The universally-used error type ist the new LoaderError, which can contain information about the general error category (such as file format, I/O, unimplemented features), an error description, and location information, such as file index or sample index. Additionally, the loader plugins try to do as little work as possible in their constructors. Right after being constructed, a user should call initialize() and check the errors returned from there. (This is done transparently by Loader itself.) If a constructor caused an error, the call to initialize should check and return it immediately. This opportunity was used to rework a lot of the internal error propagation in both loader classes, especially FlacLoader. Therefore, a couple of other refactorings may have sneaked in as well. The adoption of LibAudio users is minimal. Piano's adoption is not important, as the code will receive major refactoring in the near future anyways. SoundPlayer's adoption is also less important, as changes to refactor it are in the works as well. aplay's adoption is the best and may serve as an example for other users. It also includes new buffering behavior. Buffer also gets some attention, making it OOM-safe and thereby also propagating its errors to the user.
2021-11-24SoundPlayer+LibDSP: Move the FFT implementation to LibDSPkleines Filmröllchen
LibDSP can greatly benefit from this nice FFT implementation, so let's move it into the fitting library :^) Note that this now requires linking SoundPlayer against LibDSP. That's not an issue (LibDSP is rather small currently anyways), as we can probably make great use of it in the future anyways.
2021-11-13SoundPlayer: Add keyboard shortcuts for stop and volumeElyse
These shortcuts allow us to stop the player (key S) and adjust the volume level (key Up and key Down).
2021-11-13SoundPlayer: Make 'volume_slider' a member variableElyse
This change will allow us to modify the volume slider from any event inside the widget.
2021-11-13SoundPlayer: Allow volume output of up to 150%Elyse
Previously the volume slider could go up to 150% but the real output volume stayed the same between 100% and 150%.
2021-11-08SoundPlayer: Fix stack-use-after-scope when playing file in loop modeSimon Woertz
The path returned by GUI:FilePicker is stored on the stack when the callback is executed. The player only stored a StringView to the path however it should take ownership of the path instead since the path is accessed even after the file menu open action has returned.
2021-11-08LibGfx: Use ErrorOr<T> for Bitmap::try_load_from_file()Andreas Kling
This was used in a lot of places, so this patch makes liberal use of ErrorOr<T>::release_value_but_fixme_should_propagate_errors().
2021-11-04SoundPlayer: Allow playback progress slider jump to cursorElyse
This fix allows us to move the knob wherever we click inside the slider. The 'jump_to_cursor()' mechanism wasn't working properly because the player was overwriting the value we had just clicked.
2021-11-02Applications: Fix visibility of Object-derivative constructorsBen Wiederhake
Derivatives of Core::Object should be constructed through ClassName::construct(), to avoid handling ref-counted objects with refcount zero. Fixing the visibility means that misuses like this are more difficult.
2021-10-27Everywhere: Rename left/right-click to primary/secondaryFiliph Sandström
This resolves #10641.
2021-10-25SoundPlayer: Implement playlist shuffle modeLeandro Pereira
The shuffling algorithm uses a naïve bloom filter to provide random uniformity, avoiding items that were recently played. With 32 bits, double hashing, and an error rate of ~10%, this bloom filter should be able to hold around ~16 keys, which should be sufficient to give the illusion of fairness to the shuffling algorithm. This avoids having to shuffle the playlist itself (user might have spent quite a bit of time to sort them, so it's not a good idea to mess with it), or having to create a proxy model that shuffles (that could potentially use quite a bit of memory).
2021-10-25SoundPlayer: Make M3UParser more idiomaticLeandro Pereira
Let's use the nice APIs we have, and make the M3U parser a bit more readable, shorter, and resilient.
2021-10-25SoundPlayer: Fix inconsistencies and code duplicationLeandro Pereira
This is a first pass at refactoring SoundPlayer so that the View widget is decoupled from the player itself. In doing so, this fixed a couple of issues, including possibly inconsistent states (e.g. player could be paused and stopped at the same time). With the change, Player actually controls the show, and calls methods overriden by its subclasses to perform actions, such as update the Seek bar; the hard work of massaging the raw data is done by the Player class, so subclasses don't need to reimplement any of these things. This also removes some copies of playlist management code that happened to be copied+pasted inside callbacks of buttons -- it now lives inside a neatly packaged Playlist class, and the Player only asks for the next song to play. In addition, the menu bar has been slightly rearranged.
2021-09-12Audio: Change how volume workskleines Filmröllchen
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.
2021-09-04SoundPlayer: Convert to double before calculatingKarol Kosek
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.
2021-09-04SoundPlayer: Simplify Bars Visualization drawing logic a bitKarol Kosek
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.
2021-09-04SoundPlayer: Create only one playlist widgetKarol Kosek
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).
2021-09-04SoundPlayer: Add spacebar keyboard shortcut for play/pauseThitat Auareesuksakul
2021-09-04SoundPlayer: Don't try to dereference null-pointer buffersKarol Kosek
d049626f402f50720a1ccc4452676a56e22debbd tried to resample the buffer before checking if it points to a valid location. This caused a crash, generally at the end of the file.
2021-09-01SoundPlayer: Use GUI::ActionGroup for Visualization menuThitat Auareesuksakul
Removed the old custom checkbox selection code in the Visualization menu and replaced them with GUI::ActionGroup with set_exclusive enabled instead :^)
2021-09-01SoundPlayer: Fix file leak in M3UParser::from_file(..)Brian Gianforcaro
Found by Sonar Cloud.
2021-08-27Userland: Two low-sample rate fixeskleines Filmröllchen
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.
2021-08-27Userland+LibAudio: Make audio applications support dynamic sample ratekleines Filmröllchen
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.
2021-08-06Everywhere: Replace Model::update() with Model::invalidate()sin-ack
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>
2021-08-01Applications: Remove unused header includesBrian Gianforcaro
2021-07-21Userland: Add GUI::Window::add_menu() and use it everywhereAndreas Kling
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. :^)
2021-07-21LibGfx: Use "try_" prefix for static factory functionsAndreas Kling
Also mark them as [[nodiscard]].
2021-07-21SoundPlayer: Use full path for playlist itemsKarol Kosek
This fixes an issue with not opening tracks if they have been placed in a subfolder.
2021-07-19Everywhere: Use AK/Math.h if applicableHendiadyoin1
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.
2021-07-19SoundPlayer: Fix a spelling mistake in a variable nameGunnar Beutner
2021-07-19SoundPlayer: End M3U tag names with a colonKarol Kosek
2021-07-19SoundPlayer: Clear M3U track metadata after parsed fileKarol Kosek
Before this change, the track metadata was duplicated over and over until it was overwritten.
2021-07-12SoundPlayer: Activate window only on file dropKarol Kosek
2021-07-11SoundPlayer: Show the context menu right under the cursorKarol Kosek
The context menu used the mouse position by window, which resulted in a pop-up menu in the upper left corner of the screen.
2021-07-02AK+Everywhere: Remove StringView::find_{first,last}_of(char) methodsMax Wipfli
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.
2021-06-30AK+Everywhere: Add and use static APIs for LexicalPathMax Wipfli
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.
2021-06-30SoundPlayer: Don't limit duration inference to WAV filesngc6302h
2021-06-21SoundPlayer: Handle any input file sample rateNick Miller
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.
2021-06-17Everywhere: Add component declarationsGunnar Beutner
This adds component declarations so that users can select to not build certain parts of the OS.
2021-06-08SoundPlayer: Enable stop button when play button clickedNick Miller
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).
2021-06-08LibGUI+SoundPlayer: Add Slider option to jump to cursorNick Miller
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.