Commit graph

109 commits

Author SHA1 Message Date
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
kleines Filmröllchen
ede8582def LibAudio: Check more FLAC partition order constraints as per the spec 2023-09-09 11:23:57 -06:00
kleines Filmröllchen
dcc3d7bc35 LibAudio: Treat FLAC bps <= wasted_bps as error instead of crash
This can happen with some weird inputs, so instead, return an error; we
need at least one “effective” bit per sample so the bits per sample
cannot be less than or equal to the wasted bits per sample.
2023-09-09 11:23:57 -06:00
kleines Filmröllchen
c776ebcaf6 LibAudio: Only check subframe size if sample rate is constant 2023-09-09 11:23:57 -06:00
kleines Filmröllchen
2b61193b71 LibAudio: Account for garbage shifts in several places in FLAC loader 2023-09-09 11:23:57 -06:00
kleines Filmröllchen
b432674923 LibAudio: Prevent overflows during prediction
Saturating arithmetic leads to less screwed up audio in these cases.
2023-09-09 11:23:57 -06:00
kleines Filmröllchen
625aac2367 LibAudio: Add a FLAC encoder
This encoder can handle all integer formats and sample rates, though
only two channels well. It uses fixed LPC and performs a
close-to-optimal parameter search on the LPC order and residual Rice
parameter, leading to decent compression already.
2023-08-12 12:25:26 -06:00
kleines Filmröllchen
252b1328ea LibAudio: Expand FLAC loader debug messages
These are now indented to aid readability.
2023-08-12 12:25:26 -06:00
kleines Filmröllchen
60f1472902 LibAudio: Store all available data in the FLAC frame header
This will make it possible to write the header back out.
2023-08-12 12:25:26 -06:00
kleines Filmröllchen
e45a666419 LibAudio: Calculate and verify frame checksum
This is the second of three checksums that FLAC provides, verifying all
of a frame's data.
2023-08-12 12:25:26 -06:00
kleines Filmröllchen
111fd1e5fe LibAudio: Optimize FlacLoader by avoiding allocations
- Pre-allocate and reuse sample decompression buffers. In many FLAC
  files, the amount of samples per frame is either constant or the
  largest frame will be hit within the first couple of frames. Also,
  during audio output, we need to move and combine the samples from the
  decompression buffers into the final output buffers anyways. Avoiding
  the reallocation of these large buffers provides an improvement from
  16x to 18x decode speed on strongly compressed but otherwise usual
  input.
- Leave a FIXME for a similar improvement that can be made in the
  residual decoder.
- Pre-allocate audio chunks if frame size is known.
- Use reasonable inline capacities in several places where we know the
  maximum or usual capacity needed.
2023-07-06 19:13:36 +01:00
Zaggy1024
ddb7b59af0 LibAudio: Always add a seek point once the FLAC header has parsed 2023-07-06 14:27:57 +01:00
Zaggy1024
9d5819e9e2 LibAudio: Seek accurately to the target frame in the FLAC loader
Instead of using a seek tolerance value to get close enough to the
target, we can skip frames forward until we pass the target, then seek
back to the previous frame. That puts us in a position to immediately
decode the frame containing the target sample.
2023-07-06 14:27:57 +01:00
Zaggy1024
f2d9280342 LibAudio: Skip FLAC samples even if already close to seek target
Previously, the FLAC loader would not skip samples to reach its seek
target if it saw that the current sample in the loader is closer to the
target than the seek point it finds. This prevents seeking forward when
there are no seek points past the current position.
2023-07-06 14:27:57 +01:00
Zaggy1024
ee1903e641 LibAudio: Always insert a seek point at sample 0 if not present
Previously, the calculation of the distance to the previous seekpoint
would always behave as if a seek point existed at sample 0, meaning
that it would never place a seek point there. If we instead treat it as
the maximum distance if no sample is present, a seek point will be
placed.
2023-07-06 14:27:57 +01:00
kleines Filmröllchen
8258618caf LibAudio: Mix multi-channel files more properly
We downsample multi-channel files into stereo for now, which at least
makes the other channels listenable. The new multi-channel downmix
helper is intended to be used for other formats with the same or similar
channel arrangement, such as QOA.
2023-07-06 10:44:42 +01:00
kleines Filmröllchen
fc70d88367 LibAudio: Handle unknown-sized streams better
Especially FLAC had an issue here before, but the loader infrastructure
itself wouldn't handle end of stream properly if the "available samples"
information didn't match up.
2023-07-06 10:44:42 +01:00
kleines Filmröllchen
e9e95b1899 LibAudio: Fix escaped partitions
A missing sign extension and a wrong data type broke these before.
2023-07-06 10:44:42 +01:00
Nico Weber
5619bb3e04 LibAudio: Stop using and remove LOADER_TRY
It's no longer needed now that this code uses ErrorOr instead of Result.

Ran:

    rg -lw LOADER_TRY Userland/Libraries/LibAudio \
        | xargs sed -i '' 's/LOADER_TRY/TRY/g'

...and then manually fixed up Userland/Libraries/LibAudio/LoaderError.h
to not redefine TRY but instead remove the now-unused LOADER_TRY,
and ran clang-format.
2023-07-04 13:24:17 -06:00
kleines Filmröllchen
e82bee86dd LibAudio: Account for 0xFF start byte in FLAC UTF-8 decoder
This specialized UTF-8 decoder is more powerful than a normal UTF-8
decoder anyways, but it couldn't account for the never spec-compliant
0xff start byte. This commit makes that byte behave as expected if
taking UTF-8 to its extreme, even if it is a little silly and likely not
relevant for real applications.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
8bc56c7fb0 LibAudio: Prevent FLAC Rice partitions getting smaller than 1 sample
This would cause an integer underflow leading to us trying to allocate
over 4GB for residual samples.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
952c633a65 LibAudio: Fix 32-bit/64-bit mixup in FLAC sign extend
The bit magic for two's complement sign extension was only sign
extending to 32-bit signed. This issue was exposed by the last commit,
where now we actually use the 64-bit return value.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
59c7ce3d54 LibAudio: Prevent integer overflows in intermediate FLAC calculations
Since we can have up to 32 bits of input data, multiplications may need
up to 63 bits. This was accounted for in some places, but by far not in
all, and oss-fuzz found multiple integer overflows. We now use i64 in
all of the decoding, since we need to rescale samples to float later on
anyways. If a final sample value ends up out of range (and the range can
be a maximum of 32 bits), we may get samples past 1, but that then is a
non-compliant input file, and using over-range samples (and most likely
clipping audio) is considerably less weird than overflowing and
glitching audio.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
9bece0d0da LibAudio: Prevent multiple kinds of buffer overruns in FLAC picture load
The fuzzer found one heap buffer overflow here due to confusion between
u32* and u8* (the given size is for bytes, but we used it for 32-bit
elements, quadrupling it), and it looks like there's an opportunity for
several more. This commit modernizes the picture loader by using
String's built-in stream loader, and also adds several spec-compliance
checks: The MIME type must be ASCII in a specific range, and the picture
description must be UTF-8.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
ab9c18c176 LibAudio: Don't try to resample FLAC frames with sample rate 0
Although this sample rate is more or less bogus, we might as well not
crash.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
2e9e0dfe61 LibAudio: Check that LPC order is smaller than subframe sample count
An LPC predictor (fixed or not) contains as many warm-up samples as its
order. Therefore, the corresponding subframe must have at least this
many samples.

This turns this fuzzer-found crash into a handleable format error.
2023-07-04 12:47:08 +02:00
kleines Filmröllchen
5f1dbbaaa6 LibAudio: Extract loader stream creation from the plugins
This removes a lot of duplicated stream creation code from the plugins,
and also simplifies the way that the appropriate plugin is found. This
mirrors the ImageDecoderPlugin design and necessitates new sniffing
methods on the loaders.
2023-06-27 15:28:22 +01:00
kleines Filmröllchen
3b8ccd123b LibAudio: Compute and verify FLAC frame header checksums
This is currently not a failure condition, but we will print out a
message to the console informing the user of a potential corrupted file.
2023-05-18 22:23:15 +02:00
Lucas CHOLLET
8c34959b53 AK: Add the Input word to input-only buffered streams
This concerns both `BufferedSeekable` and `BufferedFile`.
2023-05-09 11:18:46 +02:00
Tim Schumacher
708387b850 LibAudio: Use read_until_filled to fill a buffer from a Stream
This has the advantage of recognizing when the Stream reaches EOF and
avoids an endless loop.
2023-04-12 14:02:56 -04:00
kleines Filmröllchen
1ee2091b2d LibAudio: Support FLAC files with unknown amount of samples
This is a special case of the sample count field in the header which we
treated as a format error before. Now we just take care to check stream
EOF before reading chunks.

This makes the final FLAC spec test pass, making us one of the most
compliant loaders! :^)
2023-03-19 14:15:35 +00:00
kleines Filmröllchen
b2a018ee59 LibAudio: Use specified bit depth directly
We report a rounded up PCM sample format to the outside, but use the
exact bit depth as specified in header and frames.

This makes the three FLAC spec tests with a a bit depth of 20 pass.
2023-03-19 14:15:35 +00:00
kleines Filmröllchen
0cd0565abc LibAudio: Improve FLAC seeking
"Improve" is an understatement, since this commit makes all FLAC files
seek without errors, mostly with high accuracy, and partially even fast:
- A new generic seek table type is introduced, which keeps an
  always-sorted list of seek points, which allows it to use binary
  search and fast insertion.
- Automatic seek points are inserted according to two heuristics
  (distance between seek points and minimum seek precision), which not
  only builds a seek table for already-played sections of the file, but
  improves seek precision even for files with an existing seek table.
- Manual seeking by skipping frames works properly now and is still used
  as a last resort.
2023-03-19 00:28:02 +00:00
kleines Filmröllchen
a8963a270f LibAudio: Detect and read FLAC metadata
FLAC uses the very simple vorbis comment metadata format, which we can
now read most standard and non-standard fields from.
2023-03-13 12:35:17 -04:00
Tim Schumacher
424df62b00 LibAudio: Read FLAC MD5 directly into the class member 2023-03-13 15:16:20 +00:00
Tim Schumacher
d5871f5717 AK: Rename Stream::{read,write} to Stream::{read_some,write_some}
Similar to POSIX read, the basic read and write functions of AK::Stream
do not have a lower limit of how much data they read or write (apart
from "none at all").

Rename the functions to "read some [data]" and "write some [data]" (with
"data" being omitted, since everything here is reading and writing data)
to make them sufficiently distinct from the functions that ensure to
use the entire buffer (which should be the go-to function for most
usages).

No functional changes, just a lot of new FIXMEs.
2023-03-13 15:16:20 +00:00
kleines Filmröllchen
264cc76ab4 LibAudio: Move audio stream buffering into the loader
Before, some loader plugins implemented their own buffering (FLAC&MP3),
some didn't require any (WAV), and some didn't buffer at all (QOA). This
meant that in practice, while you could load arbitrary amounts of
samples from some loader plugins, you couldn't do that with some others.
Also, it was ill-defined how many samples you would actually get back
from a get_more_samples call.

This commit fixes that by introducing a layer of abstraction between the
loader and its plugins (because that's the whole point of having the
extra class!). The plugins now only implement a load_chunks() function,
which is much simpler to implement and allows plugins to play fast and
loose with what they actually return. Basically, they can return many
chunks of samples, where one chunk is simply a convenient block of
samples to load. In fact, some loaders such as FLAC and QOA have
separate internal functions for loading exactly one chunk. The loaders
*should* load as many chunks as necessary for the sample count to be
reached or surpassed (the latter simplifies loading loops in the
implementations, since you don't need to know how large your next chunk
is going to be; a problem for e.g. FLAC). If a plugin has no problems
returning data of arbitrary size (currently WAV), it can return a single
chunk that exactly (or roughly) matches the requested sample count. If a
plugin is at the stream end, it can also return less samples than was
requested! The loader can handle all of these cases and may call into
load_chunk multiple times. If the plugin returns an empty chunk list (or
only empty chunks; again, they can play fast and loose), the loader
takes that as a stream end signal. Otherwise, the loader will always
return exactly as many samples as the user requested. Buffering is
handled by the loader, allowing any underlying plugin to deal with any
weird sample count requirement the user throws at it (looking at you,
SoundPlayer!).

This (not accidentally!) makes QOA work in SoundPlayer.
2023-03-13 13:25:42 +01:00
Dan Klishch
882dcfaddb AK+LibAudio: Remove UFixedBigInt::my_size 2023-03-05 13:49:43 +01:00
Tim Schumacher
43f98ac6e1 Everywhere: Remove the AK:: qualifier from Stream usages 2023-02-13 00:50:07 +00:00
Tim Schumacher
874c7bba28 LibCore: Remove Stream.h 2023-02-13 00:50:07 +00:00
Tim Schumacher
606a3982f3 LibCore: Move Stream-based file into the Core namespace 2023-02-13 00:50:07 +00:00
Tim Schumacher
220fbcaa7e AK: Remove the fallible constructor from FixedMemoryStream 2023-02-08 17:44:32 +00:00
Tim Schumacher
fa09152e23 AK: Remove the fallible constructor from BigEndianInputBitStream 2023-02-08 17:44:32 +00:00
Tim Schumacher
093cf428a3 AK: Move memory streams from LibCore 2023-01-29 19:16:44 -07:00
Tim Schumacher
8464da1439 AK: Move Stream and SeekableStream from LibCore
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
2023-01-29 19:16:44 -07:00
Tim Schumacher
5f2ea31816 AK: Move Handle from LibCore and name it MaybeOwned
The new name should make it abundantly clear what it does.
2023-01-29 19:16:44 -07:00
Linus Groh
ee0297d9ec LibAudio: Remove try_ prefix from fallible LoaderPlugin methods 2023-01-28 22:41:36 +01:00
Timothy Flynn
f3db548a3d AK+Everywhere: Rename FlyString to DeprecatedFlyString
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so
let's rename it to A) match the name of DeprecatedString, B) write a new
FlyString class that is tied to String.
2023-01-09 23:00:24 +00:00
Tim Schumacher
c6d71ca727 LibCore: Rename MemoryStream to FixedMemoryStream
This is to differentiate between the upcoming `AllocatingMemoryStream`,
which automatically allocates memory as needed instead of operating on a
static memory area.
2022-12-15 13:28:29 +00:00
Tim Schumacher
f909cfbe75 LibCore: Use the new Handle type for the BitStream types
This allows us to either pass a reference, which keeps compatibility
with old code, or to pass a NonnullOwnPtr, which allows us to
comfortably chain streams as usual.
2022-12-12 16:21:39 +00:00