DRM decoding at the client or at the server side?
I am working on a KiwiSDR client.
But it is not clear how to interprete DRM audio.
My question: is decoding done at the Kiwi server side or does the client have to decode the binary data?
If so, are there coding examples how to decode the data into audio?
Comments
Server side, as the DRM code came from the Dream C++ project. The code in rx/rx_sound.cpp shows DRM sound output is handled separately (because the source of the audio is special for DRM). But is essentially just like IQ mode so that any potential stereo DRM output can be heard. As with IQ mode there is never any compression applied. So process it exactly as you would IQ mode on the client and you should be good.
Oh, but I forgot to add: Even though there is a DRM "mode" button DRM is really a Kiwi extension. Which means to run it you need to open the third "EXT" web socket stream and send some commands to get the extension running. So that is a complication you wouldn't have seen previously.
Doing so will allow you to send the command that occurs when the DRM "test" buttons are pressed. This will make things easier as DRM signals are sometimes difficult to find depending on schedule.
Thank you.
I see that at start, the client opens 2 sockets to the server: a SND socket for the audio and an F socket for the waterfall. When the user switches to DRM, an EXT socket is opened and packets are read after sending a few commands like "SET auth..." and "SET ext_switch_to_client ..." and "SET lock_set" ... and then packets are received.
Are these packets always in adpcm?
Can I keep the EXT socket open when user switches back to f.i. AM without being banned by the server by keeping the socket open?
The EXT web socket is opened by the client when the extension Javascript code in the browser is loaded and starts. And then kind of hangs around in an idle start waiting for the same (or a new) extension to start. So yes, don't explicitly close the EXT socket from the client side. It should stay open, even without you sending keepalive's on it.
There is no adpcm compression on the audio socket for DRM, or on the EXT socket ever.
You should be able to ignore all the UI data that will be coming back over the EXT socket from the DRM server-side extension code (unless you want to do something with it).
I guess there's an implicit question: if you ever intend to support any of the Kiwi extensions/decoders UI output in some form. Maybe in some simplistic form if it makes sense. And only for the popular ones e.g. FT8, SSTV, FAX etc.
Thank you, but I still do not understand how to interpret the audio data when in DRM mode. Is the audio data also sent over the SND socket when in DRM mode? Problem is that when I tune into a DRM station, I only get ticking noises from the SND socket. So I wonder is the audio always in adpcm or is it in another encoding than AM, SSB etc? Possibly my adpcm decoder is not correct. It does work in AM, SSB etc, but not in DRM mode.
First, change the SND socket to IQ mode. This will disable adpcm mode automatically if it was in effect for any previous mode (AM, SSB etc). On the SND socket you will hear the actual DRM signal's digital-data sound until you send the proper commands on the EXT socket to start the DRM decoder. Then the SND socket should go quiet until the point at which the DRM algorithm locks onto the signal and begins decoding the DRM audio.
So there is now IQ DRM-signal data going into the DRM decoder but DRM stereo being output on the SND socket in what looks like IQ mode (2-channel stereo essentially).
It may help to run the actual DRM extension on the Kiwi and see how it behaves. After it is running, using one of the test recordings, click the "Monitor IQ" button. This changes the SND socket data from the output of the DRM decoder to the input to the DRM decoder, which of course is the digital-DRM data (buzzsaw-sounding OFDM signal). Both of these signals are in IQ mode (2-channel stereo) with no adpcm compression.
You can ignore this below, because I already found the reason (the id's in the ws//<url> should be the same for all sockets)
Thank you.
I try to implement DRM decoding following your instructions.
When the user selects DRM mode, I send this to the SND socket (example):
SET mod=drm low_cut=-4500 high_cut=4500 freq=15000.00
I open an EXT socket to the DRM decoder:
ws://<server>:<port>/ws/kiwi/1756999905061/EXT
However when I send the first command: SET auth t=kiwi p=#
I get no response from that socket, it seems "dead" or refuses to answer.
Is there a certain handshake? Or does my client have no access to the decoder socket?
Yes, those id's are really a unique timestamp that needs to be in common between all the web sockets (SND, W/F, EXT). It's part of how the server can tell which web sockets belong to which rx channel connections as the web sockets are being individually connected. It's not enough to just look at e.g. source IP address because that may not be unique between channel connections (for example if the proxy service is being used).
Is the DRM extension supposed to work in 3 channel mode now? I recall it wasn't originally available to be opened when set to 3 channel mode config but some time back it became available. I have never been able to get it to decode when in 3 channel mode though. Not many stations coming in with DRM in North America, so it could just be poor signals each time I happened to try.
Another question when using DRM:
Before the DRM decoder locks, the SND socket keeps sending audio packets with lots of 00 and 01...
Is there a flag in the header that I could test on to check if the audio packet has valid information?
If so I can test and throw those packets away.
I could also check on audio packets containing 00 01... but this is not so elegant.
Also: are the decode samples presented in the same format as when listening to AM?
Same sample rate? 12000 samples/second? mono?
I can hear some audio in DRM but it is like slowed down (a normal voice is heard as a bass voice).
@nitroengine Yes, it should work in 3ch mode. But I haven't tried it in quite a while. There is a sample rate conversion at the DRM input & output that has to be made.
@XPloRR The audio packets full of 00/01 occur when silence is being sent because the DRM has no decoded output available (yet). The low-value 01 is sent (instead of 00) because it prevents triggering some Firefox workaround code. A long time ago FF had this problem where its audio would go silent for no reason. So the audio.js code detected that condition and restarted the audio stream to recover. But that implied that intentionally sending silence couldn't contain all zeros. So the value 01 was used.
There are two problems with adding a flag bit to say this packet is a silent packet. First, we are out of flag bits. They are all in use. So there would have to be an expansion of the header. Second is the backward compatibility problem. Plenty of Kiwi never update to the latest version for whatever reason. So you couldn't rely on any new silence flag bit anyway.
Sending silence has the same sample rate and mono/stereo characteristics as the current audio mode. It just has the 00/01 values -- that's all. Silent mode can occur in any mode because it is used in more than the DRM case. It can happen when a Kiwi has masked frequencies and a user tunes into as masked area.
I can hear some audio in DRM but it is like slowed down (a normal voice is heard as a bass voice).
I comment on this in the other thread.