Closed Ramblurr closed 1 year ago
PulseAudio backend provides only sink, and backend dispatcher fails to select sox backend when trying to use PulseAudio source.
As noted, temporary workaround is to use ALSA emulation using -i alsa://pulse
(i.e. use ALSA backend with "pulse" ALSA device which internally connects to PulseAudio daemon).
A proper fix is to do one of the following:
I can confirm this bug is still present in 0.2.2 (e575eaa126). While using the alsa://pulse
backend works, it seems to only be able to use Pulse's "default source" (e.g. a microphone), but I would like to capture desktop audio instead. Is there a workaround available as well? Do I need to create some kind of loopback Pulse device and make it the default source?
@zopieux Hi,
You can try to set PULSE_SOURCE
environment variable. Hopefully, ALSA pulse
device will use it.
If not, I think after starting roc-send you can just open pavucontrol, open "recording" tab and connect roc-send to needed source:
You you can do the same using pactl move-source-output
.
When you restart roc-send, pulseaudio should remember your last choice, however this functionality sometimes does not always behave as you can expect.
I've added pulseaudio source support to develop
branch. It will be part of next release.
Example:
roc-send -vv -s rtp+rs8m://lo:10001 -r rs8m://lo:10002 -i pulse://<source_name>
You're welcome to test it :)
Tested with the recent roc-droid demo app:
$ ./build/src/x86_64-unknown-linux-gnu/gcc-12.2.0-release/roc-send -vv -s rtp+rs8m://192.168.1.139:10001 -r rs8m://192.168.1.139:10002 -i pulse://garbage
21:52:32.714 [5161] [err] roc_sndio: backend dispatcher: failed to open source: type=device driver=pulse path=garbage
$ ./build/src/x86_64-unknown-linux-gnu/gcc-12.2.0-release/roc-send -vv -s rtp+rs8m://192.168.1.139:10001 -r rs8m://192.168.1.139:10002 -i pulse://alsa_output.usb-RODE_Microphones_RODE_AI-1_C164EE29-00.analog-stereo.monitor
21:58:25.548 [5520] [inf] roc_sndio: pulseaudio source: opening stream: device=alsa_output.usb-RODE_Microphones_RODE_AI-1_C164EE29-00.analog-stereo.monitor n_channels=2 sample_rate=48000
21:58:25.566 [5517] [dbg] roc_peer: sender peer: initializing
21:58:25.566 [5520] [dbg] roc_sndio: pulseaudio source: stream_latency=2
…
21:58:25.566 [5517] [dbg] roc_fec: openfec encoder: initializing: codec=rs m=8
21:58:25.566 [5517] [dbg] roc_fec: fec writer: update block size: cur_sbl=0 cur_rbl=0 new_sbl=20 new_rbl=10
21:58:25.566 [5517] [dbg] roc_audio: packetizer: initializing: n_channels=2 samples_per_packet=309
21:58:25.566 [5517] [dbg] roc_audio: speex resampler: initializing: quality=5 frame_size=672 channels_num=2
…
22:00:07.545 [5517] [dbg] roc_netio: udp sender: <udpsend 0x1508f8000b70 bind=0.0.0.0:60527>: total=21402 nb=21402 nb_ratio=1.00000
22:00:16.173 [5520] [dbg] roc_sndio: pulseaudio source: stream_latency=92162
22:00:26.679 [5520] [dbg] roc_sndio: pulseaudio source: stream_latency=88066
22:00:27.684 [5517] [dbg] roc_audio: speex resampler: ratio_num=50000 ratio_den=45937 in_rate=48000 out_rate=44100 in_latency=44 out_latency=40
Works like a charm! Awesome, thanks for the quick turnaround.
I do experience a whopping 3s+ of lag between the realtime speaker output (from the sending workstation) to the receiver, though, compared to sub-500ms I get using the alsa driver, with the exact same configuration. Is this expected?
Forgot to mention, the pulse source selection works just as well, I can easily select my microphone or the stereo "monitor" (loopback).
Thanks for testing and report!
The high latency is not expected, it should be possible to set pulseaudio part of the latency from ~15s to ~60ms depending on device, and 60ms is expected to be default (since it works well for most devices).
I was able to reproduce it, looking into it.
@zopieux I've pushed a fix for the latency to develop branch (cafa5a49327763a4b7a3ab9e45e2a8fb22dbc7ec). Pulseaudio part of the latency by default is about 60ms now.
I also added --io-latency
option to roc-send (d65cfbfa5d5ad853f0c07b1010137cb66304d610), which allows to set that part of the latency manually. In my experience, on many devices you can safely set it to 20-30 ms, and sometimes even lower. (but usually you need rtkit for that).
Indeed, greatly reduced latency with develop
HEAD, and I could reduce it further using --io-latency
. Awesome thanks! Somehow it's still not going below 100ms on localhost but maybe I'm handling this wrong. I suppose we can consider this issue fixed!
Thanks for checking!
Somehow it's still not going below 100ms on localhost but maybe I'm handling this wrong.
If you mean overall latency from sender input to receiver output, you can:
--io-latency
on sender, as you're already doing, to reduce PulseAudio recording latency (default 60ms)--io-latency
on receiver too, to reduce PulseAudio playback latency (default 60ms)--sess-latency
on receiver, to reduce session pipeline latency (default 200ms)--nbsrc
(number of source packets in block, default 20)--nbrpr
(number of repair/redundancy packets in block, default 10)--packet-length
(duration of single packet; default 7ms)20 * 7ms = 140ms
minimum allowed session latency; you can reduce --nbsrc
and/or --packet-length
to reduce minimum allowed session latency; meaningful values for --nbrpr
is something in range [nbsrc/2; nbsrc]
More about latency: https://github.com/roc-streaming/roc-toolkit/discussions/255 More about FEC: https://roc-streaming.org/toolkit/docs/internals/fec.html
I also plan to add adaptive latency algorithm, so that all these parameters will be adjusting automatically on fly, depending on network characteristics. Who knows when I'll have time for it...
@zopieux @Ramblurr BTW what is your use-case for using pulseaudio input device? Just curious.
As I mentioned in my previous comment, mostly being able to roc-send
my puselaudio (well, pipewire really) output stereo mix to other devices, a bit like snapcast.
Thanks for the nice comment about all the parameters, I'd recommend putting the discussion page you wrote in the docs, it's quite helpful and would become more discoverable.
Edit: indeed, setting the receiver's --sess-latency
was definitely what helped most getting in the sub-20ms realm. Thanks!
I see, thanks. I thought you're also streaming from mic.
BTW you can also use pipewire modules for roc.
I'd recommend putting the discussion page you wrote in the docs, it's quite helpful and would become more discoverable.
Definitely, it's on my TODO.
I'm closing this. @Ramblurr feel free to reopen if needed!
As discussed in matrix..