8

I'm trying to programmatically generate a wave (sine or square) with a continuously decreasing frequency. To do so, I simply multiply the starting frequency for a decreasing value, that linearly goes from 1 to 0, at intermediate steps throughout a given time span. I was puzzled to see (and hear) that, exactly at the half of the time span, the frequency started to increase again. I checked the frequency value but everything is ok. I can use only the first 'half' of the wave, but it would be great to understand what I'm experiencing. Any help appreciated ! Thanks

rotor
  • 83
  • 3
  • It sounds to me more like you got a scale factor wrong or offset somewhere, and actually ramped your frequency modulation from 1 to -1. – hotpaw2 Apr 14 '12 at 02:46
  • 2
    Please show us exactly how you create the sine or square wave. – Jim Clay Apr 14 '12 at 12:50

1 Answers1

11

Make sure that your frequency doesn't reach values below 0 or above the half of your sample rate.

Please post more information/code about how you generate your waveform! Chances are you are not doing it correctly.

For example, if you want to generate a sine wave with a time-varying frequency $f(t)$ (for example to implement frequency modulation), generating something like:

$$y(t) = \sin (2 \pi t f(t))$$

is wrong, because your instantaneous frequency is:

$$f_i(t) = \frac{1}{2 \pi}\frac{d \phi(t)}{dt}$$

And:

$$\frac{1}{2 \pi}\frac{d 2 \pi t f(t)}{dt} \neq f(t)$$

Except in the specific case where $f(t)$ is a constant.

The correct way to generate a sine wave with time-varying frequency $f(t)$ is thus with:

$$y(t) = \sin (2 \pi \int_{0}^{t} f(\tau) d\tau)$$

In synthesizer-speak the register/variable accumulating the instantaneous frequency to evaluate the $\int_{0}^{t} f(\tau) d\tau$ quantity is called a phase accumulator.

http://en.wikipedia.org/wiki/Frequency_modulation

http://en.wikipedia.org/wiki/Instantaneous_phase

pichenettes
  • 19,413
  • 1
  • 50
  • 69
  • 1
    Many thanks for your answer, it explained what I was doing wrong. Switching to a phase accumulator based implementation solved the issue. – rotor Apr 14 '12 at 15:11