2
$\begingroup$

I am very very new to signals, and I am trying to generate sounds based on some parameters from a database. So, the database stores the following:

  • startFrequency
  • endFrequency
  • startAmplitude
  • endAmplitude
  • duration

I am generating a WAV file based on this information using the following code:

...
double currentFrequency;
double currentAmplitude;

int samplerate = 44100;
int samples = ceil(duration * samplerate);
int* mySampleBuffer = new int[samples];

for(int i=0; i<samples; i++)
{
    currentFrequency = Interpolate(i, 0, samples, startFrequency, endFrequency);
    currentAmplitude = Interpolate(i, 0, samples, startAmplitude, endAmplitude);
    mySampleBuffer[i] = static_cast<int>(INT_MAX * (sin(((double)i * currentFrequency * PI * 2)/(double)samplerate) * (currentAmplitude/maxAmplitude)));
}

writeWAVData("mySound.wav", mySampleBuffer, mySampleBufferSize, samplerate, 1);
delete[] mySampleBuffer;
...

When the currentFrequency reaches 1/2 of the startFrequency, I notice that the sound wave flips (not sure what the correct term for this is). It doesn't seem like this is correct. Could someone help me understand what is going on.

Here is a screenshot of Audacity Audacity

For this image, startFrequency is 3380 Hz, endFrequency = 1380 Hz, duration is 0.512 s, and the amplitude is constant from start to finish. I have calculated that at 0.43264 s, the currentFrequency is exactly 1/2 of the startFrequency. In the picture you can see the "flip" happen at about 0.43 seconds.

$\endgroup$
  • $\begingroup$ Forgot to delete[] mySampleBuffer; after writing to the file! $\endgroup$ – NeilMonday Jan 2 '14 at 17:13
4
$\begingroup$

Think of frequency in this context more in terms of angular velocity. If that velocity is constant, nothing changes from the usual picture. However, if the frequency changes, it is more correct to compute the actual angle that is input into the trig functions as an anti-derivative of the frequency function.

Here the interpolated frequency is

$$f(t)=(1-\tfrac tT)\,f_0+\tfrac tT\,f_T,$$

so the angle at time $t$ is

$$\phi(t)=2\pi\,\int_0^t f(s)\,ds=2\pi\, [t(1-\tfrac{t}{2T})\,f_0+\tfrac{t^2}{2T}]=\pi t\,[(2-\tfrac tT)f_0+\tfrac tT\,f_T]$$

In contrast, your formula is

$$\phi_o(t)=2\pi\,t\,f(t)=2\pi t\,[(1-\tfrac tT)f_0+\tfrac tT\,f_T]$$

has a derivative or local angular velocity of

$$\phi_o'(t)=2\pi\,[(1-2\tfrac tT)f_0+2\tfrac tT f_T]$$

which has a zero at $t=\frac T2\,\frac{f_0}{f_0-f_T}$, which given your data is located at $t=0.43264s$.

Note that the correct formula also reaches the local angular frequency of zero, but at the double of that time interval, so outside $[0,T]$.


Note on implementation: The last form of $\phi(t)$ can be constructed as

 pi*(i*dt)*(f0+interpolate(i,f0,fT,N))

with N=samples and dt=T/N, provided that

interpolate(0,f0,fT,N)==f0 and interpolate(N,f0,fT,N)==fT 
$\endgroup$
  • 1
    $\begingroup$ Lutz hit it well. instantaneous frequency is the derivative of phase. the reason that the instantaneous (angular) frequency of $\cos(\omega t)$ is $\omega$ is because you take the argument of the sinusoid and <i>differentiate</i> it, <b>not</b> divide it by $t$. it's a common mistake, even done by university professors publishing papers. (i have, more than a decade ago, corrected a published paper in the Journal of the AES regarding this.) $\endgroup$ – robert bristow-johnson Jan 2 '14 at 21:41
  • $\begingroup$ Note that for the general case (a different frequency transition curve for example), it is easier to use a phase accumulator as explained in this answer: dsp.stackexchange.com/questions/971/… $\endgroup$ – pichenettes Jan 4 '14 at 0:42
  • $\begingroup$ This sounds like numerical integration with the Euler method, $\phi(t+h)=\phi(t)+2\pi f(t)h$ for $0\le h\le \Delta t$. If I understand the options, one can use a fixed $\Delta t$ or adjust for $f(t)\Delta t$ to be an integer? $\endgroup$ – Dr. Lutz Lehmann Jan 4 '14 at 7:21
1
$\begingroup$

I think you rediscovered aliasing on your screen. Does it sound right?

$\endgroup$
  • $\begingroup$ If you zoom in, the graph is much smoother. It makes a nice non-distorted sound, but I believe I need to implement the formula LutzL posted for it to be correct. $\endgroup$ – NeilMonday Jan 2 '14 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.