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;
|
||||
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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue