Edit online

常见问题

4 Dec 2024
Read time: 1 minute(s)

播放音频文件时会先播放一段 0 数据

在 RT-Thread 的 Audio 框架中,播放音频时出现起始部分为 0 数据的问题确实比较常见。这主要是由于内存池管理机制导致的。当读取的音频数据长度小于内存池一个 block 的大小时,即使已经将音频数据写入内存池,也不会立即将该 block 加入到数据队列中,而是等到一个 block 写满才加入数据队列。尽管未加入数据队列,但 audio 框架也会立即开始传输。此时数据队列中没有任何数据,会先填充一个 period_len 长度的 0 数据,所以播放会有 0 数据出现,示意图如下:


zero-data

为了避免播放起始部分出现 0 数据,可以采取以下几种方法:
  • 在应用层增大读取音频文件的 buffer 长度,使其与内存池的 block 大小相同。

    这样在第一次写内存池时,就可以将 block 加入到数据队列。如下图所示:


    no-zero-data

  • 预填充音频数据,即在开始播放之前,先向内存池中预填充一段音频数据。这样在播放开始时,内存池中已经有数据可供传输,避免了播放起始部分出现 0 数据。

播放时应用层可设置的 buffer 大小范围是多少

在 RT-Thread 的 Audio 框架中,应用层设置的 buffer 大小范围受到内存池配置的限制。具体来说,应用层一次读取音频文件的最大 buffer 大小是 RT_AU×DIO_REPLAY_MP_BLOCK_SIZE × RT_AUDIO_REPLAY_MP_BLOCK_COUNT

Driver 层的默认配置如下:
  • RT_AUDIO_REPLAY_MP_BLOCK_SIZE 的值为 2048(字节)
  • RT_AUDIO_REPLAY_MP_BLOCK_COUNT 的值为 2

因此,可设置的最大 buffer 大小为 RT_AUDIO_REPLAY_MP_BLOCK_SIZE × RT_AUDIO_REPLAY_MP_BLOCK_COUNT = 2048 * 2 = 4096