b@13
|
1 function integratedloudness = loudness(signal, fs)
|
brecht@14
|
2 %LOUDNESS returns loudness level (scalar) according to EBU R 128
|
b@13
|
3 % specification and accepts an audio file vector (vector) and a sampling
|
b@13
|
4 % rate (fs).
|
b@13
|
5 %
|
b@13
|
6 % by Brecht De Man on Monday 25 April 2016
|
b@13
|
7
|
b@13
|
8 nrSamples = size(signal,1);
|
b@13
|
9 nrChannels = size(signal,2);
|
b@13
|
10
|
b@13
|
11 % loudness prefilters (functions below this one)
|
b@13
|
12 [b1, a1] = loudnessprefilter1(fs);
|
b@13
|
13 [b2, a2] = loudnessprefilter2(fs);
|
b@13
|
14
|
b@13
|
15 % Weighting coefficients with channel format [L, R, C, Ls, Rs]
|
b@13
|
16 G = [1.0 1.0 1.0 1.41 1.41 0.0 0.0]; % temporary
|
b@13
|
17
|
b@13
|
18 % Apply pre-filter
|
b@13
|
19 signal_intermediate = filter(b1, a1, signal);
|
b@13
|
20 signal_filtered = filter(b2, a2, signal_intermediate);
|
b@13
|
21
|
b@13
|
22 % Gating block interval duration
|
b@13
|
23 T_g = .4; % seconds
|
b@13
|
24 Gamma_a = -70.0; % absolute threshold: -70 LKFS
|
b@13
|
25 overlap = 0.75; % relative overlap (0.0 - 1.0)
|
b@13
|
26 step = 1 - overlap;
|
b@13
|
27
|
b@13
|
28 T = nrSamples/fs; % length of measurement interval in seconds
|
b@13
|
29 j_range = 1:floor((T-T_g)/(T_g*step)+1);
|
b@13
|
30 z = zeros(nrChannels, max(size(j_range)));
|
b@13
|
31 for i = 1:nrChannels % for each channel i
|
b@13
|
32 for j=j_range % for each window j
|
b@13
|
33 lbound = floor(fs*T_g*(j-1)*step+1);
|
b@13
|
34 hbound = floor(fs*T_g*((j-1)*step+1));
|
b@13
|
35 z(i,j) = (1/(T_g*fs))*sum(signal_filtered(lbound:hbound, i).^2);
|
b@13
|
36 end
|
b@13
|
37 end
|
b@13
|
38
|
b@13
|
39 G_current = G(1:nrChannels); % discard weighting coefficients G_i unused channels
|
b@13
|
40 l = zeros(size(j_range,1), 1);
|
b@13
|
41 for j=j_range % for each window j
|
b@13
|
42 l(j) = -.691 + 10.0*log10(sum(G_current*z(:,j)));
|
b@13
|
43 end
|
b@13
|
44
|
b@13
|
45 % throw out anything below absolute threshold:
|
b@13
|
46 z_avg = mean(z(:,l>Gamma_a),2);
|
b@13
|
47 Gamma_r = -.691 + 10.0*log10(G_current*z_avg) - 10.0;
|
b@13
|
48 % throw out anything below relative threshold:
|
b@13
|
49 z_avg = mean(z(:,l>Gamma_r),2);
|
b@13
|
50 integratedloudness = -.691 + 10.0*log10(G_current*z_avg);
|
b@13
|
51
|
b@13
|
52 end
|
b@13
|
53
|
b@13
|
54 function [b, a] = loudnessprefilter1(fs)
|
b@13
|
55 % LOUDNESSPREFILTER1 calculates coefficients for the first prefilter
|
b@13
|
56 % specified in EBU R 128.
|
b@13
|
57
|
b@13
|
58 % pre-filter 1 coefficients
|
b@13
|
59 f0 = 1681.9744509555319;
|
brecht@14
|
60 G = 3.99984385397334;
|
b@13
|
61 Q = 0.7071752369554193;
|
b@13
|
62 K = tan(pi * f0 / fs);
|
b@13
|
63 Vh = 10.0^(G / 20.0); % TODO: precompute
|
b@13
|
64 Vb = Vh^0.499666774155; % TODO: precompute
|
b@13
|
65 a0_ = 1.0 + K / Q + K * K;
|
b@13
|
66 b0 = (Vh + Vb * K / Q + K * K) / a0_;
|
b@13
|
67 b1 = 2.0 * (K * K - Vh) / a0_;
|
b@13
|
68 b2 = (Vh - Vb * K / Q + K * K) / a0_;
|
b@13
|
69 a0 = 1.0;
|
b@13
|
70 a1 = 2.0 * (K * K - 1.0) / a0_;
|
b@13
|
71 a2 = (1.0 - K / Q + K * K) / a0_;
|
b@13
|
72
|
b@13
|
73 b = [b0, b1, b2];
|
b@13
|
74 a = [a0, a1, a2];
|
b@13
|
75
|
b@13
|
76 % DEBUG
|
b@13
|
77 %fvtool(b,a,'fs',fs);
|
b@13
|
78
|
b@13
|
79 end
|
b@13
|
80
|
b@13
|
81 function [b, a] = loudnessprefilter2(fs)
|
b@13
|
82 % LOUDNESSPREFILTER2 calculates coefficients for the second prefilter
|
b@13
|
83 % specified in EBU R 128.
|
b@13
|
84
|
b@13
|
85 % pre-filter 2 coefficients
|
b@13
|
86 f0 = 38.13547087613982;
|
b@13
|
87 Q = 0.5003270373253953;
|
b@13
|
88 K = tan(pi * f0 / fs);
|
b@13
|
89 a0 = 1.0;
|
b@13
|
90 a1 = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
|
b@13
|
91 a2 = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
|
b@13
|
92 b0 = 1.0;
|
b@13
|
93 b1 = -2.0;
|
b@13
|
94 b2 = 1.0;
|
b@13
|
95
|
b@13
|
96 b = [b0, b1, b2];
|
b@13
|
97 a = [a0, a1, a2];
|
b@13
|
98
|
b@13
|
99 % DEBUG
|
b@13
|
100 %fvtool(b,a,'fs',fs);
|
b@13
|
101
|
b@13
|
102 end
|