大缓冲区大小播放,小大小不播放

Large buffer sizes plays, small size doesn't

本文关键字:播放 小大 缓冲区      更新时间:2023-10-16

当缓冲区大小很小(1920帧)时,我在获取声音输出时遇到问题。如果我在48kHz采样并使缓冲区大小为480000,则正弦波正确播放1秒。我想做的只是为40ms播放正弦波。

我已经计算出是48000 samples/sec * 1sec/1000ms * 40ms = 1920 frames。然而,当我尝试调用只有1920帧的snd_pcm_writei时,什么都没有出来!

这是有问题的代码:

void PCM::playSound(float freqHz, uint16_t durationMs)
{ 
    int FRAMES_LEN=48000;
    //Send the sine_buffer to sound card, with correct buffer length
    snd_pcm_sframes_t frames = snd_pcm_writei(handle, sine_buffer, FRAMES_LEN);
    if (frames < 0){
        HW_INFO() << "PCM::playSound-- snd_pcm_writei failed,trying to recover:" 
                  << snd_strerror(frames);
        frames = snd_pcm_recover(handle, frames, 0);
    }
    if (frames < 0) {
        HW_INFO() << "PCM::playSound-- snd_pcm_writei recovery failed: " 
                  << snd_strerror(frames);
    }
    HW_INFO() << "Wrote " << frames << " frames";
    return;
}

如果FRAMES_LEN48000,则此代码工作正常,并产生持续1秒的正弦波。

如果FRAMES_LEN1920,我根本听不到正弦波,但日志显示Wrote 1920 frames

发生了什么?

如果使用长度>=1920帧的滤波器进行任何类型的后处理,这是合理的。例如,这样的过滤可以丢弃任何点击声音。使用ALSA而不仅仅是与D/a转换器交谈的全部原因是为了进行音频特定处理。

您的日志记录没有欺骗您。你要求它向设备写入1920个样本,它做到了。由于您的48000个样本实验播放的声音持续了一秒钟,因此您的硬件必须以48 kHz的频率运行。假设1920帧将持续百分之四百秒。根据正弦缓冲区中正弦的频率,您可能听不到。

以下是更深入的讨论:https://sound.stackexchange.com/q/28163