X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=ss5_decode.c;h=95a1f747897630456cc56bc4f0f43f5be0e64181;hp=541f6beed9814fa588269fa8e56804378d65467c;hb=5566f74eb29be75da44e29ba72ee6f015249ce61;hpb=323cbc387b1a068f8e2bcfd1034666406ba18c93 diff --git a/ss5_decode.c b/ss5_decode.c index 541f6be..95a1f74 100644 --- a/ss5_decode.c +++ b/ss5_decode.c @@ -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; }