jketterl / openwebrx

Open source, multi-user SDR receiver software with a web interface
https://www.openwebrx.de
GNU Affero General Public License v3.0
1.02k stars 146 forks source link

Audio sample rate issue #201

Closed dl9rdz closed 3 years ago

dl9rdz commented 3 years ago

Describe the bug A client side default sampling rate of 32000 Hz causes server side exceptions, and NBFM will not work (even if the client code assumes that this sampling rate is fine for low-quality audio but not for HD audio/WBFM)

To Reproduce Launch a web browser with system audio device using a default audio rate of 32000 Hz

Expected behavior Ideally: A client side behaviour that configures the audio interface to use a working audio sampling rate Semi-ideally: A error message at the client side that tells the user that not only HD audio will not work, but also non-HD audio in NFM mode

Installation method Debian package, development version

Versions OpenWebRX version v0.21.0-dev (from prebuilt debian package)

Log messages

2020-12-25 19:18:24,217 - csdr.csdr - DEBUG - Command = nc -v 127.0.0.1 55019 | csdr shift_addfast_cc --fifo /tmp/openwebrx_pipe_shift_pipe_139739532445848 | csdr fir_decimate_cc 937 0.00016008537886872995 HAMMING | csdr bandpass_fir_fft_cc --fifo /tmp/openwebrx_pipe_bpf_pipe_139739532882160 0.029984000000000004 HAMMING | csdr squelch_and_smeter_cc --fifo /tmp/openwebrx_pipe_squelch_pipe_139739532444560 --outfifo /tmp/openwebrx_pipe_smeter_pipe_139739532444616 5 1 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr fractional_decimator_ff 1.0005961551892617 | csdr deemphasis_nfm_ff 10666 | csdr agc_ff --profile slow --max 3 | csdr convert_f_s16 | csdr encode_ima_adpcm_i16_u8
[...]
deemphasis_nfm_ff: invalid sample rate (this function works only with specific sample rates).

(and after many iterations of restarting this failing chain:)

Exception in thread csdr_watch_thread:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3/dist-packages/csdr/csdr.py", line 819, in watch_thread
    self.restart()
  File "/usr/lib/python3/dist-packages/csdr/csdr.py", line 878, in restart
    self.start()
  File "/usr/lib/python3/dist-packages/csdr/csdr.py", line 765, in start
    self.try_create_pipes(self.pipe_names, command_base)
  File "/usr/lib/python3/dist-packages/csdr/csdr.py", line 719, in try_create_pipes
    self.pipes[pipe_name] = Pipe.create(p, pipe_type, encoding=encoding)
  File "/usr/lib/python3/dist-packages/csdr/pipe.py", line 21, in create
    return WritingPipe(path, encoding=encoding)
  File "/usr/lib/python3/dist-packages/csdr/pipe.py", line 72, in __init__
    super().__init__(path, "w", encoding=encoding)
  File "/usr/lib/python3/dist-packages/csdr/pipe.py", line 31, in __init__
    os.mkfifo(self.path)
FileExistsError: [Errno 17] File exists

2020-12-25 19:26:53,909 - csdr.pipe - WARNING - could not open FIFO /tmp/openwebrx_pipe_shift_pipe_139739533151704
2020-12-25 19:26:53,909 - csdr.pipe - WARNING - could not open FIFO /tmp/openwebrx_pipe_bpf_pipe_139739532286944

Additional context The solution I described here https://groups.io/g/openwebrx/message/2296 works for me.

jketterl commented 3 years ago

ah the old nfm deemphasis bug. this has been a problem for 48kHz for a very long time since 12kHz wasn't supported, and now it's 10.666kHz...

32kHz is an odd sampling rate. I recommend changing the operating system default to something that works better for now. The solution you posted needs a deeper analysis than "works for me", and i'm currently busy with performance optimizations.

dl9rdz commented 3 years ago

Not so easy on MacOS to change OS defaults :) A Mac either works as it does (and thats find most of the time), but if not its more difficult. Anyway, if you are interested in me testing either the suggested solution (trying first a well-defined sample rate and using the default as a fallback) or the reverse (using the default unless it causes a problem, and in that case fall back to a predefined sampling rate such as 44.1k), deploying it on a local SDR and collecting feedback from some users, let me know.

I recently came across a different but possibly related issue: On one computer, OpenWebRX (accessing public servers like yours or kiev or others from repeaterbook) just did not work, nothing happening except the title bar and possibly a background image being shown. On any browser I tried (Firefox, Chrome) same problem. A closer look with a javascript debugger on Firefox shows that it fails with:

Uncaught ReferenceError: targetRate is not defined
    setupResampling http://kiev.extmail.info/compiled/receiver.js:3947
    AudioEngine http://kiev.extmail.info/compiled/receiver.js:3764
    openwebrx_init http://kiev.extmail.info/compiled/receiver.js:1422
    onload http://kiev.extmail.info/:1

I am not yet sure if it is the same issue (in my previous post I observed the message "Your audio card sampling rate ... is not supported" in the OpenWebRX log in the client browser window).

jketterl commented 3 years ago

Well, for a start I would like to investigate the API documentation and see what it has to say about that parameter and the behavior in general.

The targetRate problem seems to be #192 - that has been fixed by now, but if I remember correctly it isn't in the 0.20 releases.

jketterl commented 3 years ago

Alright, after reviewing the documentation, I'm still wondering why this wasn't pinned down right from the start. I couldn't find any indication that the sampleRate option was added recently, and it certainly would have prevented some headaches if it was enabled from the start.

Either way, I pulled your changes, and tried to make it a bit more flexible. I have turned the code to prefer 48kHz since that uses the highest possible sample rate (12kHz) on the demodulators, which influences the available filter bandwidth.

dl9rdz commented 3 years ago

Great, thanks for merging this change! Works fine here also with your extension. I guess we can close the issue then...

jketterl commented 3 years ago

I need to work on this some more, I have noticed some problems on my Linux desktop.

The changes work as expected, the AudioContext is running at a sample rate of 48kHz on my machine. The native rate on my machine seems to be 44.1kHz (or, at least that was the rate that was automatically selected before the changes).

I am assuming that the audio is now being resampled by the browser to match the soundcard, the problem is that it is doing an awful job. I am getting audio dropouts, the buffer fills up within a minute or so, and the actual measured sample rate is closer to 47kHz.

These problems do not exist when running at 44.1kHz. Additionaly, I am assuming that the same problem exists when upsampling from 44.1kHz to 48kHz, so just flipping the "preferred" array around won't help.

I guess it would be a good idea to keep using the native rate again, at least as long as it's within a "known good" list, and only override if necessary.

jwt27 commented 3 years ago

I need to work on this some more, I have noticed some problems on my Linux desktop.

The changes work as expected, the AudioContext is running at a sample rate of 48kHz on my machine. The native rate on my machine seems to be 44.1kHz (or, at least that was the rate that was automatically selected before the changes).

I am assuming that the audio is now being resampled by the browser to match the soundcard, the problem is that it is doing an awful job. I am getting audio dropouts, the buffer fills up within a minute or so, and the actual measured sample rate is closer to 47kHz.

I have the same issue with Vivaldi browser on Windows, native sample rate 96kHz. OWRX detects it as 48k and the output rate won't go above 46ksps. Above commit doesn't resolve this.

On Firefox it correctly detects the native output rate and keeps a stable 96ksps.

jketterl commented 3 years ago

96kHz is not on the "known good" list. can you confirm it's working at that rate? I can add it to the list then.

jwt27 commented 3 years ago

When I add 96k to goodRates it gets better, but still not perfect. Output rate hovering around 94ksps.

jketterl commented 3 years ago

are you running on the audioworklet code (open the log window, it will say either audioworklet or scriptprocessornode api)? there's some other bugs there. if so, you can try force the downgrade to scriptprocessornode by setting useAudioWorklets to false in AudioEngine.js for a test.

jwt27 commented 3 years ago

Says it's using ScriptProcessorNode, same as in Firefox. I think it should support AudioWorklets so I'm not sure why it's not picking that.

I hadn't used OWRX in a while due to hardware failure, so I can't precisely pinpoint when this issue started. I suspect it's in this PR, but it could be a Vivaldi issue too, although it's chromium-based so you'd think other such browsers would have the same issue.

jketterl commented 3 years ago

if you're not on audioworklets, but think you should be, there's probably a very simple answer: you're not using https. (audioworklet requires securecontext)

if you put 96kHz into the goodRates, and the frontend then also picks this rate, it should run the same as before.

i think that my problems with chrome were not present when i did the initial change, so this whole new problem may be caused by a browser update. I'm not completely sure though.

jwt27 commented 3 years ago

Just discovered I did have regular Chrome installed, and the same issue occurs there. Could try setting up a reverse proxy with https and see if the AudioWorklets api makes it better.

jketterl commented 3 years ago

That would be the first such case. From my experience, AudioWorklets only makes it worse.

https is not required for localhost, so if e.g. an ssh tunnel is more convenient to you, that should work.

jwt27 commented 3 years ago

Tried the ssh tunnel, it picks AudioWorklets at 96k now and it works perfectly!

It seems much more stable too, no stuttering when i switch tabs, as is the case on Firefox (which is very annoying when using external decoders)

jketterl commented 3 years ago

yeah that's the whole idea of the worklets... i just seem to have a lot of buffer underruns. there's a big discussion on some chrome bug ticket (don't have the link at hand right now), seems like it would require realtime priority on linux, but that's not available. no idea how the scriptprocessornode worked then.

the https requirement is a big headache for me as well. scriptprocessornode is deprecated, but the audioworklets are no adequate replacement in that aspect. the chrome devs seem to consider the unencrypted web to be deprecated.

either way, adding 96k to the list of supported rates.