]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
a whole bunch of stuff just to avoid a sonus issue silence_when_idle=400 chanvar...
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 9 Dec 2008 00:32:51 +0000 (00:32 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 9 Dec 2008 00:32:51 +0000 (00:32 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10664 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_types.h
src/switch_ivr.c
src/switch_ivr_originate.c
src/switch_resample.c
src/switch_rtp.c

index 20eb491b5ff17fe2bdf98381c35e89d0aac0ce77..c8fd6cba8ee73a4dc139254f0346464f85834cea 100644 (file)
@@ -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"
index 6c5432870b99e1cca4ca5bcdfc1f16e11905c0bc..90dfac2bf78928b37ead8ec4e7ed8bc3feb928e6 100644 (file)
@@ -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 ((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)
+       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;
 }
 
index 7dddd462c615f68ac689e81f94f0a06f77c04707..2c36fb5de7c291b1d26a9b26c34d02941bcb8ccf 100644 (file)
@@ -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;
                                                        }
index 8aac96d86bb991e5dffc3a1b18380e476aa49460..0abb3ec63c13482d6e59f20e0114368ef1e4c01c 100644 (file)
@@ -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);
index 041937ee8c1bd544c0fda1d0cad7a6649773e21f..74fe5bcd639551953133f1744ed4024a0e9d21e5 100644 (file)
@@ -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;
        }