0
$\begingroup$

I'm working on adding MFCCs to my kNN classifier. Originally my kNN classifier was using the zero-crossing-rate, centroid, bandwidth, skew, kurtosis. This was about 80% accurate for drum tracks using identical instrumental to the data it was trained with (there were at least 10+ training tracks for each part of my musical piece, ie. bass kick, snare, hihat, one of each were used in a 10 second clip repeating each 3 times).

Now I added 12 MFCCs (dropping the 0th) to this list of 5 features, and my kNN classifier has broke.

What am I doing wrong? Below is the part of my code, I have edited out the repetitive parts for extracting features, they are identical to the first one.

snareDirectory = ['/Snares/'];
snareFileList = getFileNames(snareDirectory ,'wav');

kickDirectory = ['/Kicks/'];
kickFileList = getFileNames(kickDirectory ,'wav');

HiHatDirectory = ['/Hihats/'];
HiHatFileList = getFileNames(HiHatDirectory ,'wav');

currentFrameIndex=1;
for i=1:size(snareFileList,2)
    [x,fs]=wavread([snareDirectory snareFileList{i}]);
    frameSize=.1*fs;
    currentFrame=x(1:frameSize);
    featuresSnare(i,1)=zcr(currentFrame);
    [centroid,bandwidth,skew,kurtosis]=spectralMoments(currentFrame,fs,8192);
    featuresSnare(i,2:5)=[centroid,bandwidth,skew,kurtosis];

    [mfceps] = mfcc(currentFrame ,fs)' ; %note the transpose operator!
    delta_mfceps = mfceps - [zeros(1,size(mfceps,2)); mfceps(1:end-1,:)]; %first delta
    % Calculate the mean and std of the MFCCs, MFCC-deltas.
    MFCC_mean(currentFrameIndex,:) = mean(mfceps);
    MFCC_std(currentFrameIndex,:) = std(mfceps);
    MFCC_delta_mean (currentFrameIndex,:)= mean(delta_mfceps);
    featuresSnare(i,6:17)=MFCC_mean(currentFrameIndex,2:13);
end

for i=1:size(kickFileList,2)
    {...}
end

for i=1:size(HiHatFileList,2)
   {...}
end

[trainingFeatures(:,1:5),mf,sf]=scale([featuresSnare(:,1:5); featuresKick(:,1:5); featuresHiHat(:,1:5)]);
[trainingFeatures(:,6:17),mf,sf]=scale([featuresSnare(:,6:17); featuresKick(:,6:17); featuresHiHat(:,6:17)]);
labels=[[ones(size(featuresSnare,1),1) zeros(size(featuresSnare,1),1), zeros(size(featuresSnare,1),1)]; [zeros(size(featuresKick,1),1) ones(size(featuresKick,1),1) zeros(size(featuresKick,1),1)]; [zeros(size(featuresHiHat,1),1) zeros(size(featuresHiHat,1),1) ones(size(featuresHiHat,1),1)]];
model_snare = knn(17,3,1,trainingFeatures,labels);  

[y,fs]=wavread('together.wav');
framesize=.1*round(fs); %.1 second
features=zeros(floor(size(y,1)/framesize),5);

for i=1:floor(size(y,1)/framesize);
    currentFrame=y(i*framesize:i*framesize+frameSize-1);
    features(i,1)=zcr(currentFrame);
    [centroid,bandwidth,skew,kurtosis]=spectralMoments(currentFrame,fs,8192);
    features(i,2:5)=[centroid,bandwidth,skew,kurtosis];

    currentFrameIndex=i;
    [mfceps] = mfcc(currentFrame ,fs)' ; %note the transpose operator!
    delta_mfceps = mfceps - [zeros(1,size(mfceps,2)); mfceps(1:end-1,:)]; %first delta
    % Calculate the mean and std of the MFCCs, MFCC-deltas.
    MFCC_mean(currentFrameIndex,:) = mean(mfceps);
    MFCC_std(currentFrameIndex,:) = std(mfceps);
    MFCC_delta_mean (currentFrameIndex,:)= mean(delta_mfceps);
    MFCC_delta_std(currentFrameIndex,:)= std(delta_mfceps);
    features(i,6:17)=MFCC_mean(currentFrameIndex,2:13);
end

soundsc(y,fs)
featuresScaled(1:5) = rescale(features(1:5),mf,sf); 
featuresScaled(6:17)=rescale(features(6:17),mf,sf);

[voting,model_output]=knnfwd(model_snare , featuresScaled );
output = zeros(size(model_output,1),3);
output(find(model_output==1),1)=1;
output(find(model_output==2),2)=1;
output(find(model_output==3),3)=1;

I have read this post https://stackoverflow.com/questions/16546524/how-to-use-mfcc-vectors-for-classifying-a-single-audio-file which is close to what I am trying to figure out but in my eyes I am already doing what the answer is saying.

Any help is greatly appreciated, I have spent several days trying to figure this out and have only resulted in creating a model that is 50% less accurate than without the MFCCs.

Thanks in advance!

-scarlson

$\endgroup$
  • $\begingroup$ Are you really only using one frame of MFCCs? That's what it appears your first loop is doing. Why not at least calculate them over the full recording? $\endgroup$ – Peter K. Oct 21 '15 at 2:26
  • $\begingroup$ Well the samples I am using are only clips of just the kick of the drum for example. which is no more than a 1/2 a second to two seconds long. I see where you may be going here I think. should I be taking the mffcs for the training clips over the same length window as I am for the actual data I'm trying to classify? I think I just answered my own question, but I'm new enough to this that I'm not sure. $\endgroup$ – scarlso9 Oct 21 '15 at 2:47
  • $\begingroup$ I did this, and since my training clips are short most of them saw no change, but some of them did. am I going about this wrong? thanks again. $\endgroup$ – scarlso9 Oct 21 '15 at 5:29
  • $\begingroup$ Any help would be awesome I still haven't figured this out. I know about MFCCs and knn classification but it's just I've never used them together like this. Any help is appreciated! $\endgroup$ – scarlso9 Oct 23 '15 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.