Data-Over-Voice
[lcr.git] / ss5_decode.c
index 541f6be..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.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, f3 = 0;
-       double result[NCOEFF], power, noise, snr;
+       int f1 = 0, f2 = 0;
+       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++) {
@@ -115,47 +121,35 @@ 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;
+       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];
-               snr = result[f1] / noise;
+               if (digit != ' ')
+                       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];
-               snr = (result[f1]+result[f2]) / noise;
+               if (digit != ' ')
+                       quality = (result[f1]+result[f2]) / noise;
        }
 
        /* debug powers */
 #ifdef DEBUG_LEVELS
        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));
+       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;
 }