UCM: is there a way to act when a device becomes the active one?
Mikhail Gavrilov <[email protected]>
| Newsgroups | org.alsa-project.alsa-devel |
|---|---|
| Message-ID | <CABXGCsMuopDFyQ88+00wECHTON7tQLAkoGOQvquqpAg+92vDcA@mail.gmail.com> |
Hi, Two problems from one card, and I suspect one missing piece behind both. The card is a USB interface with ten playback channels and two physical outputs, headphones and a phone jack. A UCM profile splits the ten channels into five stereo outputs, and the desktop shows five, which is right: they are five independent pairs and different applications can go to different ones. The first problem is that they all sound the same. Each physical output listens to ONE source chosen inside the card -- an internal mix or a single playback bus -- and that choice is made in the vendor's control application, which exists for Windows and macOS only. So you pick "Playback 3/4" in the sound settings, the audio goes into bus 3/4, and you hear whatever the output was last pointed at. Nothing on the system says why. A kernel driver for the card's vendor protocol publishes that selector as an ordinary enumerated control, so the host can set it now. My plan was to have each of the five outputs point the headphone stage at its own bus from that device's EnableSequence, so that choosing an output would mean hearing it. It does not work, and I think the reason is structural. WirePlumber enables every device of the verb at once, so all five sequences run at startup and the last one wins. Choosing an output afterwards is a change of default sink, which no UCM sequence observes. The second problem is worse, and it is what makes me write. The card's analogue volume belongs to the physical output, not to the bus, so all five devices name the same mixer element. Each sink then remembers its own volume while the hardware has one: set Playback 1/2 to full, move to Playback 3/4, and the slider shows something else while the control still reads 99. The desktop is showing a number that is not true. I can avoid it by naming the digital per-bus trim instead, but that attenuates before the converter and throws away resolution, which is exactly what the analogue stage exists to avoid. Both come from the same gap, as far as I can see. UCM can say "this device exists" with EnableSequence, and cannot say "this device is now the one being used". With that, the profile would point the output at the right bus and name the analogue element honestly, because only one device would be active at a time. So: is there an existing way to express this that I have missed? A modifier, a property, something on the PipeWire or PulseAudio side rather than in UCM? I know ports are the usual answer to "choosing an output switches hardware", but ports come from devices sharing a mapping, and in alsa-ucm.c the mapping name is built per device, so five split PCMs are five sinks by construction. If there is no way, would a per-device sequence that runs on activation be a reasonable thing to propose? The shape is not specific to this card: any interface whose outputs are fed from an internal matrix has it. Happy to write the patch if the direction is agreeable, and happy to be told I have the model wrong. -- Thanks, Mikhail Gavrilov.