/* * Copyright 2007 Sun Microsystems, Inc. * * This file is part of jVoiceBridge. * * jVoiceBridge is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation and distributed hereunder * to you. * * jVoiceBridge is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the License file that accompanied this * code. */ package com.sun.voip.server; import com.sun.voip.AudioConversion; import com.sun.voip.Logger; import com.sun.voip.MediaInfo; import com.sun.voip.RtpPacket; import com.sun.voip.SampleRateConverter; import com.sun.medialib.codec.dtmf.Decoder; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; import java.util.Calendar; public class DtmfDecoder { MemberReceiver memberReceiver = null; private final static char[] char_keys = { '0','1','2','3','4','5','6','7','8', '9','*','#','A','B','C','D' }; private static final int MAX_KEYS = 1; private Decoder decoder; private int[] linearData; private SampleRateConverter sampleRateConverter; private MediaInfo mediaInfo; private long totalDecodeTime; private int numberOfTimesCalled; public DtmfDecoder(MemberReceiver memberReceiver, MediaInfo mediaInfo) { this.memberReceiver = memberReceiver; this.mediaInfo = mediaInfo; decoder = new Decoder(); linearData = new int[mediaInfo.getSamplesPerPacket()]; decoder.setRate(mediaInfo.getSampleRate()); if (mediaInfo.getChannels() != 1) { /* * Must convert multi-channel to 1 */ try { sampleRateConverter = new SampleRateConverter("DtmfDecoder", mediaInfo.getSampleRate(), mediaInfo.getChannels(), mediaInfo.getSampleRate(), 1); } catch (IOException e) { Logger.println( "Call " + memberReceiver + " DtmfDecoder: " + e.getMessage()); } } } public boolean dtmfDetected() { return decoder.dtmfDetected(); } public String noDataReceived() { /* * Create a packet of silence (linear 0) * The dtmf detector needs to know when a dtmf key * is released. If a phone stops sending immediately * after the dtmf key is released, we need to append * silence so that the dtmf detector will return * the dtmf key. */ int[] silence = new int[mediaInfo.getSamplesPerPacket()]; String dtmfKeys = null; dtmfKeys = processData(silence); if (Logger.logLevel >= Logger.LOG_DETAIL) { Logger.println( "no data received, done processing dtmf with silence"); if (dtmfKeys != null) { Logger.println("silence. dtmf " + dtmfKeys); } } return dtmfKeys; } /* * data starts at RtpPacket.HEADER_SIZE */ public String processData(int[] linearData) { numberOfTimesCalled++; long start = System.currentTimeMillis(); if (sampleRateConverter != null) { try { int nSamples = linearData.length; linearData = sampleRateConverter.resample(linearData); if (Logger.logLevel >= Logger.LOG_DETAIL) { Logger.println("Resample for Dtmf: nSamples " + nSamples + " new nSamples " + linearData.length); } } catch (IOException e) { Logger.println( "Call " + memberReceiver + " DtmfDecoder: " + e.getMessage()); } } int keys[] = new int[MAX_KEYS]; // decoded key int nkeys = decoder.decode(keys, AudioConversion.intsToShorts(linearData), 0); String dtmfKeys = null; if (nkeys > 0) { char[] charKeys = new char[nkeys]; for (int i = 0; i < nkeys; i++) { charKeys[i] = char_keys[keys[i]]; } dtmfKeys = new String(charKeys); } totalDecodeTime += (System.currentTimeMillis() - start); return dtmfKeys; } public void printStatistics() { Logger.writeFile("Call " + memberReceiver.toString() + ": " + "Dtmf detector calls: " + numberOfTimesCalled); if (numberOfTimesCalled != 0) { Logger.writeFile(memberReceiver.toString() + ": Dtmf decoder average ms per call: " + ((float)((float)totalDecodeTime / numberOfTimesCalled))); } } }