audio的replay模式播放时是先发一段0来启动吗?

发布于 2020-09-09 15:39:43

对于replay的流程,我的理解如下:
使用rt_device_write来向音频播放设备写入要播放的音频数据,对于音频设备,实际调用的是audio.c里的_audio_dev_write函数。从该函数定义看,主要是将要发送的数据分成数据帧放入data_queue,然后调用底层start函数。
以潘多拉的audio代码为例,对于start的实现如下:

/* https://github.com/RT-Thread/rt-thread/blob/master/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c */

static rt_err_t sound_start(struct rt_audio_device *audio, int stream)
{
    struct sound_device *snd_dev;

    RT_ASSERT(audio != RT_NULL);
    snd_dev = (struct sound_device *)audio->parent.user_data;

    if (stream == AUDIO_STREAM_REPLAY)
    {
        LOG_D("open sound device");
        es8388_start(ES_MODE_DAC);
        HAL_SAI_Transmit_DMA(&SAI1A_Handler, snd_dev->tx_fifo, TX_FIFO_SIZE / 2);
    }

    return RT_EOK;
}

可见,其中使用了DMA发送snd_dev->tx_fifo里的数据,而这里面的数据初始状态是全0。只有发送完第一次后进入DMA中断,在DMA中断中调用rt_audio_tx_complete才会真正发送上述data_queue里的有效数据。

问题

  1. 如果我的理解没错,为什么要通过发送全0数据的方式来启动,为什么不是直接发送data_queue里的数据?
  2. 如果我理解错了,请大家指点一下正确的流程。

查看更多

关注者
0
被浏览
243
liu2guang
liu2guang 认证专家 2020-09-09

没啥考虑,就是设计的时候没有想这么多。但是这并不是说明实际会产生什么严重的后果,向DMA传入0数据,其实是不会发出声音的。在实际使用的场景下,一般是开始播放歌曲,或者是长时间暂停后恢复(短时间暂停一般是不write数据这种方式处理, 长时间一般是stop再start),那么针对这2种场景分析:

  1. 开始播放,由于0数据,其实是不会发出声音的,等一个中断后就会真实的搬运数据,其实没有什么影响
  2. 长时间暂停后恢复,虽然在整个音乐播放过程中插入一帧的0数据,但是由于是长时间暂停后恢复,人的听感上无法感知,所以问题也不大
2 个回答
HappyTime
HappyTime 2020-09-09

是的,先发送一段的数据是零;至于为什么,有什么考虑,等大神回答吧。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览