Open LightningStalker opened 3 years ago
Hi, thanks a lot for the report. Sounds like a deadlock, could be a little bug in the thread synchronization code. Slowrx hasn't been in development for many years and I kind of dread going back into the C code :), so at this point I can only suggest alternative software. I wonder if QSSTV is still state-of-the art?
QSSTV development has slowed. QSSTV gets a lot of false positives resulting in static images. It also misses many images even when signal conditions are good enough to decode them. Most of the images it does decode end up getting cut off at the top or bottom. At least it has TX capability when it works. Aside from the odd freezing and sometimes some horizontal rolling and maybe lack of support of all the protocols QSSTV supports, I have found slowrx to be much better at receiving.
Glad to hear it's still useful! I'll see if I could reproduce the hang.
I managed to reproduce a hang reliably if the FSK ID synchronisation fails.
In my fork, I'm re-working the mathematics used to handle other sample rates (since not that many modern sound cards natively support 44.1kHz, 48kHz or harmonics thereof are more common).
The fsk.c
has a while (true)
loop, in which we break
if the TestPtr
variable exceeds 200, if the AsciiByte
is observed to contain a byte less than 0x0d
, or if BytePtr
exceeds 9.
Something like the following will probably fix it (this was taken from my branch in #12):
commit 300c5e8058db3638eb5878d580202caae0380ccd
Author: Stuart Longland <me@vk4msl.com>
Date: Fri Jul 12 12:14:08 2024 +1000
fsk: Give up after 5 seconds
If FSK sync never happens, we can be stuck trying to sync to a FSK ID
that never synchronises, it's an infinite loop.
Make the infinite loop finite!
diff --git a/fsk.c b/fsk.c
index 0cb07b0..38a1e05 100644
--- a/fsk.c
+++ b/fsk.c
@@ -25,6 +25,12 @@
*/
#define FSK_5M5S_SAMPLES (FSK_11MS_SAMPLES/2)
+/*
+ * Set a limit of 5 seconds for a FSK. That allows for ~227 bits of FSK
+ * data or approximately 34 characters for an ID. That should be plenty!
+ */
+#define FSK_TIMEOUT PCM_MS_FRAMES(5000)
+
/*
* Decode FSK ID
*
@@ -40,6 +46,8 @@ void GetFSK (char* const dest, uint8_t dest_sz) {
double HiPow,LoPow,Hann[FSK_11MS_SAMPLES];
_Bool InSync = false;
+ uint32_t remain = FSK_TIMEOUT;
+
// Bit-reversion lookup table
static const uint8_t BitRev[] = {
0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
@@ -58,13 +66,21 @@ void GetFSK (char* const dest, uint8_t dest_sz) {
Hann[i] = 0.5 * (1 - cos( 2 * M_PI * i / ((double)(FSK_11MS_SAMPLES-1)) ) );
}
- while ( true ) {
+ while ( remain > 0 ) {
+ // Figure out how much data to read? If not in sync, use 5.5ms steps.
+ uint32_t read_sz = (InSync ? FSK_11MS_SAMPLES: FSK_5M5S_SAMPLES);
// Read data from DSP: half the number of samples if not in sync.
- readPcm(InSync ? FSK_11MS_SAMPLES: FSK_5M5S_SAMPLES);
+ readPcm(read_sz);
+
+ if (remain > read_sz) {
+ remain -= read_sz;
+ } else {
+ remain = 0;
+ }
if (pcm.WindowPtr < (int32_t)FSK_5M5S_SAMPLES) {
- pcm.WindowPtr += (InSync ? FSK_11MS_SAMPLES: FSK_5M5S_SAMPLES);
+ pcm.WindowPtr += read_sz;
continue;
}
@@ -73,7 +89,7 @@ void GetFSK (char* const dest, uint8_t dest_sz) {
fft.in[i] = pcm.Buffer[pcm.WindowPtr+i- FSK_5M5S_SAMPLES] * Hann[i];
}
- pcm.WindowPtr += (InSync ? FSK_11MS_SAMPLES : FSK_5M5S_SAMPLES);
+ pcm.WindowPtr += read_sz;
// FFT of last 22 ms
fftw_execute(fft.Plan2048);
@@ -124,7 +140,6 @@ void GetFSK (char* const dest, uint8_t dest_sz) {
BytePtr ++;
}
}
-
}
if (BytePtr < dest_sz) {
PCM_MS_FRAMES(5000)
is a macro that computes the number of frames from the sample rate, which I exposed in the pcm
object; but in the main-line source code, you could substitute with 5*44100
.
After running for a few days, slowrx will suddenly freeze saying "Receiving FSK ID...". The time elapsed before freeezing appears to be highly variable. It doesn't freeze completely but the receiving and decoding images freezes up and the program must be restarted.