Add -lncurses to LDD flags
[lcr.git] / ss5_decode.c
index 0a00a6f..95a1f74 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.2 // 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:
@@ -51,20 +52,37 @@ static char decode_one[8] =
  * calculate the coefficients of the given sample and decode
  */
 
-char ss5_decode(unsigned char *data, int len)
+char ss5_decode(unsigned char *data, int len, double *_quality)
 {
        signed short buf[len];
        signed long sk, sk1, sk2, low, high;
        int k, n, i;
        int f1 = 0, f2 = 0;
-       double result[NCOEFF], power, noise, snr;
+       double result[NCOEFF], power, noise;
        signed long long cos2pik_;
        char digit = ' ';
+       double quality;
 
        /* convert samples */
        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 +106,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++) {
@@ -116,34 +122,34 @@ char ss5_decode(unsigned char *data, int len)
                }
        }
 
-       snr = 0;
+       quality = 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];
                if (digit != ' ')
-                       snr = result[f1] / noise;
+                       quality = 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];
                if (digit != ' ')
-                       snr = (result[f1]+result[f2]) / noise;
+                       quality = (result[f1]+result[f2]) / noise;
        }
 
        /* debug powers */
 #ifdef DEBUG_LEVELS
-       if (noise > 0.2) {
-               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]*DIFF_DB <= result[f2]) /* f2 must be not less than 5 db below f1 */
-                       printf("jo!");
-       }
+       for (i = 0; i < NCOEFF; i++)
+               printf("%d:%3d %c ", i, (int)(result[i]*100), (f1==i || f2==i)?'*':' ');
+       printf("N:%3d digit:%c quality=%3d%%\n", (int)(noise*100), digit, (int)(quality*100));
+//     if (result[f1]*TONE_DIFF_DB <= result[f2]) /* f2 must be not less than 5 db below f1 */
+//             printf("jo!");
 #endif
 
+       if (_quality)
+               *_quality = quality;
        return digit;
 }