package javaforce.voip;
/**
* Generates DTMF tones for local playback.
*/
public class DTMF {
private static final double vol = 9000.0;
private static final double pi2 = Math.PI * 2.0;
private int offset;
private double rowPos, colPos;
private double row[] = {697, 770, 852, 941};
private double col[] = {1209, 1336, 1477};
private int iRate;
private double dRate;
private short buf[];
private char last;
public DTMF(int rate) {
setSampleRate(rate);
}
public void reset() {
offset = 0;
rowPos = 0;
colPos = 0;
}
public void setSampleRate(int rate) {
iRate = rate;
dRate = rate;
buf = new short[rate / 50]; //create 20ms buffer
}
public short[] getSamples(char dtmf) {
if (dtmf != last) {
last = dtmf;
reset();
}
int rowIdx, colIdx;
switch (dtmf) {
case '1':
rowIdx = 0;
colIdx = 0;
break;
case '2':
rowIdx = 0;
colIdx = 1;
break;
case '3':
rowIdx = 0;
colIdx = 2;
break;
case '4':
rowIdx = 1;
colIdx = 0;
break;
case '5':
rowIdx = 1;
colIdx = 1;
break;
case '6':
rowIdx = 1;
colIdx = 2;
break;
case '7':
rowIdx = 2;
colIdx = 0;
break;
case '8':
rowIdx = 2;
colIdx = 1;
break;
case '9':
rowIdx = 2;
colIdx = 2;
break;
case '*':
rowIdx = 3;
colIdx = 0;
break;
case '0':
rowIdx = 3;
colIdx = 1;
break;
case '#':
rowIdx = 3;
colIdx = 2;
break;
default:
return null;
}
//row
double rowTheta = pi2 * row[rowIdx] / dRate;
for (int a = 0; a < buf.length; a++) {
buf[a] = (short)(Math.sin(rowPos) * vol);
rowPos += rowTheta;
}
//col
double colTheta = pi2 * col[colIdx] / dRate;
for (int a = 0; a < buf.length; a++) {
buf[a] += (short) (Math.sin(colPos) * vol);
colPos += colTheta;
}
offset += buf.length;
if (offset == iRate) reset(); //1 sec complete
return buf;
}
}