我有一个实现可以以不同速度读取的音频流的类(包括反向和快速变化/“抓取”)......我对读取部分使用线性插值,一切都很好......
但是现在我也想实现以不同的速度写入流,这需要我实现一种“反向插值”,即推导出输入样本向量 Z,用向量 Y 插值将产生输出 X(我'我试着写)..
我已经设法在恒定速度下做到这一点,但对不同速度(例如加速或减速)进行概括证明更复杂..
我想这个问题已经被反复解决了,但我似乎无法在网上找到很多线索,所以我的具体问题是是否有人听说过这个问题并可以为我指出正确的方向(或者,更好的是,给我看一个解决方案 :)
谢谢!
最佳答案
我不会称它为“反向插值”,因为它不存在(我的第一个想法是你在谈论外推!)。您正在做的仍然是简单的插值,只是以不均匀的速率。
插值:在已知值之间找到一个值
外推:找到一个超出已知值的值
对恒定速率进行插值确实比“在已知值之间找到一个值”的一般任务要简单得多。我提出2个解决方案。
1)插值到一个显着更高的速率,然后只是子采样到最近的一个(尝试添加抖动)
2)解决一般问题:对于每个点,您需要使用相邻的 N 个点并为它们拟合一个 N-1 阶多项式。
让我解释一下最后一个。
对于每个输出样本,使用前 2 个和后 2 个输入样本。在单位时间尺度上将它们称为 S0 到 S3(乘以稍后的采样周期),并且您从时间 0 到 1 进行插值。Y 是您的输出,Y' 是斜率。
Y 将根据该多项式及其微分(斜率)计算
Y(t) = At^3 + Bt^2 + Ct + D
Y'(t) = 3At^2 + 2Bt + C
约束(两侧端点的值和斜率)
Y(0) = S1
Y'(0) = (S2-S0)/2
Y(1) = S2
Y'(1) = (S3-S1)/2
展开多项式
Y(0) = D
Y'(0) = C
Y(1) = A+B+C+D
Y'(1) = 3A+2B+C
插入 sample
D = S1
C = (S2-S0)/2
A + B = S2 - C - D
3A+2B = (S3-S1)/2 - C
最后 2 个是易于求解的方程组。从第二个中减去第一个的 2 倍。
3A+2B - 2(A+B)= (S3-S1)/2 - C - 2(S2 - C - D)
A = (S3-S1)/2 + C - 2(S2 - D)
那么 B 是
B = S2 - A - C - D
一旦有了 A、B、C 和 D,您就可以在多项式中输入时间“t”,以在已知样本之间找到样本值。
对每个输出样本重复,如果下一个输出样本仍在相同的 2 个输入样本之间,则重复使用 A、B、C&D。每次计算 t 类似于 Bresenham 的线算法,只是每次前进的量不同。
关于audio - 反向插值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19349093/