首先,确保您的信号通过合适的低通滤波器被限制在 4kHz 范围内,这样就不会出现混叠问题。其次,如果您不是在寻找“完全”准确的样本,那么请使用一个相当简单的重新采样函数,例如截断的 sinc 插值器......
模拟重建的方程是:
xr(t)=∑nx[n]sinc((t−nT1)/T1)
该数学推导表示模拟低通重构滤波器的输出,该滤波器由脉冲序列驱动,该脉冲序列由从以原始采样率 (44100 Hz) 采样 x(t) 获得的 x[n] 样本加权,并且T1是那个采样周期。sinc(x) 是 sin(x)/x 的缩写
你重新采样这个重构信号的方程是:
x[m]=∑nx[n]sinc((mT2−nT1)/T1)
对于 m=0,1,...,以新速率 (8000 hz) 下采样信号的长度和T2是它的时期。必须为每个输出 m 值计算 n 的内部总和,这是生成重采样信号 x[m] 所必需的
尽管上面的公式在数学上描述了采样率转换,但有时最好使用简单的技术,而不是多速率滤波器组的多相实现,例如如下所示的线性插值:假设原始信号将有足够的带宽限制,您将得到比较满意的结果。
注意:您提到了不成比例的播放时间,我不确定确切的原因,但由于分数转换,您可能在输出中有 1 个过量或 1 个缺失样本。考虑在 44100 赫兹时长度为 10.000 的原始信号,并将其转换为 8000 的速率将产生 1814.058 个样本,这些样本可能会四舍五入到 1814。有很多技巧可以克服这个实际问题,具体取决于您的整体架构。但我不确定这是否会在短时间的播放中造成明显的延迟。
下面是简单线性插值器的 matlab 代码,您可以从绘制的频谱中看到,几乎没有错误,这是因为您实际上是在对已经低通的信号进行下采样(首先,您拥有比必要更多的信息)
T1 = 1/44100;
T2 = 1/8000;
t1 = [0:T1:2];
t2 = [0:T2:2];
x = sin(2*pi*1451*t1)+0.21*cos(2*pi*853*t1); % generate a test signal
figure,stem(x); axis([ 1 length(x) -1.3 1.3]); % sufficiently low pass
L = 80;
M = 441;
K = M/L;
xd = zeros(1,floor(length(x)/K));
%x = filter(fir1(64,1/(2*K)),1,x); % optionally band limit x to avoid aliasing otherwise linear interpolator will be insufficient.
for n=1:length(xd) % you can vectorize this code for buffered processing
m = K*n;
mi = floor(m);
d = m - mi;
xd(n) = x(mi+1)*(d) + (1-d)*x(mi); % simplest linear interpolator
end
figure,stem(xd); axis([ 1 length(xd) -1.43 1.43]);
figure,plot(abs(fft(x,1024)));
figure,plot(abs(fft(xd,1024)));
% FINALY PLAY THEM to hear resulting signal
sound(x,44100,16);
sound(xd,8000,16); % seems OK