c - 上采样的正确方法是什么?

标签 c math signal-processing sampling resampling

我有一组 75 Hz 的样本,我想以 128 Hz 的频率存储它们。如果是 64 赫兹和 128 赫兹,那非常简单,我只需将所有样本加倍。但是,如果采样率不是彼此的一小部分,那么正确的方法是什么?

最佳答案

当您想避免过滤时,您可以:

  1. 将信号处理为一组连接的插值三次曲线

    但这一点与使用线性插值相同。如果不了解更多有关您的信号和目的的信息,您将无法构建 valid系数(不损害信号精度),例如如何在此处构建这种立方外观:

    在该链接内的项目符号 #3 中是我使用的系数。我认为即使您的目的也足够了,所以您可以尝试一下。如果你想做自定义插值看这里:

  2. 创建一个函数,该函数可以从采样开始的给定时间返回信号中的点

    所以做类似的事情

    double signal(double time);
    

    在哪里 time是从采样开始的时间,以 [s] 为单位。在此函数中计算您需要访问的 4 个样本。

    ix = floor(time*75.0);
    

    为您提供曲线起点样本索引。三次方需要 4 个点,一个在曲线之前,一个在曲线之后……所以对于插值三次点 p0,p1,p2,p3使用 sample ix-1,ix,ix+1,ix+2 .计算三次系数 a0,a1,a2,a3并计算三次曲线参数t (我使用范围 <0,1> )所以

    t=(time*75.0); t-=floor(t);
    

    enter image description here

    • 绿色 - 实际曲线段
    • aqua - 实际曲线段控制点 = 75.0 Hz 样本
    • red - 曲线参数插值参数t
    • 灰色 - 实际时间

    抱歉我忘了画实际的输出信号点应该是绿色和灰色的交点

  3. 只需对采样数据执行 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/

相关文章:

c - getopt() : Is optarg guaranteed to be non-NULL if optstring contains something like "a:"?

c - 当我收到此消息时如何检测我的编码错误

c - 如何确定 _POSIX_PATH_MAX 的系统值

python - 我需要找到两组横滚角和偏航角之间的角度

c++ - 如何在 C++ 中安全地平均两个无符号整数?

signal-processing - 来自加速度计数据的功率谱密度

python - 使用 FFT 和多项式插值改变人类语音的旋律

c - 带结构前缀的初始化是什么意思?

math - 为什么我们在深度学习中使用对数概率?

python - 为什么我的加窗 sinc 函数具有非线性相位?