- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我注意到 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;
最佳答案
您假设每次都生成相同的正弦波,但由于使用了 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:这张图片可能是更好/更清晰的可视化:
关于alsa snd_pcm_writei,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5920613/
我注意到 pcm.c 和 speaker-test.c 中的正弦发生器循环生成一个新的正弦缓冲区。所以它不断地重新创建相同的缓冲区。我想播放缓冲区而不是每次都重新创建它以节省一些 cpu 时间。但是,
我试图使用 ALSA 生成蜂鸣声。应发出 2 声蜂鸣声,第二声在延迟 1 秒后发出。我的代码如下所示。 if ((err = snd_pcm_prepare (playback_handle)) <
在运行我最近从 Ember 中恢复的旧程序时,我遇到了缓冲区不足的情况。 程序将原始声音文件完全加载到内存中(2100 字节长,525 帧)并准备 ALSA 进行输出(44.1khz,2 channe
如果我的问题标题很糟糕,请原谅我。我的妻子总是告诉我,我不擅长措辞。 我编写了一些代码来读取由另一个线程填充的缓冲区。缓冲区中充满了由 opus 编解码器编码的音频数据。每次 20 毫秒从远程端接收
我在 arm linux 3.10 中使用 alsa。有 3 个无线设备:两个使用 snd_pcm_readi 和 sendmsg 捕获和发送 pcm,一个作为接收器,使用 snd_pcm_write
snd_pcm_writei 和 snd_pcm_readi 有什么区别?当我尝试使用这两个功能时,它们似乎都在从缓冲区中播放?似乎只有 handle 的配置方式 SND_PCM_STREAM_CAP
我稍微修改了取自 ALSA Project website 的演示为了在我笔记本电脑的声卡(Intel PCH ALC3227 Analog,Ubuntu 18.04)上进行测试,它需要 2 个 ch
我正在尝试以重复的方式播放 1000 毫秒的 wav 文件。因此,播放 1000 毫秒,然后播放 1000 毫秒的静音,然后再次播放 1000 毫秒的音频,... 但是当我在此过程中打印计时时,我注意
我很难理解我在音频播放例程中做错了什么。我有一个线程从其他线程获取缓冲区并以与此 alsa 示例程序相同的方式播放它们:https://www.alsa-project.org/alsa-doc/al
我正在使用 ASLA Audio API 在我的嵌入式 Linux 应用程序中播放声音。我有时观察到 snd_pcm_writei API 返回 –EPIPE 错误,当该错误发生时,我调用 snd_p
用ALSA播放音频,调用snd__pcm__writei后,是立即释放sample buffer还是需要等声音播放完再释放sample buffer? 例如: unsigned short *buff
我已经尝试了多个示例程序,它们似乎有代码来处理播放时的 xruns: https://albertlockett.wordpress.com/2013/11/06/creating-digital-a
我是一名优秀的程序员,十分优秀!