有哪位高手知道怎么样从文件中提取出dtmf的做法,进来看看,或提供线索(100分)

  • 主题发起人 主题发起人 chenxz
  • 开始时间 开始时间
C

chenxz

Unregistered / Unconfirmed
GUEST, unregistred user!
就是通过语音卡吧dtmf录在一个文件中,现在想通过程序把dtmf提取出来。
请说明一下具体的原理,最好有源码。

不能用语音卡或其他的硬件作,要用纯软件的算法。

如果有结果,分数都不会是问题:)
 
你发邮件给jxhdy2001@163.com 他会给你。
如果你不想发的话那么你只有 看帮助,有N个API在等着来看。。。
 
对不起,我对DTMF不怎么了解
 
需要用硬件!
使用 MT8870 和 单片机 配合,再用串行口送回来!
 
看看这个。不能用不怪我啊,我也没用过
头文件:
#ifndef _DTMF_H
#define _DTMF_H

#ifdef P_USE_PRAGMA
#pragma interface
#endif

class PDTMFDecoder : public PObject
{
PCLASSINFO(PDTMFDecoder, PObject)

public:
PDTMFDecoder();
PString Decode(const void *buf, PINDEX bytes);

protected:
// key lookup table (initialised once)
char key[256];

// frequency table (initialised once)
int p1[8];

// variables to be retained on each cycle of the decode function
int h[8], k[8], y[8];
int nn, so, ia;
};
#endif /* _DTMF_H */

实现文件:

#ifdef __GNUC__
#pragma implementation "dtmf.h"
#endif

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

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

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

PDTMFDecoder::PDTMFDecoder() {
// Initialise the class
int i,kk;
for (kk = 0;
kk < 8;
kk++) {
y[kk] = h[kk] = k[kk] = 0;
}

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

for (i = 0;
i < 256;
i++) {
key = '?';
}

/* 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';

/* The frequencies we're trying to detect */
/* These are precalculated to save processing power */
/* static int dtmf[8] = {697, 770, 852, 941, 1209, 1336, 1477, 1633};
*/
/* p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0) * FSC) */
p1[0] = -3497;
p1[1] = -3369;
p1[2] = -3212;
p1[3] = -3027;
p1[4] = -2384;
p1[5] = -2040;
p1[6] = -1635;
p1[7] = -1164;
}

PString PDTMFDecoder::Decode(const void *buf, PINDEX bytes) {
int x;
int s, kk;
int c, d, f, n;
short *buffer = (short *)buf;

PINDEX numSamples = bytes >> 1;

PString keyString;

PINDEX pos;
for (pos = 0;
pos < numSamples;
pos++) {

/* Read (and scale) the next 16 bit sample */
x = ((int)(*buffer++)) / (32768/FSC);

/* 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 &amp;&amp;
y[kk] > ia)
s |= 1 << kk;
}

/* Hysteresis and noise supressor */
if (s != so) {
nn = 0;
so = s;
} else
if ((nn++ == 520) &amp;&amp;
(key != '?')) {
PTRACE(1,"Got 16bit PCM DTMF " << key << endl);
keyString = keyString + key;
}
}
return keyString;
}
 
不对啊,一个dtmf应该是由很长的一串来的,不应该是上面的算法。
 
这个代码不能用吗?我觉得应该是可以的。
我没有 dtmf 的 pcm 数据。所以不能测试。
你不妨试一下。 PString 是普通的字符串, PINDEX 是整数
PObject 和 PCLASSINFO 是 RTTI 信息,不用理他。
 
to xiao.lit:
你可以用cooledit生成带dtmf的pcm文件的。不行的话我可以发给你。
 
ok. pls send me one. I'll test the code if i have time.
pls keep in mind pcm file in 8k sample rate, 16bit mono.
nil@china.com.cn
 
我听了一下你发过来的 dtmf 文件,
8个音调都是只有单一的音频,不能解码的。
请重新录一个完整的 dtmf 信号,我再看看。
 
有没有进展啊。
 
接受答案了.
 
后退
顶部