summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibAudio
AgeCommit message (Collapse)Author
2021-11-15LibAudio: Add explanatory comments to the FlacLoaderkleines Filmröllchen
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-15Audio: Fix code smells and issues found by static analysiskleines Filmröllchen
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-11Everywhere: Pass AK::StringView by valueAndreas Kling
2021-11-08LibAudio: Replace log_pan with a constant power panning algoritmkleines Filmröllchen
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-08LibAudio: Improve local variable nameskleines Filmröllchen
This makes the code easier to read.
2021-11-08LibAudio: Rename Audio::Frame -> Audio::SampleDavid Isaksson
"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-08LibAudio: Refactor out linear_to_log function and add its inverseDavid Isaksson
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-08LibCore: Use ErrorOr<T> in Core::AnonymousBufferAndreas Kling
2021-11-02Libraries: Fix visibility of Object-derivative constructorsBen Wiederhake
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-09-12Audio: Add per-client volumekleines Filmröllchen
Note: While ClientAudioStream has had a volume property, it is only now used in the mixer.
2021-09-12LibDSP+LibAudio: Use logarithmic scaling in delay effectkleines Filmröllchen
With logarithmic volume scaling, the delay effect can sound more natural.
2021-09-12Audio: Change how volume workskleines Filmröllchen
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-06Everywhere: Make ByteBuffer::{create_*,copy}() OOM-safeAli Mohammad Pur
2021-08-31LibAudio: Implement decoding verbatim blocks in FLACKarol Kosek
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-31Libraries: Add LibDSPkleines Filmröllchen
LibDSP is a library for digital signal processing, and is primarily intended to support the future DAW version of Piano.
2021-08-27Userland+LibAudio: Make audio applications support dynamic sample ratekleines Filmröllchen
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-18LibAudio: Resample FLAC audio datakleines Filmröllchen
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-18LibAudio: Resample with integer ratios instead of floatskleines Filmröllchen
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-17LibAudio: Fix overflow on 24-bit FLAC LPC datakleines Filmröllchen
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-17LibAudio: Rescale integer samples correctly in FLAC loaderkleines Filmröllchen
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-17LibAudio: Use size_t in loopskleines Filmröllchen
This is more idiomatic :^)
2021-08-06LibAudio: Make playing lossy flacs more truthfulKarol Kosek
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-06LibAudio: Fix calculation of wasted bits-per-sampleKarol Kosek
The value was always zero.
2021-08-06LibAudio: Make read samples signed when decoding fixed FLAC subframesKarol Kosek
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-04LibAudio: Use an existing file stream when parsing a FLAC headerKarol Kosek
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-04LibAudio: Initialize m_stream before parsing a FLAC headerKarol Kosek
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 845d403b8c175ff99793239404ca8657d95da104 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-02LibAudio: Handle stream errors in FlacLoaderAndrew Kaster
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-07-22LibAudio: Implement loaded_samples() in the FLAC LoaderKarol Kosek
This makes aplay show current playback position.
2021-07-22LibAudio: Read custom block sizes and sample rates as big endianKarol Kosek
This fixes stucking in a loop at the end of the file, as (a) custom block sizes are usually placed there, as the remaining size might not be simply calculated as a power of two, and (b) the number of bytes to read was incorrect (the program said the block size was 32525, where flac -a said it's actually 3200). Unfortunately, I couldn't trigger the bug for the sample rates, so it may be not true, but I'd doubt it, giving the fact that flac almost everywhere uses big endian numbers.
2021-07-22LibAudio: Don't read too much bytes in FLACKarol Kosek
This fixes crash when reading the end of the file. The logic is mostly borrowed from WavLoader.
2021-07-21LibAudio: Fix UTF-8 decoding logic in FLAC decoding :^)Karol Kosek
The problem here was that the multi-byte UTF-8 encoded characters were taking one byte too much, misaligning the data completely and eventually crashing the program on the 128th frame. This change reduces the for loop by one, as it has been already calculated from the start_byte variable.
2021-07-21LibAudio: Check if zero-bit padding is actually zeroKarol Kosek
This might allow the program to return an error a bit quicker.
2021-07-19Everywhere: Use AK/Math.h if applicableHendiadyoin1
AK's version should see better inlining behaviors, than the LibM one. We avoid mixed usage for now though. Also clean up some stale math includes and improper floatingpoint usage.
2021-07-13LibAudio: Use new Vector formatterkleines Filmröllchen
2021-07-12LibAudio: Set variable type for decoding fixed subframes in FLACKarol Kosek
This fixes an crash caused by using the type from FlacSubframeHeader::order (unsigned 8-bit), which after overflowing the integer, converting it back to u32, and decrementing by one resulted in accessing an array waaay out of bounds.
2021-07-05LibAudio: Add ClientConnection::async_enqueue()kleines Filmröllchen
async_enqueue() is a wrapper over the async_enqueue_buffer() call to AudioServer. This allows users to asyncronously enqueue audio samples, when the program requires non-blocking audio streaming. This also makes ClientConnection use east-const everywhere.
2021-07-05LibAudio: Improve latency on audio queue failureskleines Filmröllchen
We don't know what is a good time to wait after an audio buffer fails to be processed by AudioServer. However, it seems like decreasing the wait time to 10ms after such a failure should improve latency and has not caused issues in my testing. After all, 10ms is quite some time in audio sample magnitudes.
2021-06-25LibAudio: Implement a basic FLAC loaderkleines Filmröllchen
This commit adds a loader for the FLAC audio codec, the Free Lossless Audio codec by the Xiph.Org foundation. LibAudio will automatically read and parse FLAC files, so users do not need to adjust. This implementation is bare-bones and needs to be improved upon. There are many bugs, verbatim subframes and any kind of seeking is not supported. However, stereo files exported by libavcodec on highest compression setting seem to work well.
2021-06-25LibAudio: Make ResampleHelper templated for different sample typeskleines Filmröllchen
Previously, ResampleHelper was fixed on handling double's, which makes it unsuitable for the upcoming FLAC loader that needs to resample integers. For this reason, ResampleHelper is templated to support theoretically any type of sample, though only the necessary i32 and double are templated right now. The ResampleHelper implementations are moved from WavLoader.cpp to Buffer.cpp. This also improves some imports in the WavLoader files.
2021-06-25LibAudio: Make LoaderPlugin::error_string return String&kleines Filmröllchen
Previously, error_string() returned char* which is bad Serenity style and caused issues when other error handling methods were tried. As both WavLoader and (future) FLAC loader store a String internally for the error message, it makes sense to return a String reference instead.
2021-06-25LibAudio: Add the Int32 sample formatkleines Filmröllchen
The signed 32-bit PCM sample format is required for the FLAC standard.
2021-06-21SoundPlayer: Handle any input file sample rateNick Miller
This commit addresses two issues: 1. If you play a 96 KHz Wave file, the slider position is incorrect, because it is assumed all files are 44.1 KHz. 2. For high-bitrate files, there are audio dropouts due to not buffering enough audio data. Issue 1 is addressed by scaling the number of played samples by the ratio between the source and destination sample rates. Issue 2 is addressed by buffering a certain number of milliseconds worth of audio data (instead of a fixed number of bytes). This makes the the buffer size independent of the source sample rate. Some of the code is redesigned to be simpler. The code that did the book-keeping of which buffers need to be loaded and which have been already played has been removed. Instead, we enqueue a new buffer based on a low watermark of samples remaining in the audio server queue. Other small fixes include: 1. Disable the stop button when playback is finished. 2. Remove hard-coded instances of 44100. 3. Update the GUI every 50 ms (was 100), which improves visualizations.
2021-06-21LibAudio: Sleep less when the audio buffer is fullNick Miller
When using `aplay` to play audio files with a sample rate of 96000, there were occasional one-second gaps in playback. This is because the Audio::ClientConnection sleeps for a full second when the audio buffer is full. One second is too long to sleep, especially for high-bitrate files. Changing the sleep to a more reasonable value like 100 ms ensures we attempt to enqueue again before the audio buffer runs empty.
2021-06-21LibAudio: Avoid reading past the end of sample dataNick Miller
Prior code in `WavLoader::get_more_samples()` would attempt to read the requested number of samples without actually checking whether that many samples were remaining in the stream. This was the cause of an audible pop at the end of a track, due to reading non-audio data that is sometimes at the end of a Wave file. Now we only attempt to read up to the end of sample data, but no further. Also, added comments to clarify the meaning of "sample", and how it should be independent of the number of channels.
2021-06-09LibAudio: Add support for WAVE_FORMAT_EXTENSIBLENick Miller
This enables support for playing float32 and float64 WAVE_FORMAT_EXTENSIBLE files. The PCM data format is encoded in the first two bytes of the SubFormat GUID inside of the WAVE_FORMAT_EXTENSIBLE `fmt` chunk. Also, fixed the RIFF header size check to allow up to maximum_wav_size (currently defined as 1 GiB). The RIFF header size is the size of the entire file, so it should be checked against the largest Wave size.
2021-06-09LibAudio: Make Loader::seek() treat its input as a sample indexNick Miller
This fixes a bug where if you try to play a Wave file a second time (or loop with `aplay -l`), the second time will be pure noise. The function `Audio::Loader::seek` is meant to seek to a specific audio sample, e.g. seek(0) should go to the first audio sample. However, WavLoader was interpreting seek(0) as the beginning of the file or stream, which contains non-audio header data. This fixes the bug by capturing the byte offset of the start of the audio data, and offseting the raw file/stream seek by that amount.
2021-06-08LibAudio: WavLoader: Avoid reading partial samplesNick Miller
When samples are requested in `Audio::Loader::get_more_samples`, the request comes in as a max number of bytes to read. However, the requested number of bytes may not be an even multiple of the bytes per sample of the loaded file. If this is the case, and the bytes are read from the file/stream, then the last sample will be a partial/runt sample, which then offsets the remainder of the stream, causing white noise in playback. This bug was discovered when trying to play 24-bit Wave files, which happened to have a sample size that never aligned with the number of requested bytes. This commit fixes the bug by only reading a multiple of "bytes per sample" for the loaded file.
2021-06-08LibAudio+LibCore: Remove unnecessary IODeviceStreamReader.hNick Miller
IODeviceStreamReader isn't pulling its weight. It's essentially a subset of InputFileStream with only one user (WavLoader). This refactors WavLoader to use InputFileStream instead.
2021-05-23Userland: Mark subclasses of IPC::{Client,Server}Connection finalAndreas Kling
2021-05-23LibIPC: Remove unnecessary IPC::ServerConnection::handshake()Andreas Kling
This is no longer used by any of our IPC pairs.