TT#136956 add more options for DTMF replacement

Change-Id: Ic78a34042ad664bd54e35647636864ea99e60385
pull/1430/head
Richard Fuchs 4 years ago
parent 9608ae6ac5
commit 6ac4f12c01

@ -1527,7 +1527,24 @@ Optionally included keys are:
audio; `tone` which replaces DTMF events with a single sine wave tone;
`random` which replaces DTMF events with random other DTMF events (both
in-band DTMF audio tones and RFC event packets); `zero` which is
similar to `random` except that a zero event is always used.
similar to `random` except that a zero event is always used; `DTMF`
which is similar to `zero` except that a different DTMF digit can be
specified.
* `frequency`
Sets the tone frequency for `DTMF-security=tone` in Hertz. The default
is 400 Hz.
* `volume`
Sets the tone volume for `DTMF-security` modes `tone`, `zero, `DTMF`,
and `random` in negative dB. The default is -10 dB. The highest
possible volume is 0 dB and the lowest possible volume is -63 dB.
* `digit`
Sets the replacement digit for `DTMF-security=DTMF`.
* `delay-buffer`

@ -30,6 +30,7 @@
#include "media_player.h"
#include "dtmf.h"
#include "codec.h"
#include "dtmf.h"
struct fragment_key {
@ -958,6 +959,8 @@ void call_ng_flags_init(struct sdp_ng_flags *out, enum call_opmode opmode) {
out->el_option = rtpe_config.endpoint_learning;
out->tos = 256;
out->delay_buffer = -1;
out->volume = 9999;
out->digit = -1;
}
static void call_ng_dict_iter(struct sdp_ng_flags *out, bencode_item_t *input,
@ -1314,6 +1317,17 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_
break;
}
break;
case CSH_LOOKUP("frequency"):
out->frequency = bencode_get_integer_str(value, out->frequency);
break;
case CSH_LOOKUP("volume"):
out->volume = bencode_get_integer_str(value, out->volume);
break;
case CSH_LOOKUP("digit"):
out->digit = bencode_get_integer_str(value, out->digit);
if (s.len == 1)
out->digit = s.s[0];
break;
#ifdef WITH_TRANSCODING
case CSH_LOOKUP("T38"):
case CSH_LOOKUP("T.38"):
@ -1341,6 +1355,10 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_
case CSH_LOOKUP("zero"):
out->block_dtmf_mode = BLOCK_DTMF_ZERO;
break;
case CSH_LOOKUP("DTMF"):
case CSH_LOOKUP("dtmf"):
out->block_dtmf_mode = BLOCK_DTMF_DTMF;
break;
default:
ilog(LOG_WARN, "Unknown 'DTMF-security' flag encountered: '" STR_FORMAT "'",
STR_FMT(&s));
@ -2357,6 +2375,25 @@ static void call_monologue_set_block_mode(struct call_monologue *ml, struct sdp_
}
}
ml->detect_dtmf = flags->detect_dtmf;
if (flags->volume >= 0 && flags->volume <= 63)
ml->tone_vol = flags->volume;
else if (flags->volume < 0 && flags->volume >= -63)
ml->tone_vol = -1 * flags->volume;
if (flags->frequency > 0)
ml->tone_freq = flags->frequency;
if (flags->block_dtmf_mode == BLOCK_DTMF_ZERO)
ml->dtmf_digit = '0';
else {
char digit = dtmf_code_to_char(flags->digit);
if (digit)
ml->dtmf_digit = digit;
else if (dtmf_code_from_char(flags->digit) != -1)
ml->dtmf_digit = flags->digit;
}
codec_update_all_handlers(ml);
}
const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {

@ -2468,7 +2468,8 @@ static void delay_frame_manipulate(struct delay_frame *dframe) {
AVFrame *frame = dframe->frame;
if (is_in_dtmf_event(media, dframe->ts, frame->sample_rate, media->buffer_delay, media->buffer_delay)) {
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, media->monologue);
struct call_monologue *ml = media->monologue;
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, ml);
switch (mode) {
case BLOCK_DTMF_SILENCE:
@ -2476,17 +2477,19 @@ static void delay_frame_manipulate(struct delay_frame *dframe) {
break;
case BLOCK_DTMF_TONE:
frame_fill_tone_samples(frame->format, frame->extended_data[0], dframe->ts,
frame->nb_samples, 400, 10, frame->sample_rate, frame->channels);
frame->nb_samples, ml->tone_freq ? : 400,
ml->tone_vol ? : 10, frame->sample_rate, frame->channels);
break;
case BLOCK_DTMF_ZERO:
case BLOCK_DTMF_DTMF:
// if we have DTMF output, use silence, otherwise use a DTMF zero
if (dframe->ch->handler->dtmf_payload_type != -1)
memset(frame->extended_data[0], 0, frame->linesize[0]);
else
frame_fill_dtmf_samples(frame->format, frame->extended_data[0],
dframe->ts,
frame->nb_samples, 0,
10, frame->sample_rate,
frame->nb_samples, dtmf_code_from_char(ml->dtmf_digit),
ml->tone_vol ? : 10, frame->sample_rate,
frame->channels);
break;
case BLOCK_DTMF_RANDOM:
@ -2516,7 +2519,8 @@ static void delay_packet_manipulate(struct delay_frame *dframe) {
if (!dframe->handler->source_pt.codec_def || !dframe->handler->source_pt.codec_def->dtmf)
return;
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, media->monologue);
struct call_monologue *ml = media->monologue;
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, ml);
// this can be a "raw" or "packet" - get the appropriate payload
str *payload = &mp->raw;
@ -2529,7 +2533,8 @@ static void delay_packet_manipulate(struct delay_frame *dframe) {
switch (mode) {
case BLOCK_DTMF_ZERO:
dtmf->event = 0;
case BLOCK_DTMF_DTMF:
dtmf->event = dtmf_code_from_char(ml->dtmf_digit);
break;
default:
break;

@ -29,7 +29,7 @@ static unsigned int dtmf_volume_from_dsp(int vol) {
else
return 63;
}
static char dtmf_code_to_char(int code) {
char dtmf_code_to_char(int code) {
static const char codes[] = "0123456789*#ABCD";
if (code < 0 || code > 15)
return 0;

@ -212,7 +212,8 @@ enum block_dtmf_mode {
BLOCK_DTMF___PCM_REPLACE_END = 4,
// block modes that replace DTMF events with other DTMF events if possible
BLOCK_DTMF_ZERO = 5,
BLOCK_DTMF___REPLACE_END = 5,
BLOCK_DTMF_DTMF = 6,
BLOCK_DTMF___REPLACE_END = 6,
};
@ -463,7 +464,12 @@ struct call_monologue {
char *sdp_username;
char *sdp_session_name;
struct ssrc_hash *ssrc_hash;
// DTMF blocking/replacement stuff:
enum block_dtmf_mode block_dtmf;
unsigned int tone_freq;
unsigned int tone_vol;
char dtmf_digit;
unsigned int block_media:1;
unsigned int silence_media:1;

@ -78,6 +78,9 @@ struct sdp_ng_flags {
enum endpoint_learning el_option;
enum block_dtmf_mode block_dtmf_mode;
int delay_buffer;
int frequency;
int volume;
char digit;
unsigned int asymmetric:1,
protocol_accept:1,
no_redis_update:1,

@ -26,6 +26,7 @@ int dtmf_event_packet(struct media_packet *, str *, int, uint64_t ts); // 0 = ok
int dtmf_event_payload(str *, uint64_t *, uint64_t, struct dtmf_event *, GQueue *);
void dtmf_event_free(void *);
int dtmf_code_from_char(char);
char dtmf_code_to_char(int code);
const char *dtmf_inject(struct call_media *media, int code, int volume, int duration, int pause,
struct call_media *sink);
bool dtmf_do_logging(void);

@ -106,13 +106,16 @@ GetOptions(
'from-tags=s@' => \$options{'from-tags'},
'DTMF-security=s' => \$options{'DTMF-security'},
'delay-buffer=i' => \$options{'delay-buffer'},
'frequency=i' => \$options{'frequency'},
'volume=i' => \$options{'volume'},
'digit=s' => \$options{'digit'},
) or die;
my $cmd = shift(@ARGV) or die;
my %packet = (command => $cmd);
for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite,media echo,label,set-label,from-label,to-label,DTMF-security')) {
for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,ICE,address family,DTLS,via-branch,media address,ptime,xmlrpc-callback,metadata,address,file,db-id,code,DTLS-fingerprint,ICE-lite,media echo,label,set-label,from-label,to-label,DTMF-security,digit')) {
if (defined($options{$x})) {
if (!$options{json}) {
$packet{$x} = \$options{$x};
@ -122,7 +125,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address,
}
}
}
for my $x (split(/,/, 'TOS,delete-delay,delay-buffer')) {
for my $x (split(/,/, 'TOS,delete-delay,delay-buffer,volume,frequency')) {
defined($options{$x}) and $packet{$x} = $options{$x};
}
for my $x (split(/,/, 'trust address,symmetric,asymmetric,unidirectional,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,full rtcp attribute,loop protect,record call,always transcode,all,SIPREC,pad crypto,generate mid,fragment,original sendrecv,symmetric codecs,asymmetric codecs,inject DTMF,detect DTMF,generate RTCP,single codec,reorder codecs,pierce NAT,SIP-source-address,allow transcoding')) {

Loading…
Cancel
Save