Package com.talixa.specan.demod.dtmf

Source Code of com.talixa.specan.demod.dtmf.DTMFDecoder

package com.talixa.specan.demod.dtmf;

import com.talixa.audio.wav.WaveFile;
import com.talixa.audio.wav.WaveReader;
import com.talixa.specan.dsp.SharedDSPFunctions;
import com.talixa.specan.fft.Complex;
import com.talixa.specan.fft.FFT;
import com.talixa.specan.fft.FrequencyTools;

public class DTMFDecoder {
 
  /*
   *           TONE TABLE
   *         1209 Hz  1336 Hz  1477 Hz  1633 Hz
   * 697 Hz    1         2        3       A
   * 770 Hz    4         5        6       B
   * 852 Hz    7         8        9       C
   * 941 Hz    *         0        #       D
   *
   * Event        Low frequency  High frequency
   * Busy signal (US)    480 Hz      620 Hz
   * Ringback tone (US)  440 Hz      480 Hz
   * Dial tone (US)    350 Hz      440 Hz
  */
   
  /*
   * 1) Run FFT on input data
   * 2) Check for spikes at frequencies
   */
 
  private static final int FFT_LEN = 256*2;
  private static final int SHIFT_VALUE = FFT_LEN;   
 
  private static final int F0697 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN,  697);
  private static final int F0770 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN,  770);
  private static final int F0852 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN,  852);
  private static final int F0941 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN,  941);
  private static final int F1209 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN, 1209);
  private static final int F1336 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN, 1336);
  private static final int F1477 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN, 1477);
  private static final int F1633 = SharedDSPFunctions.getSampleNumberByFrequency(FFT_LEN, 1633);
 
  public static String detect(short[] data) {               
    int numberSamples = data.length;
    Complex[] amplitudeData = new Complex[FFT_LEN];
    Complex[] frequencyData = new Complex[FFT_LEN]
    char lastChar = ' ';
    StringBuilder dtmfChars = new StringBuilder();
   
    for(int baseAddress = 0; (baseAddress)+FFT_LEN < numberSamples; baseAddress+=SHIFT_VALUE) {     
      // fill the data array
      for (int offset = 0; offset < FFT_LEN; offset++) {
        int desiredSampleIndex = (baseAddress)+offset;         
        short signedSample = data[desiredSampleIndex];                 
        double sample = ((double) signedSample) / (Short.MAX_VALUE);
        amplitudeData[offset] = new Complex(sample,0);
      }                             

      // run fft
      frequencyData = FFT.fft(amplitudeData)
     
      // Use FFT_LEN/2 since the data is mirrored within the array.
      double[] scaledAmpFreq = new double[FFT_LEN/2];
      for(int i=1;i < FFT_LEN/2-1;i++) {
        double re = frequencyData[i].re();
          double im = frequencyData[i].im();
          //get amplitude and scale to range 0 - RESOLUTION
          scaledAmpFreq[i]=FrequencyTools.amplitudeScaled(re,im,FFT_LEN,512)*1000;         
      }
     
      int detectVol = 75;
      char thisChar= ' ';
      if (scaledAmpFreq[F0697] > detectVol && scaledAmpFreq[F1209] > detectVol) {
        thisChar = '1';
      } else if (scaledAmpFreq[F0697] > detectVol && scaledAmpFreq[F1336] > detectVol) {
        thisChar = '2';
      } else if (scaledAmpFreq[F0697] > detectVol && scaledAmpFreq[F1477] > detectVol) {
        thisChar = '3';
      } else if (scaledAmpFreq[F0770] > detectVol && scaledAmpFreq[F1209] > detectVol) {
        thisChar = '4';
      } else if (scaledAmpFreq[F0770] > detectVol && scaledAmpFreq[F1336] > detectVol) {
        thisChar = '5';
      } else if (scaledAmpFreq[F0770] > detectVol && scaledAmpFreq[F1477] > detectVol) {
        thisChar = '6';
      } else if (scaledAmpFreq[F0852] > detectVol && scaledAmpFreq[F1209] > detectVol) {
        thisChar = '7';
      } else if (scaledAmpFreq[F0852] > detectVol && scaledAmpFreq[F1336] > detectVol) {
        thisChar = '8';
      } else if (scaledAmpFreq[F0852] > detectVol && scaledAmpFreq[F1477] > detectVol) {
        thisChar = '9';
      } else if (scaledAmpFreq[F0941] > detectVol && scaledAmpFreq[F1209] > detectVol) {
        thisChar = '*';
      } else if (scaledAmpFreq[F0941] > detectVol && scaledAmpFreq[F1336] > detectVol) {
        thisChar = '0';
      } else if (scaledAmpFreq[F0941] > detectVol && scaledAmpFreq[F1477] > detectVol) {
        thisChar = '#';           
      } else if (scaledAmpFreq[F0697] > detectVol && scaledAmpFreq[F1633] > detectVol) {
        thisChar = 'A';
      } else if (scaledAmpFreq[F0770] > detectVol && scaledAmpFreq[F1633] > detectVol) {
        thisChar = 'B';
      } else if (scaledAmpFreq[F0852] > detectVol && scaledAmpFreq[F1633] > detectVol) {
        thisChar = 'C';
      } else if (scaledAmpFreq[F0941] > detectVol && scaledAmpFreq[F1633] > detectVol) {
        thisChar = 'D';
      }
     
      if (lastChar == ' ' && thisChar != ' ') {
        dtmfChars.append(thisChar);
      }     
      lastChar = thisChar;     
    }     
       
    return dtmfChars.toString();
  }   
 
  public static void main(String[] args) {   
    testDemod();             
  }   
   
  private static final String PATH_WIN = "C:\\Users\\tgerlach\\git\\specan\\SpecAn\\res\\";
  private static final String PATH_LINUX = "/home/thomas/git/specan/SpecAn/res/"
  private static final String[] TEST_FILES = new String[] {"dtmf.wav"}
 
  public static void testDemod() {
    boolean usingWindows = System.getProperty("os.name").toLowerCase().contains("windows");
    String path;
    if (usingWindows) {
      path = PATH_WIN;
    } else {
      path = PATH_LINUX;
    }
   
    for(int i = 0; i < TEST_FILES.length; ++i) {
      System.out.print("***********************");
      System.out.print(TEST_FILES[i]);
      System.out.println("***********************");
      String inputFile = path + TEST_FILES[i];
      try {               
        WaveFile waveFile = WaveReader.readFromFile(inputFile);
        short[] data = SharedDSPFunctions.extractWaveFileData(waveFile)
        String tones = detect(data);
        System.out.println(tones);
      } catch (Exception e) {     
        e.printStackTrace();
      }
    }
  }
}
TOP

Related Classes of com.talixa.specan.demod.dtmf.DTMFDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.