FS-9085, FS-9024: [avmd] Add events
Add start/stop events. Add registration method, add fire events method.
This commit is contained in:
parent
a54a5797b7
commit
bfd8ef08b3
|
@ -106,10 +106,17 @@
|
||||||
/*! Number of expected parameters in api call. */
|
/*! Number of expected parameters in api call. */
|
||||||
#define AVMD_PARAMS 2
|
#define AVMD_PARAMS 2
|
||||||
|
|
||||||
/*! FreeSWITCH CUSTOM event type. */
|
enum avmd_event
|
||||||
#define AVMD_EVENT_BEEP "avmd::beep"
|
{
|
||||||
#define AVMD_EVENT_SESSION_START "avmd::session_start"
|
AVMD_EVENT_BEEP = 0,
|
||||||
#define AVMD_EVENT_SESSION_STOP "avmd::session_stop"
|
AVMD_EVENT_SESSION_START = 1,
|
||||||
|
AVMD_EVENT_SESSION_STOP = 2
|
||||||
|
};
|
||||||
|
const char* avmd_events_str[] = { [AVMD_EVENT_BEEP] = "avmd::beep",
|
||||||
|
[AVMD_EVENT_SESSION_START] = "avmd::start",
|
||||||
|
[AVMD_EVENT_SESSION_STOP] = "avmd::stop",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
#define AVMD_CHAR_BUF_LEN 20
|
#define AVMD_CHAR_BUF_LEN 20
|
||||||
#define AVMD_BUF_LINEAR_LEN 160
|
#define AVMD_BUF_LINEAR_LEN 160
|
||||||
|
@ -156,9 +163,19 @@ typedef struct {
|
||||||
size_t sample_count;
|
size_t sample_count;
|
||||||
} avmd_session_t;
|
} avmd_session_t;
|
||||||
|
|
||||||
static void avmd_process(avmd_session_t *session, switch_frame_t *frame);
|
static void avmd_process(avmd_session_t *s, switch_frame_t *frame);
|
||||||
|
|
||||||
static switch_bool_t avmd_callback(switch_media_bug_t * bug,
|
static switch_bool_t avmd_callback(switch_media_bug_t * bug,
|
||||||
void *user_data, switch_abc_type_t type);
|
void *user_data, switch_abc_type_t type);
|
||||||
|
static switch_status_t
|
||||||
|
avmd_register_all_events(void);
|
||||||
|
|
||||||
|
static void
|
||||||
|
avmd_unregister_all_events(void);
|
||||||
|
|
||||||
|
static void
|
||||||
|
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s,
|
||||||
|
double freq, double v);
|
||||||
|
|
||||||
/*! \brief The avmd session data initialization function.
|
/*! \brief The avmd session data initialization function.
|
||||||
* @author Eric des Courtis
|
* @author Eric des Courtis
|
||||||
|
@ -305,6 +322,98 @@ static switch_bool_t avmd_callback(switch_media_bug_t * bug,
|
||||||
return SWITCH_TRUE;
|
return SWITCH_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static switch_status_t
|
||||||
|
avmd_register_all_events(void)
|
||||||
|
{
|
||||||
|
size_t idx = 0;
|
||||||
|
const char *e = avmd_events_str[0];
|
||||||
|
while (e != NULL)
|
||||||
|
{
|
||||||
|
if (switch_event_reserve_subclass(e) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
|
"Couldn't register subclass [%s]!\n", e);
|
||||||
|
return SWITCH_STATUS_TERM;
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
e = avmd_events_str[idx];
|
||||||
|
}
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
avmd_unregister_all_events(void)
|
||||||
|
{
|
||||||
|
size_t idx = 0;
|
||||||
|
const char *e = avmd_events_str[0];
|
||||||
|
while (e != NULL)
|
||||||
|
{
|
||||||
|
switch_event_free_subclass(e);
|
||||||
|
++idx;
|
||||||
|
e = avmd_events_str[idx];
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
switch_event_t *event;
|
||||||
|
switch_status_t status;
|
||||||
|
switch_event_t *event_copy;
|
||||||
|
char buf[AVMD_CHAR_BUF_LEN];
|
||||||
|
|
||||||
|
status = switch_event_create_subclass(&event,
|
||||||
|
SWITCH_EVENT_CUSTOM, avmd_events_str[type]);
|
||||||
|
if (status != SWITCH_STATUS_SUCCESS)
|
||||||
|
return;
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID",
|
||||||
|
switch_core_session_get_uuid(fs_s));
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case AVMD_EVENT_BEEP:
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
|
||||||
|
"Beep-Status", "detected");
|
||||||
|
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", freq);
|
||||||
|
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s),
|
||||||
|
SWITCH_LOG_ERROR, "Frequency truncated [%s], [%d] attempted!\n",
|
||||||
|
buf, res);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency",
|
||||||
|
"ERROR (TRUNCATED)");
|
||||||
|
}
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
|
||||||
|
"frequency", buf);
|
||||||
|
|
||||||
|
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v);
|
||||||
|
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s),
|
||||||
|
SWITCH_LOG_ERROR, "Error, truncated [%s], [%d] attempeted!\n",
|
||||||
|
buf, res);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
|
||||||
|
"variance", "ERROR (TRUNCATED)");
|
||||||
|
}
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", buf);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVMD_EVENT_SESSION_START:
|
||||||
|
case AVMD_EVENT_SESSION_STOP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch_event_destroy(&event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch_core_session_queue_event(fs_s, &event);
|
||||||
|
switch_event_fire(&event_copy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief FreeSWITCH module loading function.
|
/*! \brief FreeSWITCH module loading function.
|
||||||
*
|
*
|
||||||
* @author Eric des Courtis
|
* @author Eric des Courtis
|
||||||
|
@ -324,19 +433,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
|
||||||
/* connect my internal structure to the blank pointer passed to me */
|
/* connect my internal structure to the blank pointer passed to me */
|
||||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||||
|
|
||||||
if (switch_event_reserve_subclass(AVMD_EVENT_BEEP) != SWITCH_STATUS_SUCCESS) {
|
if (avmd_register_all_events() != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
"Couldn't register subclass [%s]!\n", AVMD_EVENT_BEEP);
|
"Couldn't register avmd events!\n");
|
||||||
return SWITCH_STATUS_TERM;
|
|
||||||
}
|
|
||||||
if (switch_event_reserve_subclass(AVMD_EVENT_SESSION_START) != SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
|
||||||
"Couldn't register subclass [%s]!\n", AVMD_EVENT_SESSION_START);
|
|
||||||
return SWITCH_STATUS_TERM;
|
|
||||||
}
|
|
||||||
if (switch_event_reserve_subclass(AVMD_EVENT_SESSION_STOP) != SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
|
||||||
"Couldn't register subclass [%s]!\n", AVMD_EVENT_SESSION_STOP);
|
|
||||||
return SWITCH_STATUS_TERM;
|
return SWITCH_STATUS_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,8 +632,11 @@ SWITCH_STANDARD_APP(avmd_start_app)
|
||||||
switch_channel_set_private(channel, "_avmd_", bug);
|
switch_channel_set_private(channel, "_avmd_", bug);
|
||||||
|
|
||||||
/* OK */
|
/* OK */
|
||||||
|
avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0);
|
||||||
|
#ifdef AVMD_REPORT_STATUS
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
|
||||||
"Avmd on channel [%s] started!\n", switch_channel_get_name(channel));
|
"Avmd on channel [%s] started!\n", switch_channel_get_name(channel));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief FreeSWITCH application handler function.
|
/*! \brief FreeSWITCH application handler function.
|
||||||
|
@ -579,8 +681,11 @@ SWITCH_STANDARD_APP(avmd_stop_app)
|
||||||
|
|
||||||
switch_channel_set_private(channel, "_avmd_", NULL);
|
switch_channel_set_private(channel, "_avmd_", NULL);
|
||||||
switch_core_media_bug_remove(session, &bug);
|
switch_core_media_bug_remove(session, &bug);
|
||||||
|
avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0);
|
||||||
|
#ifdef AVMD_REPORT_STATUS
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
|
||||||
"Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel));
|
"Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel));
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,10 +741,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown)
|
||||||
int res;
|
int res;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch_event_free_subclass(AVMD_EVENT_BEEP);
|
avmd_unregister_all_events();
|
||||||
switch_event_free_subclass(AVMD_EVENT_SESSION_START);
|
|
||||||
switch_event_free_subclass(AVMD_EVENT_SESSION_STOP);
|
|
||||||
|
|
||||||
#ifdef AVMD_FAST_MATH
|
#ifdef AVMD_FAST_MATH
|
||||||
res = destroy_fast_acosf();
|
res = destroy_fast_acosf();
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
@ -739,6 +842,7 @@ SWITCH_STANDARD_API(avmd_api_main)
|
||||||
uuid_dup = switch_core_strdup(switch_core_session_get_pool(fs_session), uuid);
|
uuid_dup = switch_core_strdup(switch_core_session_get_pool(fs_session), uuid);
|
||||||
switch_channel_set_private(channel, "_avmd_", NULL);
|
switch_channel_set_private(channel, "_avmd_", NULL);
|
||||||
switch_core_media_bug_remove(fs_session, &bug);
|
switch_core_media_bug_remove(fs_session, &bug);
|
||||||
|
avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0);
|
||||||
#ifdef AVMD_REPORT_STATUS
|
#ifdef AVMD_REPORT_STATUS
|
||||||
stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n",
|
stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n",
|
||||||
uuid_dup, switch_channel_get_name(channel));
|
uuid_dup, switch_channel_get_name(channel));
|
||||||
|
@ -880,6 +984,7 @@ SWITCH_STANDARD_API(avmd_api_main)
|
||||||
switch_channel_set_private(channel, "_avmd_", bug);
|
switch_channel_set_private(channel, "_avmd_", bug);
|
||||||
|
|
||||||
/* OK */
|
/* OK */
|
||||||
|
avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0);
|
||||||
#ifdef AVMD_REPORT_STATUS
|
#ifdef AVMD_REPORT_STATUS
|
||||||
stream->write_function(stream, "+OK\n [%s] [%s] started!\n\n",
|
stream->write_function(stream, "+OK\n [%s] [%s] started!\n\n",
|
||||||
uuid, switch_channel_get_name(channel));
|
uuid, switch_channel_get_name(channel));
|
||||||
|
@ -904,12 +1009,8 @@ end:
|
||||||
* @param session An avmd session.
|
* @param session An avmd session.
|
||||||
* @param frame An audio frame.
|
* @param frame An audio frame.
|
||||||
*/
|
*/
|
||||||
static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
static void avmd_process(avmd_session_t *s, switch_frame_t *frame)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
switch_event_t *event;
|
|
||||||
switch_status_t status;
|
|
||||||
switch_event_t *event_copy;
|
|
||||||
switch_channel_t *channel;
|
switch_channel_t *channel;
|
||||||
|
|
||||||
circ_buffer_t *b;
|
circ_buffer_t *b;
|
||||||
|
@ -921,28 +1022,27 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
double v;
|
double v;
|
||||||
double sma_digital_freq;
|
double sma_digital_freq;
|
||||||
uint32_t sine_len_i;
|
uint32_t sine_len_i;
|
||||||
char buf[AVMD_CHAR_BUF_LEN];
|
|
||||||
int sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
int sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
||||||
size_t sample_n = 0;
|
size_t sample_n = 0;
|
||||||
|
|
||||||
b = &session->b;
|
b = &s->b;
|
||||||
|
|
||||||
/* If beep has already been detected skip the CPU heavy stuff */
|
/* If beep has already been detected skip the CPU heavy stuff */
|
||||||
if (session->state.beep_state == BEEP_DETECTED) return;
|
if (s->state.beep_state == BEEP_DETECTED) return;
|
||||||
|
|
||||||
/* Precompute values used heavily in the inner loop */
|
/* Precompute values used heavily in the inner loop */
|
||||||
sine_len_i = (uint32_t) SINE_LEN(session->rate);
|
sine_len_i = (uint32_t) SINE_LEN(s->rate);
|
||||||
//sine_len = (double)sine_len_i;
|
//sine_len = (double)sine_len_i;
|
||||||
//beep_len_i = BEEP_LEN(session->rate);
|
//beep_len_i = BEEP_LEN(session->rate);
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(session->session);
|
channel = switch_core_session_get_channel(s->session);
|
||||||
|
|
||||||
/* Insert frame of 16 bit samples into buffer */
|
/* Insert frame of 16 bit samples into buffer */
|
||||||
INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples);
|
INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples);
|
||||||
session->sample_count += frame->samples;
|
s->sample_count += frame->samples;
|
||||||
|
|
||||||
/* INNER LOOP -- OPTIMIZATION TARGET */
|
/* INNER LOOP -- OPTIMIZATION TARGET */
|
||||||
pos = session->pos;
|
pos = s->pos;
|
||||||
while (sample_n < (frame->samples - P)) {
|
while (sample_n < (frame->samples - P)) {
|
||||||
/*for (pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++) { */
|
/*for (pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++) { */
|
||||||
if ((sample_n % sine_len_i) == 0) {
|
if ((sample_n % sine_len_i) == 0) {
|
||||||
|
@ -951,35 +1051,35 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
|
|
||||||
if (omega < -0.999999 || omega > 0.999999) {
|
if (omega < -0.999999 || omega > 0.999999) {
|
||||||
#ifdef AVMD_DEBUG
|
#ifdef AVMD_DEBUG
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session),
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session),
|
||||||
SWITCH_LOG_DEBUG, "<<< AVMD RESET >>>\n");
|
SWITCH_LOG_DEBUG, "<<< AVMD RESET >>>\n");
|
||||||
#endif
|
#endif
|
||||||
v = 99999.0;
|
v = 99999.0;
|
||||||
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
||||||
RESET_SMA_BUFFER(&session->sma_b);
|
RESET_SMA_BUFFER(&s->sma_b);
|
||||||
RESET_SMA_BUFFER(&session->sqa_b);
|
RESET_SMA_BUFFER(&s->sqa_b);
|
||||||
session->samples_streak = SAMPLES_CONSECUTIVE_STREAK;
|
s->samples_streak = SAMPLES_CONSECUTIVE_STREAK;
|
||||||
sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (isnan(omega)) {
|
if (isnan(omega)) {
|
||||||
#ifdef AVMD_DEBUG
|
#ifdef AVMD_DEBUG
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session),
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session),
|
||||||
SWITCH_LOG_DEBUG, "<<< AVMD, SKIP NaN >>>\n");
|
SWITCH_LOG_DEBUG, "<<< AVMD, SKIP NaN >>>\n");
|
||||||
#endif
|
#endif
|
||||||
sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N;
|
||||||
goto loop_continue;
|
goto loop_continue;
|
||||||
}
|
}
|
||||||
if (session->sma_b.pos > 0 &&
|
if (s->sma_b.pos > 0 &&
|
||||||
(fabs(omega - session->sma_b.data[session->sma_b.pos - 1]) < 0.00000001)) {
|
(fabs(omega - s->sma_b.data[s->sma_b.pos - 1]) < 0.00000001)) {
|
||||||
#ifdef AVMD_DEBUG
|
#ifdef AVMD_DEBUG
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG,
|
||||||
"<<< AVMD, SKIP >>>\n");
|
"<<< AVMD, SKIP >>>\n");
|
||||||
#endif
|
#endif
|
||||||
goto loop_continue;
|
goto loop_continue;
|
||||||
}
|
}
|
||||||
#ifdef AVMD_DEBUG
|
#ifdef AVMD_DEBUG
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session),
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session),
|
||||||
SWITCH_LOG_DEBUG, "<<< AVMD omega [%f] >>>\n", omega);
|
SWITCH_LOG_DEBUG, "<<< AVMD omega [%f] >>>\n", omega);
|
||||||
#endif
|
#endif
|
||||||
if (sample_to_skip_n > 0) {
|
if (sample_to_skip_n > 0) {
|
||||||
|
@ -994,35 +1094,35 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
omega = 0.9999;
|
omega = 0.9999;
|
||||||
|
|
||||||
/* append */
|
/* append */
|
||||||
APPEND_SMA_VAL(&session->sma_b, omega);
|
APPEND_SMA_VAL(&s->sma_b, omega);
|
||||||
APPEND_SMA_VAL(&session->sqa_b, omega * omega);
|
APPEND_SMA_VAL(&s->sqa_b, omega * omega);
|
||||||
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
||||||
if (session->samples_streak > 0)
|
if (s->samples_streak > 0)
|
||||||
--session->samples_streak;
|
--s->samples_streak;
|
||||||
#endif
|
#endif
|
||||||
/* calculate variance (biased estimator) */
|
/* calculate variance (biased estimator) */
|
||||||
v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma);
|
v = s->sqa_b.sma - (s->sma_b.sma * s->sma_b.sma);
|
||||||
#ifdef AVMD_DEBUG
|
#ifdef AVMD_DEBUG
|
||||||
#ifdef AVMD_FAST_MATH
|
#ifdef AVMD_FAST_MATH
|
||||||
f = 0.5 * (double) fast_acosf((float)omega);
|
f = 0.5 * (double) fast_acosf((float)omega);
|
||||||
sma_digital_freq = 0.5 * (double) fast_acosf((float)session->sma_b.sma);
|
sma_digital_freq = 0.5 * (double) fast_acosf((float)s->sma_b.sma);
|
||||||
#else
|
#else
|
||||||
f = 0.5 * acos(omega);
|
f = 0.5 * acos(omega);
|
||||||
sma_digital_freq = 0.5 * acos(session->sma_b.sma);
|
sma_digital_freq = 0.5 * acos(s->sma_b.sma);
|
||||||
#endif /* AVMD_FAST_MATH */
|
#endif /* AVMD_FAST_MATH */
|
||||||
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG,
|
||||||
"<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t"
|
"<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t"
|
||||||
"streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n",
|
"streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n",
|
||||||
v, omega, f, TO_HZ(session->rate, f), session->sma_b.sma,
|
v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma,
|
||||||
TO_HZ(session->rate, sma_digital_freq), session->sqa_b.sma, session->samples_streak,
|
TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, s->samples_streak,
|
||||||
session->sma_b.pos, sample_n, session->sma_b.lpos, pos);
|
s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||||
#else
|
#else
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG,
|
||||||
"<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\tpos[%zu]"
|
"<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\tpos[%zu]"
|
||||||
" sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f,
|
" sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f,
|
||||||
TO_HZ(session->rate, f), session->sma_b.sma, TO_HZ(session->rate, sma_digital_freq),
|
TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq),
|
||||||
session->sqa_b.sma, session->sma_b.pos, sample_n, session->sma_b.lpos, pos);
|
s->sqa_b.sma, s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||||
#endif /* AVMD_REQUIRE_CONTINUOUS_STREAK */
|
#endif /* AVMD_REQUIRE_CONTINUOUS_STREAK */
|
||||||
#endif /* AVMD_DEBUG */
|
#endif /* AVMD_DEBUG */
|
||||||
}
|
}
|
||||||
|
@ -1032,58 +1132,30 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
|
||||||
* and we have at least two estimates
|
* and we have at least two estimates
|
||||||
* then we have detection */
|
* then we have detection */
|
||||||
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
#ifdef AVMD_REQUIRE_CONTINUOUS_STREAK
|
||||||
if (v < VARIANCE_THRESHOLD && (session->sma_b.lpos > 1) && (session->samples_streak == 0)) {
|
if (v < VARIANCE_THRESHOLD && (s->sma_b.lpos > 1) && (s->samples_streak == 0)) {
|
||||||
#else
|
#else
|
||||||
if (v < VARIANCE_THRESHOLD && (session->sma_b.lpos > 1)) {
|
if (v < VARIANCE_THRESHOLD && (s->sma_b.lpos > 1)) {
|
||||||
#endif
|
#endif
|
||||||
#ifdef AVMD_FAST_MATH
|
#ifdef AVMD_FAST_MATH
|
||||||
sma_digital_freq = 0.5 * (double) fast_acosf((float)session->sma_b.sma);
|
sma_digital_freq = 0.5 * (double) fast_acosf((float)s->sma_b.sma);
|
||||||
#else
|
#else
|
||||||
sma_digital_freq = 0.5 * acos(session->sma_b.sma);
|
sma_digital_freq = 0.5 * acos(s->sma_b.sma);
|
||||||
#endif /* AVMD_FAST_MATH */
|
#endif /* AVMD_FAST_MATH */
|
||||||
|
|
||||||
switch_channel_set_variable_printf(channel, "avmd_total_time",
|
switch_channel_set_variable_printf(channel, "avmd_total_time",
|
||||||
"[%d]", (int)(switch_micro_time_now() - session->start_time) / 1000);
|
"[%d]", (int)(switch_micro_time_now() - s->start_time) / 1000);
|
||||||
switch_channel_execute_on(channel, "execute_on_avmd_beep");
|
switch_channel_execute_on(channel, "execute_on_avmd_beep");
|
||||||
|
avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v);
|
||||||
/* Throw an event to FreeSWITCH */
|
|
||||||
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP);
|
|
||||||
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, "Unique-ID",
|
|
||||||
switch_core_session_get_uuid(session->session));
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");
|
|
||||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f",
|
|
||||||
TO_HZ(session->rate, sma_digital_freq));
|
|
||||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_ERROR,
|
|
||||||
"Frequency truncated [%s], [%d] attempted!\n", buf, res);
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", "ERROR (TRUNCATED)");
|
|
||||||
}
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", buf);
|
|
||||||
|
|
||||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v);
|
|
||||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_ERROR,
|
|
||||||
"Error, truncated [%s], [%d] attempeted!\n", buf, res);
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", "ERROR (TRUNCATED)");
|
|
||||||
}
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", buf);
|
|
||||||
|
|
||||||
if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) return;
|
|
||||||
|
|
||||||
switch_core_session_queue_event(session->session, &event);
|
|
||||||
switch_event_fire(&event_copy);
|
|
||||||
|
|
||||||
#ifdef AVMD_REPORT_STATUS
|
#ifdef AVMD_REPORT_STATUS
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO,
|
||||||
"<<< AVMD - Beep Detected: f = [%f], variance = [%f] >>>\n",
|
"<<< AVMD - Beep Detected: f = [%f], variance = [%f] >>>\n",
|
||||||
TO_HZ(session->rate, sma_digital_freq), v);
|
TO_HZ(s->rate, sma_digital_freq), v);
|
||||||
#endif
|
#endif
|
||||||
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(&s->sma_b);
|
||||||
RESET_SMA_BUFFER(&session->sqa_b);
|
RESET_SMA_BUFFER(&s->sqa_b);
|
||||||
session->state.beep_state = BEEP_DETECTED;
|
s->state.beep_state = BEEP_DETECTED;
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1093,8 +1165,8 @@ loop_continue:
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
session->pos += sample_n;
|
s->pos += sample_n;
|
||||||
session->pos &= b->mask;
|
s->pos &= b->mask;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue