我使用以下方法生成正弦波 -
sampling rate = 22050;
theta = 0;
for (i = 0; i < N; i++)
{
theta = phase * 2 * PI;
signal[i] = amplitude * sin(theta);
phase = phase + frequency/sampling rate;
}
当我生成频率为8000 Hz的信号时,输出会出现失真。低于此频率(例如6000Hz)的频率正确生成。如果我像这样检查相位,则会正确生成8000 Hz信号 -
if (phase > 1)
{
float temp = phase - 1;
phase = temp;
}
我认为它与Xcode中的正弦函数有关,可能是它可以接受的一系列值?有和没有相位包装的相同代码在Matlab中没有区别。有人能解释一下这里发生了什么吗?
答案 0 :(得分:1)
我认为计算应该是(2.0 * PI)*频率/采样率
这将为您提供弧度的下一个相位增量。然后可以将该值输入Sin函数以计算相位。请注意,您需要累积弧度值。
从技术上讲,你的第一个陈述是错误的,因为它的措辞。 FS / 2是奈奎斯特值。您可以产生高于此值的频率但它们将是别名。
在阶段包装方面,有不同的方法来管理它。
我对Radians的理解是,它是线性的&#39;表示在相位围绕2 pi值旋转时不重复的相位。因此,如果您通过管理弧度来管理阶段,则可能没有包装问题。
很高兴能够得到更多知识渊博的人的纠正。
答案 1 :(得分:0)
我不确定,但我相信问题可能是:
theta = phase * 2 * PI;
我认为Xcode会将结果更改为整数。您可能想尝试:
theta = phase * 2.0 * PI;
相反,请确保您的PI
变量为double
。
所有这些都使DSP.SE成为一个偏离主题的话题。 : - )
答案 2 :(得分:0)
@cixelsyd有正确的公式......这里是根据采样率创建一组给定频率样本的代码
incr_theta := (2.0 * math.Pi * given_freq) / samples_per_second
phase := -1.74 // given phase ... typically 0 note its a constant
theta := 0.0
for curr_sample := 0; curr_sample < number_of_samples; curr_sample++ {
source_buffer[curr_sample] = math.Sin(theta + phase)
theta += incr_theta
}
效率最好将delta theta的计算移到循环外...通知阶段是一个常数,因为它只是给我们一个初始偏移量