在正弦波中找到每个周期的起点(时间)
Find start point (time) of each cycle in a sine wave
我想实现正弦波在 5
秒内从 8Hz
逐渐变为 2Hz
:
此波形是在 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 */
}
这是对这个问题的落后思维,导致程序疯狂。更不用说单个波不会是正弦波,因为频率在变化(它们会轻微失真),这是您的发生器无法实现的,而且结束信号在 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]
是您要用来对信号进行采样的时间步长。如果您在 Real Time 中生成它并输出到 real HW,您可以使用 timer
或直接测量时间(使用 performance counters
在 Windows 或通过 RDTSC
或任何你可以支配的)
如果你有预定义的样本数 n
那么
dt=T/double(n-1);
此处示例输出 (n=image width
):
如果你还需要周期数,那么在 angle
cut while
循环中添加计数器增量还有你的零点(但如果采样率太小或者你需要高你需要插入真正的零位置的精度)。
我想实现正弦波在 5
秒内从 8Hz
逐渐变为 2Hz
:
此波形是在 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 */
}
这是对这个问题的落后思维,导致程序疯狂。更不用说单个波不会是正弦波,因为频率在变化(它们会轻微失真),这是您的发生器无法实现的,而且结束信号在 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]
是您要用来对信号进行采样的时间步长。如果您在 Real Time 中生成它并输出到 real HW,您可以使用timer
或直接测量时间(使用performance counters
在 Windows 或通过RDTSC
或任何你可以支配的)如果你有预定义的样本数
n
那么dt=T/double(n-1);
此处示例输出 (
n=image width
):如果你还需要周期数,那么在
angle
cutwhile
循环中添加计数器增量还有你的零点(但如果采样率太小或者你需要高你需要插入真正的零位置的精度)。