2016-06-01 2 views
1

Я обвязку достичь синусоидальной волны постепенно изменяющейся от 8Hz к 2Hz через 5 секунд:Найти начальную точку (время) каждый цикл синусоиды

img

Этот сигнал был произведен в 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 */ 
} 
+0

@DavidTansey изменение знака обнаруживает все пересечения нуля, и только половина из них является 'phase = 0', но я думаю, что проблема заключается в генерации такого сигнала, чтобы не найти нулевые пересечения. Это была просто попытка новичков приблизиться к этому, создавая отдельные грешные волны, которые для этого неправильны. – Spektre

ответ

1

Это мышление назад для этой проблемы, что приводит к безумию в программе. Не говоря уже о том, что отдельные волны не будут волной sin, потому что частота меняется (они будут слегка искажены), которых вы не достигнете с вашим генератором, а также есть очень небольшой шанс, что конечный сигнал остановится на ноле после 5 секунд. Вместо того, чтобы делать непрерывную греховную волну с переменной частотой:

  1. Сначала вычислим фактическая частота

    линейная интерполяция будет достаточно (если вам не нужно другое изменение)

    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] 
    
  2. вычислить данные

    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):

    example

    Если вам также необходимо количество периодов затем добавить счетчик приращения внутри angle сократить while петлю А также есть ваша нулевая точка тоже (но если частота дискретизации слишком мала, или вам нужна высокая точность, необходимо интерполировать реальная нулевая позиция).

+0

Удивительно подробный ответ и абсолютно точечный (без каламбур). Brilliant! – pJay

Смежные вопросы