Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume scaling on RPi #22

Closed
andyjenkinson opened this issue Dec 7, 2015 · 10 comments
Closed

Volume scaling on RPi #22

andyjenkinson opened this issue Dec 7, 2015 · 10 comments

Comments

@andyjenkinson
Copy link

Firstly just let me say a big thanks for getting so far with this project, it took me a few days to find it but I am pretty happy to get it running on the RPI1.

I have only played with it for a minute, but I did notice that the volume control scale (using the PCM mixer) is off - i.e. it's inaudible/very quiet for most of the range and all the useful variability is in the top 20% or so of the Spotify slider. I can see this reflected in alsamixer when controlling the volume from Spotify. alsamixer itself works correctly.

I believe this is likely related to a similar issue that affected mopidy, to do with the way amixer reports volume:
mopidy/mopidy-alsamixer#3

In shairport-sync a different volume algorithm has been applied that works quite well:
https://github.com/mikebrady/shairport-sync

Not sure what volume is like on other platforms or other versions of amixer, it might be that the latter is what is important in which case the lib could be updated to do something different in each case. Or, maybe apply a configurable filter in the python layer? Has anyone played about with this yet?

@maumi
Copy link

maumi commented Dec 7, 2015

I've tried some things. Badly you can't compare mopidy and spotify connect with shairport sync because they are written in python and not in C. In C you can access directly alsa. In python is not much mixer related implemented. So for me I did for now a crude hack to "linearise" the volume. You can see it in my fork of spotify connect.

@andyjenkinson
Copy link
Author

So it is the python spotify-connect-web that changes the volume directly?

Does it not user amixer? If so it can be the same problem as I don't think it is to do with the alsa library only. i.e. amixer's volume scale is a simple direct raw readout of the card values rather than one that relates to human hearing. I will have a look at your hack, thanks!

@maumi
Copy link

maumi commented Dec 8, 2015

It is the same problem. But in python aren't the same functions implemented to use from alsa like in C. You can read about it in pyalsa docu at the end of mixer part.

@Fornoth Fornoth mentioned this issue Dec 9, 2015
24 tasks
@andyjenkinson
Copy link
Author

Just to update: it is indeed a similar issue, i.e. simply that hardware volume control from cards operate on a simple scale that is not related to how humans hear. It is the same as what amixer does on command line by default (note that alsamixer does something different).

On mine I modified the volume control to translate on an exponent scale:

percent_volume = volume / 655.35
mixer_volume = math.pow( percent_volume / 100.0, 1.0/3.0) * 100.0 )

However I keep managing to break the volume control and am not sure why.

@plietar
Copy link
Contributor

plietar commented Dec 28, 2015

Are you both using the Pi's builtin "DAC"/PWM ?
From the shairport-sync README : https://github.com/mikebrady/shairport-sync

The Raspberry Pi has a built-in audio DAC that is connected to the device's headphone jack. This provides a low-quality output that is nevertheless useful for testing purposes and may be adequate for [very] casual listening. It is not HiFi -- it is quite noisy and can't play anything above about 15kHz. A further problem is that it declares itself to have a very large mixer volume control range -- all the way from -102.38dB up to +4dB, a range of 106.38 dB. In reality, only the top 35dB of it is in any way usable. To help get the most from the DAC, consider using the volume_range_db setting in the general stanza to instruct Shairport Sync to use the top of the DAC mixer's declared range. For example, if you set the volume_range_db figure to 35, the top 35 dB of the range will the used. With this setting on the Raspberry Pi, maximum volume will be +4dB and minimum volume will be -31dB, below which muting will occur.

The problem is therefore probably not the scale but simply that the minimal value returned by ALSA is incorrect.
Unfortunately pyalsaaudio does not give direct access to the volume control and instead translates the given percentage itself

@maumi
Copy link

maumi commented Dec 28, 2015

No, I use an USB sound card on my rPi2, which may be not much better than the internal DAC. But I also use the digital output (spdif) from my cubox where I have the same scaling problem.

@tommph
Copy link

tommph commented Dec 28, 2015

This is because pyalsaaudio changes the db value linearly. I've modified pyalsaaudio to scale the volume in the same way as alsamixer does and this improves things for me. I've put the changes in my fork.

@maumi
Copy link

maumi commented Dec 28, 2015

Will test it next days when I'm home. But I need to mix your version with the one where the device is properly released.

@chukysoria
Copy link
Contributor

I have added a new argument which sets an upper volume range. Same solution as on https://github.com/mikebrady/shairport-sync, like @plietar said.

@Fornoth
Copy link
Owner

Fornoth commented Jul 3, 2016

Finally merged in #34, which should fix this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants