【问题标题】:Large buffer sizes plays, small size doesn't大缓冲区大小播放,小尺寸不
【发布时间】:2016-09-15 15:04:09
【问题描述】:

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

发生了什么?

【问题讨论】:

  • 40 毫秒是非常短的时间,您最多只能听到砰砰声或咔嗒声。
  • 我仍然没有听到持续时间为 250 毫秒的任何声音,因此是 12,000 帧
  • 尝试将 FRAMES_LEN 从 48,000 降低到 2,000 左右,大约 2,000 的递减量,看看什么时候您不再听到产生的声音。
  • 你能把示波器代替扬声器连接到输出端并测量出来的部分声波吗?
  • 周期大小是多少?你有没有打电话给snd_pcm_drain()

标签: c++ c alsa


【解决方案1】:

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

这里有更深入的讨论:https://sound.stackexchange.com/q/28163

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2020-09-05
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 2011-11-26
      相关资源
      最近更新 更多