summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibAudio
AgeCommit message (Collapse)Author
2022-05-07LibAudio+LibDSP: Switch samples to 32-bit float instead of 64-bit floatkleines Filmröllchen
This has been overkill from the start, and it has been bugging me for a long time. With this change, we're probably a bit slower on most platforms but save huge amounts of space with all in-memory sample datastructures.
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-05-03LibAudio: Move WAV sample reading and conversion into own helperskleines Filmröllchen
This completely removes WavLoader's dependency on LegacyBuffer: We directly create the result sample container and write into it. I took this opportunity to rewrite most of the sample reading functions as a single templated function, which combined with the better error handling makes this "ported" code super concise.
2022-05-03LibAudio: Move WavLoader to Core::Stream APIskleines Filmröllchen
This makes the code much more readable and concise, reduces the size of the WavLoader class itself, moves almost all fallible initialization out of the constructor and should provide better error handling in general. Also, a lot of now-unnecessary imports are removed.
2022-05-03LibAudio: Refactor and modernize WavLoaderkleines Filmröllchen
* All clang-tidy warnings fixed except read_header cognitive complexity * Use size_t in more places * Replace #define's with constexpr constants * Some variable renaming for readability
2022-04-29LibAudio: Add a formatter for `Audio::Sample`Jelle Raaijmakers
Useful for debugging.
2022-04-29LibAudio: Make includes work from portsJelle Raaijmakers
The endpoints were included with a relative path that does not work by default when compiling ports. Include them from a root-relative path instead.
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-04-16LibCore+Everywhere: Make Core::Stream::read() return BytesSam Atkins
A mistake I've repeatedly made is along these lines: ```c++ auto nread = TRY(source_file->read(buffer)); TRY(destination_file->write(buffer)); ``` It's a little clunky to have to create a Bytes or StringView from the buffer's data pointer and the nread, and easy to forget and just use the buffer. So, this patch changes the read() function to return a Bytes of the data that were just read. The other read_foo() methods will be modified in the same way in subsequent commits. Fixes #13687
2022-04-06AK+Userland: Rename Array::front/back to first/lastSam Atkins
This is the name that is used for every other collection type so let's be consistent.
2022-04-01Everywhere: Run clang-formatIdan Horowitz
2022-03-27LibAudio: Make sure we initialize ResampleHelper member variablesBrian Gianforcaro
Found by Static Analysis: Sonar Cloud
2022-03-26FlacLoader: Use seektable for performing seek operationsMax Trussell
As a fallback, we perform primitive seek if there's no seektable. Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
2022-03-26FlacLoader: Parse SEEKTABLE headerMax Trussell
Populates m_seektable attribute with FlacSeekPoints. For more information see: https://datatracker.ietf.org/doc/html/draft-ietf-cellar-flac#section-11.13 Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
2022-03-18Libraries: Change enums to enum classes in LibAudioLenny Maiorani
2022-03-18Userland: Change static const variables to static constexprLenny Maiorani
`static const` variables can be computed and initialized at run-time during initialization or the first time a function is called. Change them to `static constexpr` to ensure they are computed at compile-time. This allows some removal of `strlen` because the length of the `StringView` can be used which is pre-computed at compile-time.
2022-03-15AK+Everywhere: Add sincos and use it in some placesHendiadyoin1
Calculating sin and cos at once is quite a bit cheaper than calculating them individually. x87 has even a dedicated instruction for it: `fsincos`.
2022-03-10Libraries: Use default constructors/destructors in LibAudioLenny 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-02-26LibAudio: Add an array conversion transitional API to Bufferkleines Filmröllchen
Of course, Buffer is going to be removed very soon, but much of the WavLoader behavior still depends on it. Therefore, this intermediary API will allow adopting the Loader infrastructure without digging too deep into the WavLoader legacy code. That's for later :^)
2022-02-26LibAudio: Allow resampling from any array-like typekleines Filmröllchen
2022-02-26LibAudio: Split Buffer.{h, cpp} into three fileskleines Filmröllchen
The Buffer files had contained both the ResampleHelper and the sample format utilities. Because the Buffer class (and its file) is going to be deleted soon, this commit separates those two things into their own files.
2022-02-26LibAudio: Add basic MP3 DecoderArne Elster
This is a basic MPEG-1 layer 3 audio decoder. It supports all sample rates and stereo modes except for freeformat.
2022-02-26LibAudio: Add decoding tables for MPEG-1 layer 3 audioArne Elster
All data is taken straight from ISO/IEC 11172-3. These are tables necessary for decoding MP3.
2022-02-26LibAudio: Add huffman tables for MPEG-1 layer 3 audioArne Elster
The data is taken straight from the ISO/IEC 11172-3 standard. For decoding efficiency the tables are transformed into trees at compile time using a constexpr approach. That way no runtime initialization is necessary and decoding can be faster than searching through tables.
2022-02-25Userland: Rename IPC::ServerConnection=>IPC::ConnectionToServerItamar
This was done with CLion's automatic rename feature.
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-20LibAudio: Simplify empty Audio::Buffer state to be truly emptyAndrew Kaster
The old FIXME asserting that Core::AnonymousBuffer cannot be invalid or zero-sized is no longer accurate. Add a default constructor for Audio::Buffer that has all invalid state instead of going to the OS to allocate a 1 sample buffer for the "no more samples" states in the WAV and FLAC plugins.
2022-02-06AK: Move integral log2 and exp to IntegerMath.hHendiadyoin1
2022-01-28LibAudio: Use ArrayLike concept to remove duplicate Buffer constructorkleines Filmröllchen
2022-01-24Everywhere: Convert ByteBuffer factory methods from Optional -> ErrorOrSam Atkins
Apologies for the enormous commit, but I don't see a way to split this up nicely. In the vast majority of cases it's a simple change. A few extra places can use TRY instead of manual error checking though. :^)
2022-01-22LibAudio: Convert FlacLoader to use new Core::Stream APIs :^)kleines Filmröllchen
For this change to work "easily", Loader can't take const ByteBuffer's anymore, which is fine for now.
2022-01-22LibAudio: Add LOADER_TRY to auto-convert Error to LoaderErrorkleines Filmröllchen
2022-01-22LibAudio: Add Error conversion constructor for LoaderErrorkleines Filmröllchen
This will become necessary shortly when we quickly want to promote an AK::Error to an Audio::LoaderError.
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-14LibAudio: Expose the format name from the loader pluginskleines Filmröllchen
The format of these names is "Full Abbreviation (.fileformat)". For example: "FLAC (.flac)", "RIFF WAVE (.wav)", "MPEG Layer III (.mp3)", "Vorbis (.ogg)" The reasoning is that the container and therefore the file ending may differ significantly from the actual format, and the format should be given as unambiguously as possible and necessary.
2022-01-14Everywhere: Use my new serenityos.org e-mail :^)kleines Filmröllchen
2022-01-08AK+Everywhere: Make FixedArray OOM-safecreator1creeper1
FixedArray now doesn't expose any infallible constructors anymore. Rather, it exposes fallible methods. Therefore, it can be used for OOM-safe code. This commit also converts the rest of the system to use the new API. However, as an example, VMObject can't take advantage of this yet, as we would have to endow VMObject with a fallible static construction method, which would require a very fundamental change to VMObject's whole inheritance hierarchy.
2022-01-07Everywhere: Fix many spelling errorsmjz19910
2022-01-02LibAudio: Remove frame-wise copys from FlacLoaderkleines Filmröllchen
Previously, FlacLoader would read the data for each frame into a separate vector, which are then combined via extend() in the end. This incurs an avoidable copy per frame. By having the next_frame() function write into a given Span, there's only one vector allocated per call to get_more_samples(). This increases performance by at least 100% realtime, as measured by abench, from about 1200%-1300% to (usually) 1400% on complex test files.
2022-01-02LibAudio: Alow creating a Buffer from a FixedArraykleines Filmröllchen
A FixedArray, due to its non-allocation guarantee, is great for audio programming, so it's natural to have it interface with Buffer.
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-17LibAudio: Don't unnecessarily copy the passed decode bufferkleines Filmröllchen
2021-12-17LibAudio: Remove superflous commentkleines Filmröllchen
Thanks @alimpfard for pointing that out :^)
2021-12-17LibAudio: Add an adjustable buffer size to FlacLoaderkleines Filmröllchen
This makes it easier to fine-tune the optimal input buffer size.
2021-11-28LibAudio: Optimize sample moves in FlacLoaderkleines Filmröllchen
As long as possible, entire decoded frame sample vectors are moved into the output vector, leading to up to 20% speedups by avoiding memmoves on take_first.
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-28LibAudio: Buffer API improvementskleines Filmröllchen
This consists of two changes: First, a utility function create_empty allows the user to quickly create an empty buffer. Second, most creation functions now return a NonnullRefPtr, as their failure causes a VERIFY crash anyways.
2021-11-28LibAudio: Avoid frequent read() calls in FLAC residual decodekleines Filmröllchen
Decoding the residual in FLAC subframes is by far the most I/O-heavy operation in FLAC decoding, as the residual data makes up the majority of subframe data in LPC subframes. As the residual consists of many Rice-encoded numbers with different bit sizes for differently large numbers, the residual decoder frequently reads only one or two bytes at a time. As we use a normal FileInputStream, that directly translates to many calls to the read() syscall. We can see that the I/O overhead while FLAC decoding is quite large, and much time is spent in the read() syscall's kernel code. This is optimized by using a Buffered<FileInputStream> instead, leading to 4K blocks being read at once and a large reduction in I/O overhead. Benchmarking with the new abench utility gives a 15-20% speedup on identical files, usually pushing FLAC decoding to 10-15x realtime speed on common sample rates.
2021-11-21LibAudio: Verify source and target rates for ResampleHelperJelle Raaijmakers