使用相位生成正弦波

时间:2016-03-16 13:32:04

标签: audio sampling phase nyquist

我使用以下方法生成正弦波 -

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中没有区别。有人能解释一下这里发生了什么吗?

3 个答案:

答案 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的计算移到循环外...通知阶段是一个常数,因为它只是给我们一个初始偏移量