forked from Mirrors/freeswitch
a whole bunch of stuff just to avoid a sonus issue silence_when_idle=400 chanvar to send generated silence duing sleeps etc
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10664 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
2ac1b96b29
commit
1136fcec4a
|
@ -110,6 +110,7 @@ SWITCH_BEGIN_EXTERN_C
|
|||
#define SWITCH_PATH_SEPARATOR "/"
|
||||
#endif
|
||||
#define SWITCH_URL_SEPARATOR "://"
|
||||
#define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE "send_silence_when_idle"
|
||||
#define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
|
||||
#define SWITCH_CURRENT_APPLICATION_DATA_VARIABLE "current_application_data"
|
||||
#define SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE "current_application_response"
|
||||
|
|
|
@ -47,6 +47,41 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
|
|||
int32_t left, elapsed;
|
||||
char data[2] = "";
|
||||
|
||||
switch_frame_t write_frame = { 0 };
|
||||
unsigned char *abuf = NULL;
|
||||
switch_codec_implementation_t imp = {0};
|
||||
switch_codec_t codec = { 0 };
|
||||
int sval = 0;
|
||||
const char *var;
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
|
||||
switch_core_session_get_read_impl(session, &imp);
|
||||
|
||||
if (switch_core_codec_init(&codec,
|
||||
"L16",
|
||||
NULL,
|
||||
imp.samples_per_second,
|
||||
imp.microseconds_per_packet / 1000,
|
||||
imp.number_of_channels,
|
||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
||||
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
|
||||
imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
|
||||
imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
|
||||
|
||||
write_frame.codec = &codec;
|
||||
switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||
write_frame.data = abuf;
|
||||
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
write_frame.datalen = imp.decoded_bytes_per_packet;
|
||||
write_frame.samples = write_frame.datalen / sizeof(int16_t);
|
||||
}
|
||||
|
||||
cng_frame.data = data;
|
||||
cng_frame.datalen = 2;
|
||||
cng_frame.buflen = 2;
|
||||
|
@ -134,10 +169,20 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
|
|||
}
|
||||
}
|
||||
|
||||
switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (sval) {
|
||||
switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval);
|
||||
switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
} else {
|
||||
switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (write_frame.codec) {
|
||||
switch_core_codec_destroy(&codec);
|
||||
}
|
||||
|
||||
switch_safe_free(abuf);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -749,9 +794,44 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_count(switch_core_sess
|
|||
switch_time_t started = 0, digit_started = 0;
|
||||
uint32_t abs_elapsed = 0, digit_elapsed = 0;
|
||||
uint32_t eff_timeout = 0;
|
||||
switch_frame_t write_frame = { 0 };
|
||||
unsigned char *abuf = NULL;
|
||||
switch_codec_implementation_t imp = {0};
|
||||
switch_codec_t codec = { 0 };
|
||||
int sval = 0;
|
||||
const char *var;
|
||||
|
||||
if (terminator != NULL)
|
||||
if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
|
||||
switch_core_session_get_read_impl(session, &imp);
|
||||
|
||||
if (switch_core_codec_init(&codec,
|
||||
"L16",
|
||||
NULL,
|
||||
imp.samples_per_second,
|
||||
imp.microseconds_per_packet / 1000,
|
||||
imp.number_of_channels,
|
||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
||||
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
|
||||
imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
|
||||
imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
|
||||
|
||||
write_frame.codec = &codec;
|
||||
switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||
write_frame.data = abuf;
|
||||
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
write_frame.datalen = imp.decoded_bytes_per_packet;
|
||||
write_frame.samples = write_frame.datalen / sizeof(int16_t);
|
||||
}
|
||||
|
||||
if (terminator != NULL) {
|
||||
*terminator = '\0';
|
||||
}
|
||||
|
||||
if (!switch_strlen_zero(terminators)) {
|
||||
for (i = 0; i < x; i++) {
|
||||
|
@ -838,9 +918,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_count(switch_core_sess
|
|||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (write_frame.data) {
|
||||
switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval);
|
||||
switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (write_frame.codec) {
|
||||
switch_core_codec_destroy(&codec);
|
||||
}
|
||||
|
||||
switch_safe_free(abuf);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -279,6 +279,7 @@ struct ringback {
|
|||
teletone_generation_session_t ts;
|
||||
switch_file_handle_t fhb;
|
||||
switch_file_handle_t *fh;
|
||||
int silence;
|
||||
uint8_t asis;
|
||||
};
|
||||
|
||||
|
@ -348,9 +349,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
|
|||
ringback_data = switch_channel_get_variable(caller_channel, "ringback");
|
||||
}
|
||||
|
||||
|
||||
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
|
||||
ringback_data = NULL;
|
||||
} else {
|
||||
if ((var = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
|
||||
int sval = atoi(var);
|
||||
|
||||
if (sval) {
|
||||
ringback_data = switch_core_session_sprintf(session, "ringback:%d", sval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,14 +417,27 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
|
|||
}
|
||||
ringback.fh = &ringback.fhb;
|
||||
} else {
|
||||
teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
|
||||
ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
|
||||
if (teletone_run(&ringback.ts, ringback_data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
|
||||
teletone_destroy_session(&ringback.ts);
|
||||
switch_buffer_destroy(&ringback.audio_buffer);
|
||||
ringback_data = NULL;
|
||||
if (!strncasecmp(ringback_data, "silence", 7)) {
|
||||
const char *p = ringback_data + 7;
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
if (p) {
|
||||
ringback.silence = atoi(p);
|
||||
}
|
||||
}
|
||||
if (ringback.silence <= 0) {
|
||||
ringback.silence = 400;
|
||||
}
|
||||
} else {
|
||||
teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
|
||||
ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
|
||||
if (teletone_run(&ringback.ts, ringback_data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
|
||||
teletone_destroy_session(&ringback.ts);
|
||||
switch_buffer_destroy(&ringback.audio_buffer);
|
||||
ringback_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch_safe_free(tmp_data);
|
||||
|
@ -491,9 +512,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
|
|||
write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
|
||||
break;
|
||||
}
|
||||
} else if (ringback.silence) {
|
||||
write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
|
||||
switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
|
||||
}
|
||||
|
||||
if ((ringback.fh || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
|
||||
if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
|
||||
if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
@ -769,6 +793,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||
|
||||
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
|
||||
ringback_data = NULL;
|
||||
} else {
|
||||
const char *vvar;
|
||||
|
||||
if ((vvar = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
|
||||
int sval = atoi(vvar);
|
||||
|
||||
if (sval) {
|
||||
ringback_data = switch_core_session_sprintf(session, "ringback:%d", sval);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1292,7 +1327,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||
}
|
||||
ringback.fh = &ringback.fhb;
|
||||
|
||||
|
||||
} else if (!strncasecmp(ringback_data, "silence", 7)) {
|
||||
const char *p = ringback_data + 7;
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
if (p) {
|
||||
ringback.silence = atoi(p);
|
||||
}
|
||||
}
|
||||
if (ringback.silence <= 0) {
|
||||
ringback.silence = 400;
|
||||
}
|
||||
} else {
|
||||
teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
|
||||
ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
|
||||
|
@ -1436,9 +1481,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||
write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
|
||||
break;
|
||||
}
|
||||
} else if (ringback.silence) {
|
||||
write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
|
||||
switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
|
||||
}
|
||||
|
||||
if ((ringback.fh || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
|
||||
if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
|
||||
if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -203,18 +203,19 @@ SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len)
|
|||
|
||||
SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor)
|
||||
{
|
||||
int16_t rnd = 0, rnd2, x;
|
||||
int16_t x;
|
||||
uint32_t i;
|
||||
int sum_rnd = 0;
|
||||
int16_t rnd2 = (int16_t) switch_timestamp_now();
|
||||
|
||||
assert(divisor);
|
||||
|
||||
rnd2 = (int16_t) (intptr_t) &data + (int16_t)switch_timestamp(NULL);
|
||||
|
||||
|
||||
for (i = 0; i < samples; i++, sum_rnd = 0) {
|
||||
for (x = 0; x < 10; x++) {
|
||||
rnd += (int16_t)((x + i) * rnd2);
|
||||
sum_rnd += rnd;
|
||||
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);
|
||||
|
|
|
@ -158,6 +158,7 @@ struct switch_rtp {
|
|||
uint32_t last_write_ts;
|
||||
uint32_t last_write_samplecount;
|
||||
uint32_t next_write_samplecount;
|
||||
switch_time_t last_write_timestamp;
|
||||
uint32_t flags;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_sockaddr_t *from_addr;
|
||||
|
@ -1885,15 +1886,27 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||
|
||||
rtp_session->send_msg.header.ts = htonl(rtp_session->ts);
|
||||
|
||||
|
||||
if ((rtp_session->ts > (rtp_session->last_write_ts + (rtp_session->samples_per_interval * 10)))
|
||||
|| rtp_session->ts == rtp_session->samples_per_interval) {
|
||||
m++;
|
||||
}
|
||||
|
||||
if (rtp_session->timer.interval &&
|
||||
(rtp_session->timer.samplecount - rtp_session->last_write_samplecount) > rtp_session->samples_per_interval * 2) {
|
||||
m++;
|
||||
}
|
||||
|
||||
if (!rtp_session->timer.interval &&
|
||||
((unsigned)((switch_timestamp_now() - rtp_session->last_write_timestamp))) > (rtp_session->ms_per_packet *2)) {
|
||||
m++;
|
||||
}
|
||||
|
||||
if (rtp_session->cn && payload != rtp_session->cng_pt) {
|
||||
rtp_session->cn = 0;
|
||||
m++;
|
||||
}
|
||||
|
||||
send_msg->header.m = m ? 1 : 0;
|
||||
|
||||
memcpy(send_msg->body, data, datalen);
|
||||
|
@ -2049,7 +2062,10 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||
|
||||
if (rtp_session->timer.interval) {
|
||||
rtp_session->last_write_samplecount = rtp_session->timer.samplecount;
|
||||
} else {
|
||||
rtp_session->last_write_timestamp = (uint32_t) switch_timestamp_now();
|
||||
}
|
||||
|
||||
rtp_session->last_write_ts = this_ts;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue