annotate _misc/featureextraction/.svn/text-base/mychroma.m.svn-base @ 9:4ea6619cb3f5 tip

removed log files
author matthiasm
date Fri, 11 Apr 2014 15:55:11 +0100
parents b5b38998ef3b
children
rev   line source
matthiasm@8 1 function [chromagram,t,salience] = ...
matthiasm@8 2 mychroma(filename, nBins, fmin, used_fs, fracofsecond, calcu)
matthiasm@8 3
matthiasm@8 4 if isempty(nBins)
matthiasm@8 5 nBins = 3;
matthiasm@8 6 end
matthiasm@8 7 midbin = ceil(nBins/2);
matthiasm@8 8 if isempty(fmin)
matthiasm@8 9 fmin = 55 * 2^(-7/12-(midbin-1)/12/nBins);
matthiasm@8 10 end
matthiasm@8 11
matthiasm@8 12 if isempty(used_fs)
matthiasm@8 13 used_fs=round(44100/4);
matthiasm@8 14 end
matthiasm@8 15
matthiasm@8 16 hopspersecond = 20;
matthiasm@8 17 nFFT = 2^nextpow2(used_fs/fracofsecond);
matthiasm@8 18 hopsize = used_fs/hopspersecond/nFFT;
matthiasm@8 19 noterange = 61;
matthiasm@8 20 used_instruments = 1:2;
matthiasm@8 21 nInstrument = length(used_instruments);
matthiasm@8 22
matthiasm@8 23 %% load or generate dictionary
matthiasm@8 24 dirc = what('./data');
matthiasm@8 25 dicfilename = ['mydict-' num2str(nBins) '.mat'];
matthiasm@8 26 if ~calcu && any(strcmp(dirc.mat, dicfilename))
matthiasm@8 27 load(['data/' dicfilename])
matthiasm@8 28 else
matthiasm@8 29 % dictionary parameters
matthiasm@8 30 midbin = nBins/2 + .5;
matthiasm@8 31 %hopspersecond = 10;
matthiasm@8 32 secs = .8;
matthiasm@8 33 t = linspace(0,secs,secs*used_fs)';
matthiasm@8 34
matthiasm@8 35 % make note dictionary
matthiasm@8 36 A = zeros(noterange*nBins,nFFT/2,nInstrument);
matthiasm@8 37 for iInstrument = used_instruments
matthiasm@8 38 for iMidiNote = 1:noterange
matthiasm@8 39 for iBin = 1:nBins
matthiasm@8 40 f0 = fmin * 2^((iMidiNote-1)/12 + (iBin-1)/12/nBins);
matthiasm@8 41 %wave = zeros(size(t));
matthiasm@8 42 switch iInstrument
matthiasm@8 43 case 1
matthiasm@8 44 wave = sum([sin(t*2*pi*f0*1) ...
matthiasm@8 45 0.6^1 * sin(t*2*pi*f0*2) ...
matthiasm@8 46 0.6^2 * sin(t*2*pi*f0*3) ...
matthiasm@8 47 0.6^3 * sin(t*2*pi*f0*4)],2);
matthiasm@8 48 case 2
matthiasm@8 49 wave = sin(t*2*pi*f0*1);
matthiasm@8 50 case 3
matthiasm@8 51 wave = sum([...
matthiasm@8 52 0.6^1 * sin(t*2*pi*f0*1/2) ...
matthiasm@8 53 0.6^2 * sin(t*2*pi*f0*1/3) ...
matthiasm@8 54 0.6^3 * sin(t*2*pi*f0*1/4) ...
matthiasm@8 55 0.6^4 * sin(t*2*pi*f0*1/5) ...
matthiasm@8 56 0.6^5 * sin(t*2*pi*f0*1/6) ...
matthiasm@8 57 0.6^6 * sin(t*2*pi*f0*1/7) ...
matthiasm@8 58 0.6^7 * sin(t*2*pi*f0*1/8) ...
matthiasm@8 59 0.6^8 * sin(t*2*pi*f0*1/9)],2);
matthiasm@8 60 end
matthiasm@8 61 fftframes0 = myframefft(wave,nFFT,hopsize,'hamming');
matthiasm@8 62 A(nBins*(iMidiNote-1)+iBin,:,iInstrument) = mean(abs(fftframes0(1:round(nFFT/2),:)),2);
matthiasm@8 63 end
matthiasm@8 64 end
matthiasm@8 65 end
matthiasm@8 66 save(['data/' dicfilename], 'A', 'nFFT', 'hopsize');
matthiasm@8 67 end
matthiasm@8 68
matthiasm@8 69 %% get the fft frames from a wave file
matthiasm@8 70 fprintf(1,'%s\n',filename)
matthiasm@8 71 [audiosize,fs] = wavread(filename,'size');
matthiasm@8 72 chunk_sec = 20;
matthiasm@8 73 nChunk = ceil(audiosize(1)/fs/chunk_sec);
matthiasm@8 74 songframes = [];
matthiasm@8 75 s = [];
matthiasm@8 76 start = 1;
matthiasm@8 77
matthiasm@8 78 for iChunk = 1:nChunk
matthiasm@8 79 samplemin = (iChunk-1) * chunk_sec * fs + 1;
matthiasm@8 80 samplemax = min(audiosize(1), (iChunk * chunk_sec + 1) * fs);
matthiasm@8 81
matthiasm@8 82 audiodata0 = wavread(filename,[samplemin samplemax]);
matthiasm@8 83
matthiasm@8 84 audiodata = resample(mean(audiodata0,2),used_fs,fs,20);
matthiasm@8 85
matthiasm@8 86 songframes0 = myframefft(audiodata,nFFT,hopsize,'hamming');
matthiasm@8 87
matthiasm@8 88 if size(songframes0,2)>=start
matthiasm@8 89 songframes = [songframes(:,1:end-start) abs(songframes0(1:round(nFFT/2),start:end))];
matthiasm@8 90 end
matthiasm@8 91 start = round(hopspersecond/2)+1;
matthiasm@8 92 end
matthiasm@8 93 clear songframes0
matthiasm@8 94 clear audiodata
matthiasm@8 95 clear audiodata0
matthiasm@8 96
matthiasm@8 97 T = size(songframes,2);
matthiasm@8 98 t = (0:T-1)./hopspersecond;
matthiasm@8 99 fprintf(1, '%d different notes, %d frequency bins, %d time frames\n', noterange,nFFT/2, T)
matthiasm@8 100
matthiasm@8 101 simpleS = zeros(noterange*nBins,T, nInstrument+1);
matthiasm@8 102 songframes(isnan(songframes)) = 0;
matthiasm@8 103
matthiasm@8 104 for iInstrument = 1:nInstrument
matthiasm@8 105 At = A(:,:,iInstrument);
matthiasm@8 106 for kFrame = 1:T
matthiasm@8 107 simpleS(:,kFrame,iInstrument) = At * songframes(:,kFrame);
matthiasm@8 108 end
matthiasm@8 109 end
matthiasm@8 110 simpleS(:,:,2) = max(0,conv2(simpleS(:,:,2), ...
matthiasm@8 111 repmat([-1 -1 4 -1 -1]',1,1),'same'));
matthiasm@8 112
matthiasm@8 113 %% add the instruments (i.e. the different partial decay bla)
matthiasm@8 114 %---------------------------------------------------------
matthiasm@8 115 note_s = (simpleS(:,:,1) .* simpleS(:,:,2));
matthiasm@8 116 clear simpleS
matthiasm@8 117
matthiasm@8 118 %% tuning
matthiasm@8 119
matthiasm@8 120 wrapped_s = zeros(nBins,T);
matthiasm@8 121 for iBin = 1:nBins
matthiasm@8 122 wrapped_s(iBin,:) = sum(note_s(iBin:nBins:end,:));
matthiasm@8 123 end
matthiasm@8 124 on_circle = exp(i * ((1:nBins)-midbin)/nBins * 2 * pi);
matthiasm@8 125 complex_tuning = on_circle * wrapped_s;
matthiasm@8 126 smooth_complex_tuning = conv2(complex_tuning,hamming(20*hopspersecond)','same');
matthiasm@8 127 tooflat = angle(mean(smooth_complex_tuning)) / (2 * pi) * nBins;
matthiasm@8 128 tooflat = repmat(tooflat,T,1);
matthiasm@8 129 tuned_s = note_s;
matthiasm@8 130 for iFrame = 1:T
matthiasm@8 131 tuned_s(:,iFrame) = interp1(1:nBins*noterange, note_s(:,iFrame), (1:nBins*noterange) + 1 * tooflat(iFrame),[],0);
matthiasm@8 132 end
matthiasm@8 133
matthiasm@8 134 %% reduce to 1 bin per semitone
matthiasm@8 135 wrapped_tuned_s = reshape(tuned_s,[nBins,noterange*T]);
matthiasm@8 136 wei = rectwin(nBins)';
matthiasm@8 137 reduced = reshape(wei * wrapped_tuned_s,noterange,T);
matthiasm@8 138
matthiasm@8 139 salience.full = s;
matthiasm@8 140 salience.reduced = reduced;
matthiasm@8 141
matthiasm@8 142 %% make chromagram
matthiasm@8 143
matthiasm@8 144 reduced = medfilt1(reduced',9)';
matthiasm@8 145 chromagen = [zeros(12,1) repmat(eye(12),1,5)];
matthiasm@8 146
matthiasm@8 147
matthiasm@8 148 treble_profile = ([0 zeros(1,24) linspace(0,1,6) linspace(1,1,6) ones(1,12) linspace(1,0,6) zeros(1,6)]);
matthiasm@8 149 bass_profile = [0 ones(1,18) linspace(1,0,12) ,zeros(1,noterange-31)];
matthiasm@8 150 wide_profile = max(treble_profile, bass_profile);
matthiasm@8 151
matthiasm@8 152 treble_salience = reduced .* repmat(treble_profile(:),1,T);
matthiasm@8 153 bass_salience = reduced .* repmat(bass_profile(:),1,T);
matthiasm@8 154 wide_salience = reduced .* repmat(wide_profile(:),1,T);
matthiasm@8 155
matthiasm@8 156 bass_chromag = circshift(chromagen * bass_salience,6);
matthiasm@8 157 wide_chromag = circshift(chromagen * wide_salience,6);
matthiasm@8 158
matthiasm@8 159 [peakindex,peakindex]=sort(treble_salience,'descend');
matthiasm@8 160 for iFrame = 1:T
matthiasm@8 161 treble_salience(peakindex(1,iFrame),iFrame) = treble_salience(peakindex(2,iFrame),iFrame);
matthiasm@8 162 end
matthiasm@8 163 treble_chromag = circshift(chromagen * treble_salience,6);
matthiasm@8 164
matthiasm@8 165 chromagram.treble = treble_chromag;
matthiasm@8 166 chromagram.bass = bass_chromag;
matthiasm@8 167 chromagram.wide = wide_chromag;
matthiasm@8 168
matthiasm@8 169 % csvwrite('chr.csv',[ones(25,1) [maxn(circshift(bass_chromag,4));ones(1,size(treble_chromag,2)); maxn(circshift(treble_chromag,4))]]');
matthiasm@8 170 % csvwrite('tuned_s.csv',[maxn(reduced)]');