summaryrefslogtreecommitdiff
path: root/Userland/Applications/SoundPlayer/PlaybackManager.cpp
AgeCommit message (Collapse)Author
2023-01-18SoundPlayer: Log loader errors and otherwise ignore them for nowArda Cinar
Playback can resume after encountering loader errors (though not always). Ideally, these should be visible to the user and the loader state should be reset after encountering such errors. This patch also has the side effect of not crashing on seek when playing MP3 files (However, it still does not seek to the correct location) :^)
2023-01-12SoundPlayer: Don't silently ignore parsing failuresTim Schumacher
If we failed to decode a sample we'd presumably want to tell the user, and we definitely don't want to just go into another round of decoding somewhere in the middle of a broken sample.
2023-01-12Userland: Use Core::Timer::create_foo() factory functions where possibleSam Atkins
2023-01-12LibCore+Userland: Don't auto-start new Core::TimersSam Atkins
This was unintuitive, and only useful in a few cases. In the majority, users had to immediately call `stop()`, and several who did want the timer started would call `start()` on it immediately anyway. Case in point: There are only two places I had to add a manual `start()`.
2022-07-19LibAudio: Rename ConnectionFromClient to ConnectionToServerkleines Filmröllchen
The automatic nomenclature change for IPC sockets got this one wrong.
2022-05-29Everywhere: Fix a bunch of typosLinus Groh
2022-04-21LibAudio+Userland: Use new audio queue in client-server communicationkleines Filmröllchen
Previously, we were sending Buffers to the server whenever we had new audio data for it. This meant that for every audio enqueue action, we needed to create a new shared memory anonymous buffer, send that buffer's file descriptor over IPC (+recfd on the other side) and then map the buffer into the audio server's memory to be able to play it. This was fine for sending large chunks of audio data, like when playing existing audio files. However, in the future we want to move to real-time audio in some applications like Piano. This means that the size of buffers that are sent need to be very small, as just the size of a buffer itself is part of the audio latency. If we were to try real-time audio with the existing system, we would run into problems really quickly. Dealing with a continuous stream of new anonymous files like the current audio system is rather expensive, as we need Kernel help in multiple places. Additionally, every enqueue incurs an IPC call, which are not optimized for >1000 calls/second (which would be needed for real-time audio with buffer sizes of ~40 samples). So a fundamental change in how we handle audio sending in userspace is necessary. This commit moves the audio sending system onto a shared single producer circular queue (SSPCQ) (introduced with one of the previous commits). This queue is intended to live in shared memory and be accessed by multiple processes at the same time. It was specifically written to support the audio sending case, so e.g. it only supports a single producer (the audio client). Now, audio sending follows these general steps: - The audio client connects to the audio server. - The audio client creates a SSPCQ in shared memory. - The audio client sends the SSPCQ's file descriptor to the audio server with the set_buffer() IPC call. - The audio server receives the SSPCQ and maps it. - The audio client signals start of playback with start_playback(). - At the same time: - The audio client writes its audio data into the shared-memory queue. - The audio server reads audio data from the shared-memory queue(s). Both sides have additional before-queue/after-queue buffers, depending on the exact application. - Pausing playback is just an IPC call, nothing happens to the buffer except that the server stops reading from it until playback is resumed. - Muting has nothing to do with whether audio data is read or not. - When the connection closes, the queues are unmapped on both sides. This should already improve audio playback performance in a bunch of places. Implementation & commit notes: - Audio loaders don't create LegacyBuffers anymore. LegacyBuffer is kept for WavLoader, see previous commit message. - Most intra-process audio data passing is done with FixedArray<Sample> or Vector<Sample>. - Improvements to most audio-enqueuing applications. (If necessary I can try to extract some of the aplay improvements.) - New APIs on LibAudio/ClientConnection which allows non-realtime applications to enqueue audio in big chunks like before. - Removal of status APIs from the audio server connection for information that can be directly obtained from the shared queue. - Split the pause playback API into two APIs with more intuitive names. I know this is a large commit, and you can kinda tell from the commit message. It's basically impossible to break this up without hacks, so please forgive me. These are some of the best changes to the audio subsystem and I hope that that makes up for this :yaktangle: commit. :yakring:
2022-04-01Everywhere: Run clang-formatIdan Horowitz
2022-03-25SoundPlayer: Don't crash when the reported buffer is unexpectedkleines Filmröllchen
It seems like this happens in quite some valid situations, so my initially sensible failsafe doesn't make sense. As the buffer system is hopefully gone soon, it won't be an issue in the future either way.
2022-02-25Userland: Rename IPC ClientConnection => ConnectionFromClientItamar
This was done with CLion's automatic rename feature and with: find . -name ClientConnection.h | rename 's/ClientConnection\.h/ConnectionFromClient.h/' find . -name ClientConnection.cpp | rename 's/ClientConnection\.cpp/ConnectionFromClient.cpp/'
2022-02-14Applications: Use default constructors/destructorsLenny Maiorani
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules "The compiler is more likely to get the default semantics right and you cannot implement these functions better than the compiler."
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.
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-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-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-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-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
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 *
2021-03-27SoundPlayer: Add samplerate variable to visualizationsCesar Torres
also fix conflict
2021-03-27SoundPlayer: Reduce sample buffer size and add a sample load eventCesar Torres
2021-01-17AudioServer+LibAudio: Pass audio buffers as Core::AnonymousBufferAndreas Kling
This was the last remaining user of shbufs! :^)
2021-01-12Applications: Move to Userland/Applications/Andreas Kling