mirror of
https://github.com/librespot-org/librespot.git
synced 2026-04-27 08:15:50 +03:00
[PR #660] [MERGED] High-resolution volume control and normalisation #1002
Labels
No labels
A-Alsa
SpotifyAPI
Tokio 1.0
audio
bug
can't reproduce
compilation
dependencies
duplicate
enhancement
good first issue
help wanted
high priority
imported
imported
invalid
new api
pull-request
question
reverse engineering
wiki
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/librespot#1002
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/librespot-org/librespot/pull/660
Author: @roderickvd
Created: 3/1/2021
Status: ✅ Merged
Merged: 4/10/2021
Merged by: @sashahilton00
Base:
dev← Head:hi-res-volume-control📝 Commits (10+)
f29e521High-resolution volume control and normalisation1672eb8Fix build on Rust < 1.50.05257be7Add command-line option to set F32 or S16 bit output6379926Fix examplea4ef174Fix Alsa backend for 64-bit systems5f26a74Add support for S32 output format309e264Rename steepness to knee9dcaeeeDefault to S16 output770ea15Add support for S24 and S24_3 output formatsb94879dFix GStreamer buffer pool size [ref #660 review]📊 Changes
23 files changed (+1023 additions, -909 deletions)
View changed files
📝
Cargo.lock(+64 -545)📝
audio/Cargo.toml(+3 -2)➕
audio/src/convert.rs(+59 -0)📝
audio/src/lewton_decoder.rs(+5 -2)📝
audio/src/lib.rs(+4 -2)📝
audio/src/libvorbis_decoder.rs(+12 -1)📝
examples/play.rs(+3 -2)📝
playback/Cargo.toml(+6 -6)📝
playback/src/audio_backend/alsa.rs(+51 -34)📝
playback/src/audio_backend/gstreamer.rs(+43 -27)📝
playback/src/audio_backend/jackaudio.rs(+17 -20)📝
playback/src/audio_backend/mod.rs(+56 -5)📝
playback/src/audio_backend/pipe.rs(+24 -31)📝
playback/src/audio_backend/portaudio.rs(+101 -33)📝
playback/src/audio_backend/pulseaudio.rs(+27 -20)📝
playback/src/audio_backend/rodio.rs(+96 -113)📝
playback/src/audio_backend/sdl.rs(+79 -24)📝
playback/src/audio_backend/subprocess.rs(+13 -11)📝
playback/src/config.rs(+86 -9)📝
playback/src/mixer/mod.rs(+1 -1)...and 3 more files
📄 Description
Enhancements:
Store and handle samples as 32-bit floats instead of 16-bit integers. This provides 24-25 bits of transparency, allowing for 48-54 dB of headroom to do volume control and normalisation without throwing away bits or dropping dynamic range below 96 dB CD quality.
Perform volume control and normalisation in 64-bit arithmetic for minimum quantisation noise.
Output to 32-bit float, 32-bit integer, 24-bit integer (both in padded 32-bit words and as three-byte arrays) or 16-bit integer (default), as specified on the command line.
Add a dynamic limiter with configurable threshold, attack time, release or decay time, and steepness for the sigmoid transfer function. This mimics the native Spotify limiter, offering greater dynamic range than the old limiter, that just reduced overall gain to prevent clipping.
Make the configurable threshold also apply to the old limiter, which is still available.
DRY-ups of a lot of audio backend code, at the same time enabling
OggDatapassthrough on the subprocess backend.Resolves: #608
Notes:
For the dynamic limiter, steepness between 0.5 and 2.0 work well. The default of 1.0 yields a linear function; > 1.0 rolls off softly, is steeper midway and < 1.0 has a sharp initial response, then gentler midway. Feedback on optimisation of these parameters is welcome.
Compiling
with-vorbisworks, but panics. This was already the case and is not new to this PR. See: https://github.com/tomaka/vorbis-rs/issues/19To do:
normalisation-steepnesstonormalisation-kneef32then roundPending refactoring:
DRY up sample conversion in PortAudio and SDL backendsEdit: Not much to be gained, dropped idea
UseTryFromidiom instead ofAudioPacket::f32_to_<type>()helper functionsEdit: Moved sample conversion into separate struct
Selfinstead of full struct and enum names onconfig.rsAll done!
Test status:
All backends compile successfully, but require testing.
Rodio on Raspian 10 (Raspberry Pi 3 Model B+) does not open the output correctly. See issue at: RustAudio/cpal#564. This seems to be on Alsa only, no issues on macOS Big Sur, and not strictly related to this PR.
Panics on Alsa and macOS but that's already the case in
dev.Free pass granted by @sashahilton00.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.