sine wave that slowly ramps up frequency from f1 to f2 for a given time

大城市里の小女人 提交于 2019-11-27 04:41:01
andrew cooke

if you want angular frequency (w=2 pi f) to vary linearly with time then dw/dt = a and w = w0 + (wn-w0)*t/tn (where t goes from 0 to tn, w goes from w0 to wn). phase is the integral of that, so phase = w0 t + (wn-w0)*t^2/(2tn) (as oli says):

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));
    }
}

(where interval is tn and delta is t/tn).

here's the output for the equivalent python code (1-10Hz over 5 seconds):

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)

ps incidentally, if you're listening to this (or looking at it - anything that involves human perception) i suspect you don't want a linear increase, but an exponential one. but that's a different question...

How do I change frequency smoothly for a given time period?

A smooth sinusoid requires continuous phase. Phase is the integral of frequency, so if you have a linear function for frequency (i.e. a constant-rate increase from f1 to f2), then phase will be a quadratic function of time.

You can figure out the maths with pen and paper, or I can tell you that the resulting waveform is called a linear chirp.

Should I be looking into Fourier transformations?

The Fourier transform of a linear chirp is itself a linear chirp, so probably no.

It should be fairly simple. Rather than thinking of varying the frequency, think of making an object spin faster and faster. The angular distance it has traveled might be X after N seconds, but will be more that 2X (maybe 4X) after 2N seconds. So come up with a formula for the angular distance (eg, alpha = k1 * T + k2 * T**2) and take the sine of that angular distance to find the value of the waveform at any time T.

+ (void) appendChirp:(int[])sampleData size:(int)len 
    withStartFrequency:(double)startFreq withEndFrequency:(double)endFreq 
    withGain:(double)gain {

double sampleRate = 44100.0;

for (int i = 0; i < len; i++) {

    double progress = (double)i / (double)len;
    double frequency = startFreq + (progress * (endFreq - startFreq));
    double waveLength = 1.0 / frequency;

    double timePos = (double)i / sampleRate; 
    double pos = timePos / waveLength;
    double val = sin(pos * 2.0 * M_PI); // -1 to +1 

    sampleData[i] += (int)(val * 32767.0 * gain);
}

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!