add openzap_pre_buffer_size=<ms> to prebuffer audio and cut out residual dtmf tones

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@831 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Anthony Minessale 2009-09-14 14:26:31 +00:00
parent cd26200c6d
commit 098991a58e
5 changed files with 125 additions and 11 deletions

View File

@ -934,10 +934,30 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
{
private_t *tech_pvt;
switch_status_t status;
switch_channel_t *channel;
const char *var;
tech_pvt = (private_t *) switch_core_session_get_private(session);
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_PROGRESS:
case SWITCH_MESSAGE_INDICATE_ANSWER:
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
if ((var = switch_channel_get_variable(channel, "openzap_pre_buffer_size"))) {
int tmp = atoi(var);
if (tmp > -1) {
zap_channel_command(tech_pvt->zchan, ZAP_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
}
}
}
break;
default:
break;
}
switch (tech_pvt->zchan->type) {
case ZAP_CHAN_TYPE_FXS:
case ZAP_CHAN_TYPE_EM:
@ -1119,6 +1139,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
}
if ((var = switch_event_get_header(var_event, "openzap_pre_buffer_size"))) {
int tmp = atoi(var);
if (tmp > -1) {
zap_channel_command(zchan, ZAP_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
}
}
zap_channel_clear_vars(zchan);
for (h = var_event->headers; h; h = h->next) {
if (!strncasecmp(h->name, OPENZAP_VAR_PREFIX, OPENZAP_VAR_PREFIX_LEN)) {

View File

@ -503,6 +503,7 @@ struct zap_channel {
uint32_t skip_read_frames;
zap_buffer_t *dtmf_buffer;
zap_buffer_t *gen_dtmf_buffer;
zap_buffer_t *pre_buffer;
zap_buffer_t *digit_buffer;
zap_buffer_t *fsk_buffer;
uint32_t dtmf_on;
@ -529,6 +530,7 @@ struct zap_channel {
struct zap_io_interface *zio;
zap_hash_t *variable_hash;
unsigned char rx_cas_bits;
uint32_t pre_buffer_size;
};
@ -657,6 +659,7 @@ OZ_DECLARE(zap_status_t) zap_channel_use(zap_channel_t *zchan);
OZ_DECLARE(zap_status_t) zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj);
OZ_DECLARE(zap_status_t) zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to);
OZ_DECLARE(zap_status_t) zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen);
OZ_DECLARE(void) zap_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor);
OZ_DECLARE(zap_status_t) zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t datasize, zap_size_t *datalen);
OZ_DECLARE(zap_status_t) zap_channel_add_var(zap_channel_t *zchan, const char *var_name, const char *value);
OZ_DECLARE(const char *) zap_channel_get_var(zap_channel_t *zchan, const char *var_name);

View File

@ -283,6 +283,7 @@ typedef enum {
ZAP_COMMAND_FLUSH_TX_BUFFERS,
ZAP_COMMAND_FLUSH_RX_BUFFERS,
ZAP_COMMAND_FLUSH_BUFFERS,
ZAP_COMMAND_SET_PRE_BUFFER_SIZE,
ZAP_COMMAND_COUNT
} zap_command_t;

View File

@ -323,7 +323,6 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
zap_copy_string(chan->chan_number, number, sizeof(chan->chan_number));
}
configured++;
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d DTMF: %s\n",
spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf);
@ -557,6 +556,16 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
}
}
break;
case ZAP_COMMAND_ENABLE_ECHOCANCEL:
{
//code me
}
break;
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
{
//code me
}
break;
case ZAP_COMMAND_SET_INTERVAL:
{
err=sangoma_tdm_set_usr_period(zchan->sockfd, &tdm_api, ZAP_COMMAND_OBJ_INT);
@ -984,12 +993,12 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
event_id = ZAP_OOB_NOOP;
//zap_log(ZAP_LOG_DEBUG, "%d:%d queue hardware dtmf %s\n", zchan->span_id, zchan->chan_id, tmp_dtmf);
//if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
//zap_set_flag_locked(zchan, ZAP_CHANNEL_MUTE);
//}
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
zap_set_flag_locked(zchan, ZAP_CHANNEL_MUTE);
}
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
//zap_clear_flag_locked(zchan, ZAP_CHANNEL_MUTE);
zap_clear_flag_locked(zchan, ZAP_CHANNEL_MUTE);
zap_channel_queue_dtmf(zchan, tmp_dtmf);
}
}

View File

@ -245,6 +245,7 @@ static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
zap_sleep(500);
}
zap_buffer_destroy(&zchan->pre_buffer);
zap_buffer_destroy(&zchan->digit_buffer);
zap_buffer_destroy(&zchan->gen_dtmf_buffer);
zap_buffer_destroy(&zchan->dtmf_buffer);
@ -986,7 +987,10 @@ OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t
if (zap_test_flag(check, ZAP_CHANNEL_READY) &&
!zap_test_flag(check, ZAP_CHANNEL_INUSE) &&
!zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) &&
check->state == ZAP_CHANNEL_STATE_DOWN
check->state == ZAP_CHANNEL_STATE_DOWN &&
check->type != ZAP_CHAN_TYPE_DQ921 &&
check->type != ZAP_CHAN_TYPE_DQ931
) {
if (span && span->channel_request) {
@ -1195,6 +1199,8 @@ OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan)
zap_clear_flag_locked(zchan, ZAP_CHANNEL_PROGRESS);
zap_clear_flag_locked(zchan, ZAP_CHANNEL_MEDIA);
zap_clear_flag_locked(zchan, ZAP_CHANNEL_ANSWERED);
zap_buffer_destroy(&zchan->pre_buffer);
zchan->init_state = ZAP_CHANNEL_STATE_DOWN;
zchan->state = ZAP_CHANNEL_STATE_DOWN;
zap_log(ZAP_LOG_DEBUG, "channel done %u:%u\n", zchan->span_id, zchan->chan_id);
@ -1457,6 +1463,27 @@ OZ_DECLARE(zap_status_t) zap_channel_command(zap_channel_t *zchan, zap_command_t
}
}
}
case ZAP_COMMAND_SET_PRE_BUFFER_SIZE:
{
int val = ZAP_COMMAND_OBJ_INT;
if (val < 0) {
val = 0;
}
zchan->pre_buffer_size = val * 8;
if (!zchan->pre_buffer_size) {
zap_buffer_destroy(&zchan->pre_buffer);
} else if (!zchan->pre_buffer) {
zap_buffer_create(&zchan->pre_buffer, 1024, zchan->pre_buffer_size, 0);
}
GOTO_STATUS(done, ZAP_SUCCESS);
}
break;
case ZAP_COMMAND_GET_DTMF_ON_PERIOD:
{
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
@ -1516,6 +1543,13 @@ OZ_DECLARE(zap_status_t) zap_channel_command(zap_channel_t *zchan, zap_command_t
}
}
break;
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
{
zap_buffer_destroy(&zchan->pre_buffer);
zchan->pre_buffer_size = 0;
}
break;
default:
break;
}
@ -1737,6 +1771,10 @@ OZ_DECLARE(zap_status_t) zap_channel_queue_dtmf(zap_channel_t *zchan, const char
assert(zchan != NULL);
if (zchan->pre_buffer) {
zap_buffer_zero(zchan->pre_buffer);
}
zap_mutex_lock(zchan->mutex);
inuse = zap_buffer_inuse(zchan->digit_buffer);
@ -1779,6 +1817,7 @@ static zap_status_t handle_dtmf(zap_channel_t *zchan, zap_size_t datalen)
{
zap_buffer_t *buffer = NULL;
zap_size_t dblen = 0;
int wrote = 0;
if (zchan->gen_dtmf_buffer && (dblen = zap_buffer_inuse(zchan->gen_dtmf_buffer))) {
char digits[128] = "";
@ -1800,7 +1839,6 @@ static zap_status_t handle_dtmf(zap_channel_t *zchan, zap_size_t datalen)
}
for (; *cur; cur++) {
int wrote = 0;
if ((wrote = teletone_mux_tones(&zchan->tone_session, &zchan->tone_session.TONES[(int)*cur]))) {
zap_buffer_write(zchan->dtmf_buffer, zchan->tone_session.buffer, wrote * 2);
x++;
@ -1810,7 +1848,7 @@ static zap_status_t handle_dtmf(zap_channel_t *zchan, zap_size_t datalen)
}
}
zchan->skip_read_frames = 200 * x;
zchan->skip_read_frames = wrote / (1000 / zchan->effective_interval);
}
}
@ -1855,6 +1893,28 @@ static zap_status_t handle_dtmf(zap_channel_t *zchan, zap_size_t datalen)
}
OZ_DECLARE(void) zap_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor)
{
int16_t x;
uint32_t i;
int sum_rnd = 0;
int16_t rnd2 = (int16_t) zap_current_time_in_ms * (int16_t) (intptr_t) data;
assert(divisor);
for (i = 0; i < samples; i++, sum_rnd = 0) {
for (x = 0; x < 6; x++) {
rnd2 = rnd2 * 31821U + 13849U;
sum_rnd += rnd2 ;
}
//switch_normalize_to_16bit(sum_rnd);
*data = (int16_t) ((int16_t) sum_rnd / (int) divisor);
data++;
}
}
OZ_DECLARE(zap_status_t) zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen)
{
@ -2048,11 +2108,25 @@ OZ_DECLARE(zap_status_t) zap_channel_read(zap_channel_t *zchan, void *data, zap_
}
if (zchan->skip_read_frames > 0 || zap_test_flag(zchan, ZAP_CHANNEL_MUTE)) {
memset(data, 0, *datalen);
if (zchan->pre_buffer && zap_buffer_inuse(zchan->pre_buffer)) {
zap_buffer_zero(zchan->pre_buffer);
}
memset(data, 255, *datalen);
if (zchan->skip_read_frames > 0) {
zchan->skip_read_frames--;
}
}
} else if (zchan->pre_buffer_size) {
zap_buffer_write(zchan->pre_buffer, data, *datalen);
if (zap_buffer_inuse(zchan->pre_buffer) >= zchan->pre_buffer_size) {
zap_buffer_read(zchan->pre_buffer, data, *datalen);
} else {
memset(data, 255, *datalen);
}
}
return status;
}