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

修复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
出现最多的就是这个错误,还有一些忘记了。就写到这吧。希望对遇到相同问题的人有所帮助。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值