mini2440+阿里云+Qt/android 打造智能音箱
华为在2018年10月26日发布了一款音箱,AI智能音箱,载了来自猎户星空的语音合成技术。用户通过语音或者华为智能家居App,可轻松控制音箱的播放、暂停等等操作。
以华为AI智能音箱为背景,我们自己动手制作一个智能音箱,实现功能如下:
- 音箱本身可以播放音乐,通过按键切换歌曲、暂停继续、调节音量;
- PC上通过Qt程序可以远程控制音箱的播放,实现和按键相同的功能;
- 手机端开发Android APP,功能和Qt一样;
- Qt和Android增加语音识别模块,能识别基本的播放指令。
硬件平台
- mini2440或者其他可以运行Linux操作系统、带有音频输出接口的开发板;
- Android手机、PC。
软件平台
- 运行Linux操作系统的虚拟机;
- 阿里云或者其他公网服务器(腾讯云、华为云...);
- Windows。
嵌入式端侧开发
select
音箱的控制分为两块,按键和网络(Qt和Android都通过socket和音箱通信)。主程序嵌入式select,按键在Linux操作系统中对应的是设备文件,socket也是一个文件,所以用select同时监听两个文件描述符。当有数据可读的时候,判断文件描述符并做出不同的处理。
多进程
音箱的核心任务是播放音乐。为了提升用户体验,即程序出bug的时候能保证音乐继续播放,播放方案选择多进程。
需要三个进程:
- 主进程负责接收指令(暂停、继续等等),并且根据收到的指令做出进一步的处理;
- 子进程负责创建孙进程,并且通过waitpid阻塞,知道一首音乐播放结束,回收进程资源;
- 孙进程通过exec函数调用播放进程madplay。
暂停继续功能通过信号SIGSTOP和SIGCONT实现,由父进程发送,子进程和孙进程接收。
上一首下一首功能由信号SIGKILL实现,父进程结束子进程和孙进程,重新启动子进程和孙进程,并提供下一首音乐信息。
共享内存
父进程、子进程、孙进程之间需要传递歌曲信息、播放模式等等信息,通过共享内存实现。共享内存也是通信效率最高的一种IPC方式。
服务器
如果要实现音箱的远程控制,必然离不开一台公网服务器。
libevent
服务器在整个项目中承担着转发的角色,一旦有大量的客户端上线,必将对服务器的性能提出很高的要求,所以选择libevent开源库来处理服务器端的并发操作。
libevent是一个由C语言编写的,轻量级高性能的事件通知库,支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等。
项目中服务器主要负责转发APP发送的指令,比如暂停、继续、开始、切歌等等,数据量很小,整个json包也就几十个字节,所以选择libevent非常合适。
json
json是一种非常常用的通信格式,跟传统的结构体相比,它更加的节省空间、提高通信效率。json的开源库非常多,适用于很多平台和很多语言。端侧使用json-c、服务器使用jsoncpp、APP使用QJson。Qjson是Qt自带的软件库,直接调用函数就行;jsoncpp需要安装软件包;json-c需要下载源码进行交叉编译,涉及到移植的操作。
list
服务器在运行的过程中需要保存客户端的数据,比如音箱和APP的绑定关系、音箱和APP是否在线、APP注册的用户名和密码,这些数据都保存在链表中。与之对应的,如果想要长期保存数据,还要再加上数据库。
Qt/Android
APP主要是良好的人机交互,功能的话,加上几个按键,能通过socket把指令发送到服务器就行。