[gsm] Make LCR work with current Osmocom-BB.
[lcr.git] / ss5_decode.c
index 541f6be..35e2664 100644 (file)
@@ -18,8 +18,9 @@
 
 #define NCOEFF         8       /* number of frequencies to be analyzed */
 
-#define MIN_DB         0.01995262 /* -17 db */
-#define DIFF_DB                0.31622777 /*  -5 db */
+#define TONE_MIN_DB    0.01995262 /* -17 db */
+#define TONE_DIFF_DB   0.2 // 0.31622777 /*  -5 db */
+#define NOISE_MIN_DB   (TONE_MIN_DB / 2) /* noise must be higher than the minimum of two tones */
 #define SNR            1.3     /* noise may not exceed signal by that factor */
 
 /* For DTMF recognition:
@@ -56,7 +57,7 @@ char ss5_decode(unsigned char *data, int len)
        signed short buf[len];
        signed long sk, sk1, sk2, low, high;
        int k, n, i;
-       int f1 = 0, f2 = 0, f3 = 0;
+       int f1 = 0, f2 = 0;
        double result[NCOEFF], power, noise, snr;
        signed long long cos2pik_;
        char digit = ' ';
@@ -65,6 +66,22 @@ char ss5_decode(unsigned char *data, int len)
        for (i = 0; i < len; i++)
                buf[i] = audio_law_to_s32[*data++];
 
+       /* now we do noise level calculation */
+       low = 32767;
+       high = -32768;
+       for (n = 0; n < len; n++) {
+               sk = buf[n];
+               if (sk < low)
+                       low = sk;
+               if (sk > high)
+                       high = sk;
+       }
+       noise = ((double)(high-low) / 65536.0);
+
+       /* check for minimum noise, or tone detection will not be necessary */
+       if (noise < NOISE_MIN_DB)
+               return digit;
+
        /* now we have a full buffer of signed long samples - we do goertzel */
        for (k = 0; k < NCOEFF; k++) {
                sk = 0;
@@ -88,18 +105,6 @@ char ss5_decode(unsigned char *data, int len)
                        ) / len / 62; /* level of 1 is 0 db*/
        }
 
-       /* now we do noise level calculation */
-       low = 32767;
-       high = -32768;
-       for (n = 0; n < len; n++) {
-               sk = buf[n];
-               if (sk < low)
-                       low = sk;
-               if (sk > high)
-                       high = sk;
-       }
-       noise = ((double)(high-low) / 65536.0);
-
        /* find the two loudest frequencies + one less lower frequency to detect noise */
        power = 0.0;
        for (i = 0; i < NCOEFF; i++) {
@@ -115,38 +120,22 @@ char ss5_decode(unsigned char *data, int len)
                        f2 = i;
                }
        }
-       power = 0.0;
-       for (i = 0; i < NCOEFF; i++) {
-               if (i != f1  && i != f2 && result[i] > power) {
-                       power = result[i];
-                       f3 = i;
-               }
-       }
 
-#if 0
-       /* check one frequency */
-       if (result[f1] > MIN_DB /* must be at least -17 db */
-        && result[f1]*DIFF_DB > result[f2]) /* must be 5 db above other tones */
-               digit = decode_one[f1];
-       /* check two frequencies */
-       if (result[f1] > MIN_DB && result[f2] > MIN_DB /* must be at lease -17 db */
-        && result[f1]*DIFF_DB <= result[f2] /* f2 must be not less than 5 db below f1 */
-        && result[f1]*DIFF_DB > result[f3]) /* f1 must be 5 db above other tones */
-               digit = decode_two[f1][f2];
-#endif
        snr = 0;
        /* check one frequency */
-       if (result[f1] > MIN_DB /* must be at least -17 db */
+       if (result[f1] > TONE_MIN_DB /* must be at least -17 db */
         && result[f1]*SNR > noise) { /*  */
                digit = decode_one[f1];
-               snr = result[f1] / noise;
+               if (digit != ' ')
+                       snr = result[f1] / noise;
        }
        /* check two frequencies */
-       if (result[f1] > MIN_DB && result[f2] > MIN_DB /* must be at lease -17 db */
-        && result[f1]*DIFF_DB <= result[f2] /* f2 must be not less than 5 db below f1 */
+       if (result[f1] > TONE_MIN_DB && result[f2] > TONE_MIN_DB /* must be at lease -17 db */
+        && result[f1]*TONE_DIFF_DB <= result[f2] /* f2 must be not less than 5 db below f1 */
         && (result[f1]+result[f2])*SNR > noise) { /* */
                digit = decode_two[f1][f2];
-               snr = (result[f1]+result[f2]) / noise;
+               if (digit != ' ')
+                       snr = (result[f1]+result[f2]) / noise;
        }
 
        /* debug powers */
@@ -154,6 +143,8 @@ char ss5_decode(unsigned char *data, int len)
        for (i = 0; i < NCOEFF; i++)
                printf("%d:%3d %c ", i, (int)(result[i]*100), (f1==i || f2==i)?'*':' ');
        printf("N:%3d digit:%c snr=%3d\n", (int)(noise*100), digit, (int)(snr*100));
+//     if (result[f1]*TONE_DIFF_DB <= result[f2]) /* f2 must be not less than 5 db below f1 */
+//             printf("jo!");
 #endif
 
        return digit;