我正在尝试执行以下操作
我正在使用我的 java 应用程序给另一个人打电话(已经完成并且工作正常)。
然后我正在播放录音,例如“请按 1 以继续用英语”(已经完成并且工作正常)。
现在我想检测那个人按下一个,根据我在谷歌搜索中的研究,我知道这可以使用 DTMF 来完成。如果这个人按下 1,我想根据我的条件执行操作。
我的问题是如何在 java (J2SE) 中使用 DTMF 检测该数字。我正在使用 ZTE USB 加密狗拨打电话。拨号、挂断等控制都是通过AT指令+Java IO实现的。
这是我的示例代码,但它每次都没有给出正确的拨号号码及其循环。
public class zxczczz extends javax.swing.JFrame {
/**
* Creates new form zxczczz
*/
public zxczczz() {
initComponents();
}
float[] lowFreq = new float[]{697.0F, 770.0F, 852.0F, 941.0F};
float[] highFreq = new float[]{1209.0F, 1336.0F, 1477.0F, 1633.0F};
float[] dtmfTones = new float[]{697.0F, 770.0F, 852.0F, 941.0F, 1209.0F, 1336.0F, 1477.0F, 1633.0F};
int dtmfBoard[][] = {{1, 2, 3, 12}, {4, 5, 6, 13}, {7, 8, 9, 14}, {10, 0, 11, 15}};
byte[] buffer = new byte[2048];
static final char FRAME_SIZE = 160;
AudioFormat format = getAudioFormat();
int[] buf;
public boolean wait = false;
static boolean continueParsingDtmf = false;
public AudioFormat getAudioFormat() {
// float sampleRate = 8000.0F;
float sampleRate = 44100.0F;
//int sampleSizeInBits = 16;
int sampleSizeInBits = 8;
int channels = 1;
boolean signed = true;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}
public class DtmfCapture extends Thread {
public void run() {
continueParsingDtmf = true;
try {
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine out = (TargetDataLine) AudioSystem.getLine(info);
out.open(format);
out.drain();
out.start();
int count = 0;
while (continueParsingDtmf) {
byte[] buffer = new byte[2048];
//grab audio data
count = out.read(buffer, 0, buffer.length);
if (count >= 0) {
zxczczz.DecodeDtmf dtmf = new zxczczz.DecodeDtmf(buffer);
if (!wait) {
dtmf.start(); //look for dtmf
// System.out.println("aaaaaa");
Thread.sleep(100);
} else {
Thread.sleep(1000);// wait before searching again
System.out.println(System.currentTimeMillis());
wait = false;
}
}
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class DecodeDtmf extends Thread {
byte[] buffer;
DecodeDtmf(byte[] buffer) {
this.buffer = buffer;
}
public void run() {
int[] buf;
buf = new int[buffer.length / 2];
for (int j = 0; j < buffer.length / 2 - 1; j++) {
buf[j] = (int) ((buffer[j * 2 + 1] & 0xFF) + (buffer[j * 2] << 8));
}
int tone = findDTMF(buf);
if (tone >= 0) {
wait = true;
if (tone < 10) {
System.out.println(" THE TONE IS : " + tone);
}
if (tone == 12) {
// System.out.println(" THE TONE IS : A");
// }
// if (tone == 13) {
// System.out.println(" THE TONE IS : B");
// }
// if (tone == 14) {
// System.out.println(" THE TONE IS : C");
// }
// if (tone == 15) {
// System.out.println(" THE TONE IS : D");
// }
if (tone == 10) {
// System.out.println(" THE TONE IS : *");
}
if (tone == 11) {
// System.out.println(" THE TONE IS : #");
}
}
}
/*
Check if sample has dtmf tone
*/
public int findDTMF(int[] samples) {
double[] goertzelValues = new double[8];
double lowFreqValue = 0;
int lowFreq = 0;
double sumLow = 0;
double highFreqValue = 0;
int highFreq = 0;
double sumHigh = 0;
for (int i = 0; i < 8; i++) {
goertzelValues[i] = goertzel(samples, dtmfTones[i]);
}
// System.out.println("aa="+goertzelValues);
for (int i = 0; i < 4; i++) // Find st?rste low frequency
{
sumLow += goertzelValues[i]; // Sum til signal-test
if (goertzelValues[i] > lowFreqValue) {
lowFreqValue = goertzelValues[i];
lowFreq = i;
}
// System.out.println("low = "+i);
}
for (int i = 4; i < 8; i++) // Find st?rste high frequency
{
sumHigh += goertzelValues[i]; // Sum til signal-test
if (goertzelValues[i] > highFreqValue) {
highFreqValue = goertzelValues[i];
highFreq = i - 4;
}
}
if (lowFreqValue < sumLow / 2 || highFreqValue < sumHigh / 2) // Test signalstyrke
{
return -1;
}
// System.out.println("aaa="+dtmfBoard[lowFreq][highFreq]);
return dtmfBoard[lowFreq][highFreq]; // Returner DTMF tone
}
}
public double goertzel(int[] samples, float freq) {
double vkn = 0;
double vkn1 = 0;
double vkn2 = 0;
for (int j = 0; j < samples.length - 1; j++) {
vkn2 = vkn1;
vkn1 = vkn;
vkn = 2 * Math.cos(2 * Math.PI * (freq * samples.length / format.getSampleRate()) / samples.length) * vkn1 - vkn2 + samples[j];
}
double WNk = Math.exp(-2 * Math.PI * (freq * samples.length / format.getSampleRate()) / samples.length);
//System.out.println(WNk);
return Math.abs(vkn - WNk * vkn1);
}
}
请帮我。