I am tying to achieve sine wave gradually changing from 8Hz
to 2Hz
over 5
seconds:
This waveform was produced in Cool Edit. I gave it a start frequency of 8Hz
, an end frequency of 2Hz
and a duration of 5
seconds. The sine wave gradually changes from one frequency to the other over the given time.
My question is, how can I accurately find the start time of each cycle (highlighted with a red dot), using a FOR loop?
Pseudo code:
time = 5 //Duration
freq1 = 8 //Start frequency
freq2 = 2 //End frequency
cycles = ( (freq1 + freq2) / 2 ) * time //Total number of cycles
for(i = 0; i < cycles; i++) {
/* Formula to find start time of each cycle */
}
That is backward thinking for this problem which leads to madness in the program. Not to mention the individual waves will not be a sin wave because the frequency is changing (they will be slightly distorted) which you will not achieve with your generator and also there is very slight chance the ending signal will stop on zero after 5sec. Instead do a continuous sin wave with variable frequency:
First compute actual frequency
linear interpolation will suffice (unless you need different change)
f=f0+(f1-f0)*t/T
where:
f0=8 [Hz] start frequency
f1=2 [Hz] stop frequency
T =5 [s] change time
t =<0,T> is actual time in [s]
compute the sin wave data
for (t=0.0,angle=0.0;t<=T;t+=dt)
{
f=f0+((f1-f0)*t/T); // actual frequency
signal=Amplitude*sin(angle); // your signal put it in a array or output somewhere ...
angle+=6.283185307179586476925286766559*dt*f; // update phase
while (angle>6.283185307179586476925286766559) // cut just to avoid floating rounding problems
angle-=6.283185307179586476925286766559;
}
Where dt [s]
is a time step you want to sample your signal with. If you are generating this in Real Time and outputting to real HW you can use a timer
or measure the time directly (with performance counters
on Windows or by RDTSC
or whatever you have at disposal)
If you got predefined number of samples n
for this then
dt=T/double(n-1);
Here sample output (n=image width
):
If you also need the number of periods then add counter increment inside the angle
cut while
loop And also there is your zero point too (but if samplerate is too small or you need high precision you need to interpolate the real zero position).