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

Read volume level from ALSA Loopback CTL mixer #172

Open
yannpom opened this issue Jan 6, 2022 · 8 comments
Open

Read volume level from ALSA Loopback CTL mixer #172

yannpom opened this issue Jan 6, 2022 · 8 comments
Labels
enhancement New feature or request linux Only affects Linux
Milestone

Comments

@yannpom
Copy link

yannpom commented Jan 6, 2022

Hello,

Here is my setup so you can better understand my needs:

  • Kodi & shairport-sync output audio to hw:Loopback,1,0
  • CamillaDSP reads from hw:Loopback,0,0, applies FIR, then outputs on hw:Loopback,1,5 & hw:Loopback,1,6 (using a "multi" device type)
  • Alsaloop reads from hw:Loopback,0,5 & hw:Loopback,0,6 and outputs to 2 hardware sound cards, Raspberry Pi Headphone for the sub & Hifiberry AMP for the speakers. Both hardware sound card clocks are not synchronised but it's alsaloop's job to resample accordingly and keep them in sync. It works great.

When I press the volume buttons on my phone, the value is sent to shairport-sync which can do 3 things: apply software volume, do nothing or control an ALSA CTL mixer. Currently I'm using shairport-sync software volume, but I would like to move volume control to CamillaDSP.

I could setup shairport-sync to do noting and write a script that reads shairport-sync volume and sends it to CamillaDSP webservice. But I find the following proposal more generic and more elegant:

  • shairport-sync (or whatever) controls ALSA Loopback CTL mixer (which, by the way, does not attenuate the audio).
  • CamillaDSP reads this ALSA CTL mixer and uses its value for the Volume & Loudness filters.

What do you think?

@HEnquist HEnquist added enhancement New feature or request linux Only affects Linux labels Jan 6, 2022
@HEnquist
Copy link
Owner

HEnquist commented Jan 6, 2022

This seems like a quite useful addition! I'll take a look to see what kind of changes it would require. No promises for when that will happen though (or when those changes can be implemented).

Very interesting use of loopbacks and alsaloop, thanks for sharing I haven't seen anyone else syncing individual devices in this way.

@Baffless
Copy link

Yes, this feature is very welcome!

@bitkeeper
Copy link

With moOde we also uses the alsa loop back in this way. When this would directly be support by CamillaDSP we could drop the alsa/cdsp volume sync service https://github.com/bitkeeper/mpd2cdspvolume.
The only benefit we have now is that we came make up our own volume curve.

@HEnquist HEnquist added this to the 4.0 milestone Apr 18, 2024
@HEnquist
Copy link
Owner

This is included here: #341

@HEnquist HEnquist modified the milestones: 4.0, 3.0 Apr 27, 2024
@HEnquist
Copy link
Owner

HEnquist commented May 2, 2024

This is working well, using the "PCM Playback Volume" mixer control on the loopback.
But there is a problem that I don't get. On Fedora, the loopback has this control.
Listing the controls with amixer -c 2 controls (the Loopback is card 2 on that system) includes the line numid=113,iface=MIXER,name='PCM Playback Volume'.
But doing the same in Manjaro and Raspberry Pi OS, this control isn't there (but all the others are present). How can this control be enabled? @pavhofman do you know?

@pavhofman
Copy link
Contributor

pavhofman commented May 3, 2024

There is no volume ctl created in the aloop source.

IMO it's added by the softvol configuration in /usr/share/alsa/cards/Loopback.conf . Looking at the softvol code - the volume ctl is added to the slaved card, i.e. to the actual hw device, via IOCTL call to the kernel. So the ctl becomes available for all uses of the hw device - therefore listed by amixer -c CARD.

BUT the softvol operation is applied to the stream going through the softvol plugin, i.e. only when client opens a PCM (not HW) device and the softvol plugin is in its chain. Therefore the softvol ctl does nothing when the hw card is accessed directly. But since it's defined for the hw card, it contains the set value and behaves basically identically as the PCM Volume ctl created by the gadget driver. IMO it's just a coincidence, not intended for this purpose. The softvol is defined for many other cards in default alsa configs in /usr/share/alsa/cards.

However, note that only one Volume ctl is added for the card, no separate Volume ctls for each loopback device, like in case of PCM Slave Format/Channels/xxx controls added explicitly by the driver. While one loopback card can be used for two "wires" and its controls are defined for each device ("wire"), here only one Volume ctl is available, common for both directions.

There is one more caveat. The softvol ctl is created the first time the chain containing the softvol plugin is opened. I tried to list loopback card mixer on a freshly-booted bare debian distribution without pulseaudio and could not find out why the loopback device always had the Volume ctl defined. Alsa has many systemd units storing and restoring state, caches the state, etc. But it may happen that a different linux system, freshly installed, will not initialize the softvol ctl upon boot as the softvol plugin was never opened for the given card.

IMO using that Volume ctl for this purpose in CDSP is a hack which may work OK.

@pavhofman
Copy link
Contributor

Just a note - if the loopback device configured for CDSP is a PCM which contains the softvol plugin in the chain (e.g. front:CARD=Loopback), the volume would be applied twice - by the softvol plugin and by the CDSP (or its playback device, if CDSP controls its Volume ctl instead).

@HEnquist
Copy link
Owner

HEnquist commented May 3, 2024

Thanks @pavhofman for the excellent explanation! This makes it all make sense. A simple aplay -D front:CARD=Loopback,DEV=0 makes the mysterious volume control appear.

This also means that the way I implemented it now is fragile. I think the functionality is very useful, but there needs to be more active input from the user to enable it. I will change the use_virtual_volume boolean to an optional string, to let the user provide a name of a volume control to follow. This makes it explicit which control will be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request linux Only affects Linux
Projects
None yet
Development

No branches or pull requests

5 participants