您假设每次都生成相同的正弦波,但是由于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:这张图片可能是一个更好/更清晰的可视化:
