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 volume after mode switch / ADPCM state #203

Closed dl9rdz closed 2 years ago

dl9rdz commented 3 years ago

Describe the bug When starting an OpenWebRX client (e.g., default mode WFM on audio broadcast channel), audio volume is at some level. Changing mode, e.g., to DIG/Packet or NFM, and then back to WFM, the audio has a completely different audio volume level.

This is due to the server starting a new ADPCM stream, assuming initial state, but the client side is apparently not resetting the ADPCM decoder. In case the codec is at a higher step index, this results in a significant volume amplification after decompression.

(The bug appears only if adpcm audio compression is enable in the config file)

Expected behavior Back in WFM, same audio volume as before the mode switch. Whenever the server starts a new ADPCM stream, the client should reset the ADPCM decoder.

(Additional I think the default volume in WFM mode is too low. )

Installation method Debian package

Versions 0.20.1 and 0.21.0~559.gbp57e592

jketterl commented 3 years ago

I am aware of this bug, however it is not as easy to fix as it may first seem. The problem is that audio is continuously streamed, and the client is not aware of when exactly the codec is reset on the server side. Resetting the codec when a new mode is selected therefore does not work.

I have been thinking of sending the necessary adpcm values along with the compressed audio. It has to be inline so that the synchronization is ensured. I don't intend to implement this into the current piping chains any more, so this will probably remain for some time.

dl9rdz commented 3 years ago

Sure, your decision.

I have added two simple solutions to my fork because I don't like this bug... Just either send an empty audio frame (https://github.com/dl9rdz/openwebrx/commit/d54b91068f47d4e90f2b3c93f045120899fea84c) or a dedicated command (https://github.com/dl9rdz/openwebrx/commit/0b1fb694cce763855876eb547e96ced2509fe773) at the beginning of the new audio stream. The second version eliminates the need of an additional comparison per audio frame, which the first has as disadvantage. Feel free to merge (or ignore...)

jketterl commented 3 years ago

Good idea, but unfortunately, from what I can see, this does not cover the one use case where this is most problematic: When you're visiting a new receiver and the audio startup is delayed by the browsers' autoplay policy.

If you ask me, the best solution to this problem is to turn the audio stream into more of a stream, meaning a stream of data where the client can initiate correct decoding of audio data at any given point, or at least within certain intervals that are close enough to not be noticed. ADPCM does not work very well for that purpose, but I think it is fixable at the cost of a few extra bytes. Another codec might work, too, but so far I haven't come across any that works as CPU-efficient on the server side.

dl9rdz commented 3 years ago

Ok, good point, thanks for the explanation. I was not aware that this is also an issue upon startup with delayed autoplay. But that would also not be that difficult to fix (https://github.com/dl9rdz/openwebrx/commit/fa7969591377ba80dfd046da9eecfebfe138eb38)... Possibly there are more issues I am not aware of.

Other solutions might be better, but significantly more difficult to implement.

jketterl commented 3 years ago

I just merged the big csdr rework into develop, including a few changes to the adpcm behavior: there is now some additional in-band state being sent to the client, and the rework now keeps the adpcm encoder on the server side running for as long as the connection is alive, so there should be no artifacts when switching modes any more. in my testing, i'm pretty happy with the results.

jketterl commented 2 years ago

in stable with the release of 1.2.0