项目:智能音箱
嵌入式 AI 典型场景:音频采集 + 唤醒词 + ASR + TTS + 云端对话。
一、目标
- 麦克风阵列采集
- 本地唤醒词检测(轻量模型)
- 云端语音识别(ASR)
- 对话管理
- TTS 语音合成
- 扬声器输出
二、硬件
- SoC:RK3568 / i.MX 8M Plus / 全志 R329
- 麦克风:PDM 或 I2S 接口
- 功放:I2S + D 类功放
- 喇叭:4Ω/3W
三、音频子系统
1. ALSA 框架
#include <alsa/asoundlib.h>
snd_pcm_t *pcm;
snd_pcm_open(&pcm, "default", SND_PCM_STREAM_CAPTURE, 0);
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(pcm, params);
snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(pcm, params, 1);
snd_pcm_hw_params_set_rate(pcm, params, 16000, 0);
snd_pcm_hw_params(pcm, params);
snd_pcm_prepare(pcm);
char buf[3200]; // 100ms @ 16kHz
while (1) {
snd_pcm_readi(pcm, buf, 1600); // 100ms
process_audio(buf, 3200);
}
2. 设备树
sound: sound {
compatible = "simple-audio-card";
simple-audio-card,name = "myboard-audio";
simple-audio-card,dai-link@0 {
format = "i2s";
cpu { sound-dai = <&i2s1>; };
codec { sound-dai = <&codec>; };
};
simple-audio-card,dai-link@1 {
format = "i2s";
cpu { sound-dai = <&i2s1>; };
codec { sound-dai = <&spk_amp>; };
};
};
四、唤醒词检测
使用 Snowboy / Picovoice Porcupine:
// 伪代码
while (running) {
snd_pcm_readi(pcm, audio_buf, 1600);
int wake = snowboy_run(snowboy, audio_buf);
if (wake == 1) {
play_beep();
start_capture();
upload_to_cloud();
}
}
五、ASR(云端)
// 发送录音到 ASR
void send_asr(char *wav_data, int len)
{
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "format", "wav");
cJSON_AddNumberToObject(root, "rate", 16000);
cJSON_AddRawToObject(root, "audio", base64_encode(wav_data, len));
http_post("https://api.asr.com/recognize", root);
}
六、TTS
// 云端 TTS → 播放
char *url = "https://api.tts.com/synthesize?text=hello";
char *mp3_data = http_get(url);
play_mp3(mp3_data);
七、本地 ASR(嵌入式 AI)
- Whisper.cpp:OpenAI Whisper 移植版
- Vosk:流式 STT
- Coqui STT
- DeepSpeech
git clone https://github.com/ggml-org/whisper.cpp
cd whisper.cpp
make
./main -m models/ggml-base.bin -f input.wav
ARM 量化模型:
- ggml-tiny.bin(39 MB)
- ggml-base.bin(142 MB)
适合 RK3568 / i.MX 8M Plus(带 NPU)。
八、对话管理
// 状态机
typedef enum {
STATE_IDLE,
STATE_LISTENING,
STATE_PROCESSING,
STATE_SPEAKING,
} dialog_state_t;
// FSM
if (state == STATE_IDLE && wake_detected()) {
state = STATE_LISTENING;
start_record();
}
if (state == STATE_LISTENING && silence_detected()) {
state = STATE_PROCESSING;
upload_asr();
}
if (state == STATE_PROCESSING && asr_result_ready()) {
state = STATE_SPEAKING;
play_tts();
}
if (state == STATE_SPEAKING && play_finished()) {
state = STATE_IDLE;
}
九、回声消除(AEC)
- WebRTC AEC
- Speex AEC
- 自适应滤波
// WebRTC AEC
void *aec = WebRtcAec_Create();
WebRtcAec_Init(aec, 16000, 16000);
// 远端参考(扬声器输出)
int far_buf[1600];
// 近端(麦克风输入)
int near_buf[1600];
WebRtcAec_BufferFarend(aec, far_buf, 1600);
WebRtcAec_Process(aec, near_buf, NULL, near_buf_echo_canceled, 1600, ...);
十、典型嵌入式 SoC 选型
| SoC | NPU | 适用 |
|---|---|---|
| RK3568 | 1 TOPS | 中端音箱 |
| RK3588 | 6 TOPS | 高端、视觉 |
| 全志 R329 | 0.5 TOPS | 低端语音 |
| i.MX 8M Plus | 2.3 TOPS | 高端 |
| Amlogic A311D | 5 TOPS | 高端 |