基于炬芯ATS3089X U 盘 MP3 播放器实现

ATS3089P U 盘 MP3 文件播放说明

本功能通过设备 shell 指令播放板载存储中的指定 MP3 文件。命令等待本次播放器初始化完成后返回,整首音频在后台播放;后续 GUI 可以直接调用同一套播放器接口,传入用户选择的文件路径。

准备音乐文件

本工程中电脑看到的 USB U 盘是板载 NAND 的 MSC 功能。退出 MSC 后,固件通过 FAT 文件系统访问它,路径前缀是 `/NAND:/`。这与板子作为 USB Host 读取外接 U 盘的 `/USB:/` 不同;本功能使用的是前者。

  1. 连接 USB 数据线,在设备 shell 执行 `app udisk on`。

  2. 在电脑看到的设备 U 盘根目录复制 `song.mp3`。

  3. 在电脑安全弹出 U 盘,确认文件复制已经结束。

  4. 在设备 shell 执行 `app udisk off`,待 U 盘模式退出、文件系统重新挂载后启动播放。

当前板级 FAT 配置关闭了长文件名支持,请使用 8.3 格式的 ASCII 文件名:主文件名最多 8 个字符,扩展名最多 3 个字符,例如 `song.mp3`、`test1.mp3`。首次测试建议把文件放在根目录。不要使用中文名称或带空格的长名称,以免电脑写入的名称与固件可访问的短文件名不一致。

命令与示例

```text

app udisk off

app mp3 play /NAND:/song.mp3

app mp3 status

```

`play` 必须指定 `/NAND:/` 开头、`.mp3` 结尾的完整路径,路径长度小于 128 字节。播放器会检查文件非空并启动 MP3 解析和解码;初始化完成后命令返回,不等待整首文件播放结束,shell 可继续接收其他命令。命令返回成功表示播放器已启动,后续文件读取、码流解码错误仍可能导致播放终止,请结合状态和运行日志判断。

| 命令 | 作用 |

| --- | --- |

| `app mp3 play /NAND:/song.mp3` | 从头播放指定 MP3 文件 |

| `app mp3 pause` | 保存当前压缩帧断点,暂停并关闭播放资源 |

| `app mp3 resume` | 按保存的断点重新打开文件并继续播放 |

| `app mp3 stop` | 停止播放,关闭媒体与文件资源 |

| `app mp3 status` | 查询状态、文件、位置/总时长(毫秒)、音量和最近错误 |

| `app mp3 volume` | 查询音量及当前允许的音量范围 |

| `app mp3 volume <level>` | 设置音量 |

音量范围由 `audio_policy` 的板级策略决定,命令查询时会输出实际范围。请以本机输出为准,不把固定音量上限写入测试程序或后续 GUI。

播放完毕后播放器会自动释放媒体和文件资源。`stop` 结束当前播放会话;之后执行 `play` 从文件开头开始。

`pause` 保存 SDK 提供的文件位置和时间断点,然后关闭 DSP、文件和扬声器播放通道;`resume` 使用保存的断点重新打开播放。继续位置按 MP3 压缩帧定位,精度由 SDK parser/decoder 的断点机制决定,不能保证逐个 PCM 采样点连续。

例如依次播放两首文件:

```text

app mp3 play /NAND:/song.mp3

app mp3 pause

app mp3 resume

app mp3 stop

app mp3 play /NAND:/test1.mp3

```

重新进入 U 盘模式上传或删除文件时,直接执行 `app udisk on` 即可。进入 MSC 的流程会先停止 MP3、关闭 FAT 文件流,再卸载 NAND 文件系统;也可以手动执行 `app mp3 stop` 后切换。电脑通过 MSC 访问 NAND 时,固件不能同时播放同一卷中的文件;此时 `play` 和 `resume` 会拒绝启动。

语音控制与语音回复

已有"暂停音乐"和"播放音乐"识别流程接入 MP3 播放器:存在活动的 MP3 文件时,分别暂停当前文件、继续暂停的文件。识别命令成功后沿用"我已暂停音乐"或"我已播放音乐"的中文回复。

语音回复使用资源区 `/NAND:K/` 中的 16 kHz 单声道 PCM 文件。MP3 播放与回复通过音频资源交接协调,避免同时建立相互冲突的 DAC 播放通道:暂停指令后播报并保持暂停;播放指令后,播放器暂存音乐断点、播报回复,再恢复音乐。首次上板验证时,建议先用 shell 的 `pause` / `resume` 确认 MP3 播放正常,再开启 ASR 测试语音控制。

MP3 播放原理

现有 SDK 已集成 MP3 parser、MP3 decoder 以及媒体服务。本工程配置已启用 `CONFIG_PARSER_MP3`、`CONFIG_DECODER_MP3`,生成配置中的 `CONFIG_DECODER_MP3_HW_ACCELERATION=y` 使用 DSP 解码。

数据流程如下:

```text

app mp3 play <文件路径>

-> MP3 播放器检查状态与文件

-> CPU 通过 FAT/file stream 读取 MP3 数据

-> 现有 MP3 parser 解析文件与码流

-> media_player 提交压缩音频给 DSP

-> adMUSIC.dsp 中的 MP3 decoder 输出 PCM

-> DAC、功放、扬声器输出声音

```

CPU 负责文件读取、命令处理、状态和资源生命周期;MP3 解码通过现有 DSP 媒体通道完成。`framework/media/parser_config.c` 注册 MP3 parser,`framework/media/codec_config.c` 的 `MP3_TYPE` 配置指定 DSP 解码镜像 `adMUSIC.dsp`。板级资源目录包含该镜像,媒体服务负责加载和管理 DSP 会话,应用不直接操作 DSP 的 packet 或共享内存协议。

MP3 播放将解码后的 PCM 送到扬声器。

程序入口与后续 GUI 接入

  • `application/bt_watch/src/main/mp3_player.c`:独立 MP3 播放模块,负责指定文件、播放状态、暂停继续、停止和资源清理。

  • `application/bt_watch/src/main/mp3_player.h`:供 shell、语音控制和后续 GUI 调用的公共接口。

  • `application/bt_watch/src/main/system_app_shell.c`:`app mp3` 命令入口,负责参数解析并调用播放器接口。

  • `framework/base/include/utils/stream/file_stream.h`:SDK 文件流接口,播放器通过 `file_stream_create()` / `stream_open()` 建立 FAT 输入流,供媒体服务读取文件。

  • `framework/media/`:沿用现有 parser 和媒体播放服务。

`mp3_player.h` 提供以下接口,shell、语音控制和 GUI 共用同一个播放器实例:

| 接口 | 用途 |

| --- | --- |

| `mp3_player_play(path)` | 从头播放完整路径指定的文件 |

| `mp3_player_pause()` | 保存断点并关闭当前播放通道 |

| `mp3_player_resume()` | 按保存的断点重新开始播放 |

| `mp3_player_stop()` | 停止并释放当前文件和播放资源 |

| `mp3_player_set_volume(level)` | 设置当前播放器音量 |

| `mp3_player_get_status(struct mp3_player_status *)` | 获取状态、路径、位置、总时长、音量及错误信息 |

| `mp3_player_is_active()` | 判断是否有活动的 MP3 会话,包括暂停状态 |

| `mp3_player_is_paused()` | 判断 MP3 会话是否处于暂停状态 |

| `mp3_player_prompt_pcm(path)` | 播放 `/NAND:K/` 内置的 16 kHz 单声道 PCM 回复,保存音乐断点并按原播放状态恢复 |

查询结果中的 `position_ms` 和 `total_ms` 分别表示当前位置和总时长,单位均为毫秒;`volume` 与 `max_volume` 用于显示当前音量和实际允许的上限,`last_error` 用于显示最近错误。状态为 `MP3_PLAYER_STOPPED`、`MP3_PLAYER_PLAYING`、`MP3_PLAYER_PAUSED` 或 `MP3_PLAYER_ERROR`。状态由播放器模块维护,文件结束后的资源清理由模块自动处理。

GUI 选中文件后,把完整路径作为播放消息参数发送给独立控制任务;该任务调用 `mp3_player_play(path)`。暂停、继续、停止和设置音量采用相同方式。控制接口会等待工作线程完成本次操作,例如打开文件或关闭 DSP,因此 GUI 的点击、绘制或高频刷新回调只投递请求,由独立控制任务等待调用结果。

不要从 `launcher` 任务、媒体事件回调或 IRQ 中等待这些同步控制接口。媒体切换可能需要 `launcher` 处理 `force_stop` 回调;如果 `launcher` 自身已经等待 MP3 操作完成,会阻碍资源交接。独立控制任务调用播放器接口后,再向 GUI 投递结果消息,GUI 在自己的线程更新控件。

初始化完成后,歌曲仍在后台播放。独立控制任务定期调用 `mp3_player_get_status()`,再把状态结果发送给 GUI 更新播放按钮、时间和音量控件。这样通过 shell 验证的路径与生命周期管理可直接复用到界面。

构建与验证

沿用工程原有构建流程,在仓库根目录运行 `build.cmd -n`,选择 ATS3089P(11)和 `bt_watch`。本功能的固件包使用 `ats3089p_dev_watch_261012_mp3_player.fw`,调试包使用 `ats3089p_dev_watch_261012_mp3_player_debug.fw`,位于 `application/bt_watch/outdir/ats3089p_dev_watch/_firmware/`。

本次已通过 ATS3089P 固件编译、打包及软件回归测试。`tests/mp3/run_tests.py` 执行本次固件 ELF 中的 ARM 播放控制代码,覆盖文件检查、断点暂停/恢复、EOF/错误清理、播放失败、PCM 回复资源交接、ASR 路由及旧播放器停止回调;文件系统、RTOS、DSP 和扬声器由测试桩代替。原有 ringtone/PCM、USB CDC/工厂指令和 SPP USB 模式切换测试也已通过。

实际 DSP 解码、声音输出和板上运行仍需烧录验证。建议至少检查指定文件播放、暂停继续、主动停止、文件自然结束、重复播放、语音暂停继续与中文回复,以及重新进入 U 盘复制文件。MP3 文件的采样率、声道、码率和标签由现有 SDK parser/decoder 支持范围决定;如某个文件失败,请保留实际文件和日志用于定位。

相关推荐
FW-Linker1 小时前
多链路聚合如何降低直播音画不同步概率?从网络抖动到数据包级拆分
网络·5g·智能路由器
逐梦之程1 小时前
EXCEL与DBC格式互转软件
运维·服务器·网络
重生之高冷汉堡包1 小时前
什么是数据中心代理?原理拆解、类型区别、应用场景与选型指南
服务器·网络·数据库·安全·ip
青衫客362 小时前
从网卡到 Socket:再探 Linux 网络协议栈与 iptables 数据包处理流程
linux·网络·网络协议
承渊政道2 小时前
Linux网络学习【TCP Socket编程实战:connect的断线重连与客户端访问Linux验证】
linux·网络·学习·ubuntu·tcp·socket编程
崽崽..2 小时前
【Linux】网络编程的调试工具以及连接失败的具体排查方法
linux·网络
ESDWAN2 小时前
海外股票网络环境优化与交易场景应用:从行情获取到交易系统稳定性设计
开发语言·网络·php
pt10432 小时前
Cisco设备网络安全系列-2:管理访问、控制平面与基础设施ACL防护
网络·安全
天行健,君子而铎12 小时前
数据分类分级的范式转换:从规则匹配到场景化高准确率一键部署
网络·数据库·安全