播放大缓冲区大小,小尺寸不会

时间:2016-05-18 22:45:03

标签: c++ c alsa

当我有一个小的缓冲区大小(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

发生了什么事?

2 个答案:

答案 0 :(得分:0)

如果使用长度> = 1920帧的过滤器进行任何类型的后处理,这是合理的。例如,这种过滤可以丢弃任何咔嗒声。使用ALSA而不是仅仅与D / A转换器通信的全部原因是要进行特定于音频的处理。

答案 1 :(得分:0)

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

这是一个更深入的讨论:https://sound.stackexchange.com/q/28163