跳转至

音频系统测试各种音频时播放状态总结

流式方式播放音频数据测试

测试环境:Air1602, bsp V1021, LuatOS base 26.04, DAC 播放

点我查看实际演示效果

一、各音频格式的数据结构说明

不同音频格式的文件结构差异很大,直接影响损坏后的播放表现。以下是三种格式的基本结构:

MP3

┌────────────┬──────┬──────┬──────┬──────┬──────┬──────────┐
│  ID3v2标签 │ 帧1  │ 帧2  │ 帧3  │ ...  │ 帧N  │ ID3v1标签│
│  (可选)    │≈26ms │≈26ms │≈26ms │      │≈26ms │ (可选)   │
└────────────┴──────┴──────┴──────┴──────┴──────┴──────────┘
  • ID3v2 标签头(可选):位于文件开头,存放歌名、歌手、专辑封面等元信息。大小不固定,几十字节到数 MB 都可能。解码器从 data_start 跳过它直接定位到第一帧。
  • MP3 音频帧:音频数据以“帧”为单位,每帧约 26ms 音频。每帧以 0xFF 开头(帧同步字),各帧独立可解码。某一帧损坏不影响其他帧的解码。
  • ID3v1 标签尾(可选):固定 128 字节,以 TAG 开头。解码器遇到非 0xFF 的数据会自动跳过,不影响播放。

AMR-NB

┌──────────┬──────┬──────┬──────┬──────┐
│ #!AMR\n  │ 帧1  │ 帧2  │ 帧3  │ ...  │
│ (6字节)  │12-31B│12-31B│12-31B│      │
└──────────┴──────┴──────┴──────┴──────┘
  • 文件头:固定 6 字节 #!AMR\n,用于标识 AMR 格式。
  • AMR 帧:每帧 20ms 音频,帧长 12~31 字节不等(取决于编码模式)。每帧的第 1 字节高 4 位表示帧类型。
  • 无尾部标签:AMR 格式非常纯粹,没有 ID3 之类的尾部元数据。

注意:文件头仅 6 字节,被破坏后 get_play_info 直接返回 false。AMR 解码器遇到无效帧不会报错退出,而是尝试解码输出错误 PCM(杂音),然后继续找下一帧。这是 AMR 与 MP3 最大的行为差异。

WAV (PCM)

┌─────────────────┬────────────────────────────┐
│   RIFF WAVE头   │         PCM采样数据        │
│  44字节或更多   │    原始未压缩的音频采样值  │
└─────────────────┴────────────────────────────┘
  • RIFF/WAVE 格式头:44 字节或更多,包含文件格式标识(RIFFWAVEfmtdata 等 chunk),以及采样率、位宽、声道数等参数。
  • PCM 采样数据:裸采样值,无帧结构。解码器按字节顺序读取,数据直接送 DAC 输出。

注意:WAV 是 PCM 直通格式,没有帧同步概念。解码器不检查数据合法性,所有数据(包括损坏的)都被当作有效 PCM 输出。采样率错误时播放速度会变快或变慢,但不会静音或报错。读取完文件即自然结束。

PCM

┌──────────────────────────────────────────┐
│           PCM 采样数据                   │
│     没有文件头、没有帧、没有标签         │
└──────────────────────────────────────────┘
  • 无文件头:PCM 是纯粹的采样值序列,没有任何格式描述信息。
  • 无帧结构:解码器按字节顺序读取,所有数据都被当作有效 PCM 采样值直接送 DAC。
  • 必须手动配置参数:因为没有文件头,采样率、位宽、声道数等信息必须由用户通过代码指定。参数错误会导致播放变调或杂音,但不会报错。

key 点:PCM 是最简单的音频格式,解码器对数据不做任何合法性检查。损坏数据(无论是 0xCC、0x00 还是随机值)都会被直接输出为 PCM 采样值。文件读完即自然结束。

二、流式播放 mp3 数据测试结果

流式播放 sample-6s.mp3 数据,记录正常数据、头损坏、中间损坏、尾部损坏的测试结果。

1. 正常数据播放情况

流式播放正常 sample-6s.mp3,播放过程无异常,可以正常播放完整音频。

代码运行如下:

-- 1. 解析音频文件信息
I/user.===== 开始播放 MP3 =====
I/user.文件: /luadb/sample-6s.mp3 播放模式: 流式播放
D/audio_codec find software codec 5
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 1792
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 1792
I/user.parse_audio_info read 1792
I/user.parse_audio_info seek 47 need 1792
I/user.parse_audio_info read 1792
I/user.exaudio.parse_audio_info /luadb/sample-6s.mp3 sample_rate: 44100 bits: 16 channels: 1 retries: 2
I/user.采样率: 44100 位宽: 16 声道: 1 数据起始: 47

-- 2. exaudio内部再次解析
I/user.exaudio seek 0 need 1792
I/user.exaudio seek 47 need 1792
I/user.exaudio 从文件解析到采样率: 44100 bits: 16 ch: 1 signed: true retries: 2

-- 3. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 4. 流式播放启动,data_start=47正确
I/user.exaudio 流式播放文件已打开: /luadb/sample-6s.mp3 data_start: 47
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 44100 codec_id: 5
I/user.MP3 播放启动成功

-- 5. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 44100-2-1, mode 0, new 44100-2-1, mode 1
D/audio_drv start commom param now 44100,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 6. 开始播放(共22次event 1正常解码,耗时约5.2秒)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 正常解码
D/audio_core common task recv event 1     2 正常解码
D/audio_core common task recv event 1     3 正常解码
D/audio_core common task recv event 1     4 正常解码
D/audio_core common task recv event 1     5 正常解码
D/audio_core common task recv event 1     6 正常解码
D/audio_core common task recv event 1     7 正常解码
D/audio_core common task recv event 1     8 正常解码
D/audio_core common task recv event 1     9 正常解码
D/audio_core common task recv event 1     10 正常解码
D/audio_core common task recv event 1     11 正常解码
D/audio_core common task recv event 1     12 正常解码
D/audio_core common task recv event 1     13 正常解码
D/audio_core common task recv event 1     14 正常解码
D/audio_core common task recv event 1     15 正常解码
D/audio_core common task recv event 1     16 正常解码
D/audio_core common task recv event 1     17 正常解码
D/audio_core common task recv event 1     18 正常解码
D/audio_core common task recv event 1     19 正常解码
D/audio_core common task recv event 1     20 正常解码
D/audio_core common task recv event 1     21 正常解码
D/audio_core common task recv event 1     22 正常解码

-- 7. 解码结束
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1     FIFO排空
D/audio_core play request end, fifo empty, stop decode

-- 8. sys.wait轮询(FIFO排空×4)
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1

-- 9. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.MP3 播放完成
-- --------------------------------------------------
-- event 1 次数:22次正常解码 + 5次FIFO排空 | 播放时长:~5.2秒 | 无错误日志 | 完整播放

2. 数据头损坏播放情况

流式播放 sample-6s_head.mp3(前 256 字节被覆盖为 0xCC),播报无声,无任何音频输出。

现象解释:文件头部 256 字节被损坏为 0xCC,parse_audio_info 解析文件头失败,使用默认值 data_start=0。流式播放从文件第 0 字节开始读取数据并喂给解码器,损坏的 0xCC 数据不匹配任何有效 MP3 帧同步字,解码器无法解码出有效的 PCM 音频数据,导致扬声器无声。

代码运行如下:

-- 1. 解析音频文件信息(误判data_start=0)
I/user.===== 开始播放 MP3 =====
I/user.文件: /luadb/sample-6s_head.mp3 播放模式: 流式播放
D/audio_codec find software codec 5
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 1792
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 1792
I/user.parse_audio_info read 1792
I/user.exaudio.parse_audio_info /luadb/sample-6s_head.mp3 sample_rate: 44100 bits: 16 channels: 1 retries: 1
I/user.采样率: 44100 位宽: 16 声道: 1 数据起始: 0

-- 2. exaudio内部再次解析(同样data_start=0)
I/user.exaudio seek 0 need 1792
I/user.exaudio 从文件解析到采样率: 44100 bits: 16 ch: 1 signed: true retries: 1

-- 3. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 4. 流式播放启动,data_start=0(错误!从第0字节开始喂数据)
I/user.exaudio 流式播放文件已打开: /luadb/sample-6s_head.mp3 data_start: 0
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 44100 codec_id: 5
I/user.MP3 播放启动成功

-- 5. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 44100-2-1, mode 0, new 44100-2-1, mode 1
D/audio_drv start commom param now 44100,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 6. 开始播放(立即解码失败)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1(刚启动)
E/audio_codec decode failed, ret = -6, 0, 0    解码失败
E/audio_core decode failed, ret = -6
D/audio_core current request stop, wait play end

-- 7. FIFO排空(4次)
D/audio_core common task recv event 1     2 FIFO排空
D/audio_core common task recv event 1     3 FIFO排空
D/audio_core common task recv event 1     4 FIFO排空
D/audio_core common task recv event 1     5 FIFO排空

-- 8. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.MP3 播放完成
-- --------------------------------------------------
-- event 1 次数:5次(1次刚启动 + 4次FIFO排空)| 播放时长:~0秒(无有效解码)
-- 错误:decode failed -6 | 无声

3. 中间数据损坏播放情况

流式播放 sample-6s_middle.mp3(文件约 1/3 位置 512 字节被替换为随机数据),播放约 1 秒后无声音输出。

现象解释:文件头数据完好(data_start=47 正确),前约 1 秒的 MP3 帧被正常解码输出。当读取到文件约 1/3 位置时遇到被随机数据覆盖的区域,连续多个 MP3 帧被完全破坏,解码器找不到有效的帧同步字,解码失败停止输出 PCM 数据。解码失败后 FIFO 中剩余的 PCM 缓冲数据需播放完(FIFO 排空),所以仍有 4 次 event 1。

代码运行如下:

-- 1. 解析音频文件信息(正常)
I/user.===== 开始播放 MP3 =====
I/user.文件: /luadb/sample-6s_middle.mp3 播放模式: 流式播放
D/audio_codec find software codec 5
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 1792
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 1792
I/user.parse_audio_info read 1792
I/user.parse_audio_info seek 47 need 1792
I/user.parse_audio_info read 1792
I/user.exaudio.parse_audio_info /luadb/sample-6s_middle.mp3 sample_rate: 44100 bits: 16 channels: 1 retries: 2
I/user.采样率: 44100 位宽: 16 声道: 1 数据起始: 47

-- 2. exaudio内部解析
I/user.exaudio seek 0 need 1792
I/user.exaudio seek 47 need 1792
I/user.exaudio 从文件解析到采样率: 44100 bits: 16 ch: 1 signed: true retries: 2

-- 3. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 4. 流式播放启动,data_start=47正确
I/user.exaudio 流式播放文件已打开: /luadb/sample-6s_middle.mp3 data_start: 47
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 44100 codec_id: 5
I/user.MP3 播放启动成功

-- 5. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 44100-2-1, mode 0, new 44100-2-1, mode 1
D/audio_drv start commom param now 44100,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 6. 开始播放(5次正常解码后遇到损坏区域)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 正常解码
D/audio_core common task recv event 1     2 正常解码
D/audio_core common task recv event 1     3 正常解码
D/audio_core common task recv event 1     4 正常解码
D/audio_core common task recv event 1     5 正常解码
E/audio_codec decode failed, ret = -6, 0, 0    解码失败
E/audio_core decode failed, ret = -6
D/audio_core current request stop, wait play end

-- 7. FIFO排空(4次)
D/audio_core common task recv event 1     6 FIFO排空
D/audio_core common task recv event 1     7 FIFO排空
D/audio_core common task recv event 1     8 FIFO排空
D/audio_core common task recv event 1     9 FIFO排空

-- 8. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.MP3 播放完成
-- --------------------------------------------------
-- event 1 次数:9次(5次正常解码 + 4次FIFO排空)| 播放时长:~1.0秒
-- 错误:decode failed -6 | 开头1秒正常→突然无声

4. 尾部数据损坏播放情况

流式播放 sample-6s_tail.mp3(文件末尾 512 字节被清零),播放基本完整,但最后约 0.3 秒音频被截断。

现象解释:文件头完好(data_start=47 正确),前面绝大部分 MP3 帧均正常解码输出,共约 21 次 event 1。末尾 512 字节被清零只破坏了最后 2-3 个 MP3 帧(约 0.3 秒),不影响前面 99% 的音频数据。解码失败后 FIFO 中剩余的 PCM 缓冲数据需播放完(FIFO 排空),所以仍有 4 次 event 1。

代码运行如下:

-- 1. 解析音频文件信息(正常)
I/user.===== 开始播放 MP3 =====
I/user.文件: /luadb/sample-6s_tail.mp3 播放模式: 流式播放
D/audio_codec find software codec 5
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 1792
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 1792
I/user.parse_audio_info read 1792
I/user.parse_audio_info seek 47 need 1792
I/user.parse_audio_info read 1792
I/user.exaudio.parse_audio_info /luadb/sample-6s_tail.mp3 sample_rate: 44100 bits: 16 channels: 1 retries: 2
I/user.采样率: 44100 位宽: 16 声道: 1 数据起始: 47

-- 2. exaudio内部解析
I/user.exaudio seek 0 need 1792
I/user.exaudio seek 47 need 1792
I/user.exaudio 从文件解析到采样率: 44100 bits: 16 ch: 1 signed: true retries: 2

-- 3. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 4. 流式播放启动,data_start=47正确
I/user.exaudio 流式播放文件已打开: /luadb/sample-6s_tail.mp3 data_start: 47
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 44100 codec_id: 5
I/user.MP3 播放启动成功

-- 5. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 44100-2-1, mode 0, new 44100-2-1, mode 1
D/audio_drv start commom param now 44100,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 6. 开始播放(21次正常解码后遇到损坏尾部)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 正常解码
D/audio_core common task recv event 1     2 正常解码
D/audio_core common task recv event 1     3 正常解码
D/audio_core common task recv event 1     4 正常解码
D/audio_core common task recv event 1     5 正常解码
D/audio_core common task recv event 1     6 正常解码
D/audio_core common task recv event 1     7 正常解码
D/audio_core common task recv event 1     8 正常解码
D/audio_core common task recv event 1     9 正常解码
D/audio_core common task recv event 1     10 正常解码
D/audio_core common task recv event 1     11 正常解码
D/audio_core common task recv event 1     12 正常解码
D/audio_core common task recv event 1     13 正常解码
D/audio_core common task recv event 1     14 正常解码
D/audio_core common task recv event 1     15 正常解码
D/audio_core common task recv event 1     16 正常解码
D/audio_core common task recv event 1     17 正常解码
D/audio_core common task recv event 1     18 正常解码
D/audio_core common task recv event 1     19 正常解码
D/audio_core common task recv event 1     20 正常解码
D/audio_core common task recv event 1     21 正常解码
E/audio_codec decode failed, ret = -6, 0, 0    解码失败
E/audio_core decode failed, ret = -6
D/audio_core current request stop, wait play end

-- 7. FIFO排空(4次)
D/audio_core common task recv event 1     22 FIFO排空
D/audio_core common task recv event 1     23 FIFO排空
D/audio_core common task recv event 1     24 FIFO排空
D/audio_core common task recv event 1     25 FIFO排空

-- 8. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.MP3 播放完成
-- --------------------------------------------------
-- event 1 次数:25次(21次正常解码 + 4次FIFO排空)| 播放时长:~5.2秒
-- 错误:decode failed -6 | 几乎完整,结尾略短
-- 原因:文件头完好,前99%数据正常解码。末尾512字节清零,
--       只破坏了最后2-3个MP3帧,不影响前面绝大部分内容

三、流式播放 amr 数据测试结果

流式播放 music.amr 数据,记录正常数据、头损坏、中间损坏、尾部损坏的测试结果。

1. 正常数据播放情况

流式播放正常 music.amr 文件,播放过程无异常,可以正常播放完整音频。

现象解释:AMR 文件头仅 6 字节(#!AMR\n),get_play_info 一次就读够直接返回 sample_rate=8000,无需像 MP3 那样重试。data_start=6 正确。

代码运行如下:

-- 1. 解析音频文件信息
I/user.===== 开始播放 AMR =====
I/user.文件: /luadb/music.amr 播放模式: 流式播放
D/audio_codec find software codec 2
I/user.parse_audio_info get_play_info result: true sample_rate: 8000 next_pos: 6 need_len: 0
I/user.exaudio.parse_audio_info /luadb/music.amr sample_rate: 8000 bits: 16 channels: 1
I/user.采样率: 8000 位宽: 16 声道: 1 数据起始: 6

-- 2. exaudio内部再次解析
I/user.exaudio 从文件解析到采样率: 8000 bits: 16 ch: 1 signed: true

-- 3. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 4. 流式播放启动,文件指针定位到偏移6
I/user.exaudio 流式播放文件已打开: /luadb/music.amr data_start: 6
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 8000 codec_id: 2
I/user.AMR 播放启动成功

-- 5. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 8000-2-1, mode 0, new 8000-2-1, mode 1
D/audio_drv start commom param now 8000,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 6. 开始播放
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output

-- 7. 解码播放(共2次event 1)
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 正常解码
D/audio_core common task recv event 1     2 正常解码

-- 8. 解码结束
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1     3 FIFO排空
D/audio_core play request end, fifo empty, stop decode

-- 9. sys.wait轮询等待(间隔约6秒)
D/audio_core common task recv event 1     4 FIFO排空
D/audio_core common task recv event 1     5 FIFO排空
D/audio_core common task recv event 1     6 FIFO排空
D/audio_core common task recv event 1     7 FIFO排空

-- 10. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.AMR 播放完成
-- --------------------------------------------------
-- event 1 次数:7次(2次正常解码 + 1次排空 + 4次排空)| 音频约2秒
-- 无错误日志 | 完整播放

2. 数据头损坏播放情况

流式播放 music_head.amr(前 256 字节被覆盖为 0xCC),能听到音频,但是开始播放时,会先静音约 2 秒 → 然后杂音约 4 秒 → 随后正常播放至结束。

现象解释get_play_info 因文件头 #!AMR\n 被破坏返回 result: falseparse_audio_info 使用默认值 data_start=0。流式播放从文件第 0 字节开始喂数据。前 256 字节为 0xCC 垃圾数据,AMR 解码器会先尝试同步(静音期),然后把垃圾数据当成 AMR 帧解码输出错误 PCM(杂音期)。消耗完损坏区域后,后续有效 AMR 帧被正常解码输出。9 次 event 1 中:第 1-2 次对应静音期,第 3-5 次对应杂音期,第 6-9 次对应正常音频。

代码运行如下:

-- 1. 解析失败(文件头被破坏)
I/user.===== 开始播放 AMR =====
I/user.文件: /luadb/music_head.amr 播放模式: 流式播放
D/audio_codec find software codec 2
I/user.parse_audio_info get_play_info result: false sample_rate: 0 next_pos: 0 need_len: 0
W/user.parse_audio_info: get_play_info error /luadb/music_head.amr
I/user.采样率: 8000 位宽: 16 声道: 1 数据起始: 0
W/user.exaudio get_play_info解析失败,使用默认值

-- 2. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 3. 流式播放启动,data_start=0(错误)
I/user.exaudio 流式播放文件已打开: /luadb/music_head.amr data_start: 0
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 8000 codec_id: 2
I/user.AMR 播放启动成功

-- 4. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 8000-2-1, mode 0, new 8000-2-1, mode 1
D/audio_drv start commom param now 8000,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 5. 开始播放(第1-2次event 1对应静音期,第3-5次对应杂音期,第6-9次对应正常音频)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 静音期
D/audio_core common task recv event 1     2 静音期
D/audio_core common task recv event 1     3 杂音期
D/audio_core common task recv event 1     4 杂音期
D/audio_core common task recv event 1     5 杂音期
D/audio_core common task recv event 1     6 正常音频
D/audio_core common task recv event 1     7 正常音频
D/audio_core common task recv event 1     8 正常音频
D/audio_core common task recv event 1     9 正常音频

-- 6. 解码结束
D/audio_core play request end, fifo empty, stop decode
I/user.内存信息 - lua: 2097144 sys: 27051664 317876 318008

-- 7. sys.wait轮询(FIFO排空)
D/audio_core common task recv event 1     10 FIFO排空
D/audio_core common task recv event 1     11 FIFO排空
D/audio_core common task recv event 1     12 FIFO排空
D/audio_core common task recv event 1     13 FIFO排空

-- 8. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.AMR 播放完成
-- --------------------------------------------------
-- event 1 次数:13次(9次解码处理 + 4次FIFO排空)
-- 解析报错:get_play_info error
-- 听感:静音2秒 → 杂音4秒 → 正常音频完整播完

3. 中间数据损坏播放情况

流式播放 music_middle.amr(文件约 1/3 位置 512 字节被替换为随机数据),开始正常 → 损坏处杂音约 4 秒 → 接着正常播放至结束。

现象解释:文件头完好(data_start=6 正确),前约 1/3 数据正常解码。当读取到文件 1/3 处被随机数据覆盖的区域后,AMR 解码器不会像 MP3 那样报 decode failed 退出,而是将损坏数据当成 AMR 帧解码输出错误 PCM(杂音)。消耗完损坏区域后,后续有效 AMR 帧继续正常解码输出,音频完整播完。

代码运行如下:

-- 1. 解析成功(文件头完好)
I/user.===== 开始播放 AMR =====
I/user.文件: /luadb/music_middle.amr 播放模式: 流式播放
D/audio_codec find software codec 2

I/user.parse_audio_info get_play_info result: true sample_rate: 8000 next_pos: 6 need_len: 0
I/user.exaudio.parse_audio_info /luadb/music_middle.amr sample_rate: 8000 bits: 16 channels: 1
I/user.采样率: 8000 位宽: 16 声道: 1 数据起始: 6
I/user.exaudio 从文件解析到采样率: 8000 bits: 16 ch: 1 signed: true

-- 2. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 3. 流式播放启动,data_start=6正确
I/user.exaudio 流式播放文件已打开: /luadb/music_middle.amr data_start: 6
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 8000 codec_id: 2
I/user.AMR 播放启动成功

-- 4. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 8000-2-1, mode 0, new 8000-2-1, mode 1
D/audio_drv start commom param now 8000,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 5. 开始播放(前3次正常→损坏区域杂音→剩余正常)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 6
W/audio_core print from irq 0 0 4000
D/audio_core common task recv event 1     1 正常音频
D/audio_core common task recv event 1     2 正常音频
D/audio_core common task recv event 1     3 正常音频
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1     4 FIFO排空
D/audio_core play request end, fifo empty, stop decode

-- 6. sys.wait轮询(FIFO排空)
I/user.内存信息 - lua: 2097144 sys: 27051664 317876 318008
D/audio_core common task recv event 1     5 FIFO排空
D/audio_core common task recv event 1     6 FIFO排空
D/audio_core common task recv event 1     7 FIFO排空
D/audio_core common task recv event 1     8 FIFO排空

-- 7. 播放完全结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core common task recv event 4
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.AMR 播放完成
-- --------------------------------------------------
-- 无decode failed报错,AMR解码器不会因数据损坏而停止
-- 听感:前半正常音频 → 损坏处杂音约4秒 → 接着正常播放至结束

4. 尾部数据损坏播放情况

流式播放 music_tail.amr(文件末尾 512 字节被清零),音频前面能完整播放出来,播放完毕后正常结束。

现象解释:文件头完好(data_start=6 正确),前面音频正常解码输出,听感上完整。尾部 512 字节被清零后,最后的 AMR 帧数据不完整,解码器检查帧长度时发现 FIFO 中数据不足(5/13 需要 13 字节只有 5 字节),输出一次错误日志后正常结束。

代码运行如下:

-- 1. 解析成功(文件头完好)
I/user.===== 开始播放 AMR =====
I/user.文件: /luadb/music_tail.amr 播放模式: 流式播放
D/audio_codec find software codec 2
I/user.parse_audio_info get_play_info result: true sample_rate: 8000 next_pos: 6 need_len: 0
I/user.exaudio.parse_audio_info /luadb/music_tail.amr sample_rate: 8000 bits: 16 channels: 1
I/user.采样率: 8000 位宽: 16 声道: 1 数据起始: 6
I/user.exaudio 从文件解析到采样率: 8000 bits: 16 ch: 1 signed: true

-- 2. 请求初始化
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start

-- 3. 流式播放启动,data_start=6正确
I/user.exaudio 流式播放文件已打开: /luadb/music_tail.amr data_start: 6
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 8000 codec_id: 2
I/user.AMR 播放启动成功

-- 4. 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 8000-2-1, mode 0, new 8000-2-1, mode 1
D/audio_drv start commom param now 8000,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 5. 开始播放(解码到尾帧数据不足,正常结束)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
W/audio_core print from irq 0 0 4000
D/audio_codec decode input fifo not enough 5/13/1, decode end   尾帧数据不足,但不死循环
D/audio_core play request end, fifo empty, stop decode

-- 6. sys.wait轮询
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core no request block
I/user.内存信息 - lua: 2097144 sys: 27023368 328596 328736
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.AMR 播放完成
-- --------------------------------------------------
-- event 1 次数:0次(解码尾部不足未输出有效PCM)| 听觉上音频完整播放
-- 尾部损坏正常结束(新固件已修复死循环问题)

四、流式播放 wav 数据测试结果

流式播放 alipay.wav 数据,记录正常数据、头损坏、中间损坏、尾部损坏的测试结果。

1. 正常数据播放情况

流式播放正常 alipay.wav 文件,播放过程无异常,可以正常播放完整音频。

现象解释:WAV 文件使用 RIFF 格式。get_play_info 第一次读 12 字节不够(需要 44 字节),seek 到 0 读 44 字节获取到 WAV 格式头信息但还未定位到 data 块,再次 seek 到 0 读 1024 字节才找到 data 块(data block is find 1)。最终解析出 sample_rate=22050、16bit、2 声道、data_start=44。WAV 解码以 PCM 直通模式输出,解码器每批消耗 8000 字节 FIFO 数据(输出 PCM),decode input fifo not enough X/8000 显示当前 FIFO 填充量在 4288→7936→128→7936...之间循环,说明回调喂数据的速度跟不上解码消耗,FIFO 持续处于"不够"状态但能正常播放。

代码运行如下:

===== 开始播放 WAV =====
文件: /luadb/alipay.wav 播放模式: 流式播放
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 44
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 44
I/user.parse_audio_info read 44
D/luat_wav fmt len 16 pos 36
D/luat_wav head pos 36/44 data block is find 0    44字节不够定位data块
I/user.parse_audio_info seek 0 need 1024           需要更多数据找data块
I/user.parse_audio_info read 1024
D/luat_wav fmt len 16 pos 36
D/luat_wav head pos 36/1024 data block is find 1   找到data块
I/user.exaudio.parse_audio_info sample_rate: 22050 bits: 16 channels: 2 retries: 2
I/user.采样率: 22050 位宽: 16 声道: 2 数据起始: 44
I/user.exaudio 流式播放文件已打开: alipay.wav data_start: 44
I/user.exaudio audio_v2流式播放启动成功
I/user.WAV 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4288/8000, decode end   1
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4480/8000, decode end   2
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4672/8000, decode end   3
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4864/8000, decode end   4
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5056/8000, decode end   5
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5248/8000, decode end   6
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5440/8000, decode end   7
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5632/8000, decode end   8
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5824/8000, decode end   9
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6016/8000, decode end   10
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6208/8000, decode end   11
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6400/8000, decode end   12
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6592/8000, decode end   13
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6784/8000, decode end   14
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6976/8000, decode end   15
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7168/8000, decode end   16
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7360/8000, decode end   17
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7552/8000, decode end   18
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7744/8000, decode end   19
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7936/8000, decode end   20
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 128/8000, decode end    21(回绕)
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4416/8000, decode end   22
...                                                                继续循环
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7872/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 64/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo empty, decode end                  最后一次
D/audio_core common task recv event 1
D/audio_core play request end, fifo empty, stop decode
D/audio_core common task recv event 1     FIFO排空(×4)
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.WAV 播放完成
-- --------------------------------------------------
-- 播放时长:~3.9秒(341KB, 22050Hz 16bit 2ch=88200字节/秒)
-- FIFO填充量在128~7936之间循环,回调跟不上解码消耗但能正常播放
-- 无错误日志 | 完整播放

2. 数据头损坏播放情况

流式播放 alipay_head.wav(前 256 字节被覆盖为 0xCC),播放正常(前提:手动将默认采样率配置为文件的正确值 22050Hz),如果默认采样率不匹配情况下,会导致播放的音频声音过快/过慢。

现象解释get_play_info 先读 12 字节不够,seek 到 44 读数据,但文件头损坏无法解析出采样率,retry failed 使用默认值。WAV 为 PCM 直通格式,采样率正确时播放速度即正常。即使 data_start=0(包含 44 字节 WAV 头被当作 PCM 输出),44 字节的 WAV 头极短几乎不可察觉,后续 PCM 数据完整、采样率匹配,所以播放正常直至结束。

代码运行如下:

===== 开始播放 WAV =====
文件: /luadb/alipay_head.wav 播放模式: 流式播放
I/user.parse_audio_info get_play_info result: true sample_rate: 0 next_pos: 0 need_len: 44
I/user.parse_audio_info sample_rate is 0 need retry
I/user.parse_audio_info seek 0 need 44
I/user.parse_audio_info read 44

W/user.parse_audio_info: retry failed, use default values retries: 1
I/user.采样率: 22050 位宽: 16 声道: 2 数据起始: 0
W/user.exaudio 无法从文件解析采样率,使用默认值 retries: 1
I/user.exaudio 流式播放文件已打开: alipay_head.wav data_start: 0
I/user.exaudio audio_v2流式播放启动成功
I/user.WAV 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4288/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4480/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4672/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4864/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5056/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5248/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5440/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5632/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5824/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6016/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6208/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6400/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6592/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6784/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6976/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7168/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7360/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7552/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7744/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7936/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 128/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4416/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4608/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4800/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4992/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5184/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5376/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5568/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5760/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5952/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6144/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6336/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6528/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6720/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6912/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7104/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7296/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7488/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7680/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7872/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 64/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1
D/audio_core play request end, fifo empty, stop decode
D/audio_core common task recv event 1     FIFO排空(×4)
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.WAV 播放完成
-- --------------------------------------------------
-- 解析失败但播放正常 | 正确采样率22050是关键
-- 原因:WAV是PCM直通,采样率正确时播放速度正常。
--       data_start=0仅44字节WAV头被当作PCM输出(几乎不可察觉),
--       后续PCM数据完整、采样率匹配,播放正常

3. 中间数据损坏播放情况

流式播放 alipay_middle.wav(文件约 1/3 位置 512 字节被替换为随机数据),“支付宝到账一亿元”语音播到“宝”和“到”两个字之间会有一个杂音,随后继续播放至结束

现象解释:WAV 文件头完好,parse_audio_info 解析成功(data_start=44、22050Hz、16bit、2ch)。流式播放从正确偏移 44 读取 PCM 数据。当读取到文件约 1/3 处的随机数据区域时,512 字节随机数据被直接当作 PCM 采样值输出给 DAC,产生一个短促的杂音(脉冲噪音)。WAV 是 PCM 直通格式,解码器不会因数据损坏而报错停止,杂音段后剩余 PCM 数据继续正常解码输出至结束。

代码运行如下:

===== 开始播放 WAV =====
文件: /luadb/alipay_middle.wav 播放模式: 流式播放
I/user.exaudio.parse_audio_info sample_rate: 22050 bits: 16 channels: 2 retries: 2
I/user.采样率: 22050 位宽: 16 声道: 2 数据起始: 44
I/user.exaudio 流式播放文件已打开: alipay_middle.wav data_start: 44
I/user.exaudio audio_v2流式播放启动成功
I/user.WAV 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4288/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4480/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4672/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4864/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5056/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5248/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5440/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5632/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5824/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6016/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6208/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6400/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6592/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6784/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6976/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7168/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7360/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7552/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7744/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7936/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 128/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4416/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4608/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4800/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4992/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5184/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5376/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5568/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5760/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5952/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6144/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6336/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6528/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6720/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6912/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7104/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7296/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7488/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7680/8000, decode end
D/audio_core common task recv event 1

D/audio_codec decode input fifo not enough 7872/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 64/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1
D/audio_core play request end, fifo empty, stop decode
D/audio_core common task recv event 1     FIFO排空(×4)
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.WAV 播放完成
-- --------------------------------------------------
-- 解析正常(data_start=44正确) | 播放正常至结束
-- 现象:“支付宝到账一亿元”在“到”和“账”之间有一个杂音,其余正常
-- 原因:WAV为PCM直通,损坏的512字节随机数据被直接作为PCM输出形成短促杂音,
--       之后继续正常播放,WAV不会因数据损坏而停止

4. 尾部数据损坏播放情况

流式播放 alipay_tail.wav(文件末尾 512 字节被清零),听觉上音频完整播放了

现象解释:WAV 文件头完好,解析正常(data_start=44、22050Hz),流式播放从正确偏移读取 PCM 数据。WAV 是 PCM 直通格式,解码器按字节顺序读取数据,无帧同步概念。尾部 512 字节被清零后,解码器将其作为 PCM 数据输出(极短的静音段),然后文件读取完毕、FIFO 空、播放正常结束。极短的静音尾端人耳不易察觉,所以听感上音频完整播放。

代码运行如下:

===== 开始播放 WAV =====
文件: /luadb/alipay_tail.wav 播放模式: 流式播放
I/user.exaudio.parse_audio_info sample_rate: 22050 bits: 16 channels: 2 retries: 2
I/user.采样率: 22050 位宽: 16 声道: 2 数据起始: 44
I/user.exaudio 流式播放文件已打开: alipay_tail.wav data_start: 44
I/user.exaudio audio_v2流式播放启动成功
I/user.WAV 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_drv audio driver enable audio output
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4288/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4480/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4672/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4864/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5056/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5248/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5440/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5632/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5824/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6016/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6208/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6400/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6592/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6784/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6976/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7168/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7360/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7552/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7744/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7936/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 128/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4416/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4608/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4800/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 4992/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5184/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5376/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5568/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5760/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 5952/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6144/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6336/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6528/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6720/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 6912/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7104/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7296/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7488/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7680/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 7872/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo not enough 64/8000, decode end
D/audio_core common task recv event 1
D/audio_codec decode input fifo empty, decode end
D/audio_core common task recv event 1
D/audio_core play request end, fifo empty, stop decode
D/audio_core common task recv event 1     FIFO排空(×4)
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core common task recv event 1
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.WAV 播放完成
-- --------------------------------------------------
-- 解析正常(data_start=44正确) | 正常播放至结束
-- 现象:听觉上音频完整播放,无异常
-- 原因:WAV为PCM直通,末尾清零数据输出为静音段,
--       文件读完即正常结束,尾部损坏不影响前面内容

五、流式播放 pcm 数据测试结果

流式播放 test.pcm 数据,记录正常数据、头损坏、中间损坏、尾部损坏的测试结果。

关于 PCM 格式

PCM 是裸音频数据,没有文件头、没有帧结构、没有标签。数据是纯粹的采样值序列。解码器不检查数据合法性,所有数据直接输出给 DAC。

  • parse_audio_info 直接返回默认值(16000Hz、16bit、1ch、data_start=0
  • 代码中 get_play_info 不会对 PCM 做任何解析
  • 解码器(codec_id=0)按字节顺序读取数据,不存在"解码失败"的概念
  • 日志中的 decode input fifo not enough X/8000, not end, decode end 与 WAV 类似,是 PCM 直通模式下的 FIFO 填充量循环

1. 正常数据播放情况

流式播放正常 test.pcm 文件,可以正常播放完整音频。

代码运行如下:

-- PCM无需解析,直接使用默认值
I/user.===== 开始播放 PCM =====
I/user.文件: /luadb/test.pcm 播放模式: 流式播放
I/user.parse_audio_info: PCM format, use default values
I/user.采样率: 16000 位宽: 16 声道: 1 数据起始: 0

-- 请求初始化→流式播放启动(同其他格式)
D/audio_core request_id: 1 init
D/audio_core use default driver index: 0 probe_id: 2
D/audio_core request_id: 1 add in request_block_list
D/audio_core common task recv event 4
D/audio_v2 lua request 0 start
I/user.exaudio 流式播放文件已打开: /luadb/test.pcm data_start: 0
I/user.exaudio audio_v2流式播放启动成功, request_index: 0 采样率: 16000 codec_id: 0
I/user.PCM 播放启动成功

-- 驱动初始化
D/audio_core driver 0x2 create play fifo
D/audio_codec decode input fifo empty, decode end
D/audio_drv audio driver start mode 1 driver state 1
D/audio_drv start check commom param old 16000-2-1, mode 0, new 16000-2-1, mode 1
D/audio_drv start commom param now 16000,2,1,1
D/audio_drv start check codec power 0 , param 0 0 0
D/audio_drv start check codec ready 0 , param 0
D/audio_drv start check pa power 0, param 1 45 1 10

-- 开始播放(FIFO循环消耗PCM数据)
I/user.exaudio audio_v2播放开始 0
D/audio_drv audio driver pa power on delay timer expire
D/audio_drv audio driver enable audio output
W/audio_core print from irq 0 0 4000
D/audio_codec decode input fifo not enough 4288/8000, not end, decode end
D/audio_codec decode input fifo not enough 4480/8000, not end, decode end
D/audio_codec decode input fifo not enough 4672/8000, not end, decode end
D/audio_codec decode input fifo not enough 4864/8000, not end, decode end
D/audio_codec decode input fifo not enough 5056/8000, not end, decode end
D/audio_codec decode input fifo not enough 5248/8000, not end, decode end
D/audio_codec decode input fifo empty, decode end

D/audio_core play request end, fifo empty, stop decode

-- 播放结束
D/audio_core wait play end 4
D/audio_core request_id: 1 deinit
D/audio_core no request block
D/audio_v2 lua request 0 end
I/user.exaudio audio_v2播放结束 0
I/user.播放完成 false
I/user.PCM 播放完成
-- --------------------------------------------------
-- 6次fifo not enough + empty | 完整播放

2. 数据头损坏播放情况

流式播放 test_head.pcm(前 256 字节被覆盖为 0xCC),代码运行与正常播放完全一致。因为 PCM 没有文件头可被破坏,parse_audio_info 直接返回默认值,解码器照常读取所有数据,听觉上前 256 字节 0xCC 被当作 PCM 输出产生短噪声,之后正常。

代码运行如下:

I/user.===== 开始播放 PCM =====
I/user.文件: /luadb/test_head.pcm 播放模式: 流式播放
I/user.parse_audio_info: PCM format, use default values
I/user.采样率: 16000 位宽: 16 声道: 1 数据起始: 0
I/user.exaudio audio_v2流式播放启动成功
I/user.PCM 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_codec decode input fifo not enough 4288/8000, not end, decode end
D/audio_codec decode input fifo not enough 4480/8000, not end, decode end
D/audio_codec decode input fifo not enough 4672/8000, not end, decode end
D/audio_codec decode input fifo not enough 4864/8000, not end, decode end
D/audio_codec decode input fifo not enough 5056/8000, not end, decode end
D/audio_codec decode input fifo not enough 5248/8000, not end, decode end
D/audio_codec decode input fifo empty, decode end
D/audio_core play request end, fifo empty, stop decode
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.PCM 播放完成
-- --------------------------------------------------
-- 与正常播放完全一致(PCM无文件头,损坏无影响)
-- 听感:前256字节0xCC被当作PCM输出产生极短噪声,之后正常

3. 中间数据损坏播放情况

流式播放 test_middle.pcm(文件约 1/3 位置 512 字节被替换为随机数据),代码运行与正常播放完全一致。PCM 解码器不检查数据合法性,损坏数据被直接当作 PCM 采样值输出,听觉上损坏处随机数据被直接输出为噪声,前后正常。

代码运行如下:

I/user.===== 开始播放 PCM =====
I/user.文件: /luadb/test_middle.pcm 播放模式: 流式播放
I/user.parse_audio_info: PCM format, use default values
I/user.采样率: 16000 位宽: 16 声道: 1 数据起始: 0
I/user.exaudio audio_v2流式播放启动成功
I/user.PCM 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_codec decode input fifo not enough 4288/8000, not end, decode end
D/audio_codec decode input fifo not enough 4480/8000, not end, decode end
D/audio_codec decode input fifo not enough 4672/8000, not end, decode end
D/audio_codec decode input fifo not enough 4864/8000, not end, decode end
D/audio_codec decode input fifo not enough 5056/8000, not end, decode end
D/audio_codec decode input fifo not enough 5248/8000, not end, decode end
D/audio_codec decode input fifo empty, decode end
D/audio_core play request end, fifo empty, stop decode
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.PCM 播放完成
-- --------------------------------------------------
-- 与正常播放完全一致(PCM直通,不检查数据合法性)
-- 听感:损坏处随机数据被直接输出为噪声,前后正常

4. 尾部数据损坏播放情况

流式播放 test_tail.pcm(文件末尾 512 字节被清零),代码运行与正常播放完全一致。尾部 0x00 被当作静音 PCM 数据输出,文件读完即正常结束,听觉上与正常音频区别不大。

代码运行如下:

I/user.===== 开始播放 PCM =====
I/user.文件: /luadb/test_tail.pcm 播放模式: 流式播放
I/user.parse_audio_info: PCM format, use default values
I/user.采样率: 16000 位宽: 16 声道: 1 数据起始: 0
I/user.exaudio audio_v2流式播放启动成功
I/user.PCM 播放启动成功
I/user.exaudio audio_v2播放开始
D/audio_codec decode input fifo not enough 4288/8000, not end, decode end
D/audio_codec decode input fifo not enough 4480/8000, not end, decode end
D/audio_codec decode input fifo not enough 4672/8000, not end, decode end
D/audio_codec decode input fifo not enough 4864/8000, not end, decode end
D/audio_codec decode input fifo not enough 5056/8000, not end, decode end
D/audio_codec decode input fifo not enough 5248/8000, not end, decode end
D/audio_codec decode input fifo empty, decode end
D/audio_core play request end, fifo empty, stop decode
D/audio_core wait play end 4
I/user.exaudio audio_v2播放结束
I/user.播放完成 false
I/user.PCM 播放完成
-- --------------------------------------------------
-- 与正常播放完全一致(PCM直通,所有数据包括0x00都被输出)
-- 听感:尾部0x00被输出为静音段,播放正常结束