Merge pull request #712 in FS/freeswitch from ~PIOTRGREGOR/freeswitch:bugfix/FS-8810-avmd-cosinus-table-creation-fails to master
* commit '1c39305fad68b03bf578a77e91d0c20ba8b8145e': FS-8810 fix crash on FS startup
This commit is contained in:
commit
02e83c91d9
|
@ -1,3 +1,4 @@
|
||||||
|
#include <switch.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,57 +58,94 @@ static float strip_float(float f)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void compute_table(void)
|
extern int compute_table(void)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
float f;
|
float f;
|
||||||
FILE *acos_table_file;
|
FILE *acos_table_file;
|
||||||
size_t ret;
|
size_t res;
|
||||||
|
|
||||||
acos_table_file = fopen(ACOS_TABLE_FILENAME, "w");
|
acos_table_file = fopen(ACOS_TABLE_FILENAME, "w");
|
||||||
|
|
||||||
for (i = 0; i < ACOS_TABLE_LENGTH; i++) {
|
for (i = 0; i < ACOS_TABLE_LENGTH; i++) {
|
||||||
f = acosf(float_from_index(i));
|
f = acosf(float_from_index(i));
|
||||||
ret = fwrite(&f, sizeof(f), 1, acos_table_file);
|
res = fwrite(&f, sizeof(f), 1, acos_table_file);
|
||||||
assert(ret != 0);
|
if (res != 1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fclose(acos_table_file);
|
res = fclose(acos_table_file);
|
||||||
assert(ret != EOF);
|
if (res != 0) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
fclose(acos_table_file);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int init_fast_acosf(void)
|
||||||
extern void init_fast_acosf(void)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, errsv;
|
||||||
|
FILE *acos_fp;
|
||||||
|
char err[150];
|
||||||
|
|
||||||
if (acos_table == NULL) {
|
if (acos_table == NULL) {
|
||||||
ret = access(ACOS_TABLE_FILENAME, F_OK);
|
ret = access(ACOS_TABLE_FILENAME, F_OK);
|
||||||
if (ret == 0) compute_table();
|
if (ret == -1) {
|
||||||
|
/* file doesn't exist, bad permissions,
|
||||||
acos_fd = open(ACOS_TABLE_FILENAME, O_RDONLY);
|
* or some other error occured */
|
||||||
if (acos_fd == -1) perror("Could not open file " ACOS_TABLE_FILENAME);
|
errsv = errno;
|
||||||
assert(acos_fd != -1);
|
strerror_r(errsv, err, 150);
|
||||||
acos_table = (float *)mmap(
|
if (errsv != ENOENT) return -1;
|
||||||
NULL,
|
else {
|
||||||
ACOS_TABLE_LENGTH * sizeof(float),
|
switch_log_printf(
|
||||||
PROT_READ,
|
SWITCH_CHANNEL_LOG,
|
||||||
MAP_SHARED | MAP_POPULATE,
|
SWITCH_LOG_NOTICE,
|
||||||
acos_fd,
|
"File [%s] doesn't exist. Creating file...\n", ACOS_TABLE_FILENAME
|
||||||
0
|
);
|
||||||
|
ret = compute_table();
|
||||||
|
if (ret != 0) return -2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_INFO,
|
||||||
|
"Using previously created file [%s]\n", ACOS_TABLE_FILENAME
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void destroy_fast_acosf(void)
|
acos_fp = fopen(ACOS_TABLE_FILENAME, "r");
|
||||||
{
|
if (acos_fp == NULL) return -3;
|
||||||
int ret;
|
/* can't fail */
|
||||||
|
acos_fd = fileno(acos_fp);
|
||||||
|
acos_table = (float *) mmap(
|
||||||
|
NULL, /* kernel chooses the address at which to create the mapping */
|
||||||
|
ACOS_TABLE_LENGTH * sizeof(float),
|
||||||
|
PROT_READ,
|
||||||
|
MAP_SHARED | MAP_POPULATE, /* read-ahead on the file. Later accesses to the mapping
|
||||||
|
* will not be blocked by page faults */
|
||||||
|
acos_fd,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (acos_table == MAP_FAILED) return -4;
|
||||||
|
|
||||||
ret = munmap(acos_table, ACOS_TABLE_LENGTH);
|
return 0;
|
||||||
assert(ret != -1);
|
}
|
||||||
ret = close(acos_fd);
|
|
||||||
assert(ret != -1);
|
extern int destroy_fast_acosf(void)
|
||||||
|
{
|
||||||
|
if (munmap(acos_table, ACOS_TABLE_LENGTH) == -1) return -1;
|
||||||
|
if (acos_fd != -1) {
|
||||||
|
if (close(acos_fd) == -1) return -2;
|
||||||
|
}
|
||||||
|
/* disable use of fast arc cosine file */
|
||||||
acos_table = NULL;
|
acos_table = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern float fast_acosf(float x)
|
extern float fast_acosf(float x)
|
||||||
|
|
|
@ -1,10 +1,46 @@
|
||||||
#ifndef __FAST_ACOSF_H__
|
#ifndef __FAST_ACOSF_H__
|
||||||
#define __FAST_ACOSF_H__
|
#define __FAST_ACOSF_H__
|
||||||
|
|
||||||
extern void init_fast_acosf(void);
|
|
||||||
|
#define ACOS_TABLE_FILENAME "/tmp/acos_table.dat"
|
||||||
|
|
||||||
|
/*! \brief Arc cosine table initialization.
|
||||||
|
*
|
||||||
|
* @author Eric des Courtis
|
||||||
|
* @par Changes: Piotr Gregor, 07 Feb 2016 (FS-8809, FS-8810)
|
||||||
|
* @return 0 on success, negative value otherwise:
|
||||||
|
* -1 can't access arc cos table with error != NOENT,
|
||||||
|
* -2 table creation failed (compute_table)
|
||||||
|
* -3 can access table but fopen failed
|
||||||
|
* -4 mmap failed
|
||||||
|
*/
|
||||||
|
extern int init_fast_acosf(void);
|
||||||
|
|
||||||
|
/*! \brief Arc cosine table deinitialization.
|
||||||
|
*
|
||||||
|
* @author Eric des Courtis
|
||||||
|
* @par Changes: Piotr Gregor, 09 Feb 2016 (FS-8809, FS-8810)
|
||||||
|
* @return 0 on success, negative value otherwise:
|
||||||
|
* -1 munmap failed,
|
||||||
|
* -2 close failed
|
||||||
|
*/
|
||||||
|
extern int destroy_fast_acosf(void);
|
||||||
|
|
||||||
|
/*! \brief Return arc cos for this argument.
|
||||||
|
* @details Uses previously created and mmapped file.
|
||||||
|
* @author Eric des Courtis
|
||||||
|
*/
|
||||||
extern float fast_acosf(float x);
|
extern float fast_acosf(float x);
|
||||||
extern void destroy_fast_acosf(void);
|
|
||||||
extern void compute_table(void);
|
/*! \brief Arc cosine table creation.
|
||||||
|
*
|
||||||
|
* @author Eric des Courtis
|
||||||
|
* @par Changes: Piotr Gregor, 07 Feb 2016 (FS-8809, FS-8810)
|
||||||
|
* @return 0 on success, negative value otherwise:
|
||||||
|
* -1 fwrite failed,
|
||||||
|
* -2 fclose failed
|
||||||
|
*/
|
||||||
|
extern int compute_table(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown);
|
||||||
SWITCH_STANDARD_API(avmd_api_main);
|
SWITCH_STANDARD_API(avmd_api_main);
|
||||||
|
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load);
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load);
|
||||||
SWITCH_MODULE_DEFINITION(mod_avmd, mod_avmd_load, NULL, NULL);
|
SWITCH_MODULE_DEFINITION(mod_avmd, mod_avmd_load, mod_avmd_shutdown, NULL);
|
||||||
SWITCH_STANDARD_APP(avmd_start_function);
|
SWITCH_STANDARD_APP(avmd_start_function);
|
||||||
|
|
||||||
/*! Status of the beep detection */
|
/*! Status of the beep detection */
|
||||||
|
@ -206,10 +206,16 @@ static switch_bool_t avmd_callback(switch_media_bug_t * bug, void *user_data, sw
|
||||||
/*! \brief FreeSWITCH module loading function.
|
/*! \brief FreeSWITCH module loading function.
|
||||||
*
|
*
|
||||||
* @author Eric des Courtis
|
* @author Eric des Courtis
|
||||||
* @return Load success or failure.
|
* @par Changes: Piotr Gregor, 07 Feb 2016 (FS-8809, FS-8810)
|
||||||
|
* @return On success SWITCH_STATUS_SUCCES,
|
||||||
|
* on failure SWITCH_STATUS_TERM.
|
||||||
*/
|
*/
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
|
SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
|
||||||
{
|
{
|
||||||
|
#ifdef FASTMATH
|
||||||
|
char err[150];
|
||||||
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch_application_interface_t *app_interface;
|
switch_application_interface_t *app_interface;
|
||||||
switch_api_interface_t *api_interface;
|
switch_api_interface_t *api_interface;
|
||||||
|
@ -218,7 +224,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
|
||||||
|
|
||||||
|
|
||||||
if (switch_event_reserve_subclass(AVMD_EVENT_BEEP) != SWITCH_STATUS_SUCCESS) {
|
if (switch_event_reserve_subclass(AVMD_EVENT_BEEP) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", AVMD_EVENT_BEEP);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
|
"Couldn't register subclass [%s]!\n", AVMD_EVENT_BEEP);
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,11 +237,63 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef FASTMATH
|
#ifdef FASTMATH
|
||||||
init_fast_acosf();
|
ret = init_fast_acosf();
|
||||||
|
if (ret != 0) {
|
||||||
|
strerror_r(errno, err, 150);
|
||||||
|
switch (ret) {
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Can't access file [%s], error [%s]\n",
|
||||||
|
ACOS_TABLE_FILENAME, err
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Error creating file [%s], error [%s]\n",
|
||||||
|
ACOS_TABLE_FILENAME, err
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Access rights are OK but can't open file [%s], error [%s]\n",
|
||||||
|
ACOS_TABLE_FILENAME, err
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -4:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Access rights are OK but can't mmap file [%s], error [%s]\n",
|
||||||
|
ACOS_TABLE_FILENAME, err
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Unknown error [%d] while initializing fast cos table [%s], "
|
||||||
|
"errno [%s]\n", ret, ACOS_TABLE_FILENAME, err
|
||||||
|
);
|
||||||
|
return SWITCH_STATUS_TERM;
|
||||||
|
}
|
||||||
|
return SWITCH_STATUS_TERM;
|
||||||
|
} else
|
||||||
switch_log_printf(
|
switch_log_printf(
|
||||||
SWITCH_CHANNEL_LOG,
|
SWITCH_CHANNEL_LOG,
|
||||||
SWITCH_LOG_NOTICE,
|
SWITCH_LOG_NOTICE,
|
||||||
"Advanced Voicemail detection: fast math enabled\n"
|
"Advanced Voicemail detection: fast math enabled, arc cosine table "
|
||||||
|
"is [%s]\n", ACOS_TABLE_FILENAME
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -328,11 +387,34 @@ SWITCH_STANDARD_APP(avmd_start_function)
|
||||||
*/
|
*/
|
||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown)
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown)
|
||||||
{
|
{
|
||||||
|
#ifdef FASTMATH
|
||||||
|
int res;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch_event_free_subclass(AVMD_EVENT_BEEP);
|
switch_event_free_subclass(AVMD_EVENT_BEEP);
|
||||||
|
|
||||||
#ifdef FASTMATH
|
#ifdef FASTMATH
|
||||||
destroy_fast_acosf();
|
res = destroy_fast_acosf();
|
||||||
|
if (res != 0) {
|
||||||
|
switch (res) {
|
||||||
|
case -1:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Failed unmap arc cosine table\n"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
switch_log_printf(
|
||||||
|
SWITCH_CHANNEL_LOG,
|
||||||
|
SWITCH_LOG_ERROR,
|
||||||
|
"Failed closing arc cosine table\n"
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch_log_printf(
|
switch_log_printf(
|
||||||
|
@ -537,13 +619,16 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
/* calculate variance */
|
/* calculate variance */
|
||||||
v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma);
|
v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD v=%f f=%f %fHz sma=%f sqa=%f >>>\n", v, f, TO_HZ(session->rate, f), session->sma_b.sma, session->sqa_b.sma);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG,
|
||||||
|
"<<< AVMD v=[%f] f=[%f] [%f]Hz sma=[%f] sqa=[%f] >>>\n", v, f, TO_HZ(session->rate, f),
|
||||||
|
session->sma_b.sma, session->sqa_b.sma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! If variance is less than threshold then we have detection */
|
/*! If variance is less than threshold then we have detection */
|
||||||
if (v < VARIANCE_THRESHOLD) {
|
if (v < VARIANCE_THRESHOLD) {
|
||||||
|
|
||||||
switch_channel_set_variable_printf(channel, "avmd_total_time", "%d", (int)(switch_micro_time_now() - session->start_time) / 1000);
|
switch_channel_set_variable_printf(channel, "avmd_total_time",
|
||||||
|
"[%d]", (int)(switch_micro_time_now() - session->start_time) / 1000);
|
||||||
switch_channel_execute_on(channel, "execute_on_avmd_beep");
|
switch_channel_execute_on(channel, "execute_on_avmd_beep");
|
||||||
|
|
||||||
/*! Throw an event to FreeSWITCH */
|
/*! Throw an event to FreeSWITCH */
|
||||||
|
@ -551,7 +636,8 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
if (status != SWITCH_STATUS_SUCCESS) return;
|
if (status != SWITCH_STATUS_SUCCESS) return;
|
||||||
|
|
||||||
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_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session->session));
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID",
|
||||||
|
switch_core_session_get_uuid(session->session));
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");
|
||||||
|
|
||||||
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) return;
|
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) return;
|
||||||
|
@ -559,7 +645,8 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
switch_core_session_queue_event(session->session, &event);
|
switch_core_session_queue_event(session->session, &event);
|
||||||
switch_event_fire(&event_copy);
|
switch_event_fire(&event_copy);
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD - Beep Detected >>>\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG,
|
||||||
|
"<<< AVMD - Beep Detected >>>\n");
|
||||||
switch_channel_set_variable(channel, "avmd_detect", "TRUE");
|
switch_channel_set_variable(channel, "avmd_detect", "TRUE");
|
||||||
RESET_SMA_BUFFER(&session->sma_b);
|
RESET_SMA_BUFFER(&session->sma_b);
|
||||||
RESET_SMA_BUFFER(&session->sqa_b);
|
RESET_SMA_BUFFER(&session->sqa_b);
|
||||||
|
|
Loading…
Reference in New Issue