summaryrefslogtreecommitdiff
path: root/Userland/Services/AudioServer
AgeCommit message (Collapse)Author
2023-03-06Everywhere: Remove NonnullRefPtr.h includesAndreas Kling
2023-03-06Everywhere: Stop using NonnullRefPtrVectorAndreas Kling
This class had slightly confusing semantics and the added weirdness doesn't seem worth it just so we can say "." instead of "->" when iterating over a vector of NNRPs. This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
2023-02-13LibCore: Move Stream-based sockets into the `Core` namespaceTim Schumacher
2023-02-13LibCore: Rename `File` to `DeprecatedFile`Tim Schumacher
As usual, this removes many unused includes and moves used includes further down the chain.
2023-02-08AudioServer: Use `AK::Stream` to serialize mixed samplesTim Schumacher
2023-01-29AK: Deprecate the old `AK::Stream`Tim Schumacher
This also removes a few cases where the respective header wasn't actually required to be included.
2023-01-28LibCore: Remove `try_` prefix from fallible SharedCircularQueue methodsLinus Groh
2023-01-12LibCore+Userland: Make Core::Timer::create_single_shot() return ErrorOrSam Atkins
clang-format sure has some interesting opinions about where to put a method call that comes after a lambda. :thonk:
2023-01-02Everywhere: Remove unused includes of LibC/stdlib.hBen Wiederhake
These instances were detected by searching for files that include stdlib.h, but don't match the regex: \\b(_abort|abort|abs|aligned_alloc|arc4random|arc4random_buf|arc4random_ uniform|atexit|atof|atoi|atol|atoll|bsearch|calloc|clearenv|div|div_t|ex it|_Exit|EXIT_FAILURE|EXIT_SUCCESS|free|getenv|getprogname|grantpt|labs| ldiv|ldiv_t|llabs|lldiv|lldiv_t|malloc|malloc_good_size|malloc_size|mble n|mbstowcs|mbtowc|mkdtemp|mkstemp|mkstemps|mktemp|posix_memalign|posix_o penpt|ptsname|ptsname_r|putenv|qsort|qsort_r|rand|RAND_MAX|random|reallo c|realpath|secure_getenv|serenity_dump_malloc_stats|serenity_setenv|sete nv|setprogname|srand|srandom|strtod|strtof|strtol|strtold|strtoll|strtou l|strtoull|system|unlockpt|unsetenv|wcstombs|wctomb)\\b (Without the linebreaks.) This regex is pessimistic, so there might be more files that don't actually use anything from the stdlib. In theory, one might use LibCPP to detect things like this automatically, but let's do this one step after another.
2022-11-25AudioServer: Detect improperly detached audio clientskleines Filmröllchen
Because IPC is used very little in audio server communication, a ping-pong method like WindowServer is neither a good nor a reliable way of detecting detached audio clients. AudioServer was previously doing nothing to detect the kinds of clients that never closed their connection properly, which happens e.g. when a program is force-closed. Due to reference-counting cycles, the associated client connection queues were being kept alive. However, the is_open method of local sockets reliably detects all kinds of disconnected sockets and can easily be adapted for this use case. With this fix, we no longer get "Audio client can't keep up" spam on improperly disconnected clients, and the client queues don't fill up indefinitely, reducing processing and memory usage in AudioServer.
2022-11-12AudioServer: Stop re-creating the device stream bufferAlex Chronopoulos
The buffer provided to `OutputMemoryStream` was made a private class member. This is because there is no reason to re-create it in every iteration. Also, the logic becomes more symmetric with `m_zero_filled_buffer` which is already a class member.
2022-11-12AudioServer: Stop glitching when toggling muteAlex Chronopoulos
Initialize the `AudioServer::Mixer::m_zero_filled_buffer` to zero. The garbage memory inside that buffer was causing a glitch sound when the user was toggling the mute checkbox or was moving the volume slider on and off zero. Glitching was more obvious if the toggling was happening without any sound being played in parallel. In addition to that, the `m_zero_filled_buffer` turned to `const` since there is no intention to modify its content.
2022-11-07AudioServer: Skip mixing when volume is zeroAlex Chronopoulos
When volume is zero it is not necessary to go through the mixing loop. The zero-filled buffer can be written directly to the device, instead, similar to the muted case. Tested by using the piano app and the main volume control.
2022-11-01Everywhere: Mark dependencies of most targets as PRIVATETim Schumacher
Otherwise, we end up propagating those dependencies into targets that link against that library, which creates unnecessary link-time dependencies. Also included are changes to readd now missing dependencies to tools that actually need them.
2022-10-31Userland: Use Threading::MutexLocker to lock/unlock mutexesOleg Kosenkov
2022-10-12Userland: Properly populate GENERATED_SOURCESAli Mohammad Pur
We previously put the generated headers in SOURCES, which did not mark them as GENERATED (and did not produce a proper dependency). This commit moves all generated headers into GENERATED_SOURCES, and removes useless header SOURCES.
2022-09-16Everywhere: Remove a bunch of dead write-only variablesTim Schumacher
LLVM 15 now warns (and thus errors) about this, and there is really no point in keeping them.
2022-07-12Everywhere: Add sv suffix to strings relying on StringView(char const*)sin-ack
Each of these strings would previously rely on StringView's char const* constructor overload, which would call __builtin_strlen on the string. Since we now have operator ""sv, we can replace these with much simpler versions. This opens the door to being able to remove StringView(char const*). No functional changes.
2022-06-23AudioServer: Reduce hardware audio buffer to 512 sampleskleines Filmröllchen
2022-06-23AudioServer: Make hardware write buffer size flexiblekleines Filmröllchen
This removes some old cruft to refactor the hardware buffer-related datastructures into depending on a single constant, which determines the number of samples per hardware buffer that the audio server mixes. This is set to 1024 as before, so there are no functional changes.
2022-06-23AudioServer: Explicitly cast between numeric types in the mixerkleines Filmröllchen
2022-05-03LibAudio+Userland: Remove Audio::LegacyBufferkleines Filmröllchen
The file is now renamed to Queue.h, and the Resampler APIs with LegacyBuffer are also removed. These changes look large because nobody actually needs Buffer.h (or Queue.h). It was mostly transitive dependencies on the massive list of includes in that header, which are now almost all gone. Instead, we include common things like Sample.h directly, which should give faster compile times as very few files actually need Queue.h.
2022-04-23LibWeb+AudioServer: Remove unused spaceship operatorsAndrew Kaster
We aren't actually using these for anything, and the spaceship operator requires ``<compare>`` from the STL, which we'd rather not include.
2022-04-21AudioServer: Auto-pause new clientskleines Filmröllchen
This fixes a bunch of audio clients that don't actually play audio.
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-21LibAudio+Everywhere: Rename Audio::Buffer -> Audio::LegacyBufferkleines Filmröllchen
With the following change in how we send audio, the old Buffer type is not really needed anymore. However, moving WavLoader to the new system is a bit more involved and out of the scope of this PR. Therefore, we need to keep Buffer around, but to make it clear that it's the old buffer type which will be removed soon, we rename it to LegacyBuffer. Most of the users will be gone after the next commit anyways.
2022-03-24Services: 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-03-14AudioServer: Decrease sample headroom to 5%kleines Filmröllchen
This might still be too much, but it's better than what we had before.
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-16LibCore+Everywhere: Return ErrorOr from ConfigFile::sync()Sam Atkins
Currently this method always succeeds, but that won't be true once we switch to the Core::Stream API. :^) Some of these places would ideally show an error message to the user, since failure to save a file is significant, but let's not get distracted right now.
2022-02-16LibCore+Everywhere: Return ErrorOr from ConfigFile factory methodsSam Atkins
I've attempted to handle the errors gracefully where it was clear how to do so, and simple, but a lot of this was just adding `release_value_but_fixme_should_propagate_errors()` in places.
2022-02-14AudioServer: Use first audio channel in the /dev/audio directoryLiav A
For now, just use the first audio channel in the /dev/audio directory. In the future we can add support for watching and loading other channels so we can route audio to multiple sound cards on the system.
2022-01-15LibCore+LibIPC+Everywhere: Return Stream::LocalSocket from LocalServersin-ack
This change unfortunately cannot be atomically made without a single commit changing everything. Most of the important changes are in LibIPC/Connection.cpp, LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp. The notable changes are: - IPCCompiler now generates the decode and decode_message functions such that they take a Core::Stream::LocalSocket instead of the socket fd. - IPC::Decoder now uses the receive_fd method of LocalSocket instead of doing system calls directly on the fd. - IPC::ConnectionBase and related classes now use the Stream API functions. - IPC::ServerConnection no longer constructs the socket itself; instead, a convenience macro, IPC_CLIENT_CONNECTION, is used in place of C_OBJECT and will generate a static try_create factory function for the ServerConnection subclass. The subclass is now responsible for passing the socket constructed in this function to its ServerConnection base; the socket is passed as the first argument to the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before any other arguments. - The functionality regarding taking over sockets from SystemServer has been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket implementation of this functionality hasn't been deleted due to my intention of removing this class in the near future and to reduce noise on this (already quite noisy) PR.
2022-01-14Everywhere: Use my new serenityos.org e-mail :^)kleines Filmröllchen
2021-12-24AudioServer: Ignore 'muted' clients when computing the 'output mix'Elyse
2021-12-24AudioServer: Add a 'self_muted' state to each client connectionElyse
This new state will allow us to ignore muted clients when computing the 'output mix' in the Mixer.
2021-12-24AudioServer: Add 'mute' member and methods to ClientAudioStreamElyse
When computing the 'output mix', the Mixer iterates over all client audio streams and computes a 'mixed sample' taking into account mainly the client's volume. This new member and methods will allow us to ignore a muted client when computing that mix.
2021-12-24Everywhere: Refactor 'muted' to 'main_mix_muted' in all AudioConnectionsElyse
The 'muted' methods referred to the 'main mix muted' but it wasn't really clear from the name. This change will be useful because in the next commit, a 'self muted' state will be added to each audio client connection.
2021-12-24AudioServer/Mixer: Fix remaining samples underflowMax Trussell
The `m_remaining_samples` attribute was underflowing at the end of an audio stream. This fix guards against the underflow by only decrementing the attribute when it is greater than zero. I found this bug because the SoundPlayer userland application was not correctly detecting when an audio stream was completed. This was happening because the remaining samples being returned from the client audio connection was an underflowed 16 bit integer instead of zero.
2021-12-06LibCore: Make LocalServer::take_over_from_system_server() return ErrorOrAndreas Kling
This allows us to use TRY() or MUST() when calling it.
2021-12-05Services: Cast unused IPC::new_client_connection() results to voidSam Atkins
These ones all manage their storage internally, whereas the WebContent and ImageDecoder ones require the caller to manage their lifetime. This distinction is not obvious to the user without looking through the code, so an API that makes this clearer would be nice.
2021-11-30AudioServer: Port to LibMain :^)Andreas Kling
2021-11-30LibCore: Change Core::LocalServer::on_ready_to_accept => on_acceptAndreas Kling
Everyone used this hook in the same way: immediately accept() on the socket and then do something with the newly accepted fd. This patch simplifies the hook by having LocalServer do the accepting automatically.
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-24Kernel: Allow higher audio sample rates than 65kHZ (`u16`)Jelle Raaijmakers
Executing `asctl set r 96000` no longer results in weird sample rates being set on the audio devices. SB16 checks for a sample rate between 1 and 44100 Hz, while AC97 implements double-rate support which allows sample rates between 8kHz and 96kHZ.
2021-11-21AudioServer: Use `strerror` correctly in MixerJelle Raaijmakers
2021-11-15Audio: Fix code smells and issues found by static analysiskleines Filmröllchen
This fixes all current code smells, bugs and issues reported by SonarCloud static analysis. Other issues are almost exclusively false positives. This makes much code clearer, and some minor benefits in performance or bug evasion may be gained.
2021-11-08LibAudio: Rename Audio::Frame -> Audio::SampleDavid Isaksson
"Frame" is an MPEG term, which is not only unintuitive but also overloaded with different meaning by other codecs (e.g. FLAC). Therefore, use the standard term Sample for the central audio structure. The class is also extracted to its own file, because it's becoming quite large. Bundling these two changes means not distributing similar modifications (changing names and paths) across commits. Co-authored-by: kleines Filmröllchen <malu.bertsch@gmail.com>
2021-11-02AudioServer: 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. This commit is separate from the other Servives changes because it required additional adaption of the code. Note that the old code did precisely what these changes try to prevent: Create and handle a ref-counted object with a refcount of zero.
2021-09-12AudioServer: Fix deadlock when playing two audio streamskleines Filmröllchen
Previously, AudioServer would deadlock when trying to play another audio stream, i.e. creating a queue. The m_pending_cond condition was used improperly, and the condition wait now happens independently of querying the pending queue for new clients if the mixer is running. To make the mixer's concurrency-safety code more readable, the use of raw POSIX mutex and condition syscalls is replaced with Threading::Mutex and Threading::ConditionVariable.