1)ARM+RTL8723 或RTL8821
RTL8723是USB接口的邮票芯片,集成了wifi和BT。前面已经完成了wifi的处理,这次主要说一下蓝牙语音方面。
蓝牙功能,我们主要是使用Bluez5协议栈.结合alsa使用(pulseaudio也是可以的,体积大一点)
bluez5_utils-5.62
bluez-alsa-3.1.0
先编译,我们都是利用文件系统一性编译出来。
2)驱动方面
RTL8821的驱动,加到内核里时,会出现加载失败的问题。改成ko方式,在启动后,手动加载。
/lib/firmware/下面有2个文件,rtl8821cu_config rtl8821cu_fw 。最后,再加载一下编译出来rtk_btusb.ko。
3)结合bluetoothctl, alsa等工具,打通语音功能。
先运行 dbus-daemon --system,再启动bluetoothd。
配置好/etc/asound.conf后,运行 bluealsa -p a2dp-source -p xxx 。
最后,调用bluetoothctl是比较好用的,配置对设备,连接设备,都可以。
4)
bluealsa-aplay的使用,正常运行,它可以列出playback,capture等设备。当前出现的问题,就是一直没有capture ,这是bluetoothd的编译问题导致,漏了选项。还有当初一直提示not found PCM,先从硬件上排除了问题,板子是没有任何其他语音模块的。
[root@localhost:~]# bluealsa-aplay -l
**** List of PLAYBACK Bluetooth Devices ****
hci0: 0C:52:C0:70:08:3C [BT51], trusted audio-card
SCO (CVSD): S16_LE 1 channel 8000 Hz
A2DP (SBC): S16_LE 2 channels 48000 Hz
**** List of CAPTURE Bluetooth Devices ****
hci0: 0C:52:C0:70:08:3C [BT51], trusted audio-card
SCO (CVSD): S16_LE 1 channel 8000 Hz
[root@localhost:~]#
5)测试使用aplay,arecord。整个流程完成
arecord -D bluealsa -r48000 -f S32_LE | aplay -D bluealsa -r48000
这样就可以边播放,边录入的声音。
6)经过上面5步,蓝牙功能基本上就没有问题了。我们的任务当然不只是这些。下面,还是通过RTP协议,录音上送,播放下发。
RTP一般都是使用G711A,但是蓝牙是不能直接播放这个格式的,需要进一步转换。
对方喊话时,通过RTP负载G711A语音流,一般采用长度是320字节。这时要把320字节的进行处理之后,aplay才能播放出来。
int main(int argc, char *argv[]) {
btplay_init();
printf("btplay init done\n");
int ret;
int fd;
unsigned char in_buf[1024] = {0};
fd = open("/tmp/PLAY", O_RDONLY);
if (fd < 0) {
printf("fopen PLAY fail! error\n");
return -1;
}
printf("before play\n");
std::thread th1(&play);
th1.detach();
while (1) {
ret = read(fd, in_buf, 1000);
if (ret > 0)
{
//printf("read size %d\n", ret);
}
else {
usleep(100);
continue;
}
mtx.lock();
sBuf += std::string((char *)in_buf, ret);
mtx.unlock();
}
btplay_deinit();
return 0;
}
同样,蓝牙的录音,捕获到之后,我们也需要处理,然后封装RTP包,发送到对方。
这要一来一去,就完成了蓝牙的对讲功能。
7)海康卫视的球机,我们拆开看过,它竟然使用现成的串口蓝牙模组,增加了很多成本。
功能代码资源
https://download.csdn.net/download/proing/87786214