我有一组 75 Hz 的样本,我想以 128 Hz 的频率存储它们。如果是 64 赫兹和 128 赫兹,那非常简单,我只需将所有样本加倍。但是,如果采样率不是彼此的一小部分,那么正确的方法是什么?
最佳答案
当您想避免过滤时,您可以:
将信号处理为一组连接的插值三次曲线
但这一点与使用线性插值相同。如果不了解更多有关您的信号和目的的信息,您将无法构建
valid
系数(不损害信号精度),例如如何在此处构建这种立方外观:在该链接内的项目符号 #3 中是我使用的系数。我认为即使您的目的也足够了,所以您可以尝试一下。如果你想做自定义插值看这里:
创建一个函数,该函数可以从采样开始的给定时间返回信号中的点
所以做类似的事情
double signal(double time);
在哪里
time
是从采样开始的时间,以 [s] 为单位。在此函数中计算您需要访问的 4 个样本。ix = floor(time*75.0);
为您提供曲线起点样本索引。三次方需要 4 个点,一个在曲线之前,一个在曲线之后……所以对于插值三次点
p0,p1,p2,p3
使用 sampleix-1,ix,ix+1,ix+2
.计算三次系数a0,a1,a2,a3
并计算三次曲线参数t
(我使用范围<0,1>
)所以t=(time*75.0); t-=floor(t);
- 绿色 - 实际曲线段
- aqua - 实际曲线段控制点 = 75.0 Hz 样本
- red - 曲线参数插值参数t
- 灰色 - 实际时间
抱歉我忘了画实际的输出信号点应该是绿色和灰色的交点
只需对采样数据执行 for 循环,时间步长为 1/128 秒
类似这样的:
double time,duration=samples*75.0,dt=1.0/128.0; double signal128[???]; for (time=0.0,i=0;time<duration;i++,time+=dt) signal128[i]=signal(time);
samples 是以 75.0 Hz 采样的样本中的输入信号数组大小
[注释]
- for/duration 可以在整数上完成...
- 将信号数据类型更改为您需要的类型
- 内
signal(time)
您需要处理边缘情况(信号的开始和结束) - 因为您在第一个样本之前和最后一个样本之后的信号中没有定义点。您可以复制它们或镜像下一点(镜像更好)。
- 这整个过程可以更改为连续处理而无需缓冲区只需要记住信号中的最后 4 个点,以便您可以在 RT 中执行此操作。粗略地说,您将延迟 2-3 个 75.0 Hz 样本……当您将所有这些放在一起时,您会发现这是一个 FIR 滤波器:)
- 如果您需要保留更多,则首先推导添加更多点...
关于c - 上采样的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26123310/