[GH-ISSUE #1008] Playback starts muted when --volume-ctrl=fixed #482

Closed
opened 2026-02-27 19:30:54 +03:00 by kerem · 29 comments
Owner

Originally created by @petrkutalek on GitHub (May 26, 2022).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/1008

Originally assigned to: @roderickvd on GitHub.

After updating to librespot v0.4.1 playback starts muted + volume set to 0 % when the switch --volume-ctrl is set to fixed. After changing to linear everything seems to be fine (except that I prefer a fixed volume control, I change that one on the amp).

Version:

librespot 0.4.1 fc1e745 (Built on 2022-05-25, Build ID: ncifF2fR, Profile: release)

Command line:

/usr/local/bin/librespot --name="██████" --device-type=avr --bitrate=320 --disable-gapless \
    --system-cache=/var/cache/librespot --cache=/var/cache/librespot --cache-size-limit=32G \
    --enable-volume-normalisation --normalisation-gain-type=track --normalisation-pregain=-3 --normalisation-method=dynamic \
    --backend=alsa --device=plughw:0 \
    --mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s ' \
    --format=S24 --dither=tpdf --volume-ctrl=fixed --initial-volume=100
Originally created by @petrkutalek on GitHub (May 26, 2022). Original GitHub issue: https://github.com/librespot-org/librespot/issues/1008 Originally assigned to: @roderickvd on GitHub. After updating to librespot v0.4.1 playback starts muted + volume set to 0 % when the switch `--volume-ctrl` is set to `fixed`. After changing to `linear` everything seems to be fine (except that I prefer a fixed volume control, I change that one on the amp). Version: ``` librespot 0.4.1 fc1e745 (Built on 2022-05-25, Build ID: ncifF2fR, Profile: release) ``` Command line: ``` /usr/local/bin/librespot --name="██████" --device-type=avr --bitrate=320 --disable-gapless \ --system-cache=/var/cache/librespot --cache=/var/cache/librespot --cache-size-limit=32G \ --enable-volume-normalisation --normalisation-gain-type=track --normalisation-pregain=-3 --normalisation-method=dynamic \ --backend=alsa --device=plughw:0 \ --mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s ' \ --format=S24 --dither=tpdf --volume-ctrl=fixed --initial-volume=100
kerem 2026-02-27 19:30:54 +03:00
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

I have the exact same DAC (Topping D10s). I will see if I can duplicate.

A side note:

The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering.

<!-- gh-comment-id:1138321495 --> @JasonLG1979 commented on GitHub (May 26, 2022): I have the exact same DAC (Topping D10s). I will see if I can duplicate. A side note: The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

It's also pointless and unnecessary to set the mixer device with a fixed volume of 100.

<!-- gh-comment-id:1138324481 --> @JasonLG1979 commented on GitHub (May 26, 2022): It's also pointless and unnecessary to set the mixer device with a fixed volume of 100.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

Yep, can confirm. It appears to be a quirk of that DAC.

When set to fixed I get:

[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range was detected as 127 but overridden as 0
[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (0.00)
[2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: true

Notice the volume range is 0.0.

But with the default volume scale of log I get:

[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer reported dB range > 100, which is suspect
[2022-05-26T09:37:52Z WARN  librespot_playback::mixer::alsamixer] Please manually set `--volume-range` if this is incorrect
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::mappings] Volume control is now Log(127.0)
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00)
[2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false

Now the volume range is 127.

<!-- gh-comment-id:1138351757 --> @JasonLG1979 commented on GitHub (May 26, 2022): Yep, can confirm. It appears to be a quirk of that DAC. When set to fixed I get: ``` [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range was detected as 127 but overridden as 0 [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (0.00) [2022-05-26T09:36:18Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: true ``` Notice the volume range is 0.0. But with the default volume scale of log I get: ``` [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer reported dB range > 100, which is suspect [2022-05-26T09:37:52Z WARN librespot_playback::mixer::alsamixer] Please manually set `--volume-range` if this is incorrect [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::mappings] Volume control is now Log(127.0) [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00) [2022-05-26T09:37:52Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false ``` Now the volume range is 127.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

But like I said before if you want to use a fixed volume level of 100 remove:

--mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s '

from your args.

<!-- gh-comment-id:1138355460 --> @JasonLG1979 commented on GitHub (May 26, 2022): But like I said before if you want to use a fixed volume level of 100 remove: ``` --mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s ' ``` from your args.
Author
Owner

@roderickvd commented on GitHub (May 26, 2022):

Would still be nice though to fix this little quirk with this combination of parameters, superfluous or not. The issue is probably multiplication by zero here: github.com/librespot-org/librespot@fc1e74574a/playback/src/mixer/alsamixer.rs (L240)

Try changing line 239 to:

let db_volume = if self.use_linear_in_db && self.db_range > 0.0 {

Please think along if this will work OK for the many other Alsa variants we also have to cover.

<!-- gh-comment-id:1138649925 --> @roderickvd commented on GitHub (May 26, 2022): Would still be nice though to fix this little quirk with this combination of parameters, superfluous or not. The issue is probably multiplication by zero here: https://github.com/librespot-org/librespot/blob/fc1e74574a2c1537a7a25292e9354b341c0a91cb/playback/src/mixer/alsamixer.rs#L240 Try changing line 239 to: ```rust let db_volume = if self.use_linear_in_db && self.db_range > 0.0 { ``` Please think along if this will work OK for the many other Alsa variants we also have to cover.
Author
Owner

@petrkutalek commented on GitHub (May 26, 2022):

Thank you @JasonLG1979 for your valuable comments and analysis of the problem. Librespot is an excellent project that has been a pleasure for me for a very long time, and I appreciate the work of all the developers. I understand the need to support different architectures, but the configuration of the librespot application is by far its weakest point. Even perhaps of all the projects I use. It's like woo-doo.

It's also pointless and unnecessary to set the mixer device with a fixed volume of 100.

The idea was that I want to leave the output of the DAC (--mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s ') at 100% with no option to change it (--volume-ctrl=fixed), but the --initial-volume=100 option will ensure that the mixer output is always set correctly to full at initialization, regardless of the OS settings at startup.

The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering.

Realistically, the D10s' resolution is 21-22 bits according to the measurements. That's why I thought S24 with dithering would be best, but I agree that S32 without dithering is a cleaner choice.

So I finally ended up with the following setup and everything seems to be working fine:

/usr/local/bin/librespot --name="█████" --device-type=avr --disable-discovery \
    --bitrate=320 --cache=/var/cache/librespot --cache-size-limit=32G \
    --enable-volume-normalisation --normalisation-gain-type=track --normalisation-pregain=-3 --normalisation-method=dynamic \
    --backend=alsa --device=hw:0 --format=S32 --volume-ctrl=fixed --initial-volume=100

Does this make more sense to you as a Librespot expert?

<!-- gh-comment-id:1138805773 --> @petrkutalek commented on GitHub (May 26, 2022): Thank you @JasonLG1979 for your valuable comments and analysis of the problem. Librespot is an excellent project that has been a pleasure for me for a very long time, and I appreciate the work of all the developers. I understand the need to support different architectures, but the configuration of the librespot application is by far its weakest point. Even perhaps of all the projects I use. It's like woo-doo. > It's also pointless and unnecessary to set the mixer device with a fixed volume of 100. The idea was that I want to leave the output of the DAC (`--mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s '`) at 100% with no option to change it (`--volume-ctrl=fixed`), but the `--initial-volume=100` option will ensure that the mixer output is always set correctly to full at initialization, regardless of the OS settings at startup. > The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering. Realistically, the D10s' resolution is 21-22 bits according to the measurements. That's why I thought S24 with dithering would be best, but I agree that S32 without dithering is a cleaner choice. So I finally ended up with the following setup and everything seems to be working fine: ``` /usr/local/bin/librespot --name="█████" --device-type=avr --disable-discovery \ --bitrate=320 --cache=/var/cache/librespot --cache-size-limit=32G \ --enable-volume-normalisation --normalisation-gain-type=track --normalisation-pregain=-3 --normalisation-method=dynamic \ --backend=alsa --device=hw:0 --format=S32 --volume-ctrl=fixed --initial-volume=100 ``` Does this make more sense to you as a Librespot expert?
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

--normalisation-method=dynamic is redundant because dynamic is already the default.

A devices name is always better than it's number as the index can change at boot (but it's unlikely unless you have a lot of devices) I generally use --device=hw:CARD=D10s,DEV=0.

Unless you really want track mode normalization I would leave out --normalisation-gain-type=track as the default is auto which will go back and forth between track and album depending on the context. So if you're listening to a mixed playlist it will go to track mode but when you're listening to an album it will switch to album mode.

<!-- gh-comment-id:1138823693 --> @JasonLG1979 commented on GitHub (May 26, 2022): `--normalisation-method=dynamic` is redundant because dynamic is already the default. A devices name is always better than it's number as the index can change at boot (but it's unlikely unless you have a lot of devices) I generally use `--device=hw:CARD=D10s,DEV=0`. Unless you really want track mode normalization I would leave out `--normalisation-gain-type=track` as the default is `auto` which will go back and forth between track and album depending on the context. So if you're listening to a mixed playlist it will go to track mode but when you're listening to an album it will switch to album mode.
Author
Owner

@roderickvd commented on GitHub (May 26, 2022):

I understand the need to support different architectures, but the configuration of the librespot application is by far its weakest point. Even perhaps of all the projects I use. It's like woo-doo.

We're open to suggestions.

Of course for ultimate ease of use there are other options like Raspotify. Which is not to say that there is no room for improvement here.

It's also pointless and unnecessary to set the mixer device with a fixed volume of 100.

The idea was that I want to leave the output of the DAC (--mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s ') at 100% with no option to change it (--volume-ctrl=fixed), but the --initial-volume=100 option will ensure that the mixer output is always set correctly to full at initialization, regardless of the OS settings at startup.

With OS settings you mean the OS volume level? If you use librespot's own softvol or Alsa hardware mixing then the volume is unaffected by the OS.

librespot's volume control is in 64-bit float which will be better even than the hardware control of 99.99% of devices.

The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering.

Realistically, the D10s' resolution is 21-22 bits according to the measurements. That's why I thought S24 with dithering would be best, but I agree that S32 without dithering is a cleaner choice.

That is the ENOB you are talking about: Effective Number Of Bits, determined by the measured dynamic range, and a result of the engineering of the DAC. It is not the same as the sampling bit depth.

When keeping volume at 100% you will not be able to hear a difference between 24 and 32 bit, dithered or not. At those levels of residual noise it's even hard to measure with the best equipment. Objectively 32 bit will be better and be "naturally" dithered by thermal noise.

Would be great if either of you could take that quick fix for a test drive.

<!-- gh-comment-id:1138884421 --> @roderickvd commented on GitHub (May 26, 2022): > I understand the need to support different architectures, but the configuration of the librespot application is by far its weakest point. Even perhaps of all the projects I use. It's like woo-doo. We're open to suggestions. Of course for ultimate ease of use there are other options like `Raspotify`. Which is not to say that there is no room for improvement here. > > It's also pointless and unnecessary to set the mixer device with a fixed volume of 100. > > The idea was that I want to leave the output of the DAC (`--mixer=alsa --alsa-mixer-device=hw:0 --alsa-mixer-control='D10s '`) at 100% with no option to change it (`--volume-ctrl=fixed`), but the `--initial-volume=100` option will ensure that the mixer output is always set correctly to full at initialization, regardless of the OS settings at startup. With OS settings you mean the OS volume level? If you use `librespot`'s own softvol or Alsa hardware mixing then the volume is unaffected by the OS. `librespot`'s volume control is in 64-bit float which will be better even than the hardware control of 99.99% of devices. > > The D10s supports S32 audio. Unless you have some other reason for using S24 I'd use S32 with no dithering. > > Realistically, the D10s' resolution is 21-22 bits according to the measurements. That's why I thought S24 with dithering would be best, but I agree that S32 without dithering is a cleaner choice. That is the ENOB you are talking about: Effective Number Of Bits, determined by the measured dynamic range, and a result of the engineering of the DAC. It is not the same as the sampling bit depth. When keeping volume at 100% you will not be able to hear a difference between 24 and 32 bit, dithered or not. At those levels of residual noise it's even hard to measure with the best equipment. Objectively 32 bit will be better and be "naturally" dithered by thermal noise. Would be great if either of you could take that quick fix for a test drive.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

With OS settings you mean the OS volume level? If you use librespot's own softvol or Alsa hardware mixing then the volume is unaffected by the OS.

I think the intention is to use librespot to set the hardware volume to 100 whenever it starts?

<!-- gh-comment-id:1138887473 --> @JasonLG1979 commented on GitHub (May 26, 2022): > With OS settings you mean the OS volume level? If you use `librespot`'s own softvol or Alsa hardware mixing then the volume is unaffected by the OS. I think the intention is to use librespot to set the hardware volume to 100 whenever it starts?
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

Would be great if either of you could take that quick fix for a test drive.

Nope, that's didn't fix it. IMHO in the case of --volume-ctrl=fixed hardware volume control should just not be used. We should just ignore all the hardware volume args.

<!-- gh-comment-id:1138907268 --> @JasonLG1979 commented on GitHub (May 26, 2022): > Would be great if either of you could take that quick fix for a test drive. Nope, that's didn't fix it. IMHO in the case of `--volume-ctrl=fixed` hardware volume control should just not be used. We should just ignore all the hardware volume args.
Author
Owner

@petrkutalek commented on GitHub (May 26, 2022):

Librespot suits me fine, I don't need another client. As a developer I can also appreciate its beauty inside. You know, I've been using it for a long time, I had to deal with renaming parameters, deprecated parameters, new features, failing Librespot with Rodio backend some time ago, the documentation is not completely exhaustive. So I'm always super nervous when I have to update it and I don't like doing it. However, the contextual explanation @JasonLG1979 wrote is absolutely awesome!!

My layman's view was that it makes no sense to algorithmically lower the volume in Librespot, then in the DAC, to finally raise the volume again in the final amp including noise. I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong.

In the end I used the recommended settings (softvol, no HW mixer settings) and left the work to amixer and systemd. I am very satisfied 👍️:

ExecStartPre=/usr/bin/amixer -D hw:CARD=D10s -q -- set 'D10s ' -4dB unmute
ExecStart=/usr/local/bin/librespot …
<!-- gh-comment-id:1138920670 --> @petrkutalek commented on GitHub (May 26, 2022): Librespot suits me fine, I don't need another client. As a developer I can also appreciate its beauty inside. You know, I've been using it for a long time, I had to deal with renaming parameters, deprecated parameters, new features, failing Librespot with Rodio backend some time ago, the documentation is not completely exhaustive. So I'm always super nervous when I have to update it and I don't like doing it. However, [the contextual explanation @JasonLG1979](https://github.com/librespot-org/librespot/issues/1008#issuecomment-1138823693) wrote is absolutely awesome!! My layman's view was that it makes no sense to algorithmically lower the volume in Librespot, then in the DAC, to finally raise the volume again in the final amp including noise. I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong. In the end I used the recommended settings (softvol, no HW mixer settings) and left the work to `amixer` and `systemd`. I am very satisfied 👍️: ``` ExecStartPre=/usr/bin/amixer -D hw:CARD=D10s -q -- set 'D10s ' -4dB unmute ExecStart=/usr/local/bin/librespot … ```
Author
Owner

@roderickvd commented on GitHub (May 26, 2022):

Librespot suits me fine, I don't need another client. As a developer I can also appreciate its beauty inside. You know, I've been using it for a long time, I had to deal with renaming parameters, deprecated parameters, new features, failing Librespot with Rodio backend some time ago, the documentation is not completely exhaustive. So I'm always super nervous when I have to update it and I don't like doing it.

Thanks for the support. I can imagine about your anxiety as we've been a long way from stability. But we try to make life easier with the changelog we added since v0.2.

My layman's view was that it makes no sense to algorithmically lower the volume in Librespot, then in the DAC, to finally raise the volume again in the final amp including noise. I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong.

No, you were right. Running full line level to an attenuator in the (pre-)amp gives the best dynamic range. It's just a matter of how you get to the full line level. So yeah, hardware control to your DAC to get it to 100% is the best option. And you're also right it's broken now with fixed, hence the patch I suggested.

As comfortable as you are with upgrading, I'd really appreciate if you could test it so we can come full circle on your issue report.

<!-- gh-comment-id:1138924924 --> @roderickvd commented on GitHub (May 26, 2022): > Librespot suits me fine, I don't need another client. As a developer I can also appreciate its beauty inside. You know, I've been using it for a long time, I had to deal with renaming parameters, deprecated parameters, new features, failing Librespot with Rodio backend some time ago, the documentation is not completely exhaustive. So I'm always super nervous when I have to update it and I don't like doing it. Thanks for the support. I can imagine about your anxiety as we've been a long way from stability. But we try to make life easier with the changelog we added since v0.2. > My layman's view was that it makes no sense to algorithmically lower the volume in Librespot, then in the DAC, to finally raise the volume again in the final amp including noise. I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong. No, you were right. Running full line level to an attenuator in the (pre-)amp gives the best dynamic range. It's just a matter of *how* you get to the full line level. So yeah, hardware control to your DAC to get it to 100% is the best option. And you're also right it's broken now with `fixed`, hence the patch I suggested. As comfortable as you are with upgrading, I'd really appreciate if you could test it so we can come full circle on your issue report.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong.

It's really about use case. I have my DAC connected to a stereo receiver so I generally use software volume in librespot so that if I want to I can change the volume in a client if I don't have the stereo remote handy or are not close to the receiver. But most of the time I leave it at 100% and use the volume control on the receiver. But all things being equal the software volume control in librespot is going to be better than hardware volume control on a DAC.

As comfortable as you are with upgrading, I'd really appreciate if you could test it so we can come full circle on your issue report.

Your fix doesn't work no change. If it's helpful librespot also mutes the DAC it doesn't just set the volume to 0.

<!-- gh-comment-id:1138954212 --> @JasonLG1979 commented on GitHub (May 26, 2022): > I thought it's best to let Librespot do its job with "a 1.0 coefficient", then let the DAC do the output at normal levels (i.e. 100% ??) and control the volume in the amp. But I guess I was wrong. It's really about use case. I have my DAC connected to a stereo receiver so I generally use software volume in librespot so that if I want to I can change the volume in a client if I don't have the stereo remote handy or are not close to the receiver. But most of the time I leave it at 100% and use the volume control on the receiver. But all things being equal the software volume control in librespot is going to be better than hardware volume control on a DAC. > As comfortable as you are with upgrading, I'd really appreciate if you could test it so we can come full circle on your issue report. Your fix doesn't work no change. If it's helpful librespot also mutes the DAC it doesn't just set the volume to 0.
Author
Owner

@roderickvd commented on GitHub (May 26, 2022):

Huh, that's weird. That means that the set_volume is called with a volume of 0 instead of u16::MAX. I'll have to investigate further sometime later.

<!-- gh-comment-id:1138957618 --> @roderickvd commented on GitHub (May 26, 2022): Huh, that's weird. That means that the `set_volume` is called with a volume of `0` instead of `u16::MAX`. I'll have to investigate further sometime later.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

@petrkutalek

ExecStartPre=/usr/bin/amixer -D hw:CARD=D10s -q -- set 'D10s ' -4dB unmute

Why would you do this? You're throwing away 4dB of theoretical dynamic range. Unless 0dB saturates your preamp's input don't do that. With normalization enabled you'd be better off just lowering the pregain.

<!-- gh-comment-id:1138957917 --> @JasonLG1979 commented on GitHub (May 26, 2022): @petrkutalek > `ExecStartPre=/usr/bin/amixer -D hw:CARD=D10s -q -- set 'D10s ' -4dB unmute` Why would you do this? You're throwing away 4dB of theoretical dynamic range. Unless 0dB saturates your preamp's input don't do that. With normalization enabled you'd be better off just lowering the pregain.
Author
Owner

@JasonLG1979 commented on GitHub (May 26, 2022):

The D10s is by all indications a very well designed DAC but if you're doing this to prevent inter-sample clipping --normalisation-pregain=-3 should already be sufficient.

<!-- gh-comment-id:1138968165 --> @JasonLG1979 commented on GitHub (May 26, 2022): The D10s is by all indications a very well designed DAC but if you're doing this to prevent inter-sample clipping `--normalisation-pregain=-3` should already be sufficient.
Author
Owner

@petrkutalek commented on GitHub (May 26, 2022):

Yes, @JasonLG1979 exactly. Thanks for advice, will change my settings. 👍
@roderickvd Sure, I will retest your (next) patch together with Jason to confirm/debug.

<!-- gh-comment-id:1138972685 --> @petrkutalek commented on GitHub (May 26, 2022): Yes, @JasonLG1979 exactly. Thanks for advice, will change my settings. 👍️ @roderickvd Sure, I will retest your (next) patch together with Jason to confirm/debug.
Author
Owner

@roderickvd commented on GitHub (May 27, 2022):

Your fix doesn't work no change. If it's helpful librespot also mutes the DAC it doesn't just set the volume to 0.

To be clear, does the verbose log state "Disabling playback (setting mute) on Alsa"? Can you post a full log?

<!-- gh-comment-id:1139400355 --> @roderickvd commented on GitHub (May 27, 2022): > Your fix doesn't work no change. If it's helpful librespot also mutes the DAC it doesn't just set the volume to 0. To be clear, does the verbose log state "Disabling playback (setting mute) on Alsa"? Can you post a full log?
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --initial-volume=100 --format=S32 -v

With the change:

[2022-05-27T11:55:27Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range was detected as 127 but overridden as 0
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (0.00)
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: true
...
[2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to NaN dB
<!-- gh-comment-id:1139552547 --> @JasonLG1979 commented on GitHub (May 27, 2022): ``` ./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --initial-volume=100 --format=S32 -v ``` With the change: ``` [2022-05-27T11:55:27Z INFO librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0 [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range was detected as 127 but overridden as 0 [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (0.00) [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: true ... [2022-05-27T11:55:27Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to NaN dB ```
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

Although the topping D10s is a great DAC the drivers are a bit suspect as evidenced by the fact that it doesn't support S16 on Linux, the trailing white space in the control name and that the control name "D10s " doesn't follow convention at all. There's a post on audio science review about it if I remember. I think a best effort was made but that the author is not a Linux user or experienced at all at writing Linux drivers.

<!-- gh-comment-id:1139559877 --> @JasonLG1979 commented on GitHub (May 27, 2022): Although the topping D10s is a great DAC the drivers are a bit suspect as evidenced by the fact that it doesn't support S16 on Linux, the trailing white space in the control name and that the control name "D10s " doesn't follow convention at all. There's a post on audio science review about it if I remember. I think a best effort was made but that the author is not a Linux user or experienced at all at writing Linux drivers.
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

It's a USB2 DAC but may not actually be spec compliant?

<!-- gh-comment-id:1139565485 --> @JasonLG1979 commented on GitHub (May 27, 2022): It's a USB2 DAC but may not actually be spec compliant?
Author
Owner

@roderickvd commented on GitHub (May 27, 2022):

Thanks. And what does it say without the change? Als about NaN or not?

<!-- gh-comment-id:1139615100 --> @roderickvd commented on GitHub (May 27, 2022): Thanks. And what does it say without the change? Als about `NaN` or not?
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

Thanks. And what does it say without the change? Als about NaN or not?

The log is exactly the same, no change, still NaN.

<!-- gh-comment-id:1139623349 --> @JasonLG1979 commented on GitHub (May 27, 2022): > Thanks. And what does it say without the change? Als about `NaN` or not? The log is exactly the same, no change, still `NaN`.
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

I think the problem is that a fixed volume has a range of 0.0 but it passes range_ok because it's fixed so the db range is always overridden to 0.0 no matter what the card reports. I'm not sure exactly but then maybe after that there's a division by zero that causes the NaN.

<!-- gh-comment-id:1139650761 --> @JasonLG1979 commented on GitHub (May 27, 2022): I think the problem is that a fixed volume has a range of 0.0 but it passes range_ok because it's fixed so the db range is always overridden to 0.0 no matter what the card reports. I'm not sure exactly but then maybe after that there's a division by zero that causes the NaN.
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

Yep, that was the problem.

This seems to fix it:

        let min_db = min_millibel.to_db() as f64;
        let max_db = max_millibel.to_db() as f64;
        let mut db_range = f64::abs(max_db - min_db);
        let is_fixed_vol = matches!(config.volume_ctrl, VolumeCtrl::Fixed);

        // Synchronize the volume control dB range with the mixer control,
        // unless it was already set with a command line option.
        if !config.volume_ctrl.range_ok() {
            if db_range > 100.0 && !is_fixed_vol {
                debug!("Alsa mixer reported dB range > 100, which is suspect");
                warn!("Please manually set `--volume-range` if this is incorrect");
            }
            config.volume_ctrl.set_db_range(db_range);
        } else {
            let db_range_override = config.volume_ctrl.db_range();
            if db_range_override.is_normal() {
                debug!(
                    "Alsa dB volume range was detected as {} but overridden as {}",
                    db_range, db_range_override
                );
                db_range = db_range_override;
            } else if !is_fixed_vol {
                debug!("Alsa dB volume range was detected as {}", db_range);
            }
        }
<!-- gh-comment-id:1139999831 --> @JasonLG1979 commented on GitHub (May 27, 2022): Yep, that was the problem. This seems to fix it: ```rust let min_db = min_millibel.to_db() as f64; let max_db = max_millibel.to_db() as f64; let mut db_range = f64::abs(max_db - min_db); let is_fixed_vol = matches!(config.volume_ctrl, VolumeCtrl::Fixed); // Synchronize the volume control dB range with the mixer control, // unless it was already set with a command line option. if !config.volume_ctrl.range_ok() { if db_range > 100.0 && !is_fixed_vol { debug!("Alsa mixer reported dB range > 100, which is suspect"); warn!("Please manually set `--volume-range` if this is incorrect"); } config.volume_ctrl.set_db_range(db_range); } else { let db_range_override = config.volume_ctrl.db_range(); if db_range_override.is_normal() { debug!( "Alsa dB volume range was detected as {} but overridden as {}", db_range, db_range_override ); db_range = db_range_override; } else if !is_fixed_vol { debug!("Alsa dB volume range was detected as {}", db_range); } } ```
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

With:

./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --initial-volume=100 --format=S32 -v

The log output is:

[2022-05-27T20:14:57Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00)
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false
...
[2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to 0.00 dB
<!-- gh-comment-id:1140005875 --> @JasonLG1979 commented on GitHub (May 27, 2022): With: ``` ./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --initial-volume=100 --format=S32 -v ``` The log output is: ``` [2022-05-27T20:14:57Z INFO librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0 [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00) [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false ... [2022-05-27T20:14:57Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to 0.00 dB ```
Author
Owner

@JasonLG1979 commented on GitHub (May 27, 2022):

What branch do you want me to put in the PR for?

<!-- gh-comment-id:1140006639 --> @JasonLG1979 commented on GitHub (May 27, 2022): What branch do you want me to put in the PR for?
Author
Owner

@roderickvd commented on GitHub (May 28, 2022):

Good stuff. Let’s do dev we have to catch up new-api anyway.

<!-- gh-comment-id:1140195459 --> @roderickvd commented on GitHub (May 28, 2022): Good stuff. Let’s do `dev` we have to catch up `new-api` anyway.
Author
Owner

@JasonLG1979 commented on GitHub (May 28, 2022):

Will do.

As a sanity check:

The behavior is such that --initial-volume=% sets the value of the hardware mixer in a log(?) scale in fixed mode with hardware volume enabled at startup but you can't change the volume level at any time later ofc because it's fixed. Which to me seems like pretty logical behavior.

It could come in handy if for some stupid reason your system doesn't remember the volume. I've also seen more than one DAC that if you power cycle them they default back to volume 0, muted.

./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --format=S32 -v

With --initial-volume=50

[2022-05-28T08:03:01Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00)
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false
...
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::mappings] Input volume 32767 mapped to: 50.00%
[2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -6.02 dB
[2022-05-28T08:03:01Z DEBUG librespot_playback::player] command=VolumeSet(32767)

With --initial-volume=0

[2022-05-28T08:05:01Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00)
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false
...
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Disabling playback (setting mute) on Alsa
...
[2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -99999.99 dB
[2022-05-28T08:05:01Z DEBUG librespot_playback::player] command=VolumeSet(0)

With --initial-volume=1

[2022-05-28T08:06:14Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127)
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00)
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false
...
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Enabling playback (unsetting mute) on Alsa
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::mappings] Input volume 655 mapped to: 1.00%
[2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -40.00 dB
[2022-05-28T08:06:14Z DEBUG librespot_playback::player] command=VolumeSet(655)
<!-- gh-comment-id:1140209825 --> @JasonLG1979 commented on GitHub (May 28, 2022): Will do. As a sanity check: The behavior is such that `--initial-volume=%` sets the value of the hardware mixer in a log(?) scale in fixed mode with hardware volume enabled at startup but you can't change the volume level at any time later ofc because it's fixed. Which to me seems like pretty logical behavior. It could come in handy if for some stupid reason your system doesn't remember the volume. I've also seen more than one DAC that if you power cycle them they default back to volume 0, muted. ``` ./librespot --device=hw:CARD=D10s,DEV=0 --mixer=alsa --alsa-mixer-device=hw:1 --alsa-mixer-control='D10s ' --volume-ctrl=fixed --format=S32 -v ``` With `--initial-volume=50` ``` [2022-05-28T08:03:01Z INFO librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0 [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00) [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false ... [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::mappings] Input volume 32767 mapped to: 50.00% [2022-05-28T08:03:01Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -6.02 dB [2022-05-28T08:03:01Z DEBUG librespot_playback::player] command=VolumeSet(32767) ``` With `--initial-volume=0` ``` [2022-05-28T08:05:01Z INFO librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0 [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00) [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false ... [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Disabling playback (setting mute) on Alsa ... [2022-05-28T08:05:01Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -99999.99 dB [2022-05-28T08:05:01Z DEBUG librespot_playback::player] command=VolumeSet(0) ``` With `--initial-volume=1` ``` [2022-05-28T08:06:14Z INFO librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Fixed for device: hw:1 with mixer control: D10s ,0 [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa mixer control is softvol: false [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa support for playback (mute) switch: true [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa raw volume range: [0..127] (127) [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa dB volume range: [-127.00..0.00] (127.00) [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Alsa forcing linear dB mapping: false ... [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Enabling playback (unsetting mute) on Alsa [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::mappings] Input volume 655 mapped to: 1.00% [2022-05-28T08:06:14Z DEBUG librespot_playback::mixer::alsamixer] Setting Alsa volume to -40.00 dB [2022-05-28T08:06:14Z DEBUG librespot_playback::player] command=VolumeSet(655) ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librespot#482
No description provided.