1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 06:04:57 +00:00
Commit graph

95 commits

Author SHA1 Message Date
kleines Filmröllchen
d905498fb6 AudioServer: Clean up ClientAudioStream APIs
- Use Optional references instead of pointers
- Clean up some const and nullability weirdness
- Use proper error return value for get_next_sample
2023-08-12 12:22:16 -06:00
kleines Filmröllchen
aacb4fc590 AudioServer: Move ClientAudioStream to own files
This class will only grow, and it should really have its own files.
2023-08-12 12:22:16 -06:00
Andreas Kling
ddbe6bd7b4 Userland: Rename Core::Object to Core::EventReceiver
This is a more precise description of what this class actually does.
2023-08-06 20:39:51 +02:00
Jelle Raaijmakers
5c64686666 Kernel+AudioServer: Use interrupts for Intel HDA audio buffer completion
We used to not care about stopping an audio output stream for Intel HDA
since AudioServer would continuously send new buffers to play. Since
707f5ac150ef858760eb9faa52b9ba80c50c4262 however, that has changed.

Intel HDA now uses interrupts to detect when each buffer was completed
by the device, and uses a simple heuristic to detect whether a buffer
underrun has occurred so it can stop the output stream.

This was tested on Qemu's Intel HDA (Linux x86_64) and a bare metal MSI
Starship/Matisse HD Audio Controller.
2023-07-04 00:05:34 +02:00
kleines Filmröllchen
b4fbd30b70 AudioServer+Userland: Decouple client sample rates from device rate
This change was a long time in the making ever since we obtained sample
rate awareness in the system. Now, each client has its own sample rate,
accessible via new IPC APIs, and the device sample rate is only
accessible via the management interface. AudioServer takes care of
resampling client streams into the device sample rate. Therefore, the
main improvement introduced with this commit is full responsiveness to
sample rate changes; all open audio programs will continue to play at
correct speed with the audio resampled to the new device rate.

The immediate benefits are manifold:
- Gets rid of the legacy hardware sample rate IPC message in the
  non-managing client
- Removes duplicate resampling and sample index rescaling code
  everywhere
- Avoids potential sample index scaling bugs in SoundPlayer (which have
  happened many times before) and fixes a sample index scaling bug in
  aplay
- Removes several FIXMEs
- Reduces amount of sample copying in all applications (especially
  Piano, where this is critical), improving performance
- Reduces number of resampling users, making future API changes (which
  will need to happen for correct resampling to be implemented) easier

I also threw in a simple race condition fix for Piano's audio player
loop.
2023-07-01 23:27:24 +01:00
kleines Filmröllchen
e0dce41ddf AudioServer: Add a hack to make audio "just work" on HDA for now
This should be fixed properly, but we have decided that a quick hack is
fine so that audio "just works" for most people.
2023-06-25 00:16:44 +02:00
kleines Filmröllchen
03fac609ee AudioServer+Userland: Separate audio IPC into normal client and manager
This is a sensible separation of concerns that mirrors the WindowServer
IPC split. On the one hand, there is the "normal" audio interface, used
for clients that play audio, which is the primary service of
AudioServer. On the other hand, there is the management interface,
which, like the WindowManager endpoint, provides higher-level control
over clients and the server itself.

The reasoning for this split are manifold, as mentioned we are mirroring
the WindowServer split. Another indication to the sensibility of the
split is that no single audio client used the APIs of both interfaces.
Also, useless audio queues are no longer created for managing clients
(since those don't even exist, just like there's no window backing
bitmap for window managing clients), eliminating any bugs that may occur
there as they have in the past.

Implementation-wise, we just move all the APIs and implementations from
the old AudioServer into the AudioManagerServer (and respective clients,
of course). There is one point of duplication, namely the hardware
sample rate. This will be fixed in combination with per-client sample
rate, eliminating client-side resampling and the related update bugs.
For now, we keep one legacy API to simplify the transition.

The new AudioManagerServer also gains a hardware sample rate change
callback to have exact symmetry on the main server parameters (getter,
setter, and callback).
2023-06-25 00:16:44 +02:00
Timothy Flynn
936ec94f81 AK+LibAudio+AudioServer: Silence very noisy debug statements by default
These are spammed quite heavily on the debug console, especially at the
end of audio playback.
2023-06-13 06:14:01 +02:00
Ben Wiederhake
37b5bfa068 AudioServer: Migrate from DeprecatedFile to File
Advances #17129.
2023-05-12 19:46:54 +01:00
Joel Petersson
42e118e6a9 AudioServer: Dequeue all buffers when clearing a ClientAudioStream
Previously we would exit the dequeuing loop after just one buffer
had been dequeued due to some bogus logic. This would manifest
when stopping and starting a track in SoundPlayer, where a few
miliseconds of 'old' audio would play when restarting the playback.

This commit makes sure we clear the entire queue.
2023-05-03 10:01:14 +02:00
Andreas Kling
689ca370d4 Everywhere: Remove NonnullRefPtr.h includes 2023-03-06 23:46:35 +01:00
Andreas Kling
8a48246ed1 Everywhere: Stop using NonnullRefPtrVector
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-03-06 23:46:35 +01:00
Tim Schumacher
a96339b72b LibCore: Move Stream-based sockets into the Core namespace 2023-02-13 00:50:07 +00:00
Tim Schumacher
d43a7eae54 LibCore: Rename File to DeprecatedFile
As usual, this removes many unused includes and moves used includes
further down the chain.
2023-02-13 00:50:07 +00:00
Tim Schumacher
a86184c997 AudioServer: Use AK::Stream to serialize mixed samples 2023-02-08 18:51:02 +00:00
Tim Schumacher
ae64b68717 AK: Deprecate the old AK::Stream
This also removes a few cases where the respective header wasn't
actually required to be included.
2023-01-29 19:16:44 -07:00
Linus Groh
108ea2b921 LibCore: Remove try_ prefix from fallible SharedCircularQueue methods 2023-01-28 22:41:36 +01:00
Sam Atkins
a8cf0c9371 LibCore+Userland: Make Core::Timer::create_single_shot() return ErrorOr
clang-format sure has some interesting opinions about where to put a
method call that comes after a lambda. :thonk:
2023-01-12 11:25:51 +01:00
Ben Wiederhake
6b7ce19161 Everywhere: Remove unused includes of LibC/stdlib.h
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.
2023-01-02 20:27:20 -05:00
kleines Filmröllchen
d9c1eb860f AudioServer: Detect improperly detached audio clients
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-25 17:43:16 -07:00
Alex Chronopoulos
457fda6354 AudioServer: Stop re-creating the device stream buffer
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-12 10:03:42 -07:00
Alex Chronopoulos
b22c840963 AudioServer: Stop glitching when toggling mute
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-12 10:03:42 -07:00
Alex Chronopoulos
e86cab00b6 AudioServer: Skip mixing when volume is zero
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-07 12:30:57 +00:00
Tim Schumacher
ce2f1b845f Everywhere: Mark dependencies of most targets as PRIVATE
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-11-01 14:49:09 +00:00
Oleg Kosenkov
0c27d95e76 Userland: Use Threading::MutexLocker to lock/unlock mutexes 2022-10-31 00:00:52 +01:00
Ali Mohammad Pur
166a905951 Userland: Properly populate GENERATED_SOURCES
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-10-12 15:55:15 +01:00
Tim Schumacher
8763dbcccc Everywhere: Remove a bunch of dead write-only variables
LLVM 15 now warns (and thus errors) about this, and there is really no
point in keeping them.
2022-09-16 05:39:28 +00:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
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-07-12 23:11:35 +02:00
kleines Filmröllchen
ef1c97e3d8 AudioServer: Reduce hardware audio buffer to 512 samples 2022-06-23 23:26:33 +01:00
kleines Filmröllchen
1c23a222b2 AudioServer: Make hardware write buffer size flexible
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-23 23:26:33 +01:00
kleines Filmröllchen
746d3c1131 AudioServer: Explicitly cast between numeric types in the mixer 2022-06-23 23:26:33 +01:00
kleines Filmröllchen
ab49fcfb7c LibAudio+Userland: Remove Audio::LegacyBuffer
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-03 23:09:20 +02:00
Andrew Kaster
f1d47ea618 LibWeb+AudioServer: Remove unused spaceship operators
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-23 10:43:32 -07:00
kleines Filmröllchen
612dbdc671 AudioServer: Auto-pause new clients
This fixes a bunch of audio clients that don't actually play audio.
2022-04-21 13:55:00 +02:00
kleines Filmröllchen
49b087f3cd LibAudio+Userland: Use new audio queue in client-server communication
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-21 13:55:00 +02:00
kleines Filmröllchen
cb0e95c928 LibAudio+Everywhere: Rename Audio::Buffer -> Audio::LegacyBuffer
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-21 13:55:00 +02:00
Lenny Maiorani
0b7baa7e5a Services: Use default constructors/destructors
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-24 20:09:26 -07:00
kleines Filmröllchen
79deb7d6c7 AudioServer: Decrease sample headroom to 5%
This might still be too much, but it's better than what we had before.
2022-03-14 22:46:46 +01:00
Itamar
3a71748e5d Userland: Rename IPC ClientConnection => ConnectionFromClient
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-25 22:35:12 +01:00
Sam Atkins
cd0ffe5460 LibCore+Everywhere: Return ErrorOr from ConfigFile::sync()
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-16 19:49:41 -05:00
Sam Atkins
8260135d4d LibCore+Everywhere: Return ErrorOr from ConfigFile factory methods
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-16 19:49:41 -05:00
Liav A
bf8c93fe0a AudioServer: Use first audio channel in the /dev/audio directory
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-02-14 11:39:19 +01:00
sin-ack
2e1bbcb0fa LibCore+LibIPC+Everywhere: Return Stream::LocalSocket from LocalServer
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-15 13:29:48 +03:30
kleines Filmröllchen
be6418cc50 Everywhere: Use my new serenityos.org e-mail :^) 2022-01-14 11:54:09 +01:00
Elyse
fb109ab3b4 AudioServer: Ignore 'muted' clients when computing the 'output mix' 2021-12-24 00:19:01 -08:00
Elyse
bb747c471f AudioServer: Add a 'self_muted' state to each client connection
This new state will allow us to ignore muted clients when computing the
'output mix' in the Mixer.
2021-12-24 00:19:01 -08:00
Elyse
ce5f5f543f AudioServer: Add 'mute' member and methods to ClientAudioStream
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-24 00:19:01 -08:00
Elyse
c78a8b94c5 Everywhere: Refactor 'muted' to 'main_mix_muted' in all AudioConnections
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-24 00:19:01 -08:00
Max Trussell
60fa8ac109 AudioServer/Mixer: Fix remaining samples underflow
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-24 00:05:35 -08:00
Andreas Kling
81047d8f9c LibCore: Make LocalServer::take_over_from_system_server() return ErrorOr
This allows us to use TRY() or MUST() when calling it.
2021-12-06 19:22:16 +01:00