2

我正在尝试执行以下操作

我正在使用我的 java 应用程序给另一个人打电话(已经完成并且工作正常)。

然后我正在播放录音,例如“请按 1 以继续用英语”(已经完成并且工作正常)。

现在我想检测那个人按下一个,根据我在谷歌搜索中的研究,我知道这可以使用 DTMF 来完成。如果这个人按下 1,我想根据我的条件执行操作。

我的问题是如何在 java (J2SE) 中使用 DTMF 检测该数字。我正在使用 ZTE USB 加密狗拨打电话。拨号、挂断等控制都是通过AT指令+Java IO实现的。

package tracenumber;

import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

public class DTMFDetect {

/**
 * @param args
 */

    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[2000];
    static final char FRAME_SIZE = 160;

    AudioFormat format = getAudioFormat();
    //int[] buf;
    public boolean wait = false;
    static boolean continueParsingDtmf = false;

    public DTMFDetect() 
    {
    }

    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 static void main(String args[]) throws LineUnavailableException, IOException
    {

    // start seaching for audio signals 



new DtmfCapture().start();



            // decode for a minute
    try {   Thread.sleep(60000);
    } catch (Exception e){

    }
        continueParsingDtmf = false;



    }

    public class DtmfCapture extends Thread {



        public void run() {
        continueParsingDtmf = true;
        try {
        int tone = 0;
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
        TargetDataLine out= (TargetDataLine) AudioSystem.getLine(info);
            int[] buf ;

            out.open(format);
            out.drain();
        out.start();
        int count = 0;

        while (continueParsingDtmf) {
        byte[] buffer = new byte[2000];

                    //grab audio data
        count = out.read(buffer,0,buffer.length);

        if(count > 0){
            DecodeDtmf dtmf = new DecodeDtmf(buffer);

        if (!wait){

                    dtmf.start(); //look for dtmf
        Thread.sleep(100);
         } else
              {
              Thread.sleep(4000); // 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;
                //System.out.print(time);
                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]);
                }

                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;
                    }
                }
                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;
                }
                    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);   

    return Math.abs(vkn - WNk * vkn1);
    }

}

4

0 回答 0