Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPUS codec instead ADPCM #220

Open
zygmund2000 opened this issue Mar 1, 2021 · 12 comments
Open

OPUS codec instead ADPCM #220

zygmund2000 opened this issue Mar 1, 2021 · 12 comments
Labels

Comments

@zygmund2000
Copy link

Hi,

My suggestion is to replace ADPCM codec to OPUS, I think it is better for streaming audio and in future can easily allow to provide stereo audio for receiving eg. FM ord DAB+.

@zygmund2000 zygmund2000 added the feature feature requests label Mar 1, 2021
@jketterl
Copy link
Owner

jketterl commented Mar 1, 2021

there's currently neither stereo FM nor DAB support in OpenWebRX, so I don't really see any reason to do this now. How is the CPU consumption on the encoding side in comparison with ADPCM?

@zygmund2000
Copy link
Author

Opus encoder is light and designed for streaming various audio content, I think you know that, but if you don't see reasons to implement so maybe can you give some hint how do that?

@jketterl
Copy link
Owner

Doesn't really answer my question. I wanted to know how it compares to ADPCM since that achieves a 1:4 reduction with very little CPU on the server. Client CPU isn't that much of my concern.

Hints:

  • Don't replace existing codec. There's already a switch to toggle ADPCM, expand that with a third option.
  • Implementation of the encoder needs to go into the csdr pipelines. The code there is a mess and I don't really intend to clean it up since I have already started a new pipeline implementation. You'll need a command-line tool that can accept audio input on STDIN, and will output its encoded audio on STDOUT.
  • Client implementation needs to hook into the AudioEngine. May be a little tricky if you want to engage the browser.
  • Web configuration needs to be taken into account, too.
  • If this should be optional, integrate with the feature detection.
  • Stick around and be prepared to maintain the implementation, otherwise it will be pretty short-lived.

@zygmund2000
Copy link
Author

I don't know how to answer your question about performacne at servers side, I can't compare it right now.
I know how to put any encoder into pipelilne chain (audio data are ancoding) but don't how setup it to decode it at client side, I tried view all files and understand it but for me is too complicated yet

@jketterl
Copy link
Owner

That makes two of us then. I don't know exactly how the client integration would look like either, I have never worked with browser audio codecs. The ADPCM implementation is custom stuff that doesn't follow the official API.

@voice06
Copy link

voice06 commented Jul 27, 2021

I'd like to see this at least in terms of reducing bandwidth consumption. Right now with ADPCM according to OpenWebRX its taking 177kbps for the audio stream, could probably get the same audio quality in a 56kbps opus stream.

Not a great 1 to 1 comparison to this app but if I pass nrsc5 through to ffmpeg for ogg opus encoding ffmpeg doesn't exceed 2% CPU, nrsc5 is the cpu intensive end at 6-7% cpu. ffmpeg command: /usr/bin/ffmpeg -loglevel quiet -i - -c:a libopus -b:a 56k -f ogg -

If I swap out ffmpeg for opusenc with the following settings: opusenc --bitrate 56 --raw - - I don't see opusenc exceeding 1.3% cpu

@jketterl
Copy link
Owner

jketterl commented Jun 18, 2022

I have been playing with this a bit today. As expected, implementing an encoder on the server end was easy. Decoding the audio data on the client side however turns out to be troublesome. The data cannot be decoded by decodeAudioData() in Chrome or Firefox, presumably because that expects a surrounding container format. Also, as far as I understand, this method is intended to decoded a complete file, and not a chunked stream.

There is a Javascript/WASM/emscripten implementation (or is it more of a port?) for the opus codec, but it has two problems: It is a big download, and it doesn't declare a license.

If anybody wants to have a go at this, my work is available in the opus branches of csdr, pycsdr and this repository.

@jketterl jketterl added idea and removed feature feature requests labels Jun 18, 2022
@jketterl
Copy link
Owner

update: the WebCodecs API may be the way to go. i have chunky audio, not good enough, looking for mistakes i made. and i probably broke the playback for adpcm / uncompressed...

sample rates are a problem, opus only supports selected rates... on the client side, the decoder does its own upsampling, which doesn't fit the current setup...

@jketterl
Copy link
Owner

I'm not necessarily impressed with the results right now. My personal impression is that the audio quality of ADPCM is superior at the same effective network bandwidth (48kbit). I will need to experiment some more with different modulation types.

The main problem right now is that the client decoder seems to crash for unknown reasons, and it seems like this is related to the amount of noise present on the signal. Listening to weak AM or SSB stations is therefor strongly affected by this, and since the decoder needs to be reset everytime, this also leads to a reset of the decoder state. The results are "glitchy" dropouts...

Other problems: The audio rate after the decoder on my system is always 48kHz, even when the data sent to the encoder is 12kHz. I don't really understand the reasoning behind this since the sample rate of the audio context is 44.1kHz, meaning that additional resampling would need to be implemented. I have reconfigured my soundcard to 48kHz to make it work, but there's a number of questions related to this.

Undersampling the encoder seems to lead to weird glitches, which suggests that the encoder does some internal timing to determine lost samples, so the encoder must be used at the fixed sample rates available on the codec. Also, the internal timekeeping may become confused if pipeline data is delayed during times of high load. I have not found documentation related to this, so not sure if it can be disabled.

@jketterl
Copy link
Owner

Browser support for the WebCodecs API is also lacking... Most notably, Firefox does not seem to support it at all right now...

@jketterl
Copy link
Owner

jketterl commented Jun 18, 2022

Another setback (yep they keep coming): Presumably thanks once again to the secure web advocates, the WebCodecs API is only available on https encrypted websites. Yay! This makes so much sense! /s

@jketterl
Copy link
Owner

Tried this on a number of signals today. Anything that's analog causes client decoder errors, digital signals seem to be unaffected surprisingly. Unfortunately, the error is pretty generic, it only says "receiver.js:3076 DOMException: Decoding error." so I have very little chance to work out what's actually wrong.

Keeping all the other problems in mind, I can only conclude that this is simply not viable at this point in time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants