使用线性插值实现sample rate转换。
function output = simpleResample(input, inputfs, outputfs)
inputLen = length(input(:, 1));
outputLen = floor(inputLen * outputfs / inputfs);
output = zeros(outputLen, 1);
timeStep = inputfs / outputfs;
curTime = 1;
integer = 0;
frac = 0;
for i = 1:1:outputLen
integer = floor(curTime)
frac = curTime - floor(curTime);
if integer + 1 < inputLen
output(i, 1) = input(integer, 1) + frac * ( input(integer + 1, 1) - input(integer, 1));
end
curTime = curTime + timeStep;
end
win = fir1(13, 0.6, 'low')
output = filter(win, 1, output);
end
使用sinc window实现sample rate转换,可能sinc window 没有设计好,效果不是很好。
function ouput = myResample( input, inputfs, outputfs)
inputLen = length(input(:, 1));
outputLen = floor(inputLen * outputfs / inputfs);
output = zeros(outputLen, 1);
timeStep = inputfs / outputfs;
factor = outputfs / inputfs;
L = 8;%entries per zero-crossing
Nz = 7;%number of zero-crossing
winLen = 2 * L * Nz + 1;
filterInt = 4;
filterLen = floor(winLen / filterInt);
%generate sinc window function
for i = ceil(-winLen/2) :1 : floor(winLen/2)
winIdx = i + floor(winLen/2) + 1;
tmp = pi * double(i) / L;
if i == 0
win(winIdx) = 1;
else
win(winIdx = sin(tmp)/tmp;
end
end
win = win * 0.6;
%add delay before input
delaySample = floor(filterLen / 2);
delayInput = zeros(inputLen + delaySample, 1);
delayInput(delaySample + 1 : inputLen + delaySample, 1) = input(:, 1);
curTime = 1;
t = 1;
pos = 1;
for t = 1:1:outputLen
integer = floor(curTime)
frac = curTime - floor(curTime);
filtOfsset = floor(frac * filterInt);
if integer + filtLen - 1 < inputLen + delaySample
pos = integer;
winStart = floor(winLen / 2 - filterInt * filterLen / 2) - 1;
winEnd = floor(winLen /2 + filterInt * filterLen / 2);
%filter by sinc window
for j = winStart : 1 : winEnd
if j - filtOffset < 1
winCoeff = 0;
else
winCoeff = win(j - filtOffset);
end
output(t, 1) = output(t, 1) + winCoeff * delayInput(pos, 1);
pos = pos + 1;
end
end
curTime = curTime + timeStep;
end
end