I've got a project and need to calculate MFCCs. I tried to read some tutorials and then make a MATLAB function but I seem to have wrong answers. I'd like to feed MFCCs to one of the classification model--my choice would probably be NN or SVM. I am going to classify sound samples that either belong to one of many categories or not.
To calculate MFCC, the process currently looks like below:
- Process signal by using pre-emphasis filter:
x = x - 0.95*[0;x(1:N-1)];
- Take windows of 430 samples that overlap by 215 samples (equvalence of ~ 50ms window)
- Apply Hamming window to a segment
- Calculate FFT:
X = fft(x);
Calculate energy excluding the negative frequency part (the second half), therefore I take only frequencies between 0-4kHz
N2 = max([floor(N+1)/2 floor(N/2)+1]); P = 1/N*abs(X(1:N2)).^2;
Get a bank of 40 triangularly shaped filters with centres spread over mel frequency between 20Hz and 4kHz
Apply filters on the vector of energy, sum the vectors and take natural logarithm:
L = log(mfccShapes'*P);
Apply DCT and take13 coefficients:
All_MFCC = cos( (pi/N*((0:N-1) + 0.5)).'*(0:N-1) )'*L; MFCC = All_MFCC(1:13);
I have two problems in calculation of this:
- First, in calculation in the tutorial I have read, the energy is divided by length of the frequency vector. Is that the correct step?
- The second problem is the DCT. I understand that by taking DCT, we calculate cepstrum of the frequency. But I take the DCT on summed and filters energy vectors. I have applied DCT-II, in a vectorized from, and I think it is calculated correctly. The problem is I have always very low negative value of the first coefficient.
Also, the shape of and MFCC of low energy seem to be very similar. I realised that it is similar after I take DCT.
Where is the my mistake in calculation?
Cheers! Celdor
EDIT:
I understand now why the first MFCC coeficient is very low. If I look at DCT II, its first component is just a straight line:
This is equivalent of just summing all energy log coefficients. As all of them are negative, the overall sum becomes very low.