openwebrx icon indicating copy to clipboard operation
openwebrx copied to clipboard

High latency

Open dh1tw opened this issue 7 years ago • 4 comments

Hi,

out of curiosity (without having dived into the code), why is the latency so high in Openwebrx? It take between 1-2 seconds after moving the receiving slice until the changes are hearable.

dh1tw avatar Dec 29 '16 12:12 dh1tw

Every stage of signal processing is running in a separate csdr process. IPC between them is implemented using OS pipes. A standalone example is like this:

rtl_sdr -s 240000 -f 89500000 -g 20 - | csdr convert_u8_f | csdr fmdemod_quadri_cf | csdr fractional_decimator_ff 5 | csdr deemphasis_wfm_ff 48000 50e-6 | csdr convert_f_s16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -

Scheduling is done by the OS, which typically means that a block runs until it has no more input, or it is out of its time frame.

The GNU Radio framework has its own scheduler that could be fine tuned in the code for low latency. My approach with csdr takes many problems of a dataflow system to the OS level, which made this project certainly easier to implement, but it is harder to fine tune things like buffer sizes, scheduling, etc. that affects latency. (A similar approach with pipes is used in LuaRadio.)

I've put some effort into making latency lower. Some things helped it, some other things did not: e.g. I've implemented automatic buffer size determination, but it does not make much difference.

The latency could be improved by writing a wrapper in C that would schedule calling the already existing signal processing functions, but that would decrease flexibility (now a new demodulator can be added by just adding a few lines to plugin.py, as demodulators are defined by the command line to run).

ha7ilm avatar Dec 29 '16 18:12 ha7ilm

The other thing that affects latency is the Javascript code at the client side. The client_audio_buffer_size option in config_webrx.py is related to that.

ha7ilm avatar Dec 29 '16 18:12 ha7ilm

Hi András,

thanks for the detailed description. If I understand your answer and your bachelor theses correctly, you create an entire receiver chain for each browser connected via the OpenWebRX interface.

Have you done any benchmarking which part of the receiver chain is consuming how much CPU? I can imagine that the FFT will consume quite some CPU. In particular if you are calculating the FFT up to 4 times over the same data (once per receiver chain).

Maybe It would make sense to perform the FFT just once for all the receivers and then share the FFT results via shared memory or a Publish/Subscribe middleware like ZeroMQ.

dh1tw avatar Jan 08 '17 11:01 dh1tw

FFT (for the original input signal) is calculated only once and shared among all receivers, to draw the waterfall diagram.

There is a filter later in the audio processing chain that uses FFT, but this works on a different signal for each receiver, so the result cannot be shared here.

The latency is not caused by high CPU load, rather from the way the OS schedules the operations.

ha7ilm avatar Jan 08 '17 12:01 ha7ilm