]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Added extra credits. Adjusted indentation.
authorEric des Courtis <eric.des.courtis@benbria.com>
Sun, 7 Dec 2008 19:57:03 +0000 (19:57 +0000)
committerEric des Courtis <eric.des.courtis@benbria.com>
Sun, 7 Dec 2008 19:57:03 +0000 (19:57 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10643 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/applications/mod_vmd/mod_vmd.c

index b2fd6a5982fe72f90189a20a06137ac99aa35a91..138657f1ee4aa3511870c9d16ee6182e495e6084 100644 (file)
  * 
  * Eric des Courtis <eric.des.courtis@benbria.com>
  *
+ * Special thanks to the following companies for their help:
+ *     - JohnnyVoIP
+ *     - Magor Communications Corporation
+ *
+ * Special thanks to the following people for their help:
+ *     - The FreeSWITCH Team
+ *     - Matt Battig
+ *     - Dean Swan
+ *     - Lucas Cornelisse
+ *     - Kevin Green
  *
  * mod_vmd.c -- Voicemail Detection Module
  *
@@ -108,24 +118,24 @@ SWITCH_MODULE_DEFINITION(mod_vmd, mod_vmd_load, NULL, NULL);
 SWITCH_STANDARD_APP(vmd_start_function);
 
 /* Type that holds state information about the beep */
-typedef enum vmd_state{
+typedef enum vmd_state {
     BEEP_DETECTED, BEEP_NOT_DETECTED
 } vmd_state_t;
 
 /* Type that holds data for 5 points of discreet energy separation */
-typedef struct vmd_point{
+typedef struct vmd_point {
     double freq;
     double ampl;
 } vmd_point_t;
 
 /* Type that holds codec information */
-typedef struct vmd_codec_info{
+typedef struct vmd_codec_info {
     int rate;
     int channels;
 } vmd_codec_info_t;
 
 /* Type that holds session information pertinent to the vmd module */
-typedef struct vmd_session_info{
+typedef struct vmd_session_info {
     /* State of the session */
     vmd_state_t state;
     /* Snapshot of DESA samples */
@@ -143,12 +153,12 @@ typedef struct vmd_session_info{
     switch_size_t timestamp;
 } vmd_session_info_t;
 
-static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t *frame);
-static switch_bool_t vmd_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type);
+static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame);
+static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type);
 static double freq_estimator(double *x);
 static double ampl_estimator(double *x);
-static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max);
-static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame);
+static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max);
+static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame);
 static double median(double *m, int n);
 
 /*
@@ -156,62 +166,59 @@ static double median(double *m, int n);
 #define PRINT2(a, b) do{ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, a, b); }while(0)
 */
 
-static switch_bool_t vmd_callback(switch_media_bug_t *bug, 
-                                                                 void *user_data,
-                                                                 switch_abc_type_t type)
+static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
 {
-       vmd_session_info_t *vmd_info;
-       switch_codec_t *read_codec;
-       switch_frame_t *frame;
-
-       vmd_info = (vmd_session_info_t *)user_data;
-       if(vmd_info == NULL) {
-               return SWITCH_FALSE;
-       }
-
-       switch(type){
-
-       case SWITCH_ABC_TYPE_INIT:
-               read_codec = switch_core_session_get_read_codec(vmd_info->session);
-               vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
-               vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
-               break;
-
-       case SWITCH_ABC_TYPE_READ_PING:
-       case SWITCH_ABC_TYPE_CLOSE:
-       case SWITCH_ABC_TYPE_READ:
-       case SWITCH_ABC_TYPE_WRITE:
-               break;
-
-       case SWITCH_ABC_TYPE_READ_REPLACE:
-               frame = switch_core_media_bug_get_read_replace_frame(bug);
-               return process_data(vmd_info, frame);
-
-       case SWITCH_ABC_TYPE_WRITE_REPLACE:
-               break;
-       }
-
-       return SWITCH_TRUE;
+    vmd_session_info_t *vmd_info;
+    switch_codec_t *read_codec;
+    switch_frame_t *frame;
+
+    vmd_info = (vmd_session_info_t *) user_data;
+    if (vmd_info == NULL) {
+        return SWITCH_FALSE;
+    }
+
+    switch (type) {
+
+    case SWITCH_ABC_TYPE_INIT:
+        read_codec = switch_core_session_get_read_codec(vmd_info->session);
+        vmd_info->vmd_codec.rate = read_codec->implementation->samples_per_second;
+        vmd_info->vmd_codec.channels = read_codec->implementation->number_of_channels;
+        break;
+
+    case SWITCH_ABC_TYPE_READ_PING:
+    case SWITCH_ABC_TYPE_CLOSE:
+    case SWITCH_ABC_TYPE_READ:
+    case SWITCH_ABC_TYPE_WRITE:
+        break;
+
+    case SWITCH_ABC_TYPE_READ_REPLACE:
+        frame = switch_core_media_bug_get_read_replace_frame(bug);
+        return process_data(vmd_info, frame);
+
+    case SWITCH_ABC_TYPE_WRITE_REPLACE:
+        break;
+    }
+
+    return SWITCH_TRUE;
 }
 
-static switch_bool_t process_data(vmd_session_info_t *vmd_info, 
-                                                                 switch_frame_t *frame)
+static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame)
 {
-       uint32_t i;
-       unsigned int j;
-       double pts[P];
-       int16_t *data;
-       int16_t max;
-       switch_ssize_t len;
-
-       len = frame->samples * sizeof(int16_t);
-       data = (int16_t *)frame->data;
-
-       for(max = (int16_t)abs(data[0]), i = 1; i < frame->samples; i++) {
-               if ((int16_t)abs(data[i]) > max) {
-                       max = (int16_t)abs(data[i]);
-               }
-       }
+    uint32_t i;
+    unsigned int j;
+    double pts[P];
+    int16_t *data;
+    int16_t max;
+    switch_ssize_t len;
+
+    len = frame->samples * sizeof(int16_t);
+    data = (int16_t *) frame->data;
+
+    for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) {
+        if ((int16_t) abs(data[i]) > max) {
+            max = (int16_t) abs(data[i]);
+        }
+    }
 
 /*
     if(vmd_info->data_len != len){
@@ -234,189 +241,184 @@ static switch_bool_t process_data(vmd_session_info_t *vmd_info,
     }
 */
 
-    for(i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
-       /*      convert_pts(vmd_info->data + i, pts); */
-               convert_pts(data + i, pts, max);
-               vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
-               vmd_info->points[j].ampl = ampl_estimator(pts);
-               vmd_info->pos = j % POINTS;
-               find_beep(vmd_info, frame);
+    for (i = 0, j = vmd_info->pos; i < frame->samples; j++, j %= POINTS, i += 5) {
+        /*      convert_pts(vmd_info->data + i, pts); */
+        convert_pts(data + i, pts, max);
+        vmd_info->points[j].freq = TO_HZ(freq_estimator(pts));
+        vmd_info->points[j].ampl = ampl_estimator(pts);
+        vmd_info->pos = j % POINTS;
+        find_beep(vmd_info, frame);
     }
 
     return SWITCH_TRUE;
 }
 
-static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
+static void find_beep(vmd_session_info_t * vmd_info, switch_frame_t * frame)
 {
-       int i;
-       int c;
-       double m[POINTS];
-       double med;
-       unsigned int j = (vmd_info->pos + 1) % POINTS;
-       unsigned int k = j;
-       switch_event_t *event;
-       switch_status_t status;
-       switch_event_t *event_copy;
-       switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session); 
-
-       switch(vmd_info->state){
-       case BEEP_DETECTED:
-               for(c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++){
-                       vmd_info->timestamp++;
-                       if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) &&
-                               vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
-                                       c++;
-                                       vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
-                       }
-               }
-
-               if (c < (POINTS - MAX_CHIRP)) {
-                       vmd_info->state = BEEP_NOT_DETECTED;
-                       if (vmd_info->timestamp < MIN_TIME) {
-                               break;
-                       }
-
-                       status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
-                       if (status != SWITCH_STATUS_SUCCESS) {
-                               return;
-                       }
-
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int)vmd_info->timestamp / POINTS);
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID",
-                               "%s", switch_core_session_get_uuid(vmd_info->session));
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
-
-                       if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
-                               return;
-                       }
-
-                       switch_core_session_queue_event(vmd_info->session, &event);
-                       switch_event_fire(&event_copy);
-
-                       switch_log_printf(
-                               SWITCH_CHANNEL_LOG,
-                               SWITCH_LOG_INFO,
-                               "<<< VMD - Beep Detected >>>\n"
-                               );
-                       switch_channel_set_variable(channel, "vmd_detect", "TRUE");
-
-                       vmd_info->timestamp = 0;
-               }
-
-               break;
-
-       case BEEP_NOT_DETECTED:
-
-               for(i = 0; i < POINTS; k++, k %= POINTS, i++){
-                       m[i] = vmd_info->points[k].freq;
-                       if (ISNAN(m[i])) {
-                               m[i] = 0.0;
-                       }
-               }
-
-               med = median(m, POINTS);
-               if (ISNAN(med)){
-                       for(i = 0; i < POINTS; i++){
-                               if (!ISNAN(m[i])){
-                                       med = m[i];
-                                       break;
-                               }
-                       }
-               }
-
-               for(c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++){
-                       if (vmd_info->points[j].freq < TOLERANCE_T(med) &&
-                               vmd_info->points[j].freq > TOLERANCE_B(med)){
-                                       if (vmd_info->points[j].ampl > MIN_AMPL &&
-                                               vmd_info->points[j].freq > MIN_FREQ &&
-                                               vmd_info->points[j].freq < MAX_FREQ){
-                                                       c++;
-                                       }
-                       }
-               }
-
-               if(c >= VALID){
-                       vmd_info->state = BEEP_DETECTED;
-                       vmd_info->beep_freq = med;
-                       vmd_info->timestamp = 0;
-               }
-
-               break;
-       }
+    int i;
+    int c;
+    double m[POINTS];
+    double med;
+    unsigned int j = (vmd_info->pos + 1) % POINTS;
+    unsigned int k = j;
+    switch_event_t *event;
+    switch_status_t status;
+    switch_event_t *event_copy;
+    switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);
+
+    switch (vmd_info->state) {
+    case BEEP_DETECTED:
+        for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
+            vmd_info->timestamp++;
+            if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) &&
+                vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
+                c++;
+                vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
+            }
+        }
+
+        if (c < (POINTS - MAX_CHIRP)) {
+            vmd_info->state = BEEP_NOT_DETECTED;
+            if (vmd_info->timestamp < MIN_TIME) {
+                break;
+            }
+
+            status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
+            if (status != SWITCH_STATUS_SUCCESS) {
+                return;
+            }
+
+            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
+            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
+            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(vmd_info->session));
+            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
+            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
+
+            if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
+                return;
+            }
+
+            switch_core_session_queue_event(vmd_info->session, &event);
+            switch_event_fire(&event_copy);
+
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
+            switch_channel_set_variable(channel, "vmd_detect", "TRUE");
+
+            vmd_info->timestamp = 0;
+        }
+
+        break;
+
+    case BEEP_NOT_DETECTED:
+
+        for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
+            m[i] = vmd_info->points[k].freq;
+            if (ISNAN(m[i])) {
+                m[i] = 0.0;
+            }
+        }
+
+        med = median(m, POINTS);
+        if (ISNAN(med)) {
+            for (i = 0; i < POINTS; i++) {
+                if (!ISNAN(m[i])) {
+                    med = m[i];
+                    break;
+                }
+            }
+        }
+
+        for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
+            if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
+                if (vmd_info->points[j].ampl > MIN_AMPL &&
+                    vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
+                    c++;
+                }
+            }
+        }
+
+        if (c >= VALID) {
+            vmd_info->state = BEEP_DETECTED;
+            vmd_info->beep_freq = med;
+            vmd_info->timestamp = 0;
+        }
+
+        break;
+    }
 }
 
 /* Find the median of an array of doubles */
 static double median(double *m, int n)
 {
-       int i;
-       int less;
-       int greater;
-       int equal;
-       double min;
-       double max;
-       double guess;
-       double maxltguess;
-       double mingtguess;
-
-       min = max = m[0] ;
-
-       for (i = 1; i < n; i++) {
-               if(m[i] < min) min = m[i];
-               if(m[i] > max) max = m[i];
-       }
-
-       for(;;) {
-               guess = ( min + max ) / 2;
-               less = 0;
-               greater = 0;
-               equal = 0;
-               maxltguess = min;
-               mingtguess = max;
-
-               for(i = 0; i < n; i++) {
-                       if (m[i] < guess) {
-                               less++;
-                               if(m[i] > maxltguess) {
-                                       maxltguess = m[i];
-                               }
-                       } else if (m[i] > guess) {
-                               greater++;
-                               if(m[i] < mingtguess) {
-                                       mingtguess = m[i];
-                               }
-                       } else {
-                               equal++;
-                       }
-               }
-
-               if (less <= ( n + 1 ) / 2 && greater <= ( n + 1 ) / 2) {
-                       break;
-               } else if (less > greater) {
-                       max = maxltguess;
-               } else {
-                       min = mingtguess;
-               }
-       }
-
-       if (less >= ( n + 1 ) / 2) {
-               return maxltguess;
-       } else if (less + equal >= ( n + 1 ) / 2) {
-               return guess;
-       }
-
-       return mingtguess;
+    int i;
+    int less;
+    int greater;
+    int equal;
+    double min;
+    double max;
+    double guess;
+    double maxltguess;
+    double mingtguess;
+
+    min = max = m[0];
+
+    for (i = 1; i < n; i++) {
+        if (m[i] < min)
+            min = m[i];
+        if (m[i] > max)
+            max = m[i];
+    }
+
+    for (;;) {
+        guess = (min + max) / 2;
+        less = 0;
+        greater = 0;
+        equal = 0;
+        maxltguess = min;
+        mingtguess = max;
+
+        for (i = 0; i < n; i++) {
+            if (m[i] < guess) {
+                less++;
+                if (m[i] > maxltguess) {
+                    maxltguess = m[i];
+                }
+            } else if (m[i] > guess) {
+                greater++;
+                if (m[i] < mingtguess) {
+                    mingtguess = m[i];
+                }
+            } else {
+                equal++;
+            }
+        }
+
+        if (less <= (n + 1) / 2 && greater <= (n + 1) / 2) {
+            break;
+        } else if (less > greater) {
+            max = maxltguess;
+        } else {
+            min = mingtguess;
+        }
+    }
+
+    if (less >= (n + 1) / 2) {
+        return maxltguess;
+    } else if (less + equal >= (n + 1) / 2) {
+        return guess;
+    }
+
+    return mingtguess;
 }
 
 /* Convert many points for Signed L16 to relative floating point */
-static void convert_pts(int16_t *i_pts, double *d_pts, int16_t max)
+static void convert_pts(int16_t * i_pts, double *d_pts, int16_t max)
 {
     int i;
-       for(i = 0; i < P; i++) {
-               /* Signed L16 to relative floating point conversion */
-               d_pts[i] = ((((double)(i_pts[i]) + (double)max) / (double)(2 * max)) - 0.5) * 2.0;
-       }
+    for (i = 0; i < P; i++) {
+        /* Signed L16 to relative floating point conversion */
+        d_pts[i] = ((((double) (i_pts[i]) + (double) max) / (double) (2 * max)) - 0.5) * 2.0;
+    }
 }
 
 /* Amplitude estimator for DESA-2 */
@@ -427,22 +429,18 @@ double ampl_estimator(double *x)
     freq_sq = freq_estimator(x);
     freq_sq *= freq_sq;
 
-    return sqrt( PSI(x) / sin(freq_sq) ); 
+    return sqrt(PSI(x) / sin(freq_sq));
 }
 
 /* The DESA-2 algorithm */
 double freq_estimator(double *x)
 {
-    return 0.5 * acos(
-       (((x[2] * x[2]) - (x[0] * x[4]))
-       -
-       ( (x[1] * x[1]) - (x[0] * x[2]))
-       -
-       ( (x[3] * x[3]) - (x[2] * x[4])))
-       /
-       (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
-    );
+    return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
+                       - ((x[1] * x[1]) - (x[0] * x[2]))
+                       - ((x[3] * x[3]) - (x[2] * x[4])))
+                      / (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
+
+        );
 }
 
 
@@ -451,20 +449,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
     switch_application_interface_t *app_interface;
     switch_api_interface_t *api_interface;
     /* connect my internal structure to the blank pointer passed to me */
-    *module_interface = 
-       switch_loadable_module_create_module_interface(pool, modname);
-    
-    switch_log_printf(
-       SWITCH_CHANNEL_LOG, 
-       SWITCH_LOG_NOTICE, 
-       "Voicemail detection enabled\n"
-    );
-
-    SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", 
-       vmd_start_function, "[start] [stop]", SAF_NONE);
-    
-    SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", 
-       vmd_api_main, VMD_SYNTAX);
+    *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
+
+    SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
+
+    SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
 
     /* indicate that the module should continue to be loaded */
     return SWITCH_STATUS_SUCCESS;
@@ -473,84 +464,64 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
 /* Same as api function see it for comments */
 SWITCH_STANDARD_APP(vmd_start_function)
 {
-       switch_media_bug_t *bug;
-       switch_status_t status;
-       switch_channel_t *channel;
-       vmd_session_info_t *vmd_info;
-       int i;
-
-       if (session == NULL) return;
-
-       channel = switch_core_session_get_channel(session);
-
-       /* Is this channel already set? */
-       bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
-       /* If yes */
-       if (bug != NULL){
-               /* If we have a stop remove audio bug */
-               if(strcasecmp(data, "stop") == 0){
-                       switch_channel_set_private(channel, "_vmd_", NULL);
-                       switch_core_media_bug_remove(session, &bug);
-                       return;
-               }
-
-               /* We have already started */
-               switch_log_printf(
-                       SWITCH_CHANNEL_LOG, 
-                       SWITCH_LOG_WARNING, 
-                       "Cannot run 2 at once on the same channel!\n"
-                       );
-
-               return;
-       }
-
-       vmd_info = (vmd_session_info_t *)switch_core_session_alloc(
-               session, 
-               sizeof(vmd_session_info_t)
-               );
-
-       vmd_info->state = BEEP_NOT_DETECTED;
-       vmd_info->session = session;
-       vmd_info->pos = 0;
-       /*
-       vmd_info->data = NULL;
-       vmd_info->data_len = 0;
-       */
-       for(i = 0; i < POINTS; i++){
-               vmd_info->points[i].freq = 0.0;
-               vmd_info->points[i].ampl = 0.0;
-       }
-
-       status = switch_core_media_bug_add(
-               session, 
-               vmd_callback, 
-               vmd_info,
-               0, 
-               SMBF_READ_REPLACE, 
-               &bug
-               );
-
-       if(status != SWITCH_STATUS_SUCCESS){
-               switch_log_printf(
-                       SWITCH_CHANNEL_LOG,
-                       SWITCH_LOG_ERROR,
-                       "Failure hooking to stream\n"
-                       );
-               return;
-       }
-
-       switch_channel_set_private(channel, "_vmd_", bug);
+    switch_media_bug_t *bug;
+    switch_status_t status;
+    switch_channel_t *channel;
+    vmd_session_info_t *vmd_info;
+    int i;
+
+    if (session == NULL)
+        return;
+
+    channel = switch_core_session_get_channel(session);
+
+    /* Is this channel already set? */
+    bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
+    /* If yes */
+    if (bug != NULL) {
+        /* If we have a stop remove audio bug */
+        if (strcasecmp(data, "stop") == 0) {
+            switch_channel_set_private(channel, "_vmd_", NULL);
+            switch_core_media_bug_remove(session, &bug);
+            return;
+        }
+
+        /* We have already started */
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
+
+        return;
+    }
+
+    vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
+        );
+
+    vmd_info->state = BEEP_NOT_DETECTED;
+    vmd_info->session = session;
+    vmd_info->pos = 0;
+    /*
+       vmd_info->data = NULL;
+       vmd_info->data_len = 0;
+     */
+    for (i = 0; i < POINTS; i++) {
+        vmd_info->points[i].freq = 0.0;
+        vmd_info->points[i].ampl = 0.0;
+    }
+
+    status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
+
+    if (status != SWITCH_STATUS_SUCCESS) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
+        return;
+    }
+
+    switch_channel_set_private(channel, "_vmd_", bug);
 
 }
 
 /* Called when the system shuts down */
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
 {
-    switch_log_printf(
-       SWITCH_CHANNEL_LOG, 
-       SWITCH_LOG_NOTICE, 
-       "Voicemail detection disabled\n"
-    );
+    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
 
     return SWITCH_STATUS_SUCCESS;
 }
@@ -568,11 +539,11 @@ SWITCH_STANDARD_API(vmd_api_main)
     char *uuid;
     char *command;
     int i;
-    
+
     /* No command? Display usage */
-    if(cmd == NULL){
-       stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
-       return SWITCH_STATUS_SUCCESS;
+    if (cmd == NULL) {
+        stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
+        return SWITCH_STATUS_SUCCESS;
     }
 
     /* Duplicated contents of original string */
@@ -582,23 +553,23 @@ SWITCH_STANDARD_API(vmd_api_main)
 
     /* If we don't have the expected number of parameters 
      * display usage */
-    if (argc != VMD_PARAMS){
-               stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
-               switch_safe_free(ccmd);
-               return SWITCH_STATUS_SUCCESS;
+    if (argc != VMD_PARAMS) {
+        stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
+        switch_safe_free(ccmd);
+        return SWITCH_STATUS_SUCCESS;
     }
 
     uuid = argv[0];
     command = argv[1];
-     
+
     /* using uuid locate a reference to the FreeSWITCH session */
     vmd_session = switch_core_session_locate(uuid);
 
     /* If the session was not found exit */
     if (vmd_session == NULL) {
-               switch_safe_free(ccmd);
-               stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);     
-               return SWITCH_STATUS_FALSE;
+        switch_safe_free(ccmd);
+        stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
+        return SWITCH_STATUS_FALSE;
     }
 
     /* Get current channel of the session to tag the session
@@ -608,9 +579,9 @@ SWITCH_STANDARD_API(vmd_api_main)
     /* Is this channel already set? */
     bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_vmd_");
     /* If yes */
-    if (bug != NULL){
+    if (bug != NULL) {
         /* If we have a stop remove audio bug */
-        if(strcasecmp(command, "stop") == 0) {
+        if (strcasecmp(command, "stop") == 0) {
             switch_channel_set_private(channel, "_vmd_", NULL);
             switch_core_media_bug_remove(vmd_session, &bug);
             switch_safe_free(ccmd);
@@ -618,30 +589,24 @@ SWITCH_STANDARD_API(vmd_api_main)
             return SWITCH_STATUS_SUCCESS;
         }
 
-       /* We have already started */
-       switch_log_printf(
-           SWITCH_CHANNEL_LOG, 
-           SWITCH_LOG_WARNING, 
-           "Cannot run 2 at once on the same channel!\n"
-       );
-       
-       switch_safe_free(ccmd);
-       return SWITCH_STATUS_FALSE;
+        /* We have already started */
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
+
+        switch_safe_free(ccmd);
+        return SWITCH_STATUS_FALSE;
     }
 
     /* If we don't see the expected start exit */
-    if(strcasecmp(command, "start") != 0) {
-               switch_safe_free(ccmd); 
-               stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
-               return SWITCH_STATUS_FALSE;
+    if (strcasecmp(command, "start") != 0) {
+        switch_safe_free(ccmd);
+        stream->write_function(stream, "-USAGE: %s\n", VMD_SYNTAX);
+        return SWITCH_STATUS_FALSE;
     }
 
     /* Allocate memory attached to this FreeSWITCH session for
      * use in the callback routine and to store state information */
-    vmd_info = (vmd_session_info_t *)switch_core_session_alloc(
-       vmd_session, 
-       sizeof(vmd_session_info_t)
-    );
+    vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
+        );
 
     /* Set initial values and states */
     vmd_info->state = BEEP_NOT_DETECTED;
@@ -652,40 +617,29 @@ SWITCH_STANDARD_API(vmd_api_main)
     vmd_info->data_len = 0;
 */
 
-    for(i = 0; i < POINTS; i++) {
-               vmd_info->points[i].freq = 0.0;
-               vmd_info->points[i].ampl = 0.0;
+    for (i = 0; i < POINTS; i++) {
+        vmd_info->points[i].freq = 0.0;
+        vmd_info->points[i].ampl = 0.0;
     }
 
     /* Add a media bug that allows me to intercept the 
      * reading leg of the audio stream */
-    status = switch_core_media_bug_add(
-       vmd_session, 
-       vmd_callback, 
-       vmd_info,
-       0, 
-       SMBF_READ_REPLACE, 
-       &bug
-    );
+    status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
 
     /* If adding a media bug fails exit */
     if (status != SWITCH_STATUS_SUCCESS) {
-               switch_log_printf(
-                       SWITCH_CHANNEL_LOG, 
-                       SWITCH_LOG_ERROR, 
-                       "Failure hooking to stream\n"
-       );
-    
-       switch_safe_free(ccmd);
-       return SWITCH_STATUS_FALSE;
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
+
+        switch_safe_free(ccmd);
+        return SWITCH_STATUS_FALSE;
     }
 
     /* Set the vmd tag to detect an existing vmd media bug */
     switch_channel_set_private(channel, "_vmd_", bug);
-    
+
     /* Everything went according to plan! Notify the user */
-    stream->write_function(stream, "+OK\n"); 
+    stream->write_function(stream, "+OK\n");
+
     switch_safe_free(ccmd);
     return SWITCH_STATUS_SUCCESS;
 }
@@ -701,4 +655,3 @@ SWITCH_STANDARD_API(vmd_api_main)
  * For VIM:
  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
  */
-