Added extra credits. Adjusted indentation.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10643 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Eric des Courtis 2008-12-07 19:57:03 +00:00
parent d3852f3aee
commit b31df55196
1 changed files with 289 additions and 336 deletions

View File

@ -21,6 +21,16 @@
* *
* Eric des Courtis <eric.des.courtis@benbria.com> * 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 * mod_vmd.c -- Voicemail Detection Module
* *
@ -156,9 +166,7 @@ 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) #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, static switch_bool_t vmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type)
void *user_data,
switch_abc_type_t type)
{ {
vmd_session_info_t *vmd_info; vmd_session_info_t *vmd_info;
switch_codec_t *read_codec; switch_codec_t *read_codec;
@ -194,8 +202,7 @@ static switch_bool_t vmd_callback(switch_media_bug_t *bug,
return SWITCH_TRUE; return SWITCH_TRUE;
} }
static switch_bool_t process_data(vmd_session_info_t *vmd_info, static switch_bool_t process_data(vmd_session_info_t * vmd_info, switch_frame_t * frame)
switch_frame_t *frame)
{ {
uint32_t i; uint32_t i;
unsigned int j; unsigned int j;
@ -283,8 +290,7 @@ static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop"); 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, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(vmd_info->session));
"%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(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");
@ -295,11 +301,7 @@ static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
switch_core_session_queue_event(vmd_info->session, &event); switch_core_session_queue_event(vmd_info->session, &event);
switch_event_fire(&event_copy); switch_event_fire(&event_copy);
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_INFO,
"<<< VMD - Beep Detected >>>\n"
);
switch_channel_set_variable(channel, "vmd_detect", "TRUE"); switch_channel_set_variable(channel, "vmd_detect", "TRUE");
vmd_info->timestamp = 0; vmd_info->timestamp = 0;
@ -327,11 +329,9 @@ static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
} }
for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) { for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
if (vmd_info->points[j].freq < TOLERANCE_T(med) && if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
vmd_info->points[j].freq > TOLERANCE_B(med)){
if (vmd_info->points[j].ampl > MIN_AMPL && if (vmd_info->points[j].ampl > MIN_AMPL &&
vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
vmd_info->points[j].freq < MAX_FREQ){
c++; c++;
} }
} }
@ -363,8 +363,10 @@ static double median(double *m, int n)
min = max = m[0]; min = max = m[0];
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
if(m[i] < min) min = m[i]; if (m[i] < min)
if(m[i] > max) max = m[i]; min = m[i];
if (m[i] > max)
max = m[i];
} }
for (;;) { for (;;) {
@ -433,14 +435,10 @@ double ampl_estimator(double *x)
/* The DESA-2 algorithm */ /* The DESA-2 algorithm */
double freq_estimator(double *x) double freq_estimator(double *x)
{ {
return 0.5 * acos( return 0.5 * acos((((x[2] * x[2]) - (x[0] * x[4]))
(((x[2] * x[2]) - (x[0] * x[4])) - ((x[1] * x[1]) - (x[0] * x[2]))
- - ((x[3] * x[3]) - (x[2] * x[4])))
( (x[1] * x[1]) - (x[0] * x[2])) / (2.0 * ((x[2] * x[2]) - (x[1] * x[3])))
-
( (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_application_interface_t *app_interface;
switch_api_interface_t *api_interface; switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */ /* connect my internal structure to the blank pointer passed to me */
*module_interface = *module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection enabled\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_NOTICE,
"Voicemail detection enabled\n"
);
SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", SWITCH_ADD_APP(app_interface, "vmd", "Detect beeps", "Detect voicemail beeps", vmd_start_function, "[start] [stop]", SAF_NONE);
vmd_start_function, "[start] [stop]", SAF_NONE);
SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", SWITCH_ADD_API(api_interface, "vmd", "Detected voicemail beeps", vmd_api_main, VMD_SYNTAX);
vmd_api_main, VMD_SYNTAX);
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -479,7 +470,8 @@ SWITCH_STANDARD_APP(vmd_start_function)
vmd_session_info_t *vmd_info; vmd_session_info_t *vmd_info;
int i; int i;
if (session == NULL) return; if (session == NULL)
return;
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
@ -495,18 +487,12 @@ SWITCH_STANDARD_APP(vmd_start_function)
} }
/* We have already started */ /* We have already started */
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_WARNING,
"Cannot run 2 at once on the same channel!\n"
);
return; return;
} }
vmd_info = (vmd_session_info_t *)switch_core_session_alloc( vmd_info = (vmd_session_info_t *) switch_core_session_alloc(session, sizeof(vmd_session_info_t)
session,
sizeof(vmd_session_info_t)
); );
vmd_info->state = BEEP_NOT_DETECTED; vmd_info->state = BEEP_NOT_DETECTED;
@ -521,21 +507,10 @@ SWITCH_STANDARD_APP(vmd_start_function)
vmd_info->points[i].ampl = 0.0; vmd_info->points[i].ampl = 0.0;
} }
status = switch_core_media_bug_add( status = switch_core_media_bug_add(session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
session,
vmd_callback,
vmd_info,
0,
SMBF_READ_REPLACE,
&bug
);
if (status != SWITCH_STATUS_SUCCESS) { if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_ERROR,
"Failure hooking to stream\n"
);
return; return;
} }
@ -546,11 +521,7 @@ SWITCH_STANDARD_APP(vmd_start_function)
/* Called when the system shuts down */ /* Called when the system shuts down */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
{ {
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_NOTICE,
"Voicemail detection disabled\n"
);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -619,11 +590,7 @@ SWITCH_STANDARD_API(vmd_api_main)
} }
/* We have already started */ /* We have already started */
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot run 2 at once on the same channel!\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_WARNING,
"Cannot run 2 at once on the same channel!\n"
);
switch_safe_free(ccmd); switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
@ -638,9 +605,7 @@ SWITCH_STANDARD_API(vmd_api_main)
/* Allocate memory attached to this FreeSWITCH session for /* Allocate memory attached to this FreeSWITCH session for
* use in the callback routine and to store state information */ * use in the callback routine and to store state information */
vmd_info = (vmd_session_info_t *)switch_core_session_alloc( vmd_info = (vmd_session_info_t *) switch_core_session_alloc(vmd_session, sizeof(vmd_session_info_t)
vmd_session,
sizeof(vmd_session_info_t)
); );
/* Set initial values and states */ /* Set initial values and states */
@ -659,22 +624,11 @@ SWITCH_STANDARD_API(vmd_api_main)
/* Add a media bug that allows me to intercept the /* Add a media bug that allows me to intercept the
* reading leg of the audio stream */ * reading leg of the audio stream */
status = switch_core_media_bug_add( status = switch_core_media_bug_add(vmd_session, vmd_callback, vmd_info, 0, SMBF_READ_REPLACE, &bug);
vmd_session,
vmd_callback,
vmd_info,
0,
SMBF_READ_REPLACE,
&bug
);
/* If adding a media bug fails exit */ /* If adding a media bug fails exit */
if (status != SWITCH_STATUS_SUCCESS) { if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf( switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure hooking to stream\n");
SWITCH_CHANNEL_LOG,
SWITCH_LOG_ERROR,
"Failure hooking to stream\n"
);
switch_safe_free(ccmd); switch_safe_free(ccmd);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
@ -701,4 +655,3 @@ SWITCH_STANDARD_API(vmd_api_main)
* For VIM: * For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
*/ */