Age | Commit message (Collapse) | Author |
|
This patch allows to insert "%uid" in `IPC_CLIENT_CONNECTION`
declaration and in SystemServer's ini files. This pattern is replaced
then replaced by the UID of the owner of the service. It opens a path
for seamlessly managed, per-user portal.
|
|
The files weren't starting exactly from the beginning before.
This happened because the parameter now takes the sample index, instead
of a seekpoint.
|
|
Out of 40/63 failed tests, this change reduces the number down to four.
:^)
See: #14683
|
|
This is a tangly commit and it fixes all the bugs that a plain move
would have caused (i.e. we need to touch other logic which had wrong
assumptions).
|
|
The audio enqueuer thread goes to sleep when there is no more audio data
present, and through normal Core::EventLoop events it can be woken up.
However, that waking up only happens when the thread is not currently
running, so that the wake-up events don't queue up and cause weirdness.
The atomic variable responsible for keeping track of whether the thread
is active can lead to a racy deadlock however, where the audio enqueuer
thread will never wake up again despite there being audio data to
enqueue. Consider this scenario:
- Main thread calls into async_enqueue. It detects that according to the
atomic variable, the other thread is still running, skipping the event
queue wake.
- Enqueuer thread has just finished playing the last chunk of audio and
detects that there is no audio left. It enters the if block with the
dbgln "Reached end of provided audio data..."
- Main thread enqueues audio, making the user sample queue non-empty.
- Enqueuer thread does not check this condition again, instead setting
the atomic variable to indicate that it is not running. It exits into
an event loop sleep.
- Main thread exits async_enqueue. The calling audio enqueuing system
(see e.g. Piano, but all of them function similarly) will wait until
the enqueuer thread has played enough samples before async_enqueue is
called again. However, since the enqueuer thread will never play any
audio, this condition is never fulfilled and audio playback deadlocks
This commit fixes that by allowing the event loop to not enqueue an
event that already exists, therefore overloading the audio enqueuer
event loop by at maximum one message in weird situations. We entirely
get rid of the atomic variable and the race condition is prevented.
|
|
This will conflict with apps that don't use this thread and it also
creates unnecessary overhead for non-enqueuing clients like AudioApplet.
Use the new Thread is_started info to start the thread only if necessary
(on first call to async_enqueue).
|
|
That's the standard naming convention, but I didn't follow it when
originally creating LibDSP and nobody corrected me, so here I am one
year later :^)
|
|
The automatic nomenclature change for IPC sockets got this one wrong.
|
|
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.
|
|
Error::from_string_literal now takes direct char const*s, while
Error::from_string_view does what Error::from_string_literal used to do:
taking StringViews. This change will remove the need to insert `sv`
after error strings when returning string literal errors once
StringView(char const*) is removed.
No functional changes.
|
|
This way the FlacLoader can be more easily understood by someone that
doesn't already know the format inside out.
|
|
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
* 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
|
|
Useful for debugging.
|
|
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.
|
|
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:
|
|
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.
|
|
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
|
|
This is the name that is used for every other collection type so let's
be consistent.
|
|
|
|
Found by Static Analysis: Sonar Cloud
|
|
As a fallback, we perform primitive seek if there's no seektable.
Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
|
|
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>
|
|
|
|
`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.
|
|
Calculating sin and cos at once is quite a bit cheaper than calculating
them individually.
x87 has even a dedicated instruction for it: `fsincos`.
|
|
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."
|
|
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 :^)
|
|
|
|
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.
|
|
This is a basic MPEG-1 layer 3 audio decoder. It supports all
sample rates and stereo modes except for freeformat.
|
|
All data is taken straight from ISO/IEC 11172-3. These are tables
necessary for decoding MP3.
|
|
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.
|
|
This was done with CLion's automatic rename feature.
|
|
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/'
|
|
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.
|
|
|
|
|
|
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. :^)
|
|
For this change to work "easily", Loader can't take const ByteBuffer's
anymore, which is fine for now.
|
|
|
|
This will become necessary shortly when we quickly want to promote an
AK::Error to an Audio::LoaderError.
|
|
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.
|
|
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.
|
|
|
|
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.
|