Commit Graph

92 Commits

Author SHA1 Message Date
Hendiadyoin1
fbb798f98c AK: Move integral log2 and exp to IntegerMath.h 2022-02-06 17:52:33 +00:00
kleines Filmröllchen
a79a9fb692 LibAudio: Use ArrayLike concept to remove duplicate Buffer constructor 2022-01-28 23:40:25 +01:00
Sam Atkins
45cf40653a Everywhere: Convert ByteBuffer factory methods from Optional -> ErrorOr
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-24 22:36:09 +01:00
kleines Filmröllchen
8a92573732 LibAudio: Convert FlacLoader to use new Core::Stream APIs :^)
For this change to work "easily", Loader can't take const ByteBuffer's
anymore, which is fine for now.
2022-01-22 01:13:42 +03:30
kleines Filmröllchen
4f48a086b7 LibAudio: Add LOADER_TRY to auto-convert Error to LoaderError 2022-01-22 01:13:42 +03:30
kleines Filmröllchen
9702f2010f LibAudio: Add Error conversion constructor for LoaderError
This will become necessary shortly when we quickly want to promote an
AK::Error to an Audio::LoaderError.
2022-01-22 01:13:42 +03:30
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
54ac4ba8cc LibAudio: Expose the format name from the loader plugins
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-14 21:37:23 +01:00
kleines Filmröllchen
be6418cc50 Everywhere: Use my new serenityos.org e-mail :^) 2022-01-14 11:54:09 +01:00
creator1creeper1
3c05261611 AK+Everywhere: Make FixedArray OOM-safe
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-08 22:54:05 +01:00
mjz19910
3102d8e160 Everywhere: Fix many spelling errors 2022-01-07 10:56:59 +01:00
kleines Filmröllchen
b48badc3b6 LibAudio: Remove frame-wise copys from FlacLoader
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-02 22:18:37 +01:00
kleines Filmröllchen
30130904f5 LibAudio: Alow creating a Buffer from a FixedArray
A FixedArray, due to its non-allocation guarantee, is great for audio
programming, so it's natural to have it interface with Buffer.
2022-01-02 22:18:37 +01: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
kleines Filmröllchen
982529a948 LibAudio: Don't unnecessarily copy the passed decode buffer 2021-12-17 13:13:00 -08:00
kleines Filmröllchen
0d28b6d236 LibAudio: Remove superflous comment
Thanks @alimpfard for pointing that out :^)
2021-12-17 13:13:00 -08:00
kleines Filmröllchen
9fa3aa84e1 LibAudio: Add an adjustable buffer size to FlacLoader
This makes it easier to fine-tune the optimal input buffer size.
2021-12-17 13:13:00 -08:00
kleines Filmröllchen
8608cd11e4 LibAudio: Optimize sample moves in FlacLoader
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-28 13:33:51 -08:00
kleines Filmröllchen
96d02a3e75 LibAudio: New error propagation API in Loader and Buffer
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-28 13:33:51 -08:00
kleines Filmröllchen
ec8bd8116d LibAudio: Buffer API improvements
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-28 13:33:51 -08:00
kleines Filmröllchen
14d330faba LibAudio: Avoid frequent read() calls in FLAC residual decode
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-28 13:33:51 -08:00
Jelle Raaijmakers
ddb424a2e7 LibAudio: Verify source and target rates for ResampleHelper 2021-11-21 09:27:00 +01:00
kleines Filmröllchen
d50b1465c3 LibAudio: Add explanatory comments to the FlacLoader
Some nuances in the FLAC loading code can do well with an explanation,
as these non-obvious insights are often the result of long and painful
debugging and nobody should touch the affected code without careful
deliberation.

(Of course, secretly I just want people to maintain my loader code.)
:^)
2021-11-15 23:00:11 +00:00
kleines Filmröllchen
8af97d0ce7 Audio: Fix code smells and issues found by static analysis
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-15 23:00:11 +00:00
Andreas Kling
8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
kleines Filmröllchen
61d9082da6 LibAudio: Replace log_pan with a constant power panning algoritm
This little functional change uses the most common algorithm for panning
audio, known as constant power panning. It makes it so that the total
output power (not directly the sample value, i.e. the peak) stays the
same no matter how the audio is panned.
2021-11-08 16:29:25 -08:00
kleines Filmröllchen
8945cc8358 LibAudio: Improve local variable names
This makes the code easier to read.
2021-11-08 16:29:25 -08:00
David Isaksson
b6d075bb01 LibAudio: Rename Audio::Frame -> Audio::Sample
"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-08 16:29:25 -08:00
David Isaksson
fa4255bcf1 LibAudio: Refactor out linear_to_log function and add its inverse
The conversion from a linear scale (how we think about audio) to a
logarithmic scale (how audio actually works) will be useful for other
operations, so let's extract it to its own utility function. Its inverse
will also allow reversible operations to be written more easily.
2021-11-08 16:29:25 -08:00
Andreas Kling
e2eabb4132 LibCore: Use ErrorOr<T> in Core::AnonymousBuffer 2021-11-08 00:35:27 +01:00
Ben Wiederhake
b3e9a4e603 Libraries: Fix visibility of Object-derivative constructors
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.
2021-11-02 22:56:53 +01:00
kleines Filmröllchen
bd17da9f9e Audio: Add per-client volume
Note: While ClientAudioStream has had a volume property, it is only now
used in the mixer.
2021-09-12 23:38:57 +02:00
kleines Filmröllchen
ab4a2b8b41 LibDSP+LibAudio: Use logarithmic scaling in delay effect
With logarithmic volume scaling, the delay effect can sound more
natural.
2021-09-12 23:38:57 +02:00
kleines Filmröllchen
152ec28da0 Audio: Change how volume works
Across the entire audio system, audio now works in 0-1 terms instead of
0-100 as before. Therefore, volume is now a double instead of an int.
The master volume of the AudioServer changes smoothly through a
FadingProperty, preventing clicks. Finally, volume computations are done
with logarithmic scaling, which is more natural for the human ear.

Note that this could be 4-5 different commits, but as they change each
other's code all the time, it makes no sense to split them up.
2021-09-12 23:38:57 +02:00
Ali Mohammad Pur
97e97bccab Everywhere: Make ByteBuffer::{create_*,copy}() OOM-safe 2021-09-06 01:53:26 +02:00
Karol Kosek
1c65ee6edf LibAudio: Implement decoding verbatim blocks in FLAC
They're mostly used in literal random data, so it isn't like
there is a high demand for it, but it's cool to have more complete
implementation anyway. :^)
2021-08-31 16:35:37 +02:00
kleines Filmröllchen
a749b16674 Libraries: Add LibDSP
LibDSP is a library for digital signal processing, and is primarily
intended to support the future DAW version of Piano.
2021-08-31 17:03:55 +04:30
kleines Filmröllchen
d049626f40 Userland+LibAudio: Make audio applications support dynamic sample rate
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-08-27 23:35:27 +04:30
kleines Filmröllchen
195d6d006f LibAudio: Resample FLAC audio data
FlacLoader initialized, but never used its resampler; this is now fixed
and all subframes are resampled before decorrelation occurs. FLAC files
with non-44100-Hz sample rates now play properly.
2021-08-18 18:16:48 +02:00
kleines Filmröllchen
d7ca60b998 LibAudio: Resample with integer ratios instead of floats
Floating-point ratios are inherently imprecise, and can lead to
unpredictable or nondeterministic behavior when resampling and expecting
a certain number of resulting samples. Therefore, the resampler now uses
integer ratios, with almost identical but fully predictable behavior.

This also introduces the reset() function that the FLAC loader will use
in the future.
2021-08-18 18:16:48 +02:00
kleines Filmröllchen
ba622cffe4 LibAudio: Fix overflow on 24-bit FLAC LPC data
When computing sample values from a linear predictor, the repeated
multiplication and addition can lead to very large values that may
overflow a 32-bit integer. This was never discovered with 16-bit FLAC
test files used to create and validate the first version of the FLAC
loader. However, 24-bit audio, especially with large LPC shifts, will
regularly exceed and overflow i32. Therefore, we now use 64 bits
temporarily. If the resulting value is too large for 32 bits, something
else has gone wrong :^)

This fixes playback noise on 24-bit FLACs.
2021-08-17 00:16:00 +02:00
kleines Filmröllchen
c974be91ab LibAudio: Rescale integer samples correctly in FLAC loader
The FLAC samples are signed, so we need to rescale them not by their bit
depth, but by half of the bit depth. For example, a 24-bit sample
extends from -2^23 to 2^23-1, and therefore needs to be rescaled by 2^23
to conform to the [-1, 1] double sample range.
2021-08-17 00:16:00 +02:00
kleines Filmröllchen
442aa48a61 LibAudio: Use size_t in loops
This is more idiomatic :^)
2021-08-17 00:16:00 +02:00
Karol Kosek
91c9d9ee88 LibAudio: Make playing lossy flacs more truthful
Playing a lossy flac file resulted in hearing something
you'd not like to play.  Instead of your lovely bass, you had sounds
as if you put a CD-ROM disc to a CD player.

It turned out that the size for making signed values was too big,
making all the values unsigned.

I've used lossyWav[1] (the posix port[2] to be exact)
to generate such files.

[1]: https://wiki.hydrogenaud.io/index.php?title=LossyWAV
[2]: https://github.com/MoSal/lossywav-for-posix
2021-08-06 23:50:10 +02:00
Karol Kosek
837803531a LibAudio: Fix calculation of wasted bits-per-sample
The value was always zero.
2021-08-06 23:50:10 +02:00
Karol Kosek
2ecd115176 LibAudio: Make read samples signed when decoding fixed FLAC subframes
Prior this change, decoding fixed subframes produced "unpleasant
crackling noices".

While the type doesn't appear so often when using the default settings,
encoding files in flac(1) with --fast option uses fixed subframes
almost every time.

This also applies the logic to the constant subframes,
which isn't so important, as the type is generally for the silence,
but let's use it as well to avoid inconsistency.
2021-08-06 23:50:10 +02:00
Karol Kosek
e500b39e47 LibAudio: Use an existing file stream when parsing a FLAC header
Before this change the file stream was generated two times:
one time in the parse_header(), and another time for the whole class
in the constructor.

The previous commit moved the m_stream initialization before
executing the parse_header function, so we can now reuse that here.
2021-08-04 11:00:27 +02:00
Karol Kosek
81261bc169 LibAudio: Initialize m_stream before parsing a FLAC header
Before this change opening the file in the system resulted in crash
caused by assertion saying:

  SoundPlayer(32:32): ASSERTION FAILED: m_ptr
  ../.././AK/OwnPtr.h:139
  [#0 SoundPlayer(32:32)]: Terminating SoundPlayer(32) due to signal 6
  [#0 FinalizerTask(4:4)]: 0xdeadc0de

The issue was that 845d403b8c started
using m_stream in the parse_header() function, but that variable wasn't
initialized if the Loader plugin was created using a file path
(which is used everywhere except for the fuzz testing),
resulting in a crash mentioned above.
2021-08-04 11:00:27 +02:00
Andrew Kaster
845d403b8c LibAudio: Handle stream errors in FlacLoader
The FlacLoader already has numerous checks for invalid data reads and
for invalid stream states, but it never actually handles the stream
errors on the stream object. By handling them properly we can actually
run FuzzFlacLoader for longer than a few seconds before it hits the
first assertion :^).
2021-08-02 09:05:28 +02:00
Karol Kosek
8c2be4b3dc LibAudio: Implement loaded_samples() in the FLAC Loader
This makes aplay show current playback position.
2021-07-22 22:57:05 +02:00