annotate aux/loudness.m @ 15:24be5e9ce25b tip

Update README
author Brecht De Man <brecht.deman@bcu.ac.uk>
date Thu, 20 Sep 2018 12:23:20 +0200
parents f187d96b6c81
children
rev   line source
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