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

321 commits

Author SHA1 Message Date
Filiph Siitam Sandström
fd694e8672 AK+Lagom: Make it possible to build for iOS
This commit makes it possible to build AK and most of Lagom for iOS,
based on the work for the Ladybird build demoed on discord:
1211987732
2024-03-03 13:13:42 -07:00
Hendiadyoin1
fe0fde2154 Userland+Tests: Remove unused <AK/Tuple.h> includes 2024-03-01 14:05:53 -07:00
Lucas CHOLLET
1f62984301 LibAudio/Wav: Always use u32 for the sample rate 2024-02-14 22:21:44 -05:00
Lucas CHOLLET
901baf31ff LibAudio/Wav: Remove unused methods 2024-02-14 22:21:44 -05:00
kleines Filmröllchen
5054f34b4a LibAudio: Automatically write a FLAC seektable
This contains a seekpoint every 2 seconds, allowing our own players to
work better.
2024-02-08 07:19:09 -07:00
Tim Ledbetter
d186582d30 LibAudio: Avoid UAF when loading WAV metadata 2024-01-17 16:09:59 -05:00
kleines Filmröllchen
64598473cc LibRIFF: Rework to match LibGfx needs
There's now two namespaces, RIFF (little-endian) and IFF (big-endian)
which (for the most part) contain the same kinds of structures for
handling similar data in both formats. (They also share almost all of
their implementation) The main types are ChunkHeader and (Owned)Chunk.
While Chunk has no ownership over the data it accesses (and can only be
constructed from a byte view), OwnedChunk has ownership over this data
and is aimed at reading from streams.

OwnedList, implementing the standard RIFF LIST type, is currently only
implemented for RIFF due to its only user being WAV, but it may be
generalized in the future for use by IFF.

Co-authored-by: Timothy Flynn <trflynn89@pm.me>
2024-01-15 23:23:26 -07:00
kleines Filmröllchen
d125d16287 LibAudio+LibRIFF: Move general RIFF handling to LibRIFF
This splits the RIFFTypes header/TU into the WAV specific parts, which
move to WavTypes.h, as well as the general RIFF parts which move to the
new LibRIFF.

Sidenote for the spec comments: even though they are linked from a site
that explains the WAV format, the document is the (an) overall RIFF spec
from Microsoft. A better source may be used later; the changes to the
header are as minimal as possible.
2024-01-15 23:23:26 -07:00
Lee Hanken
01930a7043 LibAudio: Correctly output mono wav files
Prevent two channels of data being written when the wav file is mono.
2024-01-08 07:20:11 -07:00
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
Andrew Kaster
c145d5410c Userland: Don't leak objects when constructor arguments throw
Similar to d253beb2f7.

Found with Ali's clang-query script in Shell:

```
for $(find AK Userland -type f -name '*.h' -o -name '*.cpp') {
    in_parallel -j 12 -- clang-query -p \
    Build/lagom/compile_commands.json $it -c \
    'm cxxNewExpr(has(cxxConstructExpr(hasAnyArgument(hasDescendant( \
        allOf(isExpandedFromMacro("TRY"), stmtExpr()))))))' \
    } | grep -v 'matches.' | tee results
```
2023-12-13 19:21:03 -07:00
Karol Kosek
00e422fe1e LibAudio: Fix use-after-free in write_vorbis_comment 2023-12-05 13:57:18 -05:00
Karol Kosek
963a6b3d3d LibAudio: Speed up WavWriter by buffering output data
We were calling write syscall twice for every sample, which effectively
hurt the writer's performance.

With this change exporting a melody in the Piano app now takes less than
a second, which previously took about 20 seconds on my machine.

Additionally, I've removed an unused `WavWriter::file()` getter.
2023-11-23 18:05:22 -05:00
Zaggy1024
f9068c7f2e LibAudio: Ensure that Serenity playback streams are always stereo
The Serenity AudioServer assumes that all audio is stereo, so we
cannot output audio with a channel count other than 2.
2023-11-12 07:57:03 +01:00
Lucas CHOLLET
b00476abac AK: Use an enum to specify the open mode instead of a bool
Let's replace this bool with an `enum class` in order to enhance
readability. This is done by repurposing `MappedFile`'s `OpenMode` into
a shared `enum` simply called `Mode`.
2023-11-08 18:19:34 +01:00
Timothy Flynn
b98864e022 LibAudio: Remove unused TRY-like macro
This was added, unused, in bc4d4f0f95.
2023-11-04 08:36:34 -04:00
kleines Filmröllchen
968038aa79 LibAudio: Use mapped files for audio playback
This is 10-20% of a speed increase on platforms with fast I/O (Linux)
and not a slowdown on Serenity. Again, the file system layer is the
limit for us :^)
2023-09-27 03:22:56 +02:00
kleines Filmröllchen
a0bcc9dd83 LibAudio: Skip empty MP3 scale factor bands in stereo intensity process
These were intentionally set up to be at the end of the granule size,
but since the stereo intensity loop is intentionally using a <= end
comparison (that’s how the scale factor bands work), we must skip these
dummy bands which would otherwise cause an out-of-bounds index.
2023-09-09 11:23:57 -06:00
kleines Filmröllchen
24f5914d18 LibAudio: Prevent overflow in QOA LMS prediction 2023-09-09 11:23:57 -06:00
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
1bf81f84a0 LibAudio: Perform all seekpoint binary searches with comparisons
One was missed in the previous fix
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
Timothy Flynn
759e07579e LibAudio: Implement PlaybackStream for macOS using Audio Unit framework
https://developer.apple.com/documentation/audiounit

Apple has a number of audio frameworks we could use. This uses the Audio
Unit framework, as it gives us most control over the rendering of the
audio frames (such as being able to quickly pause / discard buffers).
From some reading, we could implement niceties such as fading playback
in and out while seeking over a short (10ms) period. This patch does not
implement such fancy features though.

Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
2023-09-09 13:03:36 -04:00
kleines Filmröllchen
271bfa63f3 LibAudio: Fix uncommon 16-bit block size symbol
This was a silly typo :^)
2023-09-01 20:04:55 +02:00
Zaggy1024
ac6c06e235 LibAudio: Don't count buffered samples in Loader::loaded_samples()
The `Loader` uses a `Vector<Sample>` to store any samples that the
actual audio decoder returned that the loader client did not request
yet. However, it did not take that buffer into account when those
clients asked for the number of samples loaded. The buffer is an
internal implementation detail, and should not be reflected on the
external API.

This allows LibWeb to keep better track of audio position without any
desync caused by the buffer. When using the Serenity `PlaybackStream`
implementation as the back end for an `HTMLAudioElement`, this allows
us to perfectly stop on the exact last sample of the audio file, so it
will not stop before the media element can see that it has finished
playback.

Note that `Loader::get_more_samples()` also calls `loaded_samples()` to
determine how many samples are remaining to load into the output
buffer. However, this change appears to be correct even there, given
that the samples copied from the internal sample buffer are included in
that count.
2023-08-29 11:31:10 +02:00
Zaggy1024
bb156f8133 LibAudio: Add a Serenity implementation of PlaybackStream
This implementation is very naive compared to the PulseAudio one.

Instead of using a callback implemented by the audio server connection
to push audio to the buffer, we have to poll on a timer to check when
we need to push the audio buffers. Implementing cross-process condition
variables into the audio queue class could allow us to avoid polling,
which may prove beneficial to CPU usage.

Audio timestamps will be accurate to the number of samples available,
but will count in increments of about 100ms and run ahead of the actual
audio being pushed to the device by the server.

Buffer underruns are completely ignored for now as well, since the
`AudioServer` has no way to know how many samples are actually written
in a single audio buffer.
2023-08-29 11:31:10 +02:00
kleines Filmröllchen
bf3fa19314 LibAudio: Write FLAC metadata
This includes a generalization of the metadata block infrastructure, so
adding and writing blocks is handled in a generalized fashion.
2023-08-29 10:43:34 +02:00
kleines Filmröllchen
fc2301c23c LibAudio: Allow writing Vorbis comments
The vorbis comment parsing code is slightly generalized to reuse
field-role associations for artists.
2023-08-29 10:43:34 +02:00
kleines Filmröllchen
34978b364b LibAudio: Understand album (IPRD) metadata in WAV
This is in common usage, just not present in the reference I looked at.
2023-08-29 10:43:34 +02:00
kleines Filmröllchen
1e291753b0 LibAudio: Allow adding metadata to encoders 2023-08-29 10:43:34 +02:00
kleines Filmröllchen
b4b411b8a3 LibAudio: Add a sample count hinting mechanism to audio encoding 2023-08-29 10:43:34 +02:00
kleines Filmröllchen
0960a92670 LibAudio: Add more common classes to the forward declare header 2023-08-29 10:43:34 +02:00
Zaggy1024
b33a71a35e LibAudio: Remove unnecessary m_bitstream field from MP3Loader
We can just create a `BigEndianInputBitStream` where it is needed
instead of storing one in the class. After making `read_header()`
static, the only other user of the field was `read_size_information()`,
so let's do that there and then remove the field.
2023-08-26 18:43:23 -04:00
Zaggy1024
c1d4ff919a LibAudio: Remove the m_current_frame field from MP3Loader
This field was only used within one function, where it could just be a
local variable.
2023-08-26 18:43:23 -04:00
Zaggy1024
88a9ff76b0 LibAudio: Read the full MP3 frame header when synchronizing to a frame
This makes the checks for a frame header more consistent, so if the
conditions for allowed frame headers change, there are less scattered
lines that will need to be changed.

`synchronize()` will now also properly scan the second byte of the hex
sequence `FF FF F0` as a sync code, where previously it would see
`FF F` and skip on to `F0`, ignoring its preceding `FF` that would
indicate that it is a sync code.
2023-08-26 18:43:23 -04:00
Zaggy1024
cbdf49de30 LibAudio: Pass raw streams to MP3 synchronize() and read_frame()
`synchronize()` can be simplified greatly by checking whole bytes with
bitwise operations, and doing so also avoids the overhead of reading
individual bits from a bitstream.

Making `read_frame()` also take a `SeekableStream` will allow it to be
used inside `synchronize()` in the next commit.
2023-08-26 18:43:23 -04:00
Zaggy1024
1847155b12 LibAudio: Make MP3LoaderPlugin::read_header() static
This will allow us to use the function when sniffing for an MP3 file to
enable consistent checks for valid frame headers.
2023-08-26 18:43:23 -04:00
Zaggy1024
e087d35cd8 LibAudio: Accurately skip MP3 frames using the actual header size
Prevously, the header size was used to calculate the `slot_count` field
of `MP3::Header`, but `build_seek_table()` just used the maximum size
of the header instead, causing it not to seek far enough, and in cases
where a possible sync code occurred two bytes before the next frame, it
would read that possible sync code as if it was a real frame. It would
then either reject it due to bad field values, or could possibly skip
over the next real frame due to a larger calculated frame size in the
bogus frame.

By fixing this issue, we now properly calculate the duration of MP3
files where these fake sync codes occur. In the case of the raw file
for this podcast:

https://changelog.com/podcast/554

the duration goes from 1:21:57 to 1:22:47, which is the real duration
according to the player user interface.
2023-08-26 18:43:23 -04:00
Zaggy1024
5b8895fff0 LibAudio: Create MP3 seek table first and then seek sample 0 to play
The seek table must locate the first MP3 frame in the file, so it makes
sense to locate the samples for the sample table first, then that
information to seek to the first frame.
2023-08-26 18:43:23 -04:00
Zaggy1024
49be09e5b2 LibAudio: Skip ID3 tags before synchronizing to MP3 frames
Previously, we would just start from byte 0 and check individual bytes
of the file until we find two bytes starting with `FF F`, and then
assume that that was the MP3 frame sync code. However, some ID3v2 tags
do not have to be what is referred to as "unsynchronized", meaning that
they can contain that `FF F` sequence and cause our decoder to think it
has found a frame.

To avoid this happening, we can read a minimal amount of the ID3 header
to determine how many bytes to skip before attempting to find the MP3
frames.

This allows the recent podcast with Andreas to play here:

https://changelog.com/podcast/554
2023-08-26 18:43:23 -04:00
Zaggy1024
2dc75a37d2 LibAudio: Set MP3 seek points to their frame's first sample
Seek points were being created after adding to the sample count in
`build_seek_table()`, meaning that they would be offset forward by
`MP3::frame_size` samples.

This also allows us to remove the hardcoded sample 0 seek point that
was previously added, since a seek point at sample 0 will now be added
by the loop.
2023-08-26 18:43:23 -04:00
Zaggy1024
89fb4af429 LibAudio: Default-initizalize all types in MP3Types.h 2023-08-26 18:43:23 -04:00
kleines Filmröllchen
c7f416682b LibAudio: Write final FLAC audio data instead of discarding it 2023-08-16 01:10:35 +02:00
kleines Filmröllchen
1a1cba1c3f LibAudio: Use channel coupling for stereo FLAC encoding
The estimation for this is fast but not very accurate, meaning we save
around 5-10% storage space. (We also don’t try other channel coupling
methods, but I am sceptical of how much benefit that actually provides.)
2023-08-16 01:10:35 +02: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