Help with using volumescripts in a plugin I'm writing

Hi. I want to write a custom “backend” for volume controls, so that when I change volume via the web UI (or anything else, really), it doesn’t adjust the volume using ALSA, but instead calls into my code and tells it what the new volume is supposed to be; and if it needs to ask for the volume, instead of asking ALSA what the current volume is, it should call my code (background: I have a Terra Berry DAC, which has volume controls, but those can only be accessed/controlled via the serial port, and that’s what my code does).

I’m not really familiar with Volumio’s code base, but the allo_relay_volume_attenuator plugin seems to do something similar. It provides shell scripts for getting/setting volume, tells Volumio about them via commandRouter.updateVolumeScripts, and then they get called when the volume changes. I adapted that plugin for my use case, and setting the volume works – when I change the volume in the web UI, it sends the corresponding commands to the DAC, and the volume changes, and ALSA’s volume doesn’t get touched. But the “get volume” script never gets called, and as a result of that, when I start Volumio, it displays the volume from ALSA instead of from the DAC (once I change the volume, the displayed and actual value are generally the same, I suspect Volumio stores that value instead of querying it from anywhere).

Is there documentation on how to use volumescripts correctly, so my getvolume script gets called and I don’t have wrong values displayed?

In case that’s relevant: The mixer type is set to Software. As far as I understand, the only other valid values are None or Hardware. Setting it to None disables the volume controls, and I obviously don’t want that (the whole reason for doing this is that I want to use Volumio’s UI for that, after all). I can’t set it to Hardware in the Web UI. I could probably edit the configuration file by hand, but that doesn’t seem correct to me and I have no idea what other effects that might have.

The crucial code for querying the initial volume seems to be the retrievevolume function in volumecontrol.js, and as far as I can tell, that doesn’t use the provided script if the mixer type is Software or None. But I’m a bit confused by that, since the script for setting volume also gets called when the mixer type is set to Software.

So, what’s the correct way to do this? Ideally, I’d just get it to use my script instead of amixer to retrieve the volume. If there’s a way for a plugin to run JS code instead of the external scripts, that would also be fine. Or do I need to/can I somehow tell Volumio that my code provides hardware controls?

Okay, I looked into this some more, and if the mixer type is not set to “Software”, the setMuted function in volumecontrol.js always calls amixer (not my setmute script). But as mentioned above, if the mixer type is set to “Software”, my getvolume script doesn’t get called. So basically, there doesn’t seem to be a way to set this up so that all the scripts I provide to updateVolumeScripts get called.

But that is exactly what I want – just don’t touch amixer for anything: not for getting volume, not for setting volume, not for getting or setting mute status. I provide scripts to do all of this, so what do I need to do so they all get called? I feel like I’m overlooking something really obvious, this can’t be that hard, right?

1 Like

I’m also looking for a solution to control the volume externally without altering the digital stream anyway (in alsa). I would be very appreciated if someone could help me on this.