1

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

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 的信号时,输出会出现失真。低于此的频率(例如 6000 Hz)会正确生成。如果我像这样检查相位,则正确生成 8000 Hz 信号 -

if (phase > 1)  
{  
  float temp = phase - 1;  
  phase = temp;  
}  

我认为它与 Xcode 中的正弦函数有关,可能是它可以接受的一系列值?相同的代码有和没有相位环绕在 Matlab 中没有区别。有人可以解释这里发生了什么吗?

4

3 回答 3

1

我相信计算应该是 (2.0 * PI) * 频率/采样率

这将为您提供下一阶段的弧度增量。然后可以将该值输入到 Sin 函数中以计算相位。请注意,您需要累积弧度值。

从技术上讲,您的第一个陈述是不正确的,因为它的措辞。FS/2 是奈奎斯特值。您可以产生高于此的频率,但它们会混叠。

在相位缠绕方面,有不同的方法来管理它。

我对弧度的理解是,它是相位的“线性”表示,在相位围绕 2 pi 值旋转时不会重复。因此,如果您通过管理弧度来管理相位,您可能不会遇到换行问题。

很高兴被更多知识渊博的人纠正。

于 2016-03-16T20:05:24.017 回答
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 的计算移到循环之外......注意相位是一个常数,因为它只是给我们一个初始偏移量

于 2017-09-20T01:17:59.853 回答
0

我不确定,但我相信问题可能是:

theta = phase * 2 * PI;  

我认为 Xcode 会将结果更改为整数。您可能想尝试:

theta = phase * 2.0 * PI;  

相反,并确保您的PI变量是double.

所有这些都使 DSP.SE 偏离了主题。:-)

于 2016-03-23T12:59:54.830 回答