Skip to content

Commit

Permalink
优化DTMF扩展
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangyuecn committed Jun 26, 2020
1 parent 014975c commit 24be059
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 32 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,8 @@ sonic.flush(callback) //callback:fn(pcm),和同步方法相同,只是返回
## `DTMF`扩展
[dtmf.decode.js](https://github.com/xiangyuecn/Recorder/blob/master/src/extensions/dtmf.decode.js) + [lib.fft.js](https://github.com/xiangyuecn/Recorder/blob/master/src/extensions/lib.fft.js)[dtmf.encode.js](https://github.com/xiangyuecn/Recorder/blob/master/src/extensions/dtmf.encode.js),两个js一个解码、一个编码,体积小均不超过10kb,纯js实现易于移植。[参考此demo片段在线测试使用](https://xiangyuecn.github.io/Recorder/assets/工具-代码运行和静态分发Runtime.html?jsname=teach.dtmf.decode_and_encode)

1. DTMF(电话拨号按键信号)解码器,解码得到按键值:可实现实时从音频数据流中解码得到电话拨号按键信息,用于电话录音软解,软电话实时提取DTMF按键信号等;请注意:使用dtmf.decode.js必须同时引入`lib.fft.js`才能正常工作。
2. DTMF(电话拨号按键信号)编码生成器,生成按键对应的音频PCM信号:可实现生成按键对应的音频PCM信号,用于DTMF按键信号生成,软电话实时发送DTMF按键信号等。
1. DTMF(电话拨号按键信号)解码器,解码得到按键值:可实现实时从音频数据流中解码得到电话拨号按键信息,用于电话录音软解,软电话实时提取DTMF按键信号等;识别DTMF按键准确度高,误识别率低,支持识别120ms以上按键间隔+30ms以上的按键音,纯js实现易于移植;请注意:使用dtmf.decode.js必须同时引入`lib.fft.js`(由java移植过来的)才能正常工作。
2. DTMF(电话拨号按键信号)编码生成器,生成按键对应的音频PCM信号:可实现生成按键对应的音频PCM信号,用于DTMF按键信号生成,软电话实时发送DTMF按键信号等;生成信号代码、原理简单粗暴,纯js实现易于移植,0依赖

### 【方法】Recorder.DTMF_Decode(pcmData,sampleRate,prevChunk)
解码DTMF只有这个一个函数,此函数支持连续调用,将上次的返回值当做参数即可实现实时音频流数据的连续解码处理。
Expand Down Expand Up @@ -827,12 +827,12 @@ sonic.flush(callback) //callback:fn(pcm),和同步方法相同,只是返回
```

### 【方法】Recorder.DTMF_EncodeMix(set)
本方法返回EncodeMix对象,将输入的按键信号混合到持续输入的pcm流中,当.mix(inputPcm)提供的太短的pcm会无法完整放下一个完整的按键信号,所以需要不停调用.mix(inputPcm)进行混合。
本方法返回EncodeMix对象,将输入的按键信号混合到持续输入的pcm流中,当.mix(inputPcms)提供的太短的pcm会无法完整放下一个完整的按键信号,所以需要不停调用.mix(inputPcms)进行混合。
``` javascript
set={
duration:100 //按键信号持续时间
,mute:50 //按键音前后静音时长
,interval:250 //两次按键信号间隔时长
duration:100 //按键信号持续时间 ms,最小值为30ms
,mute:25 //按键音前后静音时长 ms,取值为0也是可以的
,interval:200 //两次按键信号间隔时长 ms,间隔内包含了duration+mute*2,最小值为120ms
}

EncodeMix对象:
Expand All @@ -845,7 +845,7 @@ EncodeMix对象:
newEncodes:[{key:"*",data:[Int16,...]},...] //本次混合新生成的按键信号列表 ,如果没有产生新信号将为空数组
,hasNext:false //是否还有未混合完的信号
}
注意:调用本方法会修改pcms中的内容,因此混合结果就在pcms内。
注意:调用本方法会修改pcms中的内容,因此混合结果就在pcms内。
```


Expand Down
8 changes: 4 additions & 4 deletions assets/npm-home/hash-history.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
[
{
"sha1": "326682217de610f15e0e456fdfe0725362dc5cd2",
"time": "2020-6-26 19:35:22"
},
{
"sha1": "ebbcd0cd7c989445ad1c03a053a75aed4672c10c",
"time": "2020-6-25 23:11:10"
Expand All @@ -14,9 +18,5 @@
{
"sha1": "0e8571bd082df5986d815921360eda7f64034ae5",
"time": "2020-5-16 23:29:15"
},
{
"sha1": "7c4f45cbbffd7d739bf8ed1f52d703459575a686",
"time": "2020-5-16 18:43:21"
}
]
8 changes: 4 additions & 4 deletions assets/runtime-codes/teach.dtmf.decode_and_encode.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ var sendKeysClick=function(){
var sendKeys=function(keys){
if(!dtmfMix){
dtmfMix=Recorder.DTMF_EncodeMix({
duration:100 //按键信号持续时间
,mute:50 //按键音前后静音时长
,interval:300 //两次按键信号间隔时长
duration:100 //按键信号持续时间 ms,最小值为30ms
,mute:25 //按键音前后静音时长 ms,取值为0也是可以的
,interval:200 //两次按键信号间隔时长 ms,间隔内包含了duration+mute*2,最小值为120ms
});
};
if(!rec){
Expand All @@ -80,7 +80,7 @@ var sendKeys=function(keys){
dtmfMix.add(keys);
//添加过去就不用管了,实时处理时会调用mix方法混入到pcm中。
};
var dtmfMix;
var dtmfMix=null;



Expand Down
2 changes: 1 addition & 1 deletion dist/extensions/dtmf.decode.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/extensions/dtmf.encode.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1081,9 +1081,9 @@
var sendDTMFKeys=function(keys){
if(!dtmfMix){
dtmfMix=Recorder.DTMF_EncodeMix({
duration:100 //按键信号持续时间
,mute:50 //按键音前后静音时长
,interval:300 //两次按键信号间隔时长
duration:100 //按键信号持续时间 ms,最小值为30ms
,mute:25 //按键音前后静音时长 ms,取值为0也是可以的
,interval:200 //两次按键信号间隔时长 ms,间隔内包含了duration+mute*2,最小值为120ms
});
};
if(!rec||!rec.buffers){
Expand Down
4 changes: 3 additions & 1 deletion src/extensions/dtmf.decode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
录音 Recorder扩展,DTMF(电话拨号按键信号)解码器,解码得到按键值
使用本扩展需要引入lib.fft.js支持
本扩展识别DTMF按键准确度高,误识别率低,支持识别120ms以上按键间隔+30ms以上的按键音,纯js实现易于移植
使用场景:电话录音软解,软电话实时提取DTMF按键信号等
https://github.com/xiangyuecn/Recorder
*/
Expand Down Expand Up @@ -179,7 +181,7 @@ var FindIndex=function(freq, freqs, freqStep){
var xb=Math.abs(freqs[i]-freq);
if(idxb>xb){
idxb=xb;
if(xb<freqStep*2){//2个分辨率内误差
if(xb<freqStep){//最多1个分辨率内误差
idx=i;
};
};
Expand Down
24 changes: 13 additions & 11 deletions src/extensions/dtmf.encode.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
DTMF_Encode
DTMF_EncodeMix
本扩展生成信号代码、原理简单粗暴,纯js实现易于移植,0依赖
使用场景:DTMF按键信号生成,软电话实时发送DTMF按键信号等
https://github.com/xiangyuecn/Recorder
*/
Expand Down Expand Up @@ -45,16 +47,16 @@ Recorder.DTMF_Encode=function(key,sampleRate,duration,mute){
};


/**返回EncodeMix对象,将输入的按键信号混合到持续输入的pcm流中,当.mix(inputPcm)提供的太短的pcm会无法完整放下一个完整的按键信号,所以需要不停调用.mix(inputPcm)进行混合**/
/**返回EncodeMix对象,将输入的按键信号混合到持续输入的pcm流中,当.mix(inputPcms)提供的太短的pcm会无法完整放下一个完整的按键信号,所以需要不停调用.mix(inputPcms)进行混合**/
Recorder.DTMF_EncodeMix=function(set){
return new EncodeMix(set);
};
var EncodeMix=function(set){
var This=this;
This.set={
duration:100 //按键信号持续时间
,mute:50 //按键音前后静音时长
,interval:250 //两次按键信号间隔时长
duration:100 //按键信号持续时间 ms,最小值为30ms
,mute:25 //按键音前后静音时长 ms,取值为0也是可以的
,interval:200 //两次按键信号间隔时长 ms,间隔内包含了duration+mute*2,最小值为120ms
};
for(var k in set){
This.set[k]=set[k];
Expand All @@ -76,17 +78,17 @@ EncodeMix.prototype={
index||(index=0);
var This=this,set=This.set;
var newEncodes=[];
var hasNext=0;

var state=This.state;
var pcmPos=0;
loop:
for(var i0=index;This.keys.length>This.idx && i0<pcms.length;i0++){
for(var i0=index;i0<pcms.length;i0++){
var pcm=pcms[i0];
var state=This.state;

var key=This.keys.charAt(This.idx);
while(key){
hasNext=1;
if(!key){//没有需要处理的按键,把间隔消耗掉
state.skip=Math.max(0, state.skip-pcm.length);
} else while(key){
//按键间隔处理
if(state.skip){
var op=pcm.length-pcmPos;
Expand Down Expand Up @@ -123,6 +125,7 @@ EncodeMix.prototype={
//将keyPcm混合到当前pcm中,实际是替换逻辑
var res=Mix(pcm,pcmPos,keyPcm,state.cur,true);
state.cur=res.cur;
pcmPos=res.last;

//下一个按键
if(res.cur>=keyPcm.length){
Expand All @@ -137,12 +140,11 @@ EncodeMix.prototype={
continue loop;//下一个pcm
};
};
hasNext=0;
};

return {
newEncodes:newEncodes //本次混合新生成的按键信号列表 [{key:"*",data:[Int16,...]},...],如果没有产生新信号将为空数组
,hasNext:!!hasNext //是否还有未混合完的信号
,hasNext:This.idx<This.keys.length //是否还有未混合完的信号
};
}
};
Expand Down

0 comments on commit 24be059

Please sign in to comment.