前言

  最近调试板子上的3个ADAU1761音频接口,使用pocketsphinx语音库调用alsa库的API接口打开指定的Mic进行录入语音时出现异常,默认情况只能打开第一个ADAU1761音频接口,想打开第二个或第三个ADAU1761音频接口时却出现错误,本文记录一下调试的过程。

PCM设备选择

  移植alsa lib 和alsa utils库后(移植教程见:传送门)可使用以下指令查看声卡设备和PCM设备,具体如下:

root@newboard_project:/# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ADAU1761 [ZED ADAU1761], device 0: 43c00000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0
card 1: ADAU1761_1 [ZED ADAU1761], device 0: 43c10000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0
card 2: ADAU1761_2 [ZED ADAU1761], device 0: 43c20000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0root@newboard_project:/# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: ADAU1761 [ZED ADAU1761], device 0: 43c00000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0
card 1: ADAU1761_1 [ZED ADAU1761], device 0: 43c10000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0
card 2: ADAU1761_2 [ZED ADAU1761], device 0: 43c20000.axi-i2s-adau-hifi adau-hifi-0 []Subdevices: 1/1Subdevice #0: subdevice #0root@newboard_project:/# ls -l /dev/snd
crw-rw----    1 root     root      116,   0 Jan  1 00:00 controlC0
crw-rw----    1 root     root      116,  32 Jan  1 00:00 controlC1
crw-rw----    1 root     root      116,  64 Jan  1 00:00 controlC2
crw-rw----    1 root     root      116,  24 Jan  1 00:00 pcmC0D0c
crw-rw----    1 root     root      116,  16 Jan  1 00:00 pcmC0D0p
crw-rw----    1 root     root      116,  56 Jan  1 00:00 pcmC1D0c
crw-rw----    1 root     root      116,  48 Jan  1 00:00 pcmC1D0p
crw-rw----    1 root     root      116,  88 Jan  1 00:00 pcmC2D0c
crw-rw----    1 root     root      116,  80 Jan  1 00:00 pcmC2D0p
crw-rw----    1 root     root      116,  33 Jan  1 00:00 timer

如上,共有三个声卡设备:
card 0: ADAU1761
card 1: ADAU1761_1
card 2: ADAU1761_2
在使用aplay和arecord指令进行播放和录音时可正常选择其中某一个声卡,如:

//使用ADAU1761_1录音
root@newboard_project:/# arecord -D hw:ADAU1761_1 -fS32_LE -d10 -c2 -r48000 s32_
le.wav
Recording WAVE 's32_le.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo//使用ADAU1761播放
root@newboard_project:/# aplay -D hw:ADAU1761 -fS32_LE -c2 -r48000 s32_le.wav
Playing WAVE 's32_le.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo

  移植完pocketsphinx库后(见教程:传送门),调用pocketsphinx_continuous指令打开MIC进行语音识别,默认可打开ADAU1761设备,而打开其他两个声卡出现异常,报错:
Failed to set PCM device to 16-bit signed PCM: Invalid argument
FATAL_ERROR: “continuous.c”, line 246: Failed to open audio device

查看pocketsphinx-0.8\src\programs\continuous.c 中源码,为ad_open_dev() API接口打开设备失败。

/** Main utterance processing loop:*     for (;;) {*     wait for start of next utterance;*     decode utterance until silence of at least 1 sec observed;*     print utterance result;*     }*/
static void
recognize_from_microphone()
{ad_rec_t *ad;int16 adbuf[4096];int32 k, ts, rem;char const *hyp;char const *uttid;cont_ad_t *cont;char word[256];if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),(int)cmd_ln_float32_r(config, "-samprate"))) == NULL)E_FATAL("Failed to open audio device\n");//。。。。。。。省略}

接着查看ad_open_dev函数(\sphinxbase-0.8\src\libsphinxad\ad_alsa.c文件中),里面调用snd_pcm_open函数打开PCM设备,若输入的dev是NULL,则使用DEFAULT_DEVICE设备。

ad_rec_t *
ad_open_dev(const char *dev, int32 sps)
{ad_rec_t *handle;snd_pcm_t *dspH;int err;if (dev == NULL)dev = DEFAULT_DEVICE;err = snd_pcm_open(&dspH, dev, SND_PCM_STREAM_CAPTURE, 0);if (err < 0) {fprintf(stderr,"Error opening audio device %s for capture: %s\n",dev, snd_strerror(err));return NULL;}if (setparams(sps, dspH) < 0) {return NULL;}if (setlevels(dev) < 0) {return NULL;}if ((handle = (ad_rec_t *) calloc(1, sizeof(ad_rec_t))) == NULL) {fprintf(stderr, "calloc(%d) failed\n", (int)sizeof(ad_rec_t));abort();}handle->dspH = dspH;handle->recording = 0;handle->sps = sps;handle->bps = sizeof(int16);return (handle);
}

DEFAULT_DEVICE的定义:

#define DEFAULT_DEVICE "default"

snd_pcm_open函数的使用介绍见:传送门,查看库的使用介绍,name参数的使用例程,设备名称格式分别使用hw:0,0plughw:0,0


默认情况下打开的设备是card 0,默认情况下加载/usr/local/alsa/alsa.conf文件,该文件中有默认打开的声卡参数:

# defaults
## show all name hints also for definitions without hint {} section
defaults.namehint.showall off
# show just basic name hints
defaults.namehint.basic on
# show extended name hints
defaults.namehint.extended off
#
defaults.ctl.card 0 //默认声卡0
defaults.pcm.card 0 //默认声卡0
defaults.pcm.device 0 //默认设备0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
defaults.pcm.compat 0
defaults.pcm.minperiodtime 5000         # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format "unchanged"
defaults.pcm.dmix.card defaults.pcm.card
defaults.pcm.dmix.device defaults.pcm.device
defaults.pcm.dsnoop.card defaults.pcm.card
defaults.pcm.dsnoop.device defaults.pcm.device
defaults.pcm.front.card defaults.pcm.card
defaults.pcm.front.device defaults.pcm.device
defaults.pcm.rear.card defaults.pcm.card
defaults.pcm.rear.device defaults.pcm.device
defaults.pcm.center_lfe.card defaults.pcm.card
defaults.pcm.center_lfe.device defaults.pcm.device
defaults.pcm.side.card defaults.pcm.card
defaults.pcm.side.device defaults.pcm.device
defaults.pcm.surround21.card defaults.pcm.card
defaults.pcm.surround21.device defaults.pcm.device
defaults.pcm.surround40.card defaults.pcm.card
defaults.pcm.surround40.device defaults.pcm.device
defaults.pcm.surround41.card defaults.pcm.card
defaults.pcm.surround41.device defaults.pcm.device
defaults.pcm.surround50.card defaults.pcm.card
defaults.pcm.surround50.device defaults.pcm.device
defaults.pcm.surround51.card defaults.pcm.card
defaults.pcm.surround51.device defaults.pcm.device
defaults.pcm.surround71.card defaults.pcm.card
defaults.pcm.surround71.device defaults.pcm.device
defaults.pcm.iec958.card defaults.pcm.card
defaults.pcm.iec958.device defaults.pcm.device
defaults.pcm.modem.card defaults.pcm.card
defaults.pcm.modem.device defaults.pcm.device
# truncate files via file or tee PCM
defaults.pcm.file_format        "raw"
defaults.pcm.file_truncate      true
defaults.rawmidi.card 0
defaults.rawmidi.device 0
defaults.rawmidi.subdevice -1
defaults.hwdep.card 0
defaults.hwdep.device 0
defaults.timer.class 2
defaults.timer.sclass 0
defaults.timer.card 0
defaults.timer.device 0
defaults.timer.subdevice 0                                                

  若要打开对应的声卡,修改上述参数即可实现加载对应的声卡设备。
  查看ALSA库的参数资料,其API使用的是逻辑设备名,如下:
  API库使用逻辑设备名而不是设备文件。设备名字可以是真实的硬件名字也可以是插件名字。硬件名字使用hw:i,j这样的格式。其中i是卡号,j是这块声卡上的设备号。第一个声音设备是hw:0 , 0.这个别名默认引用第一块声音设备并且在本文示例中一真会被用到。插件使用另外的唯一名字,比如 plughw:0 , 0:,表示一个插件,这个插件不提供对硬件设备的访问,而是提供像采样率转换这样的软件特性,硬件本身并不支持这样的特性。
ALSA库的资料见:传送门,逻辑设备名的使用例程见:

使用* -adcdev plughw:1,0*参数打开对应声卡,如下打开声卡1:

pocketsphinx_continuous -adcdev plughw:1,0 -hmm tdt_sc_8k/ -lm 6690.lm -dict 6690.dic

成功打开声卡1,连接MIC说话,语音识别结果如下:

使用hw:0 , 0参数打开对应声卡,弹出无效参数的错误:

pocketsphinx_continuous -adcdev hw:1,0 -hmm tdt_sc_8k/ -lm 6690.lm -dict 6690.dic


对比alsa.conf文件中hw和plughw中参数结构如下,具体使用-adcdev hw:1,0打开声卡失败的原因还未查到。

总结

  使用pocketsphinx语音库调用alsa库的API接口打开指定的声卡设备主要以下两种方法:
(1)修改alsa.conf文件中的默认声卡参数;(不推荐)
(2)使用* -adcdev plughw:n,0*参数打开对应的声卡n,例如:

pocketsphinx_continuous -adcdev plughw:1,0 -hmm tdt_sc_8k/ -lm 6690.lm -dict 6690.dic

linux——alsa中多个声卡设备时打开某一指定声卡的PCM设备相关推荐

  1. Linux系统中VI或VIM输入时小键盘无法使用

    Linux系统中VI或VIM输入时小键盘无法使用 问题描述 在使用Xshell.Webshell或者PuTTY连接Linux服务器时经常会用到VIM对文件进行编辑.这是就会发现,小键盘无法使用.想输入 ...

  2. linux校时 某个服务器,Linux系统中如何进行网络校时?

    linux系统对于大多数用户来说,肯定没有windows系统那么熟悉,下文介绍了Linux系统中如何进行网络校时方法,具体内容如下所述. 我们都知道在Linux系统上有两个时间,一个是Linux系统的 ...

  3. 在eclipse中直接运行JavaWeb项目时打开指定页面(默认的jsp)

    在Eclipse中直接运行JavaWeb项目时打开指定Jsp文件 原因 没改之前 解决方法 原因 今天做了一个JavaWeb的项目,必须先打开指定的jsp(我在这个jsp里建立了与数据库的连接,并且有 ...

  4. linux c中的文件描述符与打开文件之间的关系

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通 ...

  5. android连接此设备时打开,QtScrcpy: Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限...

    QtScrcpy QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和控制.不需要root权限. 单个应用程序最多支持16个安卓设备同时连接. 同时支持GNU/Li ...

  6. linux centos7中unzip解压zip时中文乱码的解决办法

    我使用的centos7和win7的双系统,当进入linux系统之后访问到win7盘符里面的zip压缩包,当使用linux的归档管理器打开zip包时发现里面的文件名称竟然是中文乱码状态,具体解决方式是配 ...

  7. Ubuntu Linux系统中出现jupyter notebook不能自动打开浏览器

    说实话,以前是没有这个问题的,不知道是什么因素影响的,所以我记录下当前环境版本: 组件 版本 Python 3.6.10 Ubuntu 20.04 Shell Zshell subl /home/ap ...

  8. 〖Android〗存在多个Android设备时,使用Shell脚本选择一个Android设备

    Shell脚本: #!/bin/bash devices=( $(adb devices|grep device$|awk '{print $1}'|xargs echo) )case ${#devi ...

  9. linux之vim如何快速找到第二次打开文件的指定行

    1.得到指定行的行号 vim 1.c 打开这个文件之后,比如有一行内容为 int main() 我们需要知道这是在哪一行,我们可以通过set nu命令来显示vim的行数,在vim里面用下面命令 :se ...

  10. Linux ALSA 之二:ALSA 声卡与设备

    ALSA 声卡与设备 一.ALSA Sound 初始化 1.alsa_sound_init() 入口函数 2.init_soundcore() 入口函数 二.声卡结构体与创建.注册 1.struct ...

最新文章

  1. 如何避免重构带来的危险
  2. Error while adding the mapper ‘interface *****类‘ to configuration报错原因
  3. oracle数据库 日志满了
  4. Linux Shell脚本入门教程系列之(四)Shell注释
  5. 化鲲为鹏,我有话说 ,鲲鹏ARM架构的优势
  6. 苹果召回6.3万台MacBook Pro;罗永浩回应“收购苹果”;新版Edge支持Windows 7/8 | 极客头条...
  7. python有什么用-Python到底有什么用?为什么那么多人都在学Python?
  8. HashMap,TreeMap,LinkedHashMap学习
  9. 解决maven打包 错误: 程序包com.sun.istack.internal不存在 - BBSMAX
  10. 软件体系结构 复习题
  11. 闩锁效应Latch-up effect---Phsical cell---Welltap---SOI
  12. 固态硬盘故障检测_有哪些好用的检测软件是用于判断固态硬盘故障的?
  13. Chrome浏览器保存整个网页为图片
  14. 沃德移动尾气净化设备监控管理系统
  15. Forever young
  16. pandorabox php7,飞鱼星G7免拆刷入pandorabox
  17. Oracle11g pl-sql developer安装包及教程
  18. 西普学院Crypto之先有鸡还是先有蛋
  19. 4 行代码写 3 个NPE异常,服了!
  20. python文档生成_python文档生成工具:pydoc、sphinx;django如何使用sphinx?

热门文章

  1. 材料成型及控制工程学计算机吗,材料成型及控制工程 硕士以后 工资多少,
  2. centos系统下安装daemontools详细指南
  3. 威纶通触摸屏制作自定义欢迎界面的几种方法介绍
  4. 德纳研报丨基于区块链的邮箱Damil已完成种子轮融资,会是下一个ENS吗
  5. 图像处理之边缘检测[微分算子、Canny算子和LOG算子]
  6. matlab排序函数sort的使用方法
  7. Golang Time互转秒、毫秒
  8. 计算机类核心期刊投稿的一些资料汇总
  9. GAGE EON采集卡
  10. 使用命令备份、还原驱动程序