收集了一些资料的讯息和关键词。
-
/usr/share/alsa/pcm
-
/sys/devices/platform/soc/sndcodec/sound
-
/sys/class/sound
目前linux中主流的音频体系结构是ALSA(Advanced Linux Sound Architecture),ALSA在内核驱动层提供了alsa-driver,在应用层提供了alsa-lib,应用程序只需要调用alsa-lib提供的API就可以完成对底层硬件的操作。说的这么好,但是Android中没有使用标准的ALSA,而是一个ALSA的简化版叫做tinyalsa。Android中使用tinyalsa控制管理所有模式的音频通路,我们也可以使用tinyalsa提供的工具进行查看、调试。
linux驱动由浅入深系列:tinyalsa(tinymix/tinycap/tinyplay/tinypcminfo)音频子系统之一
tinyalsa 这玩意实现会有略微差异,但都依赖于 libtinyalsa 这个库,在 tina 的 softwinner/eyesee-mpp/system/public/tinyalsa/pcm.c 代码里关键在于取 pcm_open & pcm_read 的数据,源头指向 /dev/snd/pcmCXDX 这个设备。
这也就导致了 http://www.portaudio.com/ 和 http://freenet.mcnabhosting.com/python/pyPortAudio/ 不能直接使用。
我们知道目前最上层接口的 pyAudio 依赖 pyPortAudio 依赖 portaudio, portaudio 中支持 ALSA 接口,但很可惜不是 tinyalsa , 使用的 API 为 snd_pcm_open & snd_pcm_read ,当然,想要兼容跑起来也并非不可以。
不过这里我们可以直接手工实现:
不使用 tinymix 和 tinycap 的主要原因是走 shell 接口,不能实时的进行数据的交换。
如果想要在 Python 中进行录播,则需要把 cap 的数据怼到 play 上,然而很可惜,它只能先写到文件后再读取播放。
所以假定伪代码 Python 如下:
from maix import audio
pcm = audio.Audio()
pcm.open()
pcm.play(pcm.record())
with open('/tmp/t.wav') as f:
f.write(pcm.record())
pcm.close()
记录实现的模块参考,稍后补上。
2021年01月29日 虽然我想 http://www.portaudio.com/ 然后接入 pyaudio 模块,但看起来 libtinyalsa 与 libalsa 驱动差异到需要补一个对应平台的实现,也许这样实现会对统一平台更友好,否则只能改写 https://people.csail.mit.edu/hubert/git/pyaudio.git 了。
printf("open Left Input Mixer MIC1 Boost Switch
");
ret = system("tinymix set 9 1");
ret = system("tinycap /mnt/sdcard/1.wav -D 0 -d 0 -c 1 -r 8000 -b 16 -p 64 -n 1 -t 10");
ret = system("tinyplay -d 0 -D 0 /mnt/sdcard/1.wav");