-
Notifications
You must be signed in to change notification settings - Fork 1
/
cal_mfcc.m
161 lines (120 loc) · 4.31 KB
/
cal_mfcc.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
function MFCCoeffs = cal_mfcc(x,no_frames,fs,samples_in_1_frame,samples_in_overlap)
%==============================================================================
% MFCC CALCULATIONS INFORMATION
% We divide the time domain signal into Frames of 25 ms == 200 SAMPLES
% We take the next frame at 10ms = 80 samples and so on. (Next at multiples
% of 80)
% We have neglected 40 values (5ms signal) to have integer # of frames
% Then TOTAL NUM OF FRAMES REQUIRED is 44
%================================================================================
s=cell(1,no_frames); % cell data structure to store 44 frames' data
periodogram=cell(1,no_frames);
freqs=cell(1,no_frames); % holds the fourier of s
h=hamming(samples_in_1_frame); %creates hamming window of length samples_in_1_frame
n=(1:samples_in_1_frame)/fs; % to plot s{i} against
n=n';
w=fs*(0:99)/samples_in_1_frame; % frequency axis for EACH FRAME to plot against (if needed)
w=w';
for i=1:no_frames
s{i}=x((samples_in_overlap*(i-1)+1):(samples_in_1_frame+samples_in_overlap*(i-1)));
s{i}=s{i}.*h; % Multiplying Hamming window so that the frame is Hamming like smooth
% take fourier transform
freqs{i}=fft(s{i});
freqs{i}=freqs{i}(1:100);
% Now calculate Periodogram based Power Estimate
periodogram{i}=((abs(freqs{i}).^2)/100);
%*% jaffa=[jaffa s{i}']; %For concatenating frames
end
% s{i} are the frames calculated Hamming approximated!
%=========COMPUTING MEL BANK========================================
% CHoose lower freq as 0.8Hz and max as 400Hz
melMin=1125*log(1+0.8/700);
melMax=1125*log(1+400/700);
m=linspace(melMin,melMax,10);
%Convert these back to normal scale freq in h(i)
h=zeros(1,10);
for i=1:10
h(i)=700*(exp(m(i)/1125)-1);
end
w=fs*(0:99)/samples_in_1_frame; % frequency axis for EACH FRAME to plot against (if needed)
w=w';
N=100; %size of fourier transform of each frame
FilterBank=cell(8,1);
figure('name','8 COMPONENT MEL-FILTER BANK GENERATED');
for j=2:9
filterTemp=zeros(100,1);
fofj=h(j);
fofjp1=h(j+1);
for i=1:100
if j~=1
fofjm1=h(j-1);
if w(i)< fofjm1
filterTemp(i)=0;
elseif w(i)<= fofj
filterTemp(i)= (w(i)-fofjm1)/(fofj-fofjm1);
elseif w(i)<= fofjp1
filterTemp(i)=(fofjp1-w(i))/(fofjp1-fofj);
elseif w(i)>fofjp1
filterTemp(i)=0;
end
end
if j==1
if w(i)<= fofjp1
filterTemp(i)=(fofjp1-w(i))/(fofjp1-fofj);
elseif w(i)>fofjp1
filterTemp(i)=0;
end
end
end
FilterBank{j-1}=filterTemp;
hold on;
plot(w,filterTemp);
end
xlabel('Frequency (Hz)');
ylabel('Amplitude');
title('8 component Mel-Filter Bank in frequency: 2 Hz to 400 HZ');
xlim([0 500]);
% NOW WE HAVE CALCULATED THE 13 filtered MEL BANK STARTING AT 0 Hz ENDING
% at 500hz
%=== NOW CALCULATE FILTERBANK ENERGIES ====
filterbankEnergies=cell(no_frames,1);
temp=zeros(100,1);
for j=1:no_frames
filterbankTemp=zeros(8,1);
for i=1:8
temp=periodogram{j}.*FilterBank{i};
filterbankTemp(i)=sum(temp);
end
filterbankEnergies{j}=filterbankTemp;
end
%==AWESOME!! Now we have filterbank energies calculated in
%filterbankEnergies cell data structure
%Now calculate log filterbank energies
logFilterEnergies=cell(no_frames,1);
for i=1:no_frames
logFilterEnergies{i}=log(abs(filterbankEnergies{i}));
end
% BUT INCASE log(0)=-inf WE WILL **** UP! SO If -inf found, replace by
% large neg number
tempvector=zeros(8,1);
for tempi=1:no_frames
tempvector=logFilterEnergies{tempi};
for tempj=1:8
if tempvector(tempj,1)==-inf
tempvector(tempj,1)=-10000; % SET THIS VALUE APPROPRIATELY
end
end
logFilterEnergies{tempi}=tempvector;
tempvector=zeros(8,1);
end
% done
%!!!!!! NOW FOR THE FINAL CALCULATION OF CEPSTRAL MFCC COEFFICIENTS
MFCCoeffs=cell(no_frames,1);
for i=1:no_frames
MFCCoeffs{i}=zeros(8,1);
end
append=zeros(1,1);
for i=1:no_frames
MFCCoeffs{i}=dct(logFilterEnergies{i});
append=[append MFCCoeffs{i}']; % appended MFCC coefficients
end