您的位置:首页 > 其它

修复kaldi中的在线语音识别的bug

2017-04-01 20:08 736 查看

修复kaldi中的在线语音识别的bug

当我们运行kaldi的online目录下的online-gmm-decode-faster的时候程序会显示PortAudio failed to open the default stream错误信息(kaldi的在线识别倚赖于portaudio库,这个库的作用可以理解为操作系统声音模块相关API的一个的封装。提供一个更加友好的编程接口,而且是跨平台的)。在使用portaudio之前必须要打开一个输出流或者输入流或者同时打开输入输出流。详细的了解请移步portaudio的官方文档。之所以出现这个bug是因为打开默认的输入流失败。我想portaudio是没有问题的因为V19的版本还比较稳定。而且这个问题出现处的代码与kaldi的其他代码没有联系。最有可能就是portaudio安装的不正确或者是编译设置不正确。出于这样的动机我决定重新安装portaudio。下面是详细的步骤。

portaudio的安装

kaldi代码的修改

Makfile的修改

常见错误

portaudio的安装

- 安装之前请先安装ALSA这个API,关于portaudio 的安装官方文档里有说就是先configure一下再make就成了。configure后会出现ALSA-------yes,如果是no那就请你先安装ALSA。在Makefile里在CFLAGS里面加上 -fPIC。可以将头文件库文件安装到指定的路径。就这样也可以如果你以后不是经常在这个库上作开发的话。生成的库在lib/.libs/下面。bin里面有一些测试程序。可以运行一个看看有没有问题。paex_record是一个录音的程序运行一下看看有没有错误。将pa_ringbuffer.c 改为pa_ringbuffer.cc 然后再将pa_ringbuffer.h,pa_ringbuffer.cc,pa_memorybarrier.h这三个文件考到src/online下。


kaldi代码的修改

将online下的online-audio-source.cc打开,定位到OnlinePaSource这个函数,我们要修改这个函数,错误就在这里。改成这个样子。

54   using namespace std;
55
56   // Note this will work for 32bit integers but not for 64bit.
57   // For 64bit integers even double wouldn't work
58   // You would ahve to use something like
59   // int64 rb_bits = 0; while (rb_size != 0) {++rb_bits; rb_size >>= 1;}
60   // it would be much faster than two logs of FP numbers (even floats), too,
61   // but I dont have the time to test it.
62   float f = Log(static_cast<float>(rb_size)) / Log(static_cast<float>(2));
63   int32 rb_bits = static_cast<int32>(ceil(f));
64   if (rb_bits > 30)  // ok, this limit is somewhat arbitrary
65     throw invalid_argument("PortAudio ring buffer too large!");
66   rb_size_ = 1 << rb_bits;
67   ring_buffer_ = new char[rb_size_];
68   ring_buffer_size_t rbs = PaUtil_InitializeRingBuffer(
69                                &pa_ringbuf_, sizeof(SampleType),
70                                rb_size_ / sizeof(SampleType), ring_buffer_);
71   if (rbs != 0)
72     throw runtime_error("Unexpected PortAudio ring buffer init error");
73 /*
74  *Begin: the code block is newly added to fix the bug:
75  * */
76   PaStreamParameters  inputParameters,outputParameters;
77
78   PaError paerr = Pa_Initialize();
79   if (paerr != paNoError)
80     throw runtime_error("PortAudio initialization error");
81
82   inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
83   if (inputParameters.device == paNoDevice) {
84      throw runtime_error("no device avilable");
85   }
86
87   inputParameters.channelCount = 1;                    /* stereo input */
88   inputParameters.sampleFormat = paInt16;
89   inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
90   inputParameters.hostApiSpecificStreamInfo = NULL;
91
92
93
94 /*
95  *End: the code block is newly added to fix the bug:
96  * */
97
98   // Monophone, 16-bit input hardcoded
99   KALDI_ASSERT(sizeof(SampleType) == 2 &&
100                "The current OnlinePaSource code assumes 16-bit input");
101
102   paerr=Pa_OpenStream(
103               &pa_stream_,
104               &inputParameters,
105               NULL,                  /* &outputParameters, */
106               sample_rate_,
107               0,
108               paNoFlag,      /* we won't output out of range samples so don't bother clipping them */
109               PaCallback,
110               this );
111  // paerr = Pa_OpenDefaultStream(&pa_stream_, 1, 0, paInt16, sample_rate_, 0,
112  //                              PaCallback, this);
113   if (paerr != paNoError)
114     throw runtime_error("PortAudio failed to open the default stream steve");
115 }


Makfile的修改

打开online下的Makefile

EXTRA_CXXFLAGS += -Wno-sign-compare  -fPIC -I/你portaudio安装的地方/portaudio/include


14 #ifeq ($(UNAME), Linux)
15 #ifneq "$(wildcard ../../tools/portaudio/install/lib/libportaudio.a)" ""
16 #    EXTRA_LDLIBS = ../../tools/portaudio/install/lib/libportaudio.a
17 #  else
18     EXTRA_LDLIBS =/home/xiao/temp/portaudio/lib/.libs/libportaudio.a
19 #  endif
20 #  ifneq ($(wildcard ../../tools/portaudio/install/include/pa_linux_alsa.h),)
21     EXTRA_LDLIBS += -lasound -lrt
22 #  else
23 #    EXTRA_LDLIBS += -lrt
24 #  endif
25 #  ifneq ($(wildcard ../../tools/portaudio/install/include/pa_jack.h),)
26 #    EXTRA_LDLIBS += -ljack
27 #  endif
28 #endif


将一些判断语句注释掉,将你的libportaudio.a的静态库添加进来。

在OBJFILES这个变量后面添加pa_ringbuffer.o

onlinebin 下的makefile也作相应的修改

将online下的.so,.o文件删除再make ext

常见错误

一。

/usr/bin/ld: kaldi-online.a(pa_ringbuffer.o): relocation R_X86_64_PC32 against symbol `PaUtil_FlushRingBuffer’ can not be used when making a shared object; recompile with -fPIC

/usr/bin/ld: final link failed: 错误的值

在编译的时候添加 -fPIC

出现最多的就是这个错误,还有一些忘记了。就写到这吧。希望对遇到相同问题的人有所帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语音识别 kaldi