项目进展制作日志

网页输入文字,ESP32 就能从喇叭说出来:本地语音平台播放链路实测

我把 ESP32-S3 的语音播放从“把固定音频烧进代码”改成了“在网页输入文字后动态播放”。本文记录网页、本地 TTS、任务队列、ESP32、MAX98357A 和喇叭之间怎样连成一条实际可听的链路,以及当前还没有完成的语音输入边界。

这篇日志属于作品:ESP32-S3 AI 语音对话原型

在这之前,我已经让 ESP32-S3 通过 MAX98357A 和一只 4Ω/3W 喇叭播放出三声测试音。但三声只能证明接线和基础音频输出能工作,它还不能决定自己要说什么。

这次的变化是:我可以在电脑网页里输入一句新文字,点击发送,不重新修改和烧录 ESP32 代码,喇叭就会播放新内容。

巧克力和西红柿打架,巧克力赢了。为什么呢?因为巧克力棒。

这是我实际用来测试过的一段文字。

这次打通的不是一段录音,而是一条动态链路

如果把一句 MP3 固定写进固件,每次换内容都要重新编译和上传。网页方案把“设备程序”和“要说的内容”分开:ESP32 固件继续负责联网、领取任务和播放;网页负责接收随时变化的文字。

环节负责的事情本次结果
网页输入文字并创建播放请求已实际提交
Mac 本地服务调用 TTS、保存 MP3、建立任务已生成音频
局域网任务接口让设备领取任务并上报状态已完成任务闭环
ESP32-S3下载 MP3、校验、解码并输出音频已连续处理 5 个任务
MAX98357A 与喇叭把 I²S 数字音频变成可以推动喇叭的输出用户已听见实际语音

乐鑫的 Arduino-ESP32 I²S 文档说明,I²S 使用位时钟、字选择和数据线传输 PCM 音频;在本项目中,对应的是 BCLK→GPIO16、LRC→GPIO17、DIN→GPIO18。ESP32 解码 MP3 后通过这三根信号线把音频送给 MAX98357A。

网页点击以后,设备实际做了什么

  1. 网页把输入文字提交给本地 FastAPI 服务。

  2. 服务调用当时使用的 TTS Provider 生成 MP3,并把音频保存为可领取的任务。

  3. ESP32-S3 通过 Wi-Fi 轮询服务,领取排队任务。

  4. 设备下载 MP3,并把音频放入 PSRAM。

  5. 固件解码 MP3,把 PCM 数据写入 I²S。

  6. MAX98357A 驱动喇叭播放,设备再依次回报 downloaded、playing 和 completed。

服务器数据库里原本排队的 5 个任务最后全部变成 completed,每个任务都有下载、播放中和完成事件;ESP32 串口逐条打印 playback complete。我也确认喇叭连续播放出了这些语音。这里的“5 条”是任务闭环的实测数量;现有记录不能证明上面的冷笑话一定属于这 5 条,所以我没有把两项证据强行对应。

为什么这一步比播放固定 MP3 更重要

对我来说,它最直接的意义是:我可以通过网页控制 ESP32 说什么,不必每换一句话就重新烧录代码。

这也改变了下一步的可能性。未来如果麦克风输入能够进入语音识别和 AI 生成,再把回答交给现在这条播放链路,设备才有机会形成真正的语音对话。现在的网页不是最终交互方式,但它先把“动态内容如何到达喇叭”独立验证了。

当前结论

这次验证把 ESP32 从一个只能播放固件内固定内容的设备,推进成了一个可以接收网页动态文字并播放语音的本地原型。硬件输出、网络任务和真实发声已经闭环;下一步是让它听见我说的话,再把输入链路接到现有输出链路上。

CONTINUE READING

继续阅读同一作品、元件或排查路径上的真实制作记录。