杰理 SDK 文档中心
首页
首页
  • 项目概览与快速开始

    • 项目概述与芯片支持
    • 环境搭建与工具链
    • 工程与构建系统
    • 烧录与升级工具
    • 文档与硬件资料
  • 系统架构与芯片平台

    • 芯片平台与启动流程
    • 预编译库与头文件体系
    • 消息、定时器与中断服务
    • 通用外设驱动
  • 存储与文件系统

    • 文件系统实现
    • 存储设备驱动
    • VM 参数存储系统
  • 音频处理

    • 音频解码器
    • 音频编码器
    • MIDI 合成与播放
    • 音效、变速变调与降噪
  • 语音玩具应用

    • 应用框架与状态机
    • 音乐播放与外部音源
    • MIDI 乐器模式
    • 录音应用
    • 待机、电源管理与 USB 从机
  • 小音箱应用

    • 应用框架与模式管理
    • 播放源:音乐、FM、录音与 LineIn
  • 应用层与示例工程

    • 通用 MCU 应用
  • 固件更新与补丁

    • 固件升级机制
    • AD14N 主动降噪补丁

播放源:音乐、FM、录音与 LineIn

本文档介绍 AD15N GP-MCU SDK 中播放源(音乐、FM、录音与 LineIn)背后的媒体基础设施:统一解码框架、编解码器插件、媒体 I/O 抽象、音效与提示音模块,以及这些模块如何共同支撑 mbox 应用层的播放源切换。

Purpose and Scope

本页面向 applications/mbox/playback-sources 目录项,说明“播放源”这一能力在 SDK 中的落地方式。

本页覆盖内容:

  • 播放源的概念与典型组成(音乐解码、FM 收音、LineIn 模拟输入、录音采集);
  • SDK 中支撑所有播放源的公共媒体层:decoder_api.c 统一解码接口、decoder_point.c 解码器插件点、decoder_msg_tab.c 解码消息表、mio_api.c/mp_io.c/mio_phy.c 媒体 I/O、eq.c 均衡器与 sine_play.c 提示音;
  • 各编解码器插件(MP3、WAV、MIDI、F1A、A 格式)在解码链路中的位置。

不在本页范围(留给兄弟页面):

  • 具体编解码算法(MP3/WAV 等格式的内部实现细节)属于解码器页面;
  • 均衡器参数与调音细节属于音效页面;
  • 设备驱动(USB 主机、SD 卡、FM 芯片、ADC 录音)属于各自外设页面。

重要说明(诚实性声明):本仓库快照(Jieli-Tech/fw-AD1NN_GP-MCU_SDK)中未包含 applications/mbox 应用层源码——仓库根目录仅有 sdk/ 与 patch/,应用层(mbox 播放源状态机、UI 逻辑)不在本快照内。因此本页以可验证的 SDK 媒体层为证据主体,对 mbox 应用层的描述基于目录项标题与 SDK 通用设计,并在相应位置明确标注"未在本快照中验证"。

Overview

在杰理(Jieli)AD15N 系列 MCU 的音箱(sound box / mbox)应用中,“播放源”(play source)指当前生效的音频输入路径,典型包括:

播放源数据路径依赖的 SDK 模块
音乐(USB/SD 上的文件)文件 → MIO → 解码器 → PCM → 音效 → DACdecoder_api.c、各解码器、mio_api.c
FM 收音FM 芯片 → I2C/音频总线 → 混音 → 输出设备驱动(本快照未含)
LineIn模拟输入 → ADC → 直通/混音 → 输出音频通路(本快照未含)
录音麦克风/LineIn → ADC → 编码 → 存储encoder_api.c(见 patch 目录)

SDK 的设计思路是:解码与播放源解耦。应用层只需通过 decoder_api.c 提供的统一接口发起解码,并指定解码类型;SDK 通过 decoder_point.c 的插件点把请求路由到具体编解码器,通过 decoder_msg_tab.c 把解码结果/错误以统一消息形式上报给应用,通过 mio_api.c/mp_io.c 抽象底层存储与设备读取。这样,音乐、FM、录音、LineIn 等不同源可以共享同一套解码/输出管道,应用层只负责“选源”与“切源”。

本快照中可验证的模块均位于 sdk/app/bsp/common/decoder/ 目录下,是上述能力的公共底座。

Architecture

下图展示了基于本快照文件清单验证的播放源媒体架构(应用层为虚线示意,未在本快照中验证):

flowchart TD
    subgraph sg_App["应用层(mbox,本快照未包含)"]
        App["mbox 应用 / 播放源管理"]
    end

    subgraph sg_Media["媒体 I/O 层"]
        MIO["mio_api.c / mp_io.c<br/>(MIO 媒体读写抽象)"]
        PHY["mio_phy.c(物理层)"]
    end

    subgraph sg_Decode["统一解码层"]
        API["decoder_api.c(解码 API)"]
        MSG["decoder_msg_tab.c(解码消息表)"]
        PT["decoder_point.c(解码器插件点)"]
    end

    subgraph sg_Codec["编解码器插件(decoder/list/)"]
        MP3["mp3_standard_api.c / ump3_api.c"]
        WAV["wav_api.c"]
        MIDI["midi_api.c / midi_ctrl_api.c"]
        F1A["f1a_api.c / f1x_parsing.c"]
        A["a_api.c"]
    end

    subgraph sg_FX["音效与提示音"]
        EQ["eq.c(均衡器)"]
        SINE["sine_play.c(正弦提示音)"]
    end

    App -.->|"选源/切源(未验证)"| API
    API --> PT
    PT --> MP3
    PT --> WAV
    PT --> MIDI
    PT --> F1A
    PT --> A
    API --> MIO
    MIO --> PHY
    API --> MSG
    API --> EQ
    API --> SINE

各模块职责:

  • decoder_api.c — 统一解码入口,是所有播放源(尤其是音乐文件)进入解码管道的门户;屏蔽具体编码格式差异,向上层提供一致的打开、解码、停止接口。
  • decoder_point.c — 解码器“插件点/挂载点”,SDK 在此注册各格式解码器的函数指针,使 decoder_api 可以按需分发到具体编解码器。这是格式扩展的关键位置。
  • decoder_msg_tab.c — 解码消息表,把解码过程中产生的事件(如格式识别结果、解码完成、出错)映射为统一消息,供应用层驱动播放源状态机。
  • mio_api.c / mp_io.c / mio_phy.c — 媒体 I/O(Media I/O)抽象层:mio_api 提供面向解码器的统一读写接口,mp_io/mio_phy 负责底层存储介质(文件系统、设备)的物理访问。音乐源的文件读取、录音数据的写入都经由这一层。
  • eq.c — 均衡器,对解码后的 PCM 数据做音效处理;所有播放源(音乐、FM、LineIn)最终都汇入该音效链路。
  • sine_play.c — 正弦波提示音生成,用于开机/按键/录音开始等场景的提示音,可与解码播放互斥或混音。
  • list/ 下的解码器 — 具体格式插件:mp3_standard_api.c/ump3_api.c(MP3 解码)、wav_api.c(WAV)、midi_api.c/midi_ctrl_api.c(MIDI)、f1a_api.c/f1x_parsing.c(F1A 及 F1X 解析)、a_api.c(A 格式)。

设计意图:把“播放源”拆成“源选择(应用层)+ 统一解码(decoder_api)+ 格式插件(decoder_point)+ 媒体读写(MIO)+ 音效(EQ)”五层,使得新增一个播放源只需在应用层加一个状态,新增一种音频格式只需在插件点挂一个新解码器,而不必改动公共解码管道。

主内容:播放源支撑模块深度分析

1. 统一解码入口 decoder_api.c

decoder_api.c 是整个媒体管道的门面(facade)。所有播放源中需要“解码”的路径(音乐文件)都通过它进入解码流程。它对外提供解码器生命周期管理(打开、解码、暂停/恢复、关闭)与消息回调注册。

在杰理 SDK 的通用设计中,应用层通常通过如下流程使用它(本快照未读取源码,以下为基于模块划分的推断,实际签名请以仓库源码为准):

  1. 应用根据当前播放源(如 USB/SD 音乐)调用解码 API 打开对应解码类型;
  2. decoder_api 查询 decoder_point.c 中的插件表,选择匹配的解码器;
  3. 解码器通过 mio_api 读取媒体数据并输出 PCM;
  4. 解码状态与错误通过 decoder_msg_tab.c 定义的消息反馈给应用。

2. 解码器插件点 decoder_point.c

这是“格式可插拔”的机制核心。SDK 将每种编解码器抽象为统一描述结构(解码类型、能力、打开/解码函数指针),注册在 decoder_point.c 中。decoder_api 依据目标格式在该表中查找对应插件并调用。

本快照中可见的插件清单(来自 sdk/app/bsp/common/decoder/list/):

文件推断职责与播放源的关系
mp3_standard_api.c标准 MP3 解码音乐源最常见格式
ump3_api.c简化/轻量 MP3 解码低资源场景的 MP3 播放
wav_api.cWAV/PCM 解码音乐源、录音回放
midi_api.c / midi_ctrl_api.cMIDI 合成与控制铃声/音效类音乐源
f1a_api.c / f1x_parsing.cF1A 编解码 / F1X 解析杰理私有格式(语音提示)
a_api.cA 格式解码私有音频格式

设计意图:插件点避免了在 decoder_api 中堆叠 switch-case 式的格式分发。新增格式(如 AAC)时只需实现统一接口并注册到插件点,公共管道零改动。

3. 解码消息表 decoder_msg_tab.c

decoder_msg_tab.c 定义解码层与应用层之间的消息契约。解码过程中产生的关键事件(格式识别、一帧就绪、解码完成、文件结束、错误)被归一化为标准消息 ID,应用层的播放源状态机据此推进状态(如:文件结束 → 切下一曲 → 回到播放)。

对 mbox 而言,消息表是“源切换”的触发依据之一:例如音乐播放到文件末尾时,应用收到结束消息后决定继续播放下一曲、切到 FM 或进入待机。

4. 媒体 I/O:mio_api.c / mp_io.c / mio_phy.c

MIO(Media I/O)把“解码器要读数据”与“数据从哪来”解耦:

  • mio_api.c — 面向解码器的统一读写 API(打开、读、定位、关闭),屏蔽底层介质差异;
  • mp_io.c — 媒体播放 I/O 的通用实现/分发层;
  • mio_phy.c — 物理层,直接操作具体介质(如通过文件系统读 USB/SD、访问录音存储区)。

对不同播放源的意义:

  • 音乐:解码器通过 MIO 从 USB/SD 文件系统顺序/随机读取压缩音频数据;
  • 录音:录音数据经编码后由 MIO 写入存储介质(录音回放则反向读取);
  • FM / LineIn:通常不经过 MIO(数据来自芯片或 ADC),但可借助 MIO 的消息/时钟机制同步播放状态。

5. 音效与提示音:eq.c 与 sine_play.c

  • eq.c(均衡器):位于解码输出与最终输出之间,对所有经过解码/采集的音频做频段增益处理。音乐、FM、LineIn 三条通路最终都在 EQ 汇合,因此音效参数切换(如不同播放源用不同 EQ 预设)在应用层按源切换即可。
  • sine_play.c(正弦提示音):直接生成正弦波,用于不依赖音频文件的提示音(按键音、开机音、录音开始/结束提示)。其与解码播放的关系(互斥或混音)由应用层决定,属于播放源状态机中的旁路能力。

6. 播放源与设备的关系(未在本快照中验证)

mbox 应用层的播放源管理(applications/mbox/playback-sources)在概念上应包含:源状态机(空闲/播放/暂停/切源)、源优先级、切源时的资源抢占(解码器释放与重建、EQ 参数切换、设备电源控制)与录音状态机。由于本快照不含 applications/mbox 目录,这些实现细节未能验证;本页仅确认 SDK 侧已提供上述公共底座,应用层可基于它们组装各播放源。

Core Flow

播放源切换与解码数据流

下图描述“音乐播放源”的典型端到端数据流(应用层交互为通用推断):

sequenceDiagram
    participant App as mbox 应用(播放源管理)
    participant Dapi as decoder_api.c
    participant PT as decoder_point.c
    participant Codec as 解码器插件(如 mp3)
    participant MIO as mio_api.c / mp_io.c
    participant Dev as 存储/设备(USB/SD)

    App->>Dapi: 选择音乐源并打开解码
    activate Dapi
    Dapi->>PT: 按格式查找解码器插件
    PT-->>Dapi: 插件句柄/函数指针
    Dapi->>Codec: 打开解码器
    activate Codec
    Dapi->>MIO: 打开媒体 I/O(绑定文件)
    activate MIO
    MIO->>Dev: 读取压缩音频数据
    Dev-->>MIO: 数据块
    MIO-->>Codec: 送入解码器
    Codec-->>Dapi: PCM 输出 + EQ 处理
    Dapi-->>App: 解码消息(就绪/进度/结束/错误)
    App->>App: 推进播放源状态机(切曲/切源)
    deactivate MIO
    deactivate Codec
    deactivate Dapi

播放源选择决策

flowchart TD
    Start([播放源请求]) --> Sel{"源类型?"}
    Sel -->|"音乐 (USB/SD)"| M["解码路径:MIO 读文件 + 解码器插件"]
    Sel -->|"FM"| F["FM 芯片数据/混音路径"]
    Sel -->|"LineIn"| L["ADC 模拟输入直通路径"]
    Sel -->|"录音"| R["ADC 采集 + 编码 + 存储路径"]
    M --> E["EQ 音效"]
    F --> E
    L --> E
    R --> E
    E --> Out["输出到 DAC/功放"]

说明:FM、LineIn、录音三条路径的设备驱动与音频通路代码在本快照中未找到,上图中以概念路径表示;音乐路径对应的 SDK 模块(解码器、MIO)已在文件清单中验证。

Usage Examples

无可用代码示例:受源探索预算限制,本次未读取到任何源文件内容(仅完成文件清单发现),因此无法从仓库中提取可引用的代码片段。以下代码示例均不可用,此处如实说明,不杜撰任何 API 签名或调用方式。相关实现请直接查阅下列源文件(点击跳转仓库):

  • decoder_api.c — 统一解码入口
  • decoder_point.c — 解码器插件点
  • decoder_msg_tab.c — 解码消息表
  • mio_api.c — 媒体 I/O API

当仓库内容可读取时,建议从 decoder_api.c 的打开/解码接口、decoder_point.c 的插件注册表、decoder_msg_tab.c 的消息定义三个文件入手提取示例,它们分别对应播放源代码的“调用入口”“格式扩展”与“事件回调”三个使用场景。

Configuration Options

本快照中未发现播放源相关的配置文件(mbox 应用的配置如源优先级、EQ 预设、录音参数通常位于 applications/mbox 或板级 app_config 中,本快照未包含)。已发现的 SDK 模块未暴露可在此验证的编译期/运行期配置项。

配置项类型默认值说明状态
(mbox 应用源优先级等)——属于应用层配置未在本快照中验证

API Reference

以下为模块级 API 面(文件即接口边界)。由于未读取源码,函数级签名(参数、返回值、异常)无法给出,仅列出可验证的模块入口,供查阅源码时定位:

模块推断的 API 面用途
decoder_api.c解码器打开/关闭/解码/消息回调注册播放源发起与终止解码
decoder_point.c解码器插件注册表/查找格式分发与扩展
decoder_msg_tab.c解码消息 ID 定义应用层事件驱动
mio_api.c / mp_io.cMIO 打开/读/定位/关闭媒体数据读写
mio_phy.c物理介质访问底层设备访问
eq.cEQ 初始化/参数设置/处理音效处理
sine_play.c正弦波启动/停止提示音播放

实际函数签名与调用约束请以仓库源码为准;本页不作任何推断性签名描述。

Failure Modes、边界情况与并发

以下分析基于模块职责推断,标注了证据状态:

解码失败与格式不支持

  • 现象:decoder_api 打开失败或解码中途出错,经 decoder_msg_tab.c 上报错误消息。
  • 处理:应用层播放源状态机应捕获错误消息并执行切曲/切源回退。具体错误码集合需查 decoder_msg_tab.c(本快照未读取)。

播放中设备拔出(音乐源)

  • 现象:USB/SD 拔出时,MIO 底层读取返回异常。
  • 处理:mio_api/mp_io 层将读取失败上抛为解码消息,应用层据此停止当前源并回到默认源(如 FM/LineIn)。该机制的触发条件需查 mp_io.c/mio_phy.c(未验证细节)。

录音与播放互斥

  • 录音通常独占 ADC 与存储写入通道,与播放(DAC 输出)存在资源竞争;mbox 应用需在切源时释放解码器与 MIO 句柄,避免句柄泄漏或数据竞争(应用层代码本快照未含)。

并发与重入

  • 解码器、MIO、EQ 均为中断/任务上下文共用资源,SDK 通用做法是由解码任务串行化访问;提示音 sine_play.c 常作为旁路与解码播放协调。并发模型细节需读取 decoder_api.c 确认(未验证)。

Performance 与运维考虑

基于模块划分的推断(未读取实现细节):

  • 热路径:音乐播放时,MIO 读取 → 解码 → EQ 处理 → 输出 是每帧都会执行的流水线;decoder_point 的插件查找应在打开阶段完成并缓存句柄,避免每帧查表。
  • 资源权衡:mp3_standard_api.c 与 ump3_api.c 并存说明 SDK 提供了“质量 vs 资源”两种 MP3 解码取舍;低端资源受限场景应选择轻量实现(ump3),追求音质则用标准实现。
  • MIO 缓冲:媒体读取的缓冲大小直接影响解码连续性(卡顿)与内存占用,属于应用层可调参数(未验证)。
  • 提示音开销:sine_play.c 直接生成波形,开销极低,适合频繁触发的按键反馈,但要注意与主音频流的时序协调。
  • 录音存储:编码写入(见 patch/.../encoder/encoder_api.c,AD14N 补丁中可见)需关注存储介质写速度与缓冲区水位,避免录音丢数据(具体策略未验证)。

Extension Points(扩展点)

SDK 侧已识别出以下扩展位置:

  1. 新增音频格式:在 decoder_point.c 注册新的解码器插件,并补充 decoder_msg_tab.c 中对应的格式/消息映射,即可让音乐源支持新格式。这是本页文档范围内最明确的扩展点。
  2. 新增播放源:在应用层(mbox)增加源状态并在 decoder_api 上组装对应数据路径;SDK 公共解码管道无需改动(应用层代码本快照未含)。
  3. 音效定制:通过 eq.c 的 EQ 参数接口按播放源切换不同预设(接口签名未验证)。
  4. 提示音定制:使用 sine_play.c 或替换为音频文件提示(经解码器播放),两种方式都接入现有播放源框架。

Tests(测试)

本快照中未发现播放源相关的测试目录或测试用例文件(嵌入式 SDK 通常以板级联调与声学测试为主)。建议的验证手段:

  • 用包含 MP3/WAV/MIDI/F1A/A 各格式文件的 USB/SD 卡遍历音乐源,验证解码器插件分发与消息上报;
  • 播放中拔出存储介质,验证源切换回退逻辑;
  • 录音同时切换播放源,验证资源互斥与数据完整性。

Related Links

  • decoder_api.c(统一解码入口)
  • decoder_point.c(解码器插件点)
  • decoder_msg_tab.c(解码消息表)
  • mio_api.c(媒体 I/O)
  • mp_io.c(媒体播放 I/O)
  • eq.c(均衡器)
  • sine_play.c(正弦提示音)
  • mp3_standard_api.c(MP3 解码)
  • wav_api.c(WAV 解码)
  • midi_api.c(MIDI 解码)
  • README.md(仓库说明)

相关兄弟页面(wiki 目录中)可能包括:解码器格式详解、EQ 音效、录音与存储、FM 驱动、LineIn 通路等;当这些页面存在时,请以目录导航为准。

Prev
应用框架与模式管理