【问题标题】:alsa snd_pcm_writeialsa snd_pcm_writei
【发布时间】:2023-03-20 05:59:01
【问题描述】:

我注意到 pcm.c 和 speaker-test.c 中的正弦发生器在循环中生成了一个新的正弦缓冲区。所以它不断地重新创建相同的缓冲区。我想播放缓冲区而不是每次都重新创建它以节省一些 cpu 时间。但是,当我尝试通过首先构建缓冲区然后将相同的缓冲区发送到 snd_pcm_writei 来运行代码时,我在每个缓冲区的末尾都会听到一点咔哒声。但是,当它每次都被重建然后发送到 snd_pcm_writei 时,缓冲区末尾没有一点点击。为什么每次播放前都需要重建正弦缓冲区,以免产生咔嗒声?

任何帮助将不胜感激?

来自 pcm.c:

while (1) {
    generate_sine(areas, 0, period_size, &phase);
    ptr = samples;
    cptr = period_size;

【问题讨论】:

    标签: alsa


    【解决方案1】:

    您假设每次都生成相同的正弦波,但是由于使用了 phase 变量,并且正弦波并不总是完全适合缓冲区,因此每次迭代都会生成不同的正弦波,移位有点。

    不是每次都生成正弦波会导致正弦波“中断”。

    我将尝试使用锯齿波而不是正弦波进行一些可视化。想象一下缓冲区大小为 16,波形值从 A 到 H。

    // Old way
      phase = 0        phase = 2        phase = 4
    ABCDEFGHGFEDCBAB|CDEFGHGFEDCBABCD|EFGHGFEDCBABCDEF....
    
    // New way
      phase = 0        phase = 0        phase = 0
    ABCDEFGHGFEDCBAB|ABCDEFGHGFEDCBAB|ABCDEFGHGFEDCBAB....
    

    请注意,缓冲区边缘只有小块声音“格式错误”(例如AB|AB 而不是AB|CD)。这就是为什么它在大多数情况下听起来都是正确的,中间有一些令人不安的短“点击”。

    在极少数情况下,如果缓冲区长度是波长的倍数,或者当 phase 与之前的迭代中的值相同时,您可能确实会跳过生成缓冲区,但您不能每次都这样做时间。

    编辑:查看generate_sine 函数,看看phase 是如何变化的:

    static void generate_sine(const snd_pcm_channel_area_t *areas, 
                              snd_pcm_uframes_t offset,
                              int count, double *_phase)
    {
        static double max_phase = 2. * M_PI;
        double phase = *_phase;
        double step = max_phase*freq/(double)rate;
    
        [...]
    
                 phase += step;
                 if (phase >= max_phase)
                        phase -= max_phase;
         }
         *_phase = phase;
    }
    

    EDIT2:这张图片可能是一个更好/更清晰的可视化:

    【讨论】:

    • 你可以使用codegolf.stackexchange.com/questions/951/… 来做一个更好的例子:)
    • @ninjalj:谢谢,但我现在决定添加一张图片。更好的是一个交互式小程序,您可以在其中更改缓冲区长度并收听声音,但我想这太过分了:)
    • 感谢两位的帮助。我刚刚开始看到缓冲区长度末尾的相位值是关键因素。然后根据您的确认,我应该能够通过确保该阶段在缓冲区的开始和结束时始终为 0 来创建一个可以连续重播的缓冲区。
    猜你喜欢
    • 2014-10-31
    • 2014-11-18
    • 2016-09-06
    • 2011-01-11
    • 1970-01-01
    • 2015-08-25
    • 2020-04-11
    • 2010-11-21
    • 2016-08-12
    相关资源
    最近更新 更多