QiwiQ a KiwiSDR client for Android: looking for feedback, testers and comments
Hi all,
I’ve been programming a mobile client for the KiwiSDR protocol, and I finally have something worth sharing: QiwiQ.
It’s a dark-theme, portrait-mode KiwiSDR app for Android.
Instead of running in the browser, my app processes the KiwiSDR stream locally on your phone.
With no official KiwiSDR protocol documentation available, I relied on example Python code and reverse-engineered browser clients to piece together how the protocol operates.
Features:
• Connects to the public shared KiwiSDR network of servers.
• Built-in waterfall FFT display with zoom and pan.
• Direct band buttons for fast hopping between ham/shortwave bands.
• Frequency logging and memory list.
• Audio options: noise reduction, compressor, ADPCM compression.
• Gestures for tuning: swipe digits, waterfall
• Knobs for volume, squelch and filters.
• Theme colors for the LCD display
It’s still early days, but it’s working pretty well, I guess ;-).
Download my QiwiQ.apk at: https://vanbarel.eu.org/tools/qiwiq/
Side-load on Android, feedback/bugs very welcome!
Comments
There are different LCD color themes:
Nice job! Are you using Android's WebView component to run JavaScript code?
Is there a way to enter a kiwi URL directly rather than selecting from the list? I'd like to try to access my own kiwi which is currently not public.
BTW: Nice and professionally looking work (app & website)!
In support of your efforts I bought a license. But I also had to order a newer Android tablet because my extremely old Lenovo tablet running Android Go 8.1 (not upgradable, lol) only outputs audio for about 10 seconds before stopping. I'm certain this is a performance issue of the ancient tablet. So don't worry about it. I'll have more feedback for you next week.
Hi, @XPloRR I think there is a little problem with CW. Usually, the displayed frequency is supposed to be the transmitter's one. So you have to offset the Kiwi up or down with the value of the wanted beat tone, and set the audio filter accordingly.
Nice job, indeed !
Talking about audio stop, I have not been able to prevent the lock screen coming after inactivity timout to stop the audio stream on my last Android (15), on both QiwiQ and the usual browser Kiwi interface. This doesn't occur on an extremely old (also) Android. Probably a parameter to set somewhere...
I think I did what I needed to, but it's not working right for me?
On my own KiwiSDR, it never starts the audio or waterfall when I try and connect.
I tried another nearby Kiwi, and the audio and waterfall load on that one, but the audio is continuously chopping in and out, almost like a clicking every half second.
https://youtube.com/shorts/5wn0nqdl4CE?feature=share
Screen recorded what I'm hearing, and the video sound is accurate. I get choppy sound, switch to my own Kiwi, (not on this local network), and then switch to another...
-Nate
N8BTR
@Nate_R What kind of Android device? Could it be underpowered?
Samsung Galaxy A36 5G phone. About a month old.
5G wifi on fiber..
So the device itself shouldn't be. Tried turning off the waterfall and no dice.
I've got a Sam Galaxy Tab A9 coming tomorrow or Monday. So we'll see how that does.
cool!!
Trying v1.38 now with the Tab A9 running Android 15.
Turns out the "audio stops after 10 seconds" problem seems specific to the connected Kiwi. A lot of Kiwi have this problem. Some stop after a longer interval. Some (notably KPH) run fine. Might be how the code reacts to the underrun condition when the Kiwi/network can't momentarily keep up with the audio buffering?
When I first started using the app the waterfall worked. Now it only says "DEMO" no matter what I do. The "WF" button won't stay lit (button outlined in red) for more than a few seconds. I tried changing the zoom, band presets, color (COL button/slider) etc.
IQ mode is not being processed at the correct rate. Easy to hear by listening to any voice signal. The voice is slow and pitch low. Also there is clicking which probably means a buffer is being over/underrun when read. Remember that in IQ mode there are twice as many samples per audio packet compared to the uncompressed mono modes (AM, SSB, ...) So 1024 16-bit I,Q samples (512 I&Q sample pairs) compared to 512 16-bit samples total for uncompressed mono. So each IQ audio packet is twice as large. See comments in web/openwebrx/audio.js
I understand the "WF button doesn't work" problem now. It will get fixed in the next version when a separate connection isn't opened when the WF is in use. It occurs now because a lot of Kiwi have this option set on the admin control tab: "Prevent multiple connections from the same IP address". So the second connection (WF) fails.
Just now saw all these comments (i was talking in another thread with jks, will use this one now ;-))
I am currently fixing a lot of problems, like the 2 connections will be 1 for all (wf, snd and ext).
Fixing other problems like enter in the search screen.
Also spend alot of work making the audio packets engine faster (should now be 35% faster).
There is a bit more latency, but fewer packets should be dropped.
Also reacting/closing sockets cleanly when connection cannot be made with server.
Compiling now version 1.39. will test and release soon.
Also working on DRM (can already decode using ext socket, but cannot assemble the audio, sounds like half the frequency, it seems the audio format is different in DRM mode).
Will try to answer other questions asap, note that I am a newbie as far as shortwave is concerned, so I probably made mistakes interpreting what I read the last weeks (only been reading for 4 weeks about the ham/shortwave/amateur radio stuff)
...
I put some printfs into the server code and looked more closely (I can't always remember exactly how this stuff works). Here's what you should be seeing for the different modes:
mono: hdr 10 data 1024
mono: hdr 10 data 1280
stereo: hdr 20 data 2048
stereo: hdr 20 data 4096
"Stereo" happens for the modes IQ, DRM, SAS and QAM. "hdr" is the size of the header at the beginning of the audio packet. Note it's twice as large for stereo packets to make room for a possible GPS timestamp.
These sizes apply to silent periods as well. Silence will always occupy a full packet. So if you test for the 00/01 data for a certain amount at the beginning it's very likely the packet is actual silence. Those values are very unlikely to appear in actual audio. But also the silent packets don't occur very often or for that long. So I don't know if there is any advantage to treating them any differently from regular audio.
The 1024/1280, 2048/4096 variation happens because of upstream buffering issues. So sometimes more audio data has to be output to prevent the audio buffering from filling up. Hopefully your networking library will allow you to determine the actual data length per packet read.
@XPloRR Do you write iOS apps as well? We've had many requests for a comprehensive Kiwi iOS app over the years. But no success in getting anyone to do it who would be remunerated by selling licenses on the app store (i.e. we have no money to fund development ourselves).
Related: I mentioned previously that I bought a license. But currently there is no feedback when you enter the license key. So unclear if it's been accepted or not. Perhaps the linkage with the licensing backend isn't setup yet.
I am sorry I do not write for iOS.
If you bought a coffee and entered the key you received, you will not get the fading DEMO text over the waterfall and the waterfall smoothly fading out after 20 minutes.
Maybe I should add an indication that the serial is accepted. Will put it on my todo list.
Ps. I think I found a bug in kiwi, which only seems to happen on mobile: when I set the waterfall speed to 0 (to halt it), it influences the SND packets, some packets get lost every few seconds only when using ADPCM. I could avoid the bug by keeping the waterfall busy by sending it more often a keepalive. It took me several hours to find the correlation. I was looking in my audioprocessor, but the problem was not there.
Is there an flag in the header indicating it is an IQ packet?
Is there a flag in the header indicating it is an IQ packet?
Yes.
#define SND_FLAG_STEREO 0x08
See rx/rx_sound.h::snd_pkt_real_t/snd_pkt_iq_t for the header formal. rx/rx_sound.cpp for the "#define SND_FLAG" values of the "u1_t flags" field.
I finally managed to decode DRM, but the audio is distorted.
Is decoded DRM data sent in the same format as IQ (which I can interpret correctly)?
Is it sent in stereo or mono?
What is the sample rate?
what do you mean by:
mono: hdr 10 data 1024
mono: hdr 10 data 1280
stereo: hdr 20 data 2048
stereo: hdr 20 data 4096
does 10 mean the 10th byte after the SND header, which is also 10, so the 20th byte of the total packet?
so 20 means the 30th byte of the total packet?
Ps. I think I found a bug in kiwi...
Let me try and replicate the problem you see using Kiwirecorder.
Sorry, I meant for IQ mode the
union { u1[]/s2[] }
part ofsnd_pkt_iq_t
will be 2048 or 4096 bytes long at random. And the header size ofsnd_pkt_iq_t.h
will always be a constant 20 bytes (see rx/rx_sound.h). Yes, for mono modes the data starts 10 bytes into the packet (directly after the header). And for IQ modes 20 bytes into the packet (snd_pkt_iq_t.h
is larger thansnd_pkt_real_t.h
).DRM is always sent in the same way as IQ mode. Same sizes and sample rate of 12 kHz (let's not worry about Kiwi configured for 3-channel mode for the moment). Always in stereo.
Yeah, so there's something wrong when you set the WF speed to zero (off). I'm having problems with Kiwirecorder when I do this although not the symptoms you describe. The WF connection simply gets closed after 10 seconds. The audio doesn't seem to be affected. Interestingly, this problem does not occur when reverting to the older version of the little web server the Kiwi server code uses (we recently updated that code).
For now I think the simplest thing to do is to change the WF speed to the 1 Hz setting (speed=1) when you want the WF switched off and just ignore the small amount of data returned. This will allow the keep alive mechanism to continuing working.
In a few days I'm going on vacation for the rest of the month. So I'll have limited time to look at things while I'm gone.
I checked, but IQ packets seem to be in mono (real+imaginary part).
I did some raw testing and I suspect that DRM is not presented in IQ format as a real+imaginary value, but as a pcm encoded stereo signal (different from IQ).
So I suspect:
IQ format is double size (real+imaginary values).
DRM is pcm stereo (double sized) Left+Right presented after decoding as pcm L + R values.
So the SND_FLAG_STEREO = 0x0008 is not a stereo/mono flag but a way of telling that the following data starts 10 bytes further and has 2 integers per sample, not 1 as in AM, SSB, ...
Can you confirm?