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 * ---------------------------------------------------------------------------- 8 * 9 * $Id: dtmfdecode.c,v 1.3 2003/10/06 09:43:27 itojun Exp $ 10 * 11 * $FreeBSD$ 12 * 13 * Extract DTMF signalling from ISDN4BSD A-law coded audio data 14 * 15 * A-law to linear conversion from the sox package. 16 * 17 */ 18 19#include <stdio.h> 20#include <math.h> 21 22/* Integer math scaling factor */ 23#define FSC (1<<12) 24 25/* A-law parameters */ 26#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ 27#define QUANT_MASK (0xf) /* Quantization field mask. */ 28#define SEG_SHIFT (4) /* Left shift for segment number. */ 29#define SEG_MASK (0x70) /* Segment field mask. */ 30 31static int alaw2linear(unsigned char a_val) 32{ 33 int t; 34 int seg; 35 36 a_val ^= 0x55; 37 38 t = (a_val & QUANT_MASK) << 4; 39 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; 40 switch (seg) { 41 case 0: 42 t += 8; 43 break; 44 case 1: 45 t += 0x108; 46 break; 47 default: 48 t += 0x108; 49 t <<= seg - 1; 50 } 51 return ((a_val & SIGN_BIT) ? t : -t); 52} 53 54#ifdef USE_COS 55/* The frequencies we're trying to detect */ 56static int dtmf[8] = {697, 770, 852, 941, 1209, 1336, 1477, 1633}; 57#else 58/* precalculated: p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC) */ 59static int p1[8] = {-3497, -3369, -3212, -3027, -2384, -2040, -1635, -1164}; 60#endif 61 62/* This is the Q of the filter (pole radius) */ 63#define POLRAD .99 64 65#define P2 ((int)(POLRAD*POLRAD*FSC)) 66 67int 68main(int argc, char **argv) 69{ 70 int i, kk, t, nn, s, so, ia; 71 int x, c, d, f, h[8], k[8], n, y[8]; 72#ifdef USE_COS 73 int p1[8]; 74#endif 75 int alaw[256]; 76 char key[256]; 77 78 for (kk = 0; kk < 8; kk++) { 79 y[kk] = h[kk] = k[kk] = 0; 80#ifdef USE_COS 81 p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC); 82#endif 83 } 84 85 for (i = 0; i < 256; i++) { 86 key[i] = '?'; 87 alaw[i] = alaw2linear(i) / (32768/FSC); 88 } 89 90 /* We encode the tones in 8 bits, translate those to symbol */ 91 key[0x00] = '\0'; 92 93 key[0x11] = '1'; key[0x12] = '4'; key[0x14] = '7'; key[0x18] = '*'; 94 key[0x21] = '2'; key[0x22] = '5'; key[0x24] = '8'; key[0x28] = '0'; 95 key[0x41] = '3'; key[0x42] = '6'; key[0x44] = '9'; key[0x48] = '#'; 96 key[0x81] = 'A'; key[0x82] = 'B'; key[0x84] = 'C'; key[0x88] = 'D'; 97 98 nn = 0; 99 ia = 0; 100 so = 0; 101 t = 0; 102 while ((i = getchar()) != EOF) 103 { 104 t++; 105 106 /* Convert to our format */ 107 x = alaw[i]; 108 109 /* Input amplitude */ 110 if (x > 0) 111 ia += (x - ia) / 128; 112 else 113 ia += (-x - ia) / 128; 114 115 /* For each tone */ 116 s = 0; 117 for (kk = 0; kk < 8; kk++) { 118 119 /* Turn the crank */ 120 c = (P2 * (x - k[kk])) / FSC; 121 d = x + c; 122 f = (p1[kk] * (d - h[kk])) / FSC; 123 n = x - k[kk] - c; 124 k[kk] = h[kk] + f; 125 h[kk] = f + d; 126 127 /* Detect and Average */ 128 if (n > 0) 129 y[kk] += (n - y[kk]) / 64; 130 else 131 y[kk] += (-n - y[kk]) / 64; 132 133 /* Threshold */ 134 if (y[kk] > FSC/10 && y[kk] > ia) 135 s |= 1 << kk; 136 } 137 138 /* Hysteresis and noise supressor */ 139 if (s != so) { 140/* printf("x %d %x -> %x\n",t,so, s); */ 141 nn = 0; 142 so = s; 143 } else if (nn++ == 520 && key[s]) { 144 putchar(key[s]); 145/* printf(" %d %x\n",t,s); */ 146 } 147 } 148 putchar('\n'); 149 return (0); 150} 151