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:
parent
cd26200c6d
commit
098991a58e
|
@ -934,10 +934,30 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
||||||
{
|
{
|
||||||
private_t *tech_pvt;
|
private_t *tech_pvt;
|
||||||
switch_status_t status;
|
switch_status_t status;
|
||||||
|
switch_channel_t *channel;
|
||||||
|
const char *var;
|
||||||
|
|
||||||
tech_pvt = (private_t *) switch_core_session_get_private(session);
|
tech_pvt = (private_t *) switch_core_session_get_private(session);
|
||||||
assert(tech_pvt != NULL);
|
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) {
|
switch (tech_pvt->zchan->type) {
|
||||||
case ZAP_CHAN_TYPE_FXS:
|
case ZAP_CHAN_TYPE_FXS:
|
||||||
case ZAP_CHAN_TYPE_EM:
|
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;
|
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);
|
zap_channel_clear_vars(zchan);
|
||||||
for (h = var_event->headers; h; h = h->next) {
|
for (h = var_event->headers; h; h = h->next) {
|
||||||
if (!strncasecmp(h->name, OPENZAP_VAR_PREFIX, OPENZAP_VAR_PREFIX_LEN)) {
|
if (!strncasecmp(h->name, OPENZAP_VAR_PREFIX, OPENZAP_VAR_PREFIX_LEN)) {
|
||||||
|
|
|
@ -503,6 +503,7 @@ struct zap_channel {
|
||||||
uint32_t skip_read_frames;
|
uint32_t skip_read_frames;
|
||||||
zap_buffer_t *dtmf_buffer;
|
zap_buffer_t *dtmf_buffer;
|
||||||
zap_buffer_t *gen_dtmf_buffer;
|
zap_buffer_t *gen_dtmf_buffer;
|
||||||
|
zap_buffer_t *pre_buffer;
|
||||||
zap_buffer_t *digit_buffer;
|
zap_buffer_t *digit_buffer;
|
||||||
zap_buffer_t *fsk_buffer;
|
zap_buffer_t *fsk_buffer;
|
||||||
uint32_t dtmf_on;
|
uint32_t dtmf_on;
|
||||||
|
@ -529,6 +530,7 @@ struct zap_channel {
|
||||||
struct zap_io_interface *zio;
|
struct zap_io_interface *zio;
|
||||||
zap_hash_t *variable_hash;
|
zap_hash_t *variable_hash;
|
||||||
unsigned char rx_cas_bits;
|
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_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_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(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_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(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);
|
OZ_DECLARE(const char *) zap_channel_get_var(zap_channel_t *zchan, const char *var_name);
|
||||||
|
|
|
@ -283,6 +283,7 @@ typedef enum {
|
||||||
ZAP_COMMAND_FLUSH_TX_BUFFERS,
|
ZAP_COMMAND_FLUSH_TX_BUFFERS,
|
||||||
ZAP_COMMAND_FLUSH_RX_BUFFERS,
|
ZAP_COMMAND_FLUSH_RX_BUFFERS,
|
||||||
ZAP_COMMAND_FLUSH_BUFFERS,
|
ZAP_COMMAND_FLUSH_BUFFERS,
|
||||||
|
ZAP_COMMAND_SET_PRE_BUFFER_SIZE,
|
||||||
ZAP_COMMAND_COUNT
|
ZAP_COMMAND_COUNT
|
||||||
} zap_command_t;
|
} zap_command_t;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
zap_copy_string(chan->chan_number, number, sizeof(chan->chan_number));
|
||||||
}
|
}
|
||||||
configured++;
|
configured++;
|
||||||
|
|
||||||
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d DTMF: %s\n",
|
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);
|
spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf);
|
||||||
|
|
||||||
|
@ -557,6 +556,16 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ZAP_COMMAND_ENABLE_ECHOCANCEL:
|
||||||
|
{
|
||||||
|
//code me
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
|
||||||
|
{
|
||||||
|
//code me
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ZAP_COMMAND_SET_INTERVAL:
|
case ZAP_COMMAND_SET_INTERVAL:
|
||||||
{
|
{
|
||||||
err=sangoma_tdm_set_usr_period(zchan->sockfd, &tdm_api, ZAP_COMMAND_OBJ_INT);
|
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;
|
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);
|
//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) {
|
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);
|
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) {
|
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);
|
zap_channel_queue_dtmf(zchan, tmp_dtmf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,6 +245,7 @@ static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
|
||||||
zap_sleep(500);
|
zap_sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zap_buffer_destroy(&zchan->pre_buffer);
|
||||||
zap_buffer_destroy(&zchan->digit_buffer);
|
zap_buffer_destroy(&zchan->digit_buffer);
|
||||||
zap_buffer_destroy(&zchan->gen_dtmf_buffer);
|
zap_buffer_destroy(&zchan->gen_dtmf_buffer);
|
||||||
zap_buffer_destroy(&zchan->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) &&
|
if (zap_test_flag(check, ZAP_CHANNEL_READY) &&
|
||||||
!zap_test_flag(check, ZAP_CHANNEL_INUSE) &&
|
!zap_test_flag(check, ZAP_CHANNEL_INUSE) &&
|
||||||
!zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) &&
|
!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) {
|
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_PROGRESS);
|
||||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_MEDIA);
|
zap_clear_flag_locked(zchan, ZAP_CHANNEL_MEDIA);
|
||||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_ANSWERED);
|
zap_clear_flag_locked(zchan, ZAP_CHANNEL_ANSWERED);
|
||||||
|
zap_buffer_destroy(&zchan->pre_buffer);
|
||||||
|
|
||||||
zchan->init_state = ZAP_CHANNEL_STATE_DOWN;
|
zchan->init_state = ZAP_CHANNEL_STATE_DOWN;
|
||||||
zchan->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);
|
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:
|
case ZAP_COMMAND_GET_DTMF_ON_PERIOD:
|
||||||
{
|
{
|
||||||
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
|
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;
|
break;
|
||||||
|
|
||||||
|
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
|
||||||
|
{
|
||||||
|
zap_buffer_destroy(&zchan->pre_buffer);
|
||||||
|
zchan->pre_buffer_size = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1737,6 +1771,10 @@ OZ_DECLARE(zap_status_t) zap_channel_queue_dtmf(zap_channel_t *zchan, const char
|
||||||
|
|
||||||
assert(zchan != NULL);
|
assert(zchan != NULL);
|
||||||
|
|
||||||
|
if (zchan->pre_buffer) {
|
||||||
|
zap_buffer_zero(zchan->pre_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
zap_mutex_lock(zchan->mutex);
|
zap_mutex_lock(zchan->mutex);
|
||||||
|
|
||||||
inuse = zap_buffer_inuse(zchan->digit_buffer);
|
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_buffer_t *buffer = NULL;
|
||||||
zap_size_t dblen = 0;
|
zap_size_t dblen = 0;
|
||||||
|
int wrote = 0;
|
||||||
|
|
||||||
if (zchan->gen_dtmf_buffer && (dblen = zap_buffer_inuse(zchan->gen_dtmf_buffer))) {
|
if (zchan->gen_dtmf_buffer && (dblen = zap_buffer_inuse(zchan->gen_dtmf_buffer))) {
|
||||||
char digits[128] = "";
|
char digits[128] = "";
|
||||||
|
@ -1800,7 +1839,6 @@ static zap_status_t handle_dtmf(zap_channel_t *zchan, zap_size_t datalen)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; *cur; cur++) {
|
for (; *cur; cur++) {
|
||||||
int wrote = 0;
|
|
||||||
if ((wrote = teletone_mux_tones(&zchan->tone_session, &zchan->tone_session.TONES[(int)*cur]))) {
|
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);
|
zap_buffer_write(zchan->dtmf_buffer, zchan->tone_session.buffer, wrote * 2);
|
||||||
x++;
|
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)
|
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)) {
|
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) {
|
if (zchan->skip_read_frames > 0) {
|
||||||
zchan->skip_read_frames--;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue