firefox and sndio env vars: minor updates

This commit is contained in:
John McQuah 2024-09-08 20:08:16 +00:00
parent f7ffaabe8b
commit 8f7c8f592b

View File

@ -1,5 +1,7 @@
# sndiod environment variables respected by Firefox?
In November 2020 the openbsd-tech mailing list received a patch (Footnote 1) that seemed to promise a simple way of emulating a full-duplex soundcard (dividing between two physical cards the responsibilities of playback and recording). In the 3+ years since that patch was merged, I never found an opportunity to test my assumptions on what it actually can do. Finally in September 2024, I have two hardware configurations --- and a relatively common use-case --- that can put these assumptions to the test. Here are my findings with sndiod running on CRUX, and Firefox 130.0 built from source. In all these trials, the Firefox ``about:support`` page indicates that it is using the sndio backend, not ALSA.
## Desktop Example
A pair of USB speakers (playback-only) is sometimes connected, but the internal (full-duplex) soundcard is always present and its kernel module loaded at boot. When the USB speakers are detected, I want the audio output directed to them, while still relying on the internal soundcard for microphone input through its 3.5-mm jack. Here are my sndiod flags.
@ -8,11 +10,11 @@ A pair of USB speakers (playback-only) is sometimes connected, but the internal
sndiod_flags="-f rsnd/Generic_1 -m play,rec -s default -F rsnd/Chroma -m play -s chroma"
```
(The speakers identify themselves as Chroma, just like the conductor in The Phantom Tollbooth.)
(The speakers identify themselves as Chroma, just like the conductor of the sunset orchestra in The Phantom Tollbooth.)
According to sndio(7), we should be able to export AUDIORECDEVICE=snd/default before launching firefox, to ensure that the browser does not try to use the device specified by -F for audio input (but one would expect the "-m play" flag to prevent this behaviour already). There should be no need to set AUDIOPLAYDEVICE for this experiment, but in the interest of science I added that column to the table below. The last two columns were initially populated using onlinemictest.com and youtube.com, respectively. But repeating the experiment with other online services eliminated the possibility that those particular sites had bugs in their implementations of streaming multimedia protocols, so the blame lies entirely with firefox or sndiod. In all of these trials the USB speakers are powered on and plugged into the USB port. When they are disconnected, sndiod falls back to the internal soundcard, whose full-duplex capabilities are not the subject of this investigation (they work reliably, allowing a trivial solution to the problem by running a patch cord from the soundcard's 3.5mm output jack to the Aux In port of the USB speakers).
| Trial | AUDIODEVICE | AUDIOPLAYDEVICE | AUDIORECDEVICE | mic working? | sound routed where? |
| Trial | AUDIODEVICE | AUDIOPLAYDEVICE | AUDIORECDEVICE | mic working? | sound playback where? |
|:-----:|:-----------:|:---------------:|:--------------:|:-----------------:|:------------------------:|
| 0 | | | | No | internal card 3.5mm jack |
| 1 | snd/default | | | Yes | internal card 3.5mm jack |
@ -22,7 +24,7 @@ According to sndio(7), we should be able to export AUDIORECDEVICE=snd/default be
## Laptop Example
The kernel drivers for the internal soundcard need to be accompanied by binary firmware from the SOF project, and this combination only reliably enables playback, not the internal microphone (Footnote 1). To work around this lack of full-duplex support, I want to use the microphone of a USB webcam for audio input, while still routing audio output to the internal speakers. (Note that the webcam is not a full-duplex USB soundcard but only supports audio input, so this situation complements nicely the Desktop Example, in which the USB soundcard only worked for audio output). Here are my sndiod flags.
The kernel drivers for the internal soundcard need to be accompanied by binary firmware from the SOF project, and this combination only reliably enables playback, not the internal microphone (Footnote 2). To work around this lack of full-duplex support, I want to use the microphone of a USB webcam for audio input, while still routing audio output to the internal speakers. (Note that the webcam is not a full-duplex USB soundcard but only supports audio input, so this situation complements nicely the Desktop Example, in which the USB soundcard only worked for audio output). Here are my sndiod flags.
```
sndiod_flags="-f rsnd/Generic -m play -s default -F rsnd/Webcam -m rec -s webcam"
@ -30,7 +32,7 @@ sndiod_flags="-f rsnd/Generic -m play -s default -F rsnd/Webcam -m rec -s webcam
According to sndio(7), we should be able to export AUDIORECDEVICE=snd/webcam before launching firefox, to ensure that the browser does not try to use the internal card for audio input (but one would expect the "-m play" flag to prevent this behaviour already). Again I have added a column for AUDIOPLAYDEVICE. Even though this experiment is not primarily concerned with playback, by setting AUDIOPLAYDEVICE I should be able to override AUDIODEVICE when the latter variable is set to a card that performs only input.
| Trial | AUDIODEVICE | AUDIOPLAYDEVICE | AUDIORECDEVICE | mic working? | sound routed where? |
| Trial | AUDIODEVICE | AUDIOPLAYDEVICE | AUDIORECDEVICE | mic working? | sound playback where? |
|:-----:|:-----------:|:---------------:|:--------------:|:-----------------:|:------------------------:|
| 0 | | | | No | internal speakers |
| 1 | snd/default | | | No | internal speakers |
@ -40,13 +42,15 @@ According to sndio(7), we should be able to export AUDIORECDEVICE=snd/webcam bef
## Conclusion
Firefox appears to respect only AUDIODEVICE, not AUDIOPLAYDEVICE or AUDIORECDEVICE. If we allow that the browser is not operating in a strict "play only mode" or "record only mode", then the observed behaviour does not technically violate the description in the sndio(7) man-page. Generalizing from the results above, creating a virtual full-duplex soundcard on Linux using sndio environment variables is not as straightforward as the traditional approach using ~/.asoundrc (Footnote 2) or a more featureful sound server like pulseaudio/pipewire. Not having a parallel OpenBSD installation on the same hardware to repeat the experiments above, I hesitate to suggest that sndio(7) be revised to emphasize this limitation. (The laptop's internal soundcard --- needing binary firmware --- is probably not supported on OpenBSD anyway.) If the sndio environment variables introduced in November 2020 (Footnote 3) do in fact allow OpenBSD users to define a virtual full-duplex soundcard, then something is broken in the porting of sndiod to other operating systems. But if the same results also hold on OpenBSD, then the man-page deserves further elaboration to prevent false expectations of what the environment variables can achieve.
Firefox appears to respect only AUDIODEVICE, not AUDIOPLAYDEVICE or AUDIORECDEVICE. If we allow that the browser is not operating in a strict "play only mode" or "record only mode", then the observed behaviour does not technically violate the description in the sndio(7) man-page. Generalizing from the results above, creating a virtual full-duplex soundcard on Linux using sndio environment variables is not as straightforward as the traditional approach using ~/.asoundrc (Footnote 3) or a more featureful sound server like pulseaudio/pipewire. Not having a parallel OpenBSD installation on the same hardware to repeat the experiments above, I hesitate to suggest that sndio(7) be revised to emphasize this limitation. (The laptop's internal soundcard --- needing binary firmware --- is probably not supported on OpenBSD anyway.) If the sndio environment variables introduced in November 2020 do in fact allow OpenBSD users to define a virtual full-duplex soundcard, then something is broken in the porting of sndiod to other operating systems. But if the same results also hold on OpenBSD, then the man-page deserves further elaboration to prevent false expectations of what the environment variables can achieve.
## Footnotes
1. Command-line recording via ``ffmpeg -i hw:0,5 -t 30 -o test.wav`` does work, but on-the-fly resampling seems to be broken, either in the ALSA driver or the SOF firmware, and hence real-time communications apps cannot rely on the internal microphone for input.
1. https://marc.info/?l=openbsd-tech&m=160562971904202&w=2
2. Sample ~/.asoundrc that uses one physical device for playback and a different device for capture:
2. Command-line recording via ``ffmpeg -i hw:0,5 -t 30 -o test.wav`` does work, but on-the-fly resampling seems to be broken, either in the ALSA driver or the SOF firmware, and hence real-time communications apps cannot rely on the internal microphone for input.
3. Sample ~/.asoundrc that uses one physical device for playback and a different device for capture:
```
pcm.dmixer {
type dmix
@ -71,5 +75,3 @@ pcm.!default {
slave.pcm "asymed"
}
```
3. https://marc.info/?l=openbsd-tech&m=160562971904202&w=2