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