Найти начальную точку (время) каждого цикла в синусоиде
Я пытаюсь достичь синусоиды, постепенно меняющейся от 8Hz
в 2Hz
над 5
секунды:
Эта форма волны была создана в Cool Edit. Я дал ему стартовую частоту 8Hz
конечная частота 2Hz
и продолжительность 5
секунд. Синусоида постепенно изменяется от одной частоты к другой в течение заданного времени.
У меня вопрос, как я могу точно найти время начала каждого цикла (выделено красной точкой), используя цикл FOR?
Псевдокод:
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 */
}
1 ответ
Это обратное мышление для этой проблемы, которая приводит к безумию в программе. Не говоря уже о том, что отдельные волны не будут синусоидальными, потому что частота меняется (они будут слегка искажены), чего вы не достигнете с вашим генератором, а также очень мала вероятность того, что сигнал окончания остановится на нуле через 5 секунд. Вместо этого сделайте непрерывную волну греха с переменной частотой:
Сначала вычислите фактическую частоту
Подойдет линейная интерполяция (если вам не нужны другие изменения)
f=f0+(f1-f0)*t/T
где:
f0=8 [Hz] start frequency f1=2 [Hz] stop frequency T =5 [s] change time t =<0,T> is actual time in [s]
вычислить данные синусоидальной волны
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; }
куда
dt [s]
это временной шаг, с которым вы хотите сэмплировать ваш сигнал. Если вы генерируете это в реальном времени и выводите в реальное HW, вы можете использоватьtimer
или измерить время напрямую (с помощьюperformance counters
в Windows илиRDTSC
или что у вас есть в распоряжении)Если вы получили заранее определенное количество образцов
n
для этого тогдаdt=T/double(n-1);
Вот пример вывода (
n=image width
):Если вам также нужно количество периодов, добавьте приращение счетчика внутри
angle
резатьwhile
loop И также есть ваша нулевая точка (но если частота выборки слишком мала или вам нужна высокая точность, вам нужно интерполировать реальную нулевую позицию).