- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试执行以下操作
public class zxczczz extends javax.swing.JFrame {
/**
* Creates new form zxczczz
*/
public zxczczz() {
initComponents();
}
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[2048];
static final char FRAME_SIZE = 160;
AudioFormat format = getAudioFormat();
int[] buf;
public boolean wait = false;
static boolean continueParsingDtmf = false;
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 class DtmfCapture extends Thread {
public void run() {
continueParsingDtmf = true;
try {
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine out = (TargetDataLine) AudioSystem.getLine(info);
out.open(format);
out.drain();
out.start();
int count = 0;
while (continueParsingDtmf) {
byte[] buffer = new byte[2048];
//grab audio data
count = out.read(buffer, 0, buffer.length);
if (count >= 0) {
zxczczz.DecodeDtmf dtmf = new zxczczz.DecodeDtmf(buffer);
if (!wait) {
dtmf.start(); //look for dtmf
// System.out.println("aaaaaa");
Thread.sleep(100);
} else {
Thread.sleep(1000);// 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;
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]);
}
// System.out.println("aa="+goertzelValues);
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;
}
// System.out.println("low = "+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;
}
// System.out.println("aaa="+dtmfBoard[lowFreq][highFreq]);
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);
//System.out.println(WNk);
return Math.abs(vkn - WNk * vkn1);
}
}
最佳答案
我正在为 ActionScript 中的 DTMF 检测寻找相同的东西
我发现了一些东西,也许你可以用 java 重新编码
package {
import flash.utils.ByteArray;
public class DTMFprocessor
{
/*
The following constants are used to find the DTMF tones. The COL1 is the column Hz that we
are searching for, and the COL2 is the row Hz. The DTMF_LAYOUT is the order that the cols and
rows intersect at.
*/
private static const COL1:Array = [697, 770, 852, 941];
private static const COL2:Array = [1209, 1336, 1477, 1633];
private static const DTMF_LAYOUT:Array = [ ["1","2","3","A"] ,
["4","5","6","B"] ,
["7","8","9","C"] ,
["*","0","#","D"] ];
private var sampleRate:int;
private var lastFound:String = "";
public var DTMFToneSensitivity:int = 15;
/**
* DTMF Processor Constructor
*
* @param sampleRate This is the sample rate, in frames per second that the application is operating in.
*
*/
public function DTMFprocessor(sampleRate:int = 44100)
{
this.sampleRate = sampleRate;
}
/**
* Generates DTMF byteArrays that can be played by the Sound() object.
*
* @param length length, in ms that the tone will be generated for.
* @param tone the string representing the tone that will be generated [0-9, A-D, *, #]
* @return the byteArray that contains the DTMF tone.
*
*/
public function generateDTMF(length:int, tone:String):ByteArray
{
var mySound:ByteArray = new ByteArray();
var neededSamples:int = Math.floor(length * sampleRate / 1000);
var mySampleCol:Number = 0;
var mySampleRow:Number = 0;
var hz:Object = findDTMF(tone.charAt(0));
for (var i:int = 0; i < neededSamples; i++)
{
mySampleCol = Math.sin(i * hz.col * Math.PI * 2 / sampleRate) * 0.5;
mySampleRow = Math.sin(i * hz.row * Math.PI * 2 / sampleRate) * 0.5;
mySound.writeFloat(mySampleRow + mySampleCol);
}
return mySound;
}
/**
* Searches a ByteArray (from a Sound() object) for a valid DTMF tone.
*
* @param tone ByteArray that should contain a valid DTMF tone.
* @return string representation of DTMF tones. Will return a blank string ('') if nothing is found
*
*/
public function searchDTMF(tone:ByteArray):String
{
var position:int = 0;
var charFound:String = "";
// seed blank values for strongest tone to be found in the byteArray
var maxCol:int = -1;
var maxColValue:int = 0;
var maxRow:int = -1;
var maxRowValue:int = 0;
var foundTones:String = "";
// reset the byteArray to the beginning, should we have gotten it in any other state.
tone.position = position;
// break up the byteArray in manageable chunks of 8192 bytes.
for (var bufferLoop:int =0; bufferLoop < tone.bytesAvailable; bufferLoop =+ 8192)
{
position = bufferLoop;
// search for the column tone.
for (var col:int = 0; col < 4; col++)
{
if (powerDB(goertzel(tone,8192,COL1[col],position)) > maxColValue)
{
maxColValue = powerDB(goertzel(tone,8192,COL1[col],position));
maxCol = col;
}
}
// search for the row tone.
for (var row:int = 0; row < 4; row++)
{
if (powerDB(goertzel(tone,8192,COL2[row],position)) > maxRowValue)
{
maxRowValue = powerDB(goertzel(tone,8192,COL2[row],position));
maxRow = row;
}
}
// was there enough strength in both the column and row to be valid?
if ((maxColValue < DTMFToneSensitivity) || (maxRowValue < DTMFToneSensitivity))
{
charFound = "";
}
else
{
charFound = DTMF_LAYOUT[maxCol][maxRow];
}
if (lastFound != charFound)
{
trace("Found DTMF Tone:",charFound);
lastFound = charFound; // this is so we don't have duplicates.
foundTones = foundTones + lastFound;
}
}
return foundTones;
}
/**
* Converts amplitude to dB (power).
*
* @param value amplitude value
* @return dB
*
*/
private function powerDB(value:Number):Number
{
return 20 * Math.log(Math.abs(value))*Math.LOG10E;
}
/**
* This function returns the amplitude of the a seeked wave in the buffer.
*
* @param buffer the byteArray that is being searched.
* @param bufferSize the size of the buffer that we wish to search.
* @param frequency the frequency (in Hz) that we are searching for.
* @param bufferPos the starting point that we want to search from.
* @return amplitude of the searched frequency, if any.
*
*/
private function goertzel(buffer:ByteArray, bufferSize:int, frequency:int, bufferPos:int):Number
{
var skn:Number = 0;
var skn1:Number = 0;
var skn2:Number = 0;
buffer.position = bufferPos;
for (var i:int=0; i < bufferSize; i++)
{
skn2 = skn1;
skn1 = skn;
if (buffer.bytesAvailable > 0)
skn = 2 * Math.cos(2 * Math.PI * frequency / sampleRate) * skn1 - skn2 + buffer.readFloat();
}
var wnk:Number = Math.exp(-2 * Math.PI * frequency / sampleRate);
return (skn - wnk * skn1);
}
/**
* Returns the Hz of the string tone that is searched.
*
* @param tone character that is being search for
* @return an untyped object that has col and row properties that contain the Hz of the DTMF tone.
*
*/
private function findDTMF(tone:String):Object
{
var myDTMF:Object = new Object();
switch(tone)
{
case "1":
myDTMF.col = COL1[0];
myDTMF.row = COL2[0];
break;
case "2":
myDTMF.col = COL1[0];
myDTMF.row = COL2[1];
break;
case "3":
myDTMF.col = COL1[0];
myDTMF.row = COL2[2];
break;
case "A":
myDTMF.col = COL1[0];
myDTMF.row = COL2[3];
break;
case "4":
myDTMF.col = COL1[1];
myDTMF.row = COL2[0];
break;
case "5":
myDTMF.col = COL1[1];
myDTMF.row = COL2[1];
break;
case "6":
myDTMF.col = COL1[1];
myDTMF.row = COL2[2];
break;
case "B":
myDTMF.col = COL1[1];
myDTMF.row = COL2[3];
break;
case "7":
myDTMF.col = COL1[2];
myDTMF.row = COL2[0];
break;
case "8":
myDTMF.col = COL1[2];
myDTMF.row = COL2[1];
break;
case "9":
myDTMF.col = COL1[2];
myDTMF.row = COL2[2];
break;
case "C":
myDTMF.col = COL1[2];
myDTMF.row = COL2[3];
break;
case "*":
myDTMF.col = COL1[3];
myDTMF.row = COL2[0];
break;
case "0":
myDTMF.col = COL1[3];
myDTMF.row = COL2[1];
break;
case "#":
myDTMF.col = COL1[3];
myDTMF.row = COL2[2];
break;
case "D":
myDTMF.col = COL1[3];
myDTMF.row = COL2[2];
break;
default:
myDTMF.col = 0;
myDTMF.row = 0;
}
return myDTMF;
}
}
}
关于Java (J2SE) DTMF 音调检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17539366/
我开发了 android 应用程序,可以在单击按钮时调用其他人,但现在我想在需要时将 dtmf 音调从应用程序发送到该呼出电话。那么该怎么做呢? 最佳答案 其实是可以的。它不是那么明显,也不是那么优雅
我有以下拨号方案: exten => 224,1,NoOp(IN CALL : ${CALLERID(num)} => ${EXTEN}) exten => 224,n,Dial(${
我想知道是否有人遇到过在 iPhone SDK 中生成铃声的方法。我正在尝试生成 DTMF 音调,但似乎找不到任何实质性内容。我还希望能够指定播放音调的时间(即模拟按住按钮而不是简单地按下按钮....
所以我打开了一个我在 audacity 中生成的 DTMF 音调的 .raw 文件。我抓取了一个类似于维基百科文章中的 jar 装 goertzel 算法。虽然它似乎没有解码正确的数字。 解码后的数字
我正在尝试为基于 WebRTC 的 Android/iOS 应用程序实现 DTMF。是否有适用于 Android 的 DTMF API?我试过调用以下内容: m_peerConnectionFacto
所以我打开了一个我在 audacity 中生成的 DTMF 音调的 .raw 文件。我抓取了一个类似于维基百科文章中的 jar 装 goertzel 算法。虽然它似乎没有解码正确的数字。 解码后的数字
我正在尝试为基于 WebRTC 的 Android/iOS 应用程序实现 DTMF。是否有适用于 Android 的 DTMF API?我试过调用以下内容: m_peerConnectionFacto
我需要在我的应用程序中开发拨号盘,就像原生 iPhone 手机应用程序拨号盘一样。我已将 .wav 文件添加到我的项目中,以便在单击数字按钮时播放声音,但它们太大声了。但 iPhone 手机应用程序拨
我正在尝试执行以下操作 我正在使用我的 java 应用程序给另一个人打电话(已经完成并且工作正常)。 然后我正在播放录音,例如“请按 1 以继续用英语”(已经完成并且工作正常)。 现在我想检测那个人按
我已经阅读了有关用于检测带内 dtmf 的 freeswitch 中的 start_dtmf 应用程序。 我已经测试过这个,但它没有检测到任何 DTMF。 请帮我。 最佳答案 老问题,但值得
我只需要一段 java 代码,它可以从麦克风中检测 DTMF,并将字符打印到 System.out。我一直在寻找,但找不到。 最佳答案 关于用 Java 捕获音频的 Oracle 文档: http:/
从此处找到的示例开始:https://trac.pjsip.org/repos/wiki/Getting-Started/Android ,我设法构建并运行了 pjsua2 示例应用程序。 问题是我无
有什么方法可以动态生成上行链路 DTMF 音(即接收器听到它)? 当我查看 android 源代码时,我看到了一个名为 startDTMF() 的函数,这正是我所需要的,但我找不到任何允许我访问该函数
我正在使用 android SIP(android.net.sip) 进行 VOIP 通话。正在尝试发送 DTMF。在SipAudioCall类的android中给出了两个方法 void sendDt
我想在接听电话后调用一个号码,这通常是通过通话中的拨号盘完成的。 我尝试了以下方法,但开始调用新电话(ACTION_VIEW 也是如此)。 Intent dial = new Intent(Inten
我正在调用一个带有号码的通话应用程序,然后通过 发送 dtmf 音 String number = "tel:+1234567,890#"; Intent c1 = new Intent(androi
Android 的新手。我有一个应用程序正在运行,我正在生成 DTMF 信号并解释微 Controller 生成的内容。我成功地生成了音调,但是音调是通过扬声器播放的,我想通过一个拼接的耳机插孔播放音
我有一个拨号方案,我想要的是,如果用户按任意键然后再次播放文件,但我不明白如何在拨号方案中获取dtmf 值。这是我的拨号方案: [callme] exten => s,1,Answer exten
我正在开展一个项目,该项目要求我的应用能够在通话期间以语音的上行链路频率发送 DTMF 音。 我的两个条件是: 我们不使用定制的 Android 平台 我们不需要root手机 我花了几天时间做功课,并
我正在将 CallKit 与 VOIP 应用集成。我能够拨入和拨出电话。我遵循了以下步骤: 配置 Audio Session 在(didActivate)中启动音频 在(didDeActivate)中
我是一名优秀的程序员,十分优秀!