So, I'm working with the filter banks used in Mp3, in Matlab. I am obtaining quite a huge distortion in the output and I don't really know whether I'm making something wrong.
I've reviewed the literature and I'd say I'm making it properly, so I don't really understand what I'm making wrong.
So I'm basing the work on a filter with 512 coefficients that can be found on page 9-13, here: https://www.mp3-tech.org/programmer/docs/jacaba_main.pdf (I think it comes from a standard so no big deal there, I guess).
I want to make a filter bank with 32 branches. I want to, based on that Low Pass filter prototype, calculate the 32 branches that will cover the entire bandwidth, so I make:
(note "h" is the variable with the filter coefficients)
branches=32;
hh=zeros(branches-1,length(h));
n=0:511;
for k=0:1:branches-1
hh(k+1,:)=h.*cos(((2*k+1)*pi*(n-16))/(2*32));
end
That one for the generation of the analysis filters coefficients and the following one for the synthesis filters:
branches=32;
hh=zeros(branches-1,length(h));
n=0:511;
for k=0:1:branches-1
hh(k+1,:)=h.*cos(((2*k+1)*pi*(n+16))/(2*32));
end
As per the way of applying the filters to the input signal and to reconstruct the output signal:
yy=zeros(branches,floor(length(wav_in)/32)+1)
for k=1:1:branches
yy(k,:)=decimate(filter(hh(k,:),1,wav_in),branches);
end
This will provide a matrix with all the outputs of the shifted analysis filters (yy
).
Now, in order to reconstruct the signal, with the synthesis filters: (Note it's a different function so we will not have problems with the variables names)
yy = zeros(1,length(xd(1,:))*32)
for k=1:1:branches
yy=yy+(filter(hh(k,:),1,upsample(xd(k,:),branches)));
end
The filter responses look good (it seems like that to me, at least):
If I use as an input a 1 kHz tone, I have:
The output is "After". As you can see the signal is very distorted. In general, I am following the approach in "How sound is processed in MP3 player?" by T. Dutoit and N. Moreau.
I think it is not working and honestly, I don't have a single clue on what I'm doing wrong. (Maybe how I'm applying the filter banks?).
cos(((((2*k+1)*pi*(n-16))/(2*32))))
is plain bad code. Same goes for things like doing a convolution of complicated expressions just to get its length. The convolution of two sequences has a defined length, and there's no reason to actually first upsample something to a defined length, and then convolve it with something of a defined length, just to calculatelength()
of that. I'll have to ask you to make your code acceptably well-written before asking about it. $\endgroup$