Fix up for #886Closes: #898
And...
* Don't silently ignore non-Unicode while parsing env vars.
* Iterating over `std::env::args` will panic! on invalid unicode. Let's not do that. `getopts` will catch missing args and exit if those args are required after our error message about the arg not being valid unicode.
* Gaurd against empty strings. There are a few places while parsing options strings that we don't immediately evaluate their validity let's at least makes sure that they are not empty if present.
* `args` is only used in `get_setup` it doesn't need to be in main.
* Nicer help header.
* Get rid of `use std::io::{stderr, Write};` and just use `rpassword::prompt_password_stderr`.
* Get rid of `get_credentials` it was clunky, ugly and only used once. There is no need for it to be a separate function.
* Handle an empty password prompt and password prompt parsing errors.
* + Other random misc clean ups.
Make librespot able to parse environment variables for options and flags.
To avoid name collisions environment variables must be prepended with `LIBRESPOT_` so option/flag `foo-bar` becomes `LIBRESPOT_FOO_BAR`.
Verbose logging mode (`-v`, `--verbose`) logs all parsed environment variables and command line arguments (credentials are redacted).
* Don't panic when parsing options. Instead list valid values and exit.
* Get rid of needless .expect in playback/src/audio_backend/mod.rs.
* Enforce reasonable ranges for option values (breaking).
* Don't evaluate options that would otherwise have no effect.
* Add pub const MIXERS to mixer/mod.rs very similar to the audio_backend's implementation. (non-breaking though)
* Use different option descriptions and error messages based on what backends are enabled at build time.
* Add a -q, --quiet option that changed the logging level to warn.
* Add a short name for every flag and option.
* Note removed options.
* Other misc cleanups.
* Remove deprecated use of std::u16::MAX
* Use `FromStr` for fallible `&str` conversions
* DRY up strings into constants
* Change `as_ref().map()` into `as_deref()`
* Use `Duration` for time constants and functions
* Optimize `Vec` with response times
* Move comments for `rustdoc` to parse
Dithering lowers digital-to-analog conversion ("requantization") error, linearizing output, lowering distortion and replacing it with a constant, fixed noise level, which is more pleasant to the ear than the distortion.
Guidance:
- On S24, S24_3 and S24, the default is to use triangular dithering. Depending on personal preference you may use Gaussian dithering instead; it's not as good objectively, but it may be preferred subjectively if you are looking for a more "analog" sound akin to tape hiss.
- Advanced users who know that they have a DAC without noise shaping have a third option: high-passed dithering, which is like triangular dithering except that it moves dithering noise up in frequency where it is less audible. Note: 99% of DACs are of delta-sigma design with noise shaping, so unless you have a multibit / R2R DAC, or otherwise know what you are doing, this is not for you.
- Don't dither or shape noise on S32 or F32. On F32 it's not supported anyway (there are no integer conversions and so no rounding errors) and on S32 the noise level is so far down that it is simply inaudible even after volume normalisation and control.
New command line option:
--dither DITHER Specify the dither algorithm to use - [none, gpdf,
tpdf, tpdf_hp]. Defaults to 'tpdf' for formats S16
S24, S24_3 and 'none' for other formats.
Notes:
This PR also features some opportunistic improvements. Worthy of mention are:
- matching reference Vorbis sample conversion techniques for lower noise
- a cleanup of the convert API
This is a squashed commit featuring the following:
Connect:
- Synchronize player volume with mixer volume on playback
- Fix step size on volume up/down events
- Remove no-op mixer started/stopped logic
Playback:
- Move from `connect` to `playback` crate
- Make cubic volume control available to all mixers with `--volume-ctrl cubic`
- Normalize volumes to `[0.0..1.0]` instead of `[0..65535]` for greater precision and performance (breaking)
- Add `--volume-range` option to set dB range and control `log` and `cubic` volume control curves
- Fix `log` and `cubic` volume controls to be mute at zero volume
Alsa mixer:
- Complete rewrite (breaking)
- Query card dB range for the `log` volume control unless specified otherwise
- Query dB range from Alsa softvol (previously only from hardware)
- Use `--device` name for `--mixer-card` unless specified otherwise
- Fix consistency for `cubic` between cards that report minimum volume as mute, and cards that report some dB value
- Fix `--volume-ctrl {linear|log}` to work as expected
- Removed `--mixer-linear-volume` option; use `--volume-ctrl linear` instead
fe37186 added the restriction that `Sink`s must be `Send`. It turned
out later that this restrictions was unnecessary, and since some
`Sink`s aren't `Send` yet, this restriction is lifted again.
librespot-org/librespot#601 refactored the `RodioSink` in order to make
it `Send`. These changes are partly reverted in favour of the initial
simpler design.
Furthermore, there were some compile errors in the gstreamer backend
which are hereby fixed.
Usage: `--format {F32|S16}`. Default is F32.
- Implemented for all backends, except for JACK audio which itself
only supports 32-bit output at this time. Setting JACK audio to S16
will panic and instruct the user to set output to F32.
- The F32 default works fine for Rodio on macOS, but not on Raspian 10
with Alsa as host. Therefore users on Linux systems are warned to set
output to S16 in case of garbled sound with Rodio. This seems an issue
with cpal incorrectly detecting the output stream format.
- While at it, DRY up lots of code in the backends and by that virtue,
also enable OggData passthrough on the subprocess backend.
- I tested Rodio, ALSA, pipe and subprocess quite a bit, and call on
others to join in and test the other backends.
- Store and output samples as 32-bit floats instead of 16-bit integers.
This provides 24-25 bits of transparency, allowing for 42-48 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.
- 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.
Resolves: librespot-org/librespot#608
* Remove default impl for `SessionConfig`
* Move util mod to single file
* Restore privacy of mods
* Move `fn get_credentials` to application
* Remove `extern crate` statements
The locations of credentials, volume and audio are now stored
in three separate Optional<PathBuf>s.
Removed the clearing of the cache if an error occurs. This might
be added again later.
Refactored the old `--linear-volume` flag to a more generic `--volume-ctrl` flag that takes the options of `[linear, log, fixed]`. It defaults as previously to log.
* Enable gapless playback via runtime flag
* Set gapless playback as default, use `--disable-gapless` to turn it off
* Ensure sink restarts b/w tracks when gapless is disabled
Since port 80 is the default port for the HTTP protocol, `url.port()` returns `None`, causing an "invalid proxy" message. Using `port_or_known_default()` will only return `None` if the both the port has been omitted and an unknown protocol has been specified.
Ensure the player events are emitted correctly.
Only call the external script on events we want to notify about.
Stop sink when loading to pause.
cargo fmt
- change communication between player and spirc to use player events channel.
- enhance player events channel
- have spirc send loading messages to Spotify
- enable preloading of tracks in the player