Added silence detection in voice receive mode.
This commit is contained in:
parent
3cfb46944c
commit
724fa0901a
|
@ -50,10 +50,11 @@ The following commands are supported:
|
|||
the application. See below for data format
|
||||
|
||||
AT+VSD=x,y Set silence-detection parameters.
|
||||
NO EFFECT, supported for compatibility
|
||||
only. Possible parameters:
|
||||
x = 0 ... 31
|
||||
y = 0 ... 255
|
||||
Possible parameters:
|
||||
x = 0 ... 31 sensitivity threshold level.
|
||||
(default 0 , deactivated)
|
||||
y = 0 ... 255 range of interval in units
|
||||
of 0.1 second. (default 70)
|
||||
AT+VSD=? Report possible parameters.
|
||||
AT+VSD? Show current parameters.
|
||||
|
||||
|
@ -102,13 +103,14 @@ General behavior and description of data formats/protocol.
|
|||
<DLE>C Touchtone "C" received.
|
||||
<DLE>D Touchtone "D" received.
|
||||
|
||||
<DLE>q quiet. Silence detected after non-silence.
|
||||
<DLE>s silence. Silence detected from the
|
||||
start of recording.
|
||||
|
||||
Currently unsupported DLE sequences:
|
||||
|
||||
<DLE>c FAX calling tone received.
|
||||
<DLE>b busy tone received.
|
||||
<DLE>q quiet. Silence detected after non-silence.
|
||||
<DLE>s silence. Silence detected from the
|
||||
start of recording.
|
||||
|
||||
Audio playback.
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
* Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de)
|
||||
* DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
|
||||
* Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,6 +21,9 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.11 1998/04/10 10:35:10 paul
|
||||
* fixed (silly?) warnings from egcs on Alpha.
|
||||
*
|
||||
* Revision 1.10 1998/02/20 17:09:40 fritz
|
||||
* Changes for recent kernels.
|
||||
*
|
||||
|
@ -660,3 +664,92 @@ isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
|
|||
len -= c;
|
||||
}
|
||||
}
|
||||
|
||||
silence_state *
|
||||
isdn_audio_silence_init(silence_state * s)
|
||||
{
|
||||
if (!s)
|
||||
s = (silence_state *) kmalloc(sizeof(silence_state), GFP_ATOMIC);
|
||||
if (s) {
|
||||
s->idx = 0;
|
||||
s->state = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
|
||||
{
|
||||
silence_state *s = info->silence_state;
|
||||
int i;
|
||||
signed char c;
|
||||
|
||||
if (!info->emu.vpar[1]) return;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (fmt)
|
||||
c = isdn_audio_alaw_to_ulaw[*buf++];
|
||||
else
|
||||
c = *buf++;
|
||||
|
||||
if (c > 0) c -= 128;
|
||||
c = abs(c);
|
||||
|
||||
if (c > (info->emu.vpar[1] * 4)) {
|
||||
s->idx = 0;
|
||||
s->state = 1;
|
||||
} else {
|
||||
if (s->idx < 210000) s->idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isdn_audio_eval_silence(modem_info * info)
|
||||
{
|
||||
silence_state *s = info->silence_state;
|
||||
struct sk_buff *skb;
|
||||
unsigned long flags;
|
||||
int di;
|
||||
int ch;
|
||||
char what;
|
||||
char *p;
|
||||
|
||||
what = ' ';
|
||||
|
||||
if (s->idx > (info->emu.vpar[2] * 800)) {
|
||||
s->idx = 0;
|
||||
if (!s->state) { /* silence from beginning of rec */
|
||||
what = 's';
|
||||
} else {
|
||||
what = 'q';
|
||||
}
|
||||
}
|
||||
if ((what == 's') || (what == 'q')) {
|
||||
printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
|
||||
(what=='s') ? "silence":"quiet");
|
||||
skb = dev_alloc_skb(2);
|
||||
p = (char *) skb_put(skb, 2);
|
||||
p[0] = 0x10;
|
||||
p[1] = what;
|
||||
if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
|
||||
printk(KERN_WARNING
|
||||
"isdn_audio: insufficient skb_headroom, dropping\n");
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
|
||||
ISDN_AUDIO_SKB_LOCK(skb) = 0;
|
||||
save_flags(flags);
|
||||
cli();
|
||||
di = info->isdn_driver;
|
||||
ch = info->isdn_channel;
|
||||
__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
|
||||
dev->drv[di]->rcvcount[ch] += 2;
|
||||
restore_flags(flags);
|
||||
/* Schedule dequeuing */
|
||||
if ((dev->modempoll) && (info->rcvsched))
|
||||
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
|
||||
wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.5 1997/02/03 22:45:21 fritz
|
||||
* Reformatted according CodingStyle
|
||||
*
|
||||
* Revision 1.4 1996/06/06 14:43:32 fritz
|
||||
* Changed to support DTMF decoding on audio playback also.
|
||||
*
|
||||
|
@ -48,6 +51,11 @@ typedef struct dtmf_state {
|
|||
int buf[DTMF_NPOINTS];
|
||||
} dtmf_state;
|
||||
|
||||
typedef struct silence_state {
|
||||
int state;
|
||||
unsigned int idx;
|
||||
} silence_state;
|
||||
|
||||
extern void isdn_audio_ulaw2alaw(unsigned char *, unsigned long);
|
||||
extern void isdn_audio_alaw2ulaw(unsigned char *, unsigned long);
|
||||
extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int);
|
||||
|
@ -57,3 +65,6 @@ extern int isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out);
|
|||
extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int);
|
||||
extern void isdn_audio_eval_dtmf(modem_info *);
|
||||
dtmf_state *isdn_audio_dtmf_init(dtmf_state *);
|
||||
extern void isdn_audio_calc_silence(modem_info *, unsigned char *, int, int);
|
||||
extern void isdn_audio_eval_silence(modem_info *);
|
||||
silence_state *isdn_audio_silence_init(silence_state *);
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.57 1998/06/26 15:12:36 fritz
|
||||
* Added handling of STAT_ICALL with incomplete CPN.
|
||||
* Added AT&L for ttyI emulator.
|
||||
* Added more locking stuff in tty_write.
|
||||
*
|
||||
* Revision 1.56 1998/06/18 23:31:51 fritz
|
||||
* Replaced cli()/restore_flags() in isdn_tty_write() by locking.
|
||||
* Removed direct-senddown feature in isdn_tty_write because it will
|
||||
|
@ -425,6 +430,8 @@ isdn_tty_readmodem(void)
|
|||
r = 0;
|
||||
#ifdef CONFIG_ISDN_AUDIO
|
||||
isdn_audio_eval_dtmf(info);
|
||||
if (info->emu.vpar[1])
|
||||
isdn_audio_eval_silence(info);
|
||||
#endif
|
||||
if ((tty = info->tty)) {
|
||||
if (info->mcr & UART_MCR_RTS) {
|
||||
|
@ -481,6 +488,8 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
|
|||
|
||||
if (info->vonline)
|
||||
isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt);
|
||||
if ((info->vonline & 1) && (info->emu.vpar[1]))
|
||||
isdn_audio_calc_silence(info, skb->data, skb->len, ifmt);
|
||||
#endif
|
||||
if ((info->online < 2)
|
||||
#ifdef CONFIG_ISDN_AUDIO
|
||||
|
@ -3462,6 +3471,11 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
|
|||
printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
|
||||
PARSE_ERROR1;
|
||||
}
|
||||
info->silence_state = isdn_audio_silence_init(info->silence_state);
|
||||
if (!info->silence_state) {
|
||||
printk(KERN_WARNING "isdn_tty: Couldn't malloc silence state\n");
|
||||
PARSE_ERROR1;
|
||||
}
|
||||
if (m->vpar[3] < 5) {
|
||||
info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]);
|
||||
if (!info->adpcmr) {
|
||||
|
@ -3488,31 +3502,27 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
|
|||
break;
|
||||
case '=':
|
||||
p[0]++;
|
||||
switch (*p[0]) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
par1 = isdn_getnum(p);
|
||||
if ((par1 < 0) || (par1 > 31))
|
||||
PARSE_ERROR1;
|
||||
if (*p[0] != ',')
|
||||
PARSE_ERROR1;
|
||||
p[0]++;
|
||||
par2 = isdn_getnum(p);
|
||||
if ((par2 < 0) || (par2 > 255))
|
||||
PARSE_ERROR1;
|
||||
m->vpar[1] = par1;
|
||||
m->vpar[2] = par2;
|
||||
break;
|
||||
case '?':
|
||||
p[0]++;
|
||||
isdn_tty_at_cout("\r\n<0-31>,<0-255>",
|
||||
info);
|
||||
break;
|
||||
default:
|
||||
if ((*p[0]>='0') && (*p[0]<='9')) {
|
||||
par1 = isdn_getnum(p);
|
||||
if ((par1 < 0) || (par1 > 31))
|
||||
PARSE_ERROR1;
|
||||
}
|
||||
if (*p[0] != ',')
|
||||
PARSE_ERROR1;
|
||||
p[0]++;
|
||||
par2 = isdn_getnum(p);
|
||||
if ((par2 < 0) || (par2 > 255))
|
||||
PARSE_ERROR1;
|
||||
m->vpar[1] = par1;
|
||||
m->vpar[2] = par2;
|
||||
break;
|
||||
} else
|
||||
if (*p[0] == '?') {
|
||||
p[0]++;
|
||||
isdn_tty_at_cout("\r\n<0-31>,<0-255>",
|
||||
info);
|
||||
break;
|
||||
} else
|
||||
PARSE_ERROR1;
|
||||
break;
|
||||
default:
|
||||
PARSE_ERROR1;
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.55 1998/06/26 15:13:17 fritz
|
||||
* Added handling of STAT_ICALL with incomplete CPN.
|
||||
* Added AT&L for ttyI emulator.
|
||||
* Added more locking stuff in tty_write.
|
||||
*
|
||||
* Revision 1.54 1998/06/18 23:32:01 fritz
|
||||
* Replaced cli()/restore_flags() in isdn_tty_write() by locking.
|
||||
* Removed direct-senddown feature in isdn_tty_write because it will
|
||||
|
@ -716,6 +721,7 @@ typedef struct modem_info {
|
|||
void *adpcms; /* state for adpcm decompression */
|
||||
void *adpcmr; /* state for adpcm compression */
|
||||
void *dtmf_state; /* state for dtmf decoder */
|
||||
void *silence_state; /* state for silence detection */
|
||||
#endif
|
||||
struct tty_struct *tty; /* Pointer to corresponding tty */
|
||||
atemu emu; /* AT-emulator data */
|
||||
|
|
Loading…
Reference in New Issue