我使用 asterisk 13、pocketsphinx 以及插件和服务器(基于 astsphinx)构建了一个德语数字语音识别系统,以将 asterisk 与 pocketsphinx 连接起来。当使用向识别引擎播放 wav 文件的调用测试系统时,一切正常,直到第 50 次调用左右。然后 Asterisk 因分段错误而崩溃并重新启动。阅读 gdb 回溯后,我发现问题发生在选择格式编解码器 ID 时。
这是 gdb 回溯:
> [New process 21378]
> #0 0x08155419 in ast_format_get_codec_id (format=0xb6d0cae0) at format.c:319 319 format.c: No such file or directory. in format.c
> (gdb) bt
> #0 0x08155419 in ast_format_get_codec_id (format=0xb6d0cae0) at format.c:319
> #1 0x081592ad in ast_format_cap_get_compatible (cap1=0xb506b188, cap2=0x8b2c110, result=0x8b3a908) at format_cap.c:591
> #2 0xb6e026a8 in ast_speech_new (engine_name=0xb4ed0fa8 "Sphinx-En", cap=0x8b2c110) at res_speech.c:198
> #3 0xb61fcf2f in speech_create (chan=0x8b279c0, data=0xb4ed0fa8 "Sphinx-En") at app_speech_utils.c:551
> #4 0x081bec23 in pbx_exec (c=0x8b279c0, app=0xb59ad958, data=0xb4ed0fa8 "Sphinx-En") at pbx_app.c:494
> #5 0x081b6973 in pbx_extension_helper (c=0x8b279c0, con=0x0, context=0x8b28048 "/25", exten=0x8b28098 "3000", priority=3,
> label=0x0,
> callerid=0xb4d045c0 "25", action=E_SPAWN, found=0xb4ed3348, combined_find_spawn=1) at pbx.c:2886
> #6 0x081bba90 in __ast_pbx_run (c=0x8b279c0, args=0x0) at pbx.c:4111
> #7 0x081bd580 in pbx_thread (data=0x8b279c0) at pbx.c:4610
> #8 0x08234c1b in dummy_start (data=0x8b27480) at utils.c:1239
> #9 0xb7245e6c in ?? () from /lib/libpthread.so.0
> #10 0x08b27480 in ?? ()
> #11 0x00000000 in ?? ()
有什么想法可能导致这种情况吗?
(回答 Burgis 的通话请求:)这是拨号计划内的通话:
exten => 3000,1,Answer()
exten => 3000,n,Set(SPEECH_DTMF_MAXLEN=1)
exten => 3000,n,SpeechCreate(Sphinx-En)
exten => 3000,n,SpeechActivateGrammar(digits.gram)
exten => 3000,n,SpeechStart()
exten => 3000,n(repeat),SpeechBackground(beep,10)
exten => 3000,n,Log(NOTICE,">>>>>>>>>>>RESULT")
exten => 3000,n,Log(NOTICE,${SPEECH_TEXT(0)})
exten => 3000,n,Wait(2)
exten => 3000,n,Goto(repeat)
答案1
好的,我们找到了解决方案:分段错误是由 asterisk 自己的 res_speech 模块中的一个错误引起的:res_speech.c 中有一个错误(matt-jordan 于 2014 年 7 月 21 日提交,媒体格式:重新设计媒体处理以提高性能...)。
在函数中:
struct ast_speech *ast_speech_new(const char *engine_name, const struct ast_format_cap *cap):
RAII_VAR(struct ast_format *, best, NULL, ao2_cleanup);
变量定义不正确,因为最好的将不会在这里分配。最好的仅指向ast_format_slin。如果函数返回,ao2_清理减少引用ast_format_slin这不起作用。
代替:
RAII_VAR(struct ast_format *, best, NULL, ao2_cleanup);
和:
struct ast_format *best=NULL;
并且没有发生崩溃(在调用语音 API 约 45 次之后)。