b@0
|
1 function lkfs = loudness_itu(x, fs)
|
b@0
|
2 %LOUDNESS_ITU compute loudness (LKFS) based on ITU-R BS.1770-2
|
b@0
|
3 % LOUDNESS_ITU(x, fs, mode) compute loudness based on ITU-R BS.1770-2
|
b@0
|
4 % specification. x is an input signal (mono/stereo/5.1ch) with sampling
|
b@0
|
5 % frequency fs.
|
b@0
|
6 %
|
b@0
|
7 % Input signal has to be either in mono (M), stereo (L and R), or
|
b@0
|
8 % 5.1ch(L, R, C, LFE, Ls, and Rs) in respective channel order.
|
b@0
|
9 %
|
b@0
|
10 % Example: loudness calculation
|
b@0
|
11 % [x,fs] = wavread('soundfile.wav');
|
b@0
|
12 % lkfs = LOUDNESS_ITU(x, fs);
|
b@0
|
13 %
|
b@0
|
14 % 2012-01-06 MARUI Atsushi
|
b@0
|
15
|
b@0
|
16 % constants
|
b@0
|
17 blockSize = 400; % in ms
|
b@0
|
18 overlapSize = 0.75; % in percentage
|
b@0
|
19 channelWeights = [1 1 1 0 sqrt(2) sqrt(2)]; % in L, R, C, LFE, Ls, Rs order
|
b@0
|
20 absoluteThreshold = -70; % in dB
|
b@0
|
21 relativeThreshold = -10; % in dB
|
b@0
|
22
|
b@0
|
23 % preparation
|
b@0
|
24 if size(x,1)~=length(x)
|
b@0
|
25 x = x';
|
b@0
|
26 end
|
b@0
|
27 numch = size(x,2);
|
b@0
|
28
|
b@0
|
29 if fs~=48000
|
b@0
|
30 x = resample(x, 48000, fs);
|
b@0
|
31 fs = 48000;
|
b@0
|
32 end
|
b@0
|
33
|
b@0
|
34 switch(numch)
|
b@0
|
35 case 5
|
b@0
|
36 chwat = channelWeights([1 2 3 5 6]);
|
b@0
|
37 otherwise
|
b@0
|
38 chwat = channelWeights(1:numch);
|
b@0
|
39 end
|
b@0
|
40
|
b@0
|
41 % K-filter
|
b@0
|
42 B1 = [
|
b@0
|
43 1.53512485958697
|
b@0
|
44 -2.69169618940638
|
b@0
|
45 1.19839281085285
|
b@0
|
46 ];
|
b@0
|
47 A1 = [
|
b@0
|
48 1.0
|
b@0
|
49 -1.69065929318241
|
b@0
|
50 0.73248077421585
|
b@0
|
51 ];
|
b@0
|
52 B2 = [
|
b@0
|
53 1.0
|
b@0
|
54 -2.0
|
b@0
|
55 1.0
|
b@0
|
56 ];
|
b@0
|
57 A2 = [
|
b@0
|
58 1.0
|
b@0
|
59 -1.99004745483398
|
b@0
|
60 0.99007225036621
|
b@0
|
61 ];
|
b@0
|
62 y = filter(B2,A2,filter(B1,A1,x));
|
b@0
|
63
|
b@0
|
64 % Mean square
|
b@0
|
65 numBlock = ceil(length(y)/ blockSize) + 1;
|
b@0
|
66 yy = zeros(numBlock * blockSize, numch);
|
b@0
|
67 yy(1:length(y),:) = y;
|
b@0
|
68 j = 0:(length(y) - blockSize)/(blockSize * (1-overlapSize));
|
b@0
|
69 z = zeros(length(j), numch);
|
b@0
|
70 for n1 = 1:length(j)
|
b@0
|
71 yyy = yy(blockSize*j(n1)*(1-overlapSize)+1:blockSize*(j(n1)*(1-overlapSize)+1)+1,:);
|
b@0
|
72 z(n1,:) = sum(yyy .^ 2) / blockSize;
|
b@0
|
73 end
|
b@0
|
74 l = -0.691 + 10*log10(sum(repmat(chwat,length(z),1) .* z, 2));
|
b@0
|
75
|
b@0
|
76 % Gating (absolute)
|
b@0
|
77 Jg = l > absoluteThreshold;
|
b@0
|
78 zz = repmat(channelWeights(1:numch),length(z),1) .* z;
|
b@0
|
79 L_KG = -0.691 + 10*log10(chwat * sum(zz(Jg,:), 1)' / sum(Jg));
|
b@0
|
80
|
b@0
|
81 % Gating (relative)
|
b@0
|
82 Gamma_r = L_KG + relativeThreshold;
|
b@0
|
83 Jg = l > Gamma_r;
|
b@0
|
84 L_KG = -0.691 + 10*log10(chwat * sum(zz(Jg,:), 1)' / sum(Jg));
|
b@0
|
85
|
b@0
|
86 % OPTIONAL: draw pretty figure
|
b@0
|
87 if false
|
b@0
|
88 t = (blockSize*(j*(1-overlapSize)+1)+1)/fs;
|
b@0
|
89 h = plot(t, l, 'color', [.5 .5 .5]);
|
b@0
|
90 hold on;
|
b@0
|
91 h = line([t(1) t(end)], [L_KG L_KG]);
|
b@0
|
92 set(h, 'Color', 'b');
|
b@0
|
93 set(h, 'LineStyle', '--');
|
b@0
|
94 set(h, 'LineWidth', 1);
|
b@0
|
95 h = line([t(1) t(end)], [Gamma_r Gamma_r]);
|
b@0
|
96 set(h, 'Color', 'b');
|
b@0
|
97 set(h, 'LineStyle', ':');
|
b@0
|
98 set(gca, 'Xlim', [t(1) t(end)]);
|
b@0
|
99 hold off;
|
b@0
|
100 legend({'momentary', 'integrated', 'relative gate'});
|
b@0
|
101 end
|
b@0
|
102
|
b@0
|
103 % output
|
b@0
|
104 lkfs = L_KG; |