Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
1c39305f
提交
1c39305f
authored
2月 21, 2016
作者:
Piotr Gregor
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FS-8810 fix crash on FS startup
The float-int-float fast arc cosine mapping is now properly constructed (reused).
上级
566cc419
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
204 行增加
和
42 行删除
+204
-42
fast_acosf.c
src/mod/applications/mod_avmd/fast_acosf.c
+66
-27
fast_acosf.h
src/mod/applications/mod_avmd/fast_acosf.h
+39
-3
mod_avmd.c
src/mod/applications/mod_avmd/mod_avmd.c
+99
-12
没有找到文件。
src/mod/applications/mod_avmd/fast_acosf.c
浏览文件 @
1c39305f
#include <switch.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef _MSC_VER
...
...
@@ -12,6 +13,7 @@
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
...
...
@@ -56,57 +58,94 @@ static float strip_float(float f)
}
#endif
extern
void
compute_table
(
void
)
extern
int
compute_table
(
void
)
{
uint32_t
i
;
float
f
;
FILE
*
acos_table_file
;
size_t
ret
;
float
f
;
FILE
*
acos_table_file
;
size_t
res
;
acos_table_file
=
fopen
(
ACOS_TABLE_FILENAME
,
"w"
);
for
(
i
=
0
;
i
<
ACOS_TABLE_LENGTH
;
i
++
)
{
f
=
acosf
(
float_from_index
(
i
));
ret
=
fwrite
(
&
f
,
sizeof
(
f
),
1
,
acos_table_file
);
assert
(
ret
!=
0
);
res
=
fwrite
(
&
f
,
sizeof
(
f
),
1
,
acos_table_file
);
if
(
res
!=
1
)
{
goto
fail
;
}
}
ret
=
fclose
(
acos_table_file
);
assert
(
ret
!=
EOF
);
}
res
=
fclose
(
acos_table_file
);
if
(
res
!=
0
)
{
return
-
2
;
}
return
0
;
fail:
fclose
(
acos_table_file
);
return
-
1
;
}
extern
void
init_fast_acosf
(
void
)
extern
int
init_fast_acosf
(
void
)
{
int
ret
;
int
ret
,
errsv
;
FILE
*
acos_fp
;
char
err
[
150
];
if
(
acos_table
==
NULL
)
{
ret
=
access
(
ACOS_TABLE_FILENAME
,
F_OK
);
if
(
ret
==
0
)
compute_table
();
if
(
ret
==
-
1
)
{
/* file doesn't exist, bad permissions,
* or some other error occured */
errsv
=
errno
;
strerror_r
(
errsv
,
err
,
150
);
if
(
errsv
!=
ENOENT
)
return
-
1
;
else
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_NOTICE
,
"File [%s] doesn't exist. Creating file...
\n
"
,
ACOS_TABLE_FILENAME
);
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
);
}
}
acos_fd
=
open
(
ACOS_TABLE_FILENAME
,
O_RDONLY
);
if
(
acos_fd
==
-
1
)
perror
(
"Could not open file "
ACOS_TABLE_FILENAME
);
assert
(
acos_fd
!=
-
1
);
acos_table
=
(
float
*
)
mmap
(
NULL
,
acos_fp
=
fopen
(
ACOS_TABLE_FILENAME
,
"r"
);
if
(
acos_fp
==
NULL
)
return
-
3
;
/* 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
,
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
;
return
0
;
}
extern
void
destroy_fast_acosf
(
void
)
extern
int
destroy_fast_acosf
(
void
)
{
int
ret
;
ret
=
munmap
(
acos_table
,
ACOS_TABLE_LENGTH
);
assert
(
ret
!=
-
1
);
ret
=
close
(
acos_fd
);
assert
(
ret
!=
-
1
);
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
;
return
0
;
}
extern
float
fast_acosf
(
float
x
)
...
...
src/mod/applications/mod_avmd/fast_acosf.h
浏览文件 @
1c39305f
#ifndef __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
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
src/mod/applications/mod_avmd/mod_avmd.c
浏览文件 @
1c39305f
...
...
@@ -93,7 +93,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown);
SWITCH_STANDARD_API
(
avmd_api_main
);
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
);
/*! 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.
*
* @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
)
{
#ifdef FASTMATH
char
err
[
150
];
int
ret
;
#endif
switch_application_interface_t
*
app_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
)
{
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
;
}
...
...
@@ -227,14 +234,66 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_NOTICE
,
"Advanced Voicemail detection enabled
\n
"
);
);
#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_CHANNEL_LOG
,
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
...
...
@@ -246,7 +305,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load)
avmd_start_function
,
"[start] [stop]"
,
SAF_NONE
);
);
SWITCH_ADD_API
(
api_interface
,
"avmd"
,
"Voicemail beep detection"
,
avmd_api_main
,
AVMD_SYNTAX
);
...
...
@@ -328,11 +387,34 @@ SWITCH_STANDARD_APP(avmd_start_function)
*/
SWITCH_MODULE_SHUTDOWN_FUNCTION
(
mod_avmd_shutdown
)
{
#ifdef FASTMATH
int
res
;
#endif
switch_event_free_subclass
(
AVMD_EVENT_BEEP
);
#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
switch_log_printf
(
...
...
@@ -537,13 +619,16 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
/* calculate variance */
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
(
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"
);
/*! 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
;
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"
);
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_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"
);
RESET_SMA_BUFFER
(
&
session
->
sma_b
);
RESET_SMA_BUFFER
(
&
session
->
sqa_b
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论