]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add openzap_pre_buffer_size=<ms> to prebuffer audio and cut out residual dtmf tones
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 14 Sep 2009 14:26:31 +0000 (14:26 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 14 Sep 2009 14:26:31 +0000 (14:26 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@831 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/freetdm/mod_openzap/mod_openzap.c
libs/freetdm/src/include/openzap.h
libs/freetdm/src/include/zap_types.h
libs/freetdm/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c
libs/freetdm/src/zap_io.c

index 02c1eebad93af286bfb436bd6cf74b1cb1f4f43a..ddefd6e7fdf5ac3d087fa1512d0af25026965e3d 100644 (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)) {
index 6b0c703f23a235ad3b9d39ef6f2c46aa63ec0be3..ee09acc2fbd6e4b7af07c091f72d84e1519165ec 100644 (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);
index d745a72f466059bc65de92470756f9c73b0a00ff..2db87513a0468add8fb59d83158a5c0ecdaacb03 100644 (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;
 
index e6b26852bb631310faeefcd787481c7733329047..a7f54595f2e307990c8934b1fd8892620d285370 100644 (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);
                     } 
                 }
index 7d2ea3b094744ffa1133d5fdc3d8c7ad9d8f0973..98df71f723389d84f43b6d6427d1a353b87acd77 100644 (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;
 }