正弦波在给定时间内从f1缓慢上升到f2

kat*_*tta 9 c c++ algorithm math waveform

我正在编写交流程序,以产生一个正弦波,在给定时间间隔内缓慢地将频率从f1加速到f2.

我已经编写了这个c程序,将频率从0到10 Hz加速,但问题是360度完成后频率会发生变化.如果我尝试在0到360度之间改变频率,那么转换不平滑且突然.

这是我用过的罪的等式y =幅度*sin(频率*相位)

int main(int argc, char *argv[]) {

double y, freq,phase;
int count; // for convenience of plotting in matlab so all the waves are spread on x axis.
  for (freq = 0; freq < 10; freq+=1) {
      for (phase = 0; phase < 360; phase++) { // phase is 360 degrees
      y = 3 * sin((count*6.283185)+(freq*(phase*(3.14159/180))));   
    printf("%f %f %f \n", freq, phase, y);
   }
  count++;
  }
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
  1. 如何在给定时间段内平滑地改变频率?
  2. 我应该研究傅立叶变换吗?

and*_*oke 14

如果你想角频率(W = 2 PI F)随时间线性变化,然后dw/dt = aw = w0 + (wn-w0)*t/tn(其中t从0到tn,w从进入w0wn).阶段是其中的组成部分,因此phase = w0 t + (wn-w0)*t^2/(2tn)(正如oli所说):

void sweep(double f_start, double f_end, double interval, int n_steps) {
    for (int i = 0; i < n_steps; ++i) {
        double delta = i / (float)n_steps;
        double t = interval * delta;
        double phase = 2 * PI * t * (f_start + (f_end - f_start) * delta / 2);
        while (phase > 2 * PI) phase -= 2 * PI; // optional
        printf("%f %f %f", t, phase * 180 / PI, 3 * sin(phase));
    }
}
Run Code Online (Sandbox Code Playgroud)

(其中interval是tn,delta是t/tn).

这是等效python代码的输出(1-10Hz超过5秒):

1-10 Hz超过5秒

from math import pi, sin

def sweep(f_start, f_end, interval, n_steps):
    for i in range(n_steps):
        delta = i / float(n_steps)
        t = interval * delta
        phase = 2 * pi * t * (f_start + (f_end - f_start) * delta / 2)
        print t, phase * 180 / pi, 3 * sin(phase)

sweep(1, 10, 5, 1000)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果你正在听这个(或者看着它 - 任何涉及人类感知的东西),我怀疑你不想要线性增加,而是指数增长.但这是一个不同的问题 ......


Oli*_*rth 9

如何在给定时间段内平滑地改变频率?

平滑的正弦曲线需要连续相位.相位是频率的积分,因此如果您具有频率的线性函数(即从f1到f2的恒定速率增加),则相位将是时间的二次函数.

你可以用笔和纸来计算数学,或者我可以告诉你结果波形被称为线性啁啾.

我应该研究傅立叶变换吗?

线性啁啾的傅立叶变换本身就是线性啁啾,所以可能没有.