⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtmfdecodes.c

📁 DTMF的识别算法
💻 C
字号:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

/* Integer math scaling factor */
#define FSC	(1<<12)

/* Alaw parameters */
#define SIGN_BIT        (0x80)          /* Sign bit for an A-law byte. */
#define QUANT_MASK      (0xf)           /* Quantization field mask. */
#define SEG_SHIFT       (4)             /* Left shift for segment number. */
#define SEG_MASK        (0x70)          /* Segment field mask. */

static int alaw2linear(a_val)
unsigned char a_val;
{
        int             t;
        int             seg;

        a_val ^= 0x55;

        t = (a_val & QUANT_MASK) << 4;
        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
        switch (seg) {
        case 0:
                t += 8;
                break;
        case 1:
                t += 0x108;
                break;
        default:
                t += 0x108;
                t <<= seg - 1;
        }
        return ((a_val & SIGN_BIT) ? t : -t);
}

#ifdef USE_COS
/* The frequencies we're trying to detect */
static int dtmf[8] = {697, 770, 852, 941, 1209, 1336, 1477, 1633};
#else
/* precalculated: p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC) */
static int p1[8] = {-3497, -3369, -3212, -3027, -2384, -2040, -1635, -1164};
#endif

/* This is the Q of the filter (pole radius) */
#define POLRAD .99

#define P2 ((int)(POLRAD*POLRAD*FSC))


int main(int argc, char **argv)
{
	int i, kk, t, nn, s, so, ia, DtmfHoldTime;
	int x, c, d, f, h[8], k[8], n, y[8];
#ifdef USE_COS
	int p1[8];
#endif	
	int alaw[256];
	char key[256];

	FILE *inFileHandle;

	for (kk = 0; kk < 8; kk++) {
		y[kk] = h[kk] = k[kk] = 0;
#ifdef USE_COS
		p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC);
#endif		
	}

	for (i = 0; i < 256; i++) {
		key[i] = '?';
		alaw[i] = alaw2linear(i) / (32768/FSC);
	}

	/* We encode the tones in 8 bits, translate those to symbol */
	key[0x00] = '\0';

	key[0x11] = '1'; key[0x12] = '4'; key[0x14] = '7'; key[0x18] = '*';
	key[0x21] = '2'; key[0x22] = '5'; key[0x24] = '8'; key[0x28] = '0';
	key[0x41] = '3'; key[0x42] = '6'; key[0x44] = '9'; key[0x48] = '#';
	key[0x81] = 'A'; key[0x82] = 'B'; key[0x84] = 'C'; key[0x88] = 'D';

	nn = 0;
	ia = 0;
	so = 0;
	t = 0;

	inFileHandle = fopen(argv[1], "rb");
	if (inFileHandle == NULL){
		printf("Source File not exist\n");
		return (0);
	}

//	while ((i = getchar()) != EOF)
	while (!feof(inFileHandle)){
		i = 0;
		fread(&i, 1, 1, inFileHandle);

		t++;

		/* Convert to our format */
		x = alaw[i];

		/* Input amplitude */
		if (x > 0)
			ia += (x - ia) / 128;
		else
			ia += (-x - ia) / 128;

		/* For each tone */
		s = 0;
		for(kk = 0; kk < 8; kk++) {

			/* Turn the crank */
			c = (P2 * (x - k[kk])) / FSC;
			d = x + c;
			f = (p1[kk] * (d - h[kk])) / FSC;
			n = x - k[kk] - c;
			k[kk] = h[kk] + f;
			h[kk] = f + d;

			/* Detect and Average */
			if (n > 0)
				y[kk] += (n - y[kk]) / 64;
			else
				y[kk] += (-n - y[kk]) / 64;

			/* Threshold */
			if (y[kk] > FSC/10 && y[kk] > ia)
				s |= 1 << kk;
		}

		/* Hysteresis and noise supressor */
		if (s != so) {
/* printf("x %d %x -> %x\n",t,so, s); */
			nn = 0;
			so = s;
		} 
		else{
			if ((nn++ == DtmfHoldTime) && key[s]) {
				putchar(key[s]);
			}
/* printf(" %d %x\n",t,s); */
		}
	}
	putchar('\n');
	return (0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -