Nuke unused macro and comment
[dragonfly.git] / usr.sbin / i4b / dtmfdecode / dtmfdecode.c
blobc86d28f7b196735b0ec56234d22315471d3832df
1 /*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
9 * $Id: dtmfdecode.c,v 1.6 1999/12/13 21:25:24 hm Exp $
11 * $FreeBSD: src/usr.sbin/i4b/dtmfdecode/dtmfdecode.c,v 1.4.2.1 2001/08/01 17:45:02 obrien Exp $
12 * $DragonFly: src/usr.sbin/i4b/dtmfdecode/dtmfdecode.c,v 1.3 2003/11/16 15:17:35 eirikn Exp $
14 * Extract DTMF signalling from ISDN4BSD A-law coded audio data
16 * A-Law to linear conversion from the sox package.
20 #include <stdio.h>
21 #include <math.h>
23 /* Integer math scaling factor */
24 #define FSC (1<<12)
26 /* Alaw parameters */
27 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
28 #define QUANT_MASK (0xf) /* Quantization field mask. */
29 #define SEG_SHIFT (4) /* Left shift for segment number. */
30 #define SEG_MASK (0x70) /* Segment field mask. */
32 static int
33 alaw2linear(unsigned char a_val)
35 int t;
36 int seg;
38 a_val ^= 0x55;
40 t = (a_val & QUANT_MASK) << 4;
41 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
42 switch (seg) {
43 case 0:
44 t += 8;
45 break;
46 case 1:
47 t += 0x108;
48 break;
49 default:
50 t += 0x108;
51 t <<= seg - 1;
53 return ((a_val & SIGN_BIT) ? t : -t);
56 #ifdef USE_COS
57 /* The frequencies we're trying to detect */
58 static int dtmf[8] = {697, 770, 852, 941, 1209, 1336, 1477, 1633};
59 #else
60 /* precalculated: p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC) */
61 static int p1[8] = {-3497, -3369, -3212, -3027, -2384, -2040, -1635, -1164};
62 #endif
64 /* This is the Q of the filter (pole radius) */
65 #define POLRAD .99
67 #define P2 ((int)(POLRAD*POLRAD*FSC))
69 int
70 main(int argc, char **argv)
72 int i, kk, t, nn, s, so, ia;
73 int x, c, d, f, h[8], k[8], n, y[8];
74 #ifdef USE_COS
75 int p1[8];
76 #endif
77 int alaw[256];
78 char key[256];
80 for (kk = 0; kk < 8; kk++) {
81 y[kk] = h[kk] = k[kk] = 0;
82 #ifdef USE_COS
83 p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC);
84 #endif
87 for (i = 0; i < 256; i++) {
88 key[i] = '?';
89 alaw[i] = alaw2linear(i) / (32768/FSC);
92 /* We encode the tones in 8 bits, translate those to symbol */
93 key[0x00] = '\0';
95 key[0x11] = '1'; key[0x12] = '4'; key[0x14] = '7'; key[0x18] = '*';
96 key[0x21] = '2'; key[0x22] = '5'; key[0x24] = '8'; key[0x28] = '0';
97 key[0x41] = '3'; key[0x42] = '6'; key[0x44] = '9'; key[0x48] = '#';
98 key[0x81] = 'A'; key[0x82] = 'B'; key[0x84] = 'C'; key[0x88] = 'D';
100 nn = 0;
101 ia = 0;
102 so = 0;
103 t = 0;
104 while ((i = getchar()) != EOF)
106 t++;
108 /* Convert to our format */
109 x = alaw[i];
111 /* Input amplitude */
112 if (x > 0)
113 ia += (x - ia) / 128;
114 else
115 ia += (-x - ia) / 128;
117 /* For each tone */
118 s = 0;
119 for(kk = 0; kk < 8; kk++) {
121 /* Turn the crank */
122 c = (P2 * (x - k[kk])) / FSC;
123 d = x + c;
124 f = (p1[kk] * (d - h[kk])) / FSC;
125 n = x - k[kk] - c;
126 k[kk] = h[kk] + f;
127 h[kk] = f + d;
129 /* Detect and Average */
130 if (n > 0)
131 y[kk] += (n - y[kk]) / 64;
132 else
133 y[kk] += (-n - y[kk]) / 64;
135 /* Threshold */
136 if (y[kk] > FSC/10 && y[kk] > ia)
137 s |= 1 << kk;
140 /* Hysteresis and noise supressor */
141 if (s != so) {
142 /* printf("x %d %x -> %x\n",t,so, s); */
143 nn = 0;
144 so = s;
145 } else if (nn++ == 520 && key[s]) {
146 putchar(key[s]);
147 /* printf(" %d %x\n",t,s); */
150 putchar('\n');
151 return (0);