/ added an option to use the AST vad DSP for DTMF detection

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5059 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Ben Kramer 21 years ago
parent fccd0750b2
commit 37fcb4fc3f

@ -32,6 +32,7 @@ extern "C" {
#include <asterisk/pbx.h> #include <asterisk/pbx.h>
#include <asterisk/options.h> #include <asterisk/options.h>
#include <asterisk/callerid.h> #include <asterisk/callerid.h>
#include <asterisk/dsp.h>
} }
@ -145,6 +146,14 @@ static int UseNativeBridge=1;
/* Use Asterisk Indication or VPB */ /* Use Asterisk Indication or VPB */
static int use_ast_ind=0; static int use_ast_ind=0;
/* Use Asterisk DTMF detection or VPB */
static int use_ast_dtmfdet=0;
static int relaxdtmf=0;
/* Use Asterisk DTMF play back or VPB */
static int use_ast_dtmf=0;
/* Set EC suppression threshold */ /* Set EC suppression threshold */
static int ec_supp_threshold=-1; static int ec_supp_threshold=-1;
@ -271,6 +280,8 @@ static struct vpb_pvt {
void *dtmfidd_timer; /* Void pointer for DTMF IDD vpb_timer */ void *dtmfidd_timer; /* Void pointer for DTMF IDD vpb_timer */
int dtmfidd_timer_id; /* unique timer ID for DTMF IDD timer */ int dtmfidd_timer_id; /* unique timer ID for DTMF IDD timer */
struct ast_dsp *vad; /* AST Voice Activation Detection dsp */
double lastgrunt; /* time stamp (secs since epoc) of last grunt event */ double lastgrunt; /* time stamp (secs since epoc) of last grunt event */
ast_mutex_t lock; /* This one just protects bridge ptr below */ ast_mutex_t lock; /* This one just protects bridge ptr below */
@ -721,8 +732,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
int res=0; int res=0;
if (option_verbose > 3) if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: got event: [%d=>%d]\n", ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: got event: [%d=>%d]\n", p->dev, e->type, e->data);
p->dev, e->type, e->data);
f.src = type; f.src = type;
switch (e->type) { switch (e->type) {
@ -767,8 +777,11 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
} }
break; break;
case VPB_DTMF_DOWN:
case VPB_DTMF: case VPB_DTMF:
if (p->owner->_state == AST_STATE_UP) { if (use_ast_dtmfdet){
f.frametype = -1;
} else if (p->owner->_state == AST_STATE_UP) {
f.frametype = AST_FRAME_DTMF; f.frametype = AST_FRAME_DTMF;
f.subclass = e->data; f.subclass = e->data;
} else } else
@ -1471,15 +1484,33 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t
vpb_timer_open(&tmp->dtmfidd_timer, tmp->handle, tmp->dtmfidd_timer_id, dtmf_idd); vpb_timer_open(&tmp->dtmfidd_timer, tmp->handle, tmp->dtmfidd_timer_id, dtmf_idd);
if (mode == MODE_FXO){ if (mode == MODE_FXO){
vpb_set_event_mask(tmp->handle, VPB_EVENTS_ALL ); if (use_ast_dtmfdet)
vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF );
else
vpb_set_event_mask(tmp->handle, VPB_EVENTS_ALL );
} }
else { else {
vpb_set_event_mask(tmp->handle, VPB_EVENTS_STAT ); /*
if (use_ast_dtmfdet)
vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF );
else
*/
vpb_set_event_mask(tmp->handle, VPB_EVENTS_STAT );
} }
if ((tmp->vpb_model == vpb_model_v12pci) && (echo_cancel)){ if ((tmp->vpb_model == vpb_model_v12pci) && (echo_cancel)){
vpb_hostecho_on(tmp->handle); vpb_hostecho_on(tmp->handle);
} }
if (use_ast_dtmfdet) {
tmp->vad = ast_dsp_new();
ast_dsp_set_features(tmp->vad, DSP_FEATURE_DTMF_DETECT);
ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF );
if (relaxdtmf)
ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
}
else {
tmp->vad = NULL;
}
/* define grunt tone */ /* define grunt tone */
vpb_settonedet(tmp->handle,&toned_ungrunt); vpb_settonedet(tmp->handle,&toned_ungrunt);
@ -1689,7 +1720,7 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
ast->name, call.tone_map[j].tone_id, call.tone_map[j].call_id); ast->name, call.tone_map[j].tone_id, call.tone_map[j].call_id);
} }
if (option_verbose > 4) if (option_verbose > 3)
ast_verbose("%s: Disabling Loop Drop detection\n",p->dev); ast_verbose("%s: Disabling Loop Drop detection\n",p->dev);
vpb_disable_event(p->handle, VPB_MDROP); vpb_disable_event(p->handle, VPB_MDROP);
vpb_sethook_sync(p->handle,VPB_OFFHOOK); vpb_sethook_sync(p->handle,VPB_OFFHOOK);
@ -1697,13 +1728,13 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
#ifndef DIAL_WITH_CALL_PROGRESS #ifndef DIAL_WITH_CALL_PROGRESS
vpb_sleep(300); vpb_sleep(300);
if (option_verbose > 4) if (option_verbose > 3)
ast_verbose("%s: Disabling Loop Drop detection\n",p->dev); ast_verbose("%s: Enabling Loop Drop detection\n",p->dev);
vpb_enable_event(p->handle, VPB_MDROP); vpb_enable_event(p->handle, VPB_MDROP);
res = vpb_dial_async(p->handle, dialstring); res = vpb_dial_async(p->handle, dialstring);
#else #else
if (option_verbose > 4) if (option_verbose > 3)
ast_verbose("%s: Disabling Loop Drop detection\n",p->dev); ast_verbose("%s: Enabling Loop Drop detection\n",p->dev);
vpb_enable_event(p->handle, VPB_MDROP); vpb_enable_event(p->handle, VPB_MDROP);
res = vpb_call_async(p->handle, dialstring); res = vpb_call_async(p->handle, dialstring);
#endif #endif
@ -1749,12 +1780,18 @@ static int vpb_hangup(struct ast_channel *ast)
if (option_verbose > 1) if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "%s: Hangup requested\n", ast->name); ast_verbose(VERBOSE_PREFIX_2 "%s: Hangup requested\n", ast->name);
if (!ast->pvt || !ast->pvt->pvt) { if (!ast->pvt || !ast->pvt->pvt) {
ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name); ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name);
res = ast_mutex_unlock(&p->lock); res = ast_mutex_unlock(&p->lock);
/* /*
if (option_verbose > 3) ast_verbose("%s: unLOCKING in hangup [%d]\n", p->dev,res); if (option_verbose > 3) ast_verbose("%s: unLOCKING in hangup [%d]\n", p->dev,res);
*/ */
/* Free up ast dsp if we have one */
if ((use_ast_dtmfdet)&&(p->vad)) {
ast_dsp_free(p->vad);
p->vad = NULL;
}
return 0; return 0;
} }
@ -1765,13 +1802,13 @@ static int vpb_hangup(struct ast_channel *ast)
if( p->readthread ){ if( p->readthread ){
pthread_join(p->readthread, NULL); pthread_join(p->readthread, NULL);
if(option_verbose>3) if(option_verbose>3)
ast_verbose( VERBOSE_PREFIX_4 "%s: stopped record thread on %s\n",ast->name,p->dev); ast_verbose( VERBOSE_PREFIX_4 "%s: stopped record thread \n",ast->name);
} }
/* Stop play */ /* Stop play */
if (p->lastoutput != -1) { if (p->lastoutput != -1) {
if(option_verbose>1) if(option_verbose>1)
ast_verbose( VERBOSE_PREFIX_2 "%s: Ending play mode on %s\n",ast->name,p->dev); ast_verbose( VERBOSE_PREFIX_2 "%s: Ending play mode \n",ast->name);
vpb_play_terminate(p->handle); vpb_play_terminate(p->handle);
ast_mutex_lock(&p->play_lock); { ast_mutex_lock(&p->play_lock); {
vpb_play_buf_finish(p->handle); vpb_play_buf_finish(p->handle);
@ -1827,6 +1864,12 @@ static int vpb_hangup(struct ast_channel *ast)
p->owner = NULL; p->owner = NULL;
ast->pvt->pvt=NULL; ast->pvt->pvt=NULL;
/* Free up ast dsp if we have one */
if ((use_ast_dtmfdet)&&(p->vad)) {
ast_dsp_free(p->vad);
p->vad = NULL;
}
ast_mutex_lock(&usecnt_lock); { ast_mutex_lock(&usecnt_lock); {
usecnt--; usecnt--;
} ast_mutex_unlock(&usecnt_lock); } ast_mutex_unlock(&usecnt_lock);
@ -2166,7 +2209,7 @@ static void *do_chanreads(void *pvt)
if( getdtmf_var && ( strcasecmp( getdtmf_var, "yes" ) == 0 ) ) if( getdtmf_var && ( strcasecmp( getdtmf_var, "yes" ) == 0 ) )
ignore_dtmf = 0; ignore_dtmf = 0;
if( ignore_dtmf != p->last_ignore_dtmf ) { if(( ignore_dtmf != p->last_ignore_dtmf ) &&(!use_ast_dtmfdet)){
if(option_verbose>1) if(option_verbose>1)
ast_verbose( VERBOSE_PREFIX_2 "%s:Now %s DTMF \n", ast_verbose( VERBOSE_PREFIX_2 "%s:Now %s DTMF \n",
p->dev, ignore_dtmf ? "ignoring" : "listening for"); p->dev, ignore_dtmf ? "ignoring" : "listening for");
@ -2251,7 +2294,13 @@ static void *do_chanreads(void *pvt)
fr->subclass = afmt; fr->subclass = afmt;
fr->data = readbuf; fr->data = readbuf;
fr->datalen = readlen; fr->datalen = readlen;
fr->frametype = AST_FRAME_VOICE;
if ((use_ast_dtmfdet)&&(p->vad)){
fr = ast_dsp_process(p->owner,p->vad,fr);
if (fr && (fr->frametype == AST_FRAME_DTMF))
ast_log(LOG_DEBUG, "%s: chanreads: Detected DTMF '%c'\n",p->dev, fr->subclass);
}
/* Using trylock here to prevent deadlock when channel is hungup /* Using trylock here to prevent deadlock when channel is hungup
* (ast_hangup() immediately gets lock) * (ast_hangup() immediately gets lock)
*/ */
@ -2364,7 +2413,8 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
} }
tmp->pvt->pvt = me; tmp->pvt->pvt = me;
/* set call backs */ /* set call backs */
tmp->pvt->send_digit = vpb_digit; if (use_ast_dtmf == 0)
tmp->pvt->send_digit = vpb_digit;
tmp->pvt->call = vpb_call; tmp->pvt->call = vpb_call;
tmp->pvt->hangup = vpb_hangup; tmp->pvt->hangup = vpb_hangup;
tmp->pvt->answer = vpb_answer; tmp->pvt->answer = vpb_answer;
@ -2527,6 +2577,18 @@ int load_module()
use_ast_ind = 1; use_ast_ind = 1;
ast_log(LOG_NOTICE,"VPB driver using Asterisk Indication functions!\n"); ast_log(LOG_NOTICE,"VPB driver using Asterisk Indication functions!\n");
} }
else if (strcasecmp(v->name, "ast-dtmf") == 0) {
use_ast_dtmf = 1;
ast_log(LOG_NOTICE,"VPB driver using Asterisk DTMF play functions!\n");
}
else if (strcasecmp(v->name, "ast-dtmf-det") == 0) {
use_ast_dtmfdet = 1;
ast_log(LOG_NOTICE,"VPB driver using Asterisk DTMF detection functions!\n");
}
else if (strcasecmp(v->name, "relaxdtmf") == 0) {
relaxdtmf = 1;
ast_log(LOG_NOTICE,"VPB driver using Relaxed DTMF with Asterisk DTMF detections functions!\n");
}
else if (strcasecmp(v->name, "ecsuppthres") ==0) { else if (strcasecmp(v->name, "ecsuppthres") ==0) {
ec_supp_threshold = atoi(v->value); ec_supp_threshold = atoi(v->value);
} }

Loading…
Cancel
Save