Mercurial > hg > ape
changeset 13:22964a1dc292
Accurate EBU R128 / ITU-R BS.1770 loudness calculation; batch resample bash script
author | Brecht De Man <b.deman@qmul.ac.uk> |
---|---|
date | Tue, 26 Apr 2016 14:54:32 +0200 |
parents | 866c5da4d357 |
children | f187d96b6c81 |
files | aux/clipfade.m aux/getLoudness.m aux/loudness.m aux/loudness_itu.m aux/loudness_match.m aux/loudnesstest.m aux/resample aux/stereo2mono.m |
diffstat | 8 files changed, 123 insertions(+), 508 deletions(-) [+] |
line wrap: on
line diff
--- a/aux/clipfade.m Fri Jun 26 20:56:42 2015 +0100 +++ b/aux/clipfade.m Tue Apr 26 14:54:32 2016 +0200 @@ -26,7 +26,7 @@ end for i = 1:length(list) - [audio,fsfile] = audioread([folder slash list(i).name], [starttime*fs+1 endtime*fs]); % read part of file + [audio,fsfile] = audioread([folder slash list(i).name], [floor(starttime*fs)+1 ceil(endtime*fs)]); % read part of file assert(fsfile == fs); % check file has expected sampling rate Nfade = fadetime*fs; % make fade vector (based on sampling rate)
--- a/aux/getLoudness.m Fri Jun 26 20:56:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,344 +0,0 @@ -function result = getloudness( vector, Fs, timescale, plotBOOL ) -%GETLOUDNESS returns loudness levels according to EBU R 128 specification -% Function getLoudness accepts an audio file vector (vector), a sampling -% rate (Fs), a timescale ('M' - Momentary, 'S' - Short, 'I' - Integrated) -% and a boolean of whether or not to plot the results, and returns either a -% scalar for Integrated timescales, or a vector of loudnesses with a -% refresh rate of 10 Hz. -% -% Calling sequence: -% result = getLoudness(vector, Fs, timescale, plotBOOL) - -% % Defining filter coefficients for the pre-filter, according to ITU-R BS.1770-1 -% % Modelling a spherical head -% prefilterBcoeffs = [1.53512485958697, -2.69169618940638, 1.19839281085285]; -% prefilterAcoeffs = [1.0, -1.69065929318241, 0.73248077421585]; -% -% % Defining filter coefficients for the RLB, according to ITU-R BS.1770-1 -% rlbBcoeffs = [1.0, -2.0, 1.0]; -% rlbAcoeffs = [1.0, -1.99004745483398, 0.99007225036621]; - - % MY 44.1kHZ Coefficients - -% prefilterBcoeffs = [1.53093728623786, -2.65120001232265, 1.16732946528280]; -% prefilterAcoeffs = [1.0, -1.66410930225081, 0.711176041448821]; - -% by Pedro Pestana; modified by Brecht De Man - - rlbBcoeffs = [[0.994975383507587;], [-1.98995076701517;], [0.994975383507587;]]; - rlbAcoeffs = [1, -1.98992552008493, 0.989976013945421]; - - % loudness prefilter function below this one (see Pestana 2013) - [prefilterBcoeffs, prefilterAcoeffs] = getloudnessprefilter(10, Fs); - - - % Weighting coefficients with channel format [L, R, C, Ls, Rs] - nrChannels = size(vector,2); - switch nrChannels - case 1, - G = [1.0]; - case 2, - G = [1.0 1.0]; - case 5, - G = [1.0 1.0 1.0 1.41 1.41]; - case 6, - G = [1.0 1.0 1.0 1.41 1.41]; % double check... AES is L,R,C,LFE,Ls,Rs - otherwise, - fprintf('Unsuported number of channels\n'); - end - - pfVector = filter(prefilterBcoeffs, prefilterAcoeffs, vector); %Apply pre-filter - rlbVector = filter(rlbBcoeffs, rlbAcoeffs, pfVector);% Apply RLB filter - vectorSquared = rlbVector.^2; - - switch timescale - case 'M' - % MODE: MOMENTARY - winDur = 400; % window time in miliseconds - winSize = Fs*winDur/1000; % window duration in samples - olapSize = Fs*100/1000; % not specified - maxI = floor( length(vector)/olapSize - winSize/olapSize + 1); % number of iterations - for i = 1:maxI - blockEnergy(i,:) = sum( vectorSquared( (i-1)*olapSize+1 : (i-1)*olapSize+winSize ,:) )./winSize; - time(i) = (i*olapSize)/Fs; - end - gTimesZ = bsxfun(@times, blockEnergy, G); - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - if(plotBOOL) - plot(time, loudness, 'b-', 'LineWidth', 2); - axis([0 length(vector)/Fs -70 0]); - xlabel('Time (s)'); - ylabel('Momentary Loudness (dB)') - grid on; - end - - result = loudness; - - case 'S' - % MODE: SHORT - winDur = 3000; % window time in miliseconds - winSize = Fs*winDur/1000; % window duration in samples - olapSize = Fs*100/1000; % 10 Hz refresh rate as per spec - maxI = floor( length(vector)/olapSize - winSize/olapSize + 1); % number of iterations - for i = 1:maxI - blockEnergy(i,:) = sum( vectorSquared( (i-1)*olapSize+1 : (i-1)*olapSize+winSize ,:) )./winSize; - time(i) = (i*olapSize)/Fs; - end - gTimesZ = bsxfun(@times, blockEnergy, G); - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - if(plotBOOL) - plot(time, loudness, 'r-.', 'LineWidth', 2); - axis([0 length(vector)/Fs -70 0]); - xlabel('Time (s)'); - ylabel('Short Term Loudness (dB)') - grid on; - end - - result = loudness; - - case 'I' - - % MODE: INTEGRATED - - % Gating block interval duration - winDur = 400; % in miliseconds - winSize = Fs*winDur/1000; % in samples - overlap = 0.5; % overlap. Specs: 1/(1-n) must be a natural number exc. 1 - olapSize = overlap*winSize; % block start interval - maxI = floor( length(vector)/olapSize - winSize/olapSize + 1 ); % number of iterations - - for i = 1:maxI - % equation 3 - blockEnergy(i,:) = sum(vectorSquared( (i-1)*olapSize+1 : (i-1)*olapSize+winSize,:))./winSize; - end - - % equation 4 - loudness - gTimesZ = bsxfun(@times, blockEnergy, G); %element-by-elemnt array multiple of G and blockEnergy - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - % applying the absolute gate - absGate = loudness >= -70; - absgatedLoudness = loudness(absGate); - absgatedEnergy = blockEnergy(absGate,:); - overallAbsLoudness = -0.691 + 10 .* log10( sum((sum(absgatedEnergy)./size(absgatedEnergy,1)).*G) ); - - % applying the relative gate 8 dB down from overallAbsLoudness - relGateLevel = overallAbsLoudness - 8; - relGate = loudness >= relGateLevel; - relgatedLoudness = loudness(relGate); - relgateEnergy = blockEnergy(relGate,:); - overallRelLoudness = -0.691 + 10 .* log10( sum((sum(relgateEnergy)./size(relgateEnergy,1)).*G) ); - - result = overallRelLoudness; - - - case 'ITU' - - % MODE: ITU (brecht) - - % Gating block interval duration - winDur = 400; % in miliseconds - winSize = Fs*winDur/1000; % in samples - overlap = 0.75; % overlap. Specs: 1/(1-n) must be a natural number exc. 1 - olapSize = overlap*winSize; % block start interval - maxI = floor( length(vector)/olapSize - winSize/olapSize + 1 ); % number of iterations - - for i = 1:maxI - % equation 3 - blockEnergy(i,:) = sum(vectorSquared( (i-1)*olapSize+1 : (i-1)*olapSize+winSize,:))./winSize; - end - - % equation 4 - loudness - gTimesZ = bsxfun(@times, blockEnergy, G); %element-by-elemnt array multiple of G and blockEnergy - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - % applying the absolute gate - absGate = loudness >= -70; - absgatedLoudness = loudness(absGate); - absgatedEnergy = blockEnergy(absGate,:); - overallAbsLoudness = -0.691 + 10 .* log10( sum((sum(absgatedEnergy)./size(absgatedEnergy,1)).*G) ); - - % applying the relative gate 10 dB down from overallAbsLoudness - relGateLevel = overallAbsLoudness - 10; - relGate = loudness >= relGateLevel; - relgatedLoudness = loudness(relGate); - relgateEnergy = blockEnergy(relGate,:); - overallRelLoudness = -0.691 + 10 .* log10( sum((sum(relgateEnergy)./size(relgateEnergy,1)).*G) ); - - result = overallRelLoudness; - - case 'B' - - % MODE: INTEGRATED - modified by Brecht De Man to follow ITU-R BS.1770-3 - % and Pestana 2013 - - % GAIN??? - - % Gating block interval duration - winDur = 280; % in miliseconds (see Pestana 2013) - winSize = Fs*winDur/1000; % in samples - overlap = 0.75; %! % overlap. Specs: 1/(1-n) must be a natural number exc. 1 - olapSize = overlap*winSize; % block start interval - maxI = floor( length(vector)/olapSize - winSize/olapSize + 1 ); % number of iterations - - for i = 1:maxI - % equation 3 - blockEnergy(i,:) = sum(vectorSquared( (i-1)*olapSize+1 : (i-1)*olapSize+winSize,:))./winSize; - end - - % equation 4 - loudness - gTimesZ = bsxfun(@times, blockEnergy, G); %element-by-elemnt array multiple of G and blockEnergy - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - % applying the absolute gate - absGate = loudness >= -70; - absgatedLoudness = loudness(absGate); - absgatedEnergy = blockEnergy(absGate,:); - overallAbsLoudness = -0.691 + 10 .* log10( sum((sum(absgatedEnergy)./size(absgatedEnergy,1)).*G) ); - - % applying the relative gate 10 dB (!) down from overallAbsLoudness - relGateLevel = overallAbsLoudness - 10; % ! - relGate = loudness >= relGateLevel; - relgatedLoudness = loudness(relGate); - relgateEnergy = blockEnergy(relGate,:); - overallRelLoudness = -0.691 + 10 .* log10( sum((sum(relgateEnergy)./size(relgateEnergy,1)).*G) ); - - result = overallRelLoudness; - - otherwise - - % MODE: My short-time measure - - winDur = 3000; % window time in miliseconds - winSize = Fs*winDur/1000; % window duration in samples - blockEnergy = sum(vectorSquared(:))./winSize; - - % equation 4 - loudness - gTimesZ = bsxfun(@times, blockEnergy, G); %element-by-elemnt array multiple of G and blockEnergy - loudness = -0.691 + 10 .* log10(sum(gTimesZ,2)); - - winSize=0; - olapSize=0; - - result = loudness; - - end -end - - - -function [prefilterBcoeffs, prefilterAcoeffs] = getloudnessprefilter(gainIndB, fs) -% GET LOUDNESS calculates coefficients for prefilter with arbitrary gain as -% specified in EBU R 128 and the modification proposed in Pestana 2013. -% -% by Brecht De Man at Centre for Digital Music on 24 April 2014 - -if nargin < 2 - fs = 44100; % standard 44.1kHz - if nargin < 1 - gainIndB = 4.0; % as recommended in EBU R 128 / ITU-R BS.1770-3 - end -end - -f0 = 1681.9; -%Q = ? -%BW = ? -S = 1; - -A = sqrt(10^(gainIndB/20)); -w0 = 2*pi*f0/fs; -alpha = sin(w0/2) * sqrt( (A+1/A) * (1/S-1) + 2); - -b0 = A*((A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha); -b1 = -2*A*((A-1) + (A+1)*cos(w0)); -b2 = A*((A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha); -a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha; -a1 = 2*((A-1) - (A+1)*cos(w0)); -a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha; - -% b0 = (1 - cos(w0))/2; -% b1 = 1 - cos(w0); -% b2 = (1 - cos(w0))/2; -% a0 = 1 + alpha; -% a1 = -2*cos(w0); -% a2 = 1 - alpha; - -% b0 = b0/a0; -% b1 = b1/a0; -% b2 = b2/a0; -% a0 = a0/a0; -% a1 = a1/a0; -% a2 = a2/a0; - -prefilterBcoeffs = [b0, b1, b2]; -prefilterAcoeffs = [a0, a1, a2]; - - -% % DEBUG: comparison with ITU/EBU standard hard coded coefficients -% [Hpf,Wpf] = freqz(prefilterBcoeffs, prefilterAcoeffs, 20000, fs); % response in radians per sample -% -% subplot(2,1,1) -% semilogx(20*log10(abs(Hpf))); -% axis([0 20000 -10 15]); -% grid on -% set(gca, 'XTickMode','manual'); -% set(gca, 'XTickLabel',num2str(get(gca,'XTick')')); -% -% -% % fs=48k, 4dB gain -% prefilterBcoeffs = [1.53512485958697, -2.69169618940638, 1.19839281085285]; -% prefilterAcoeffs = [1.0, -1.69065929318241, 0.73248077421585]; -% -% [Hpf,Wpf] = freqz(prefilterBcoeffs, prefilterAcoeffs, 20000,48000); % response in radians per sample -% -% subplot(2,1,2) -% semilogx(20*log10(abs(Hpf))); -% axis([0 20000 -10 10]); -% grid on -% set(gca, 'XTickMode','manual'); -% set(gca, 'XTickLabel',num2str(get(gca,'XTick')')); - - -% see -% S. Mansbridge, S. Finn, and J. D. Reiss, "Implementation and Evaluation -% of Autonomous Multi-track Fader Control," 132nd Convention of the Audio -% Engineering Society, 2012. -% f_c = 1681.97; -% Omega = tan(pi*f_c/fs); -% V_H = 1.58; % probably gain (?+4dB) -% V_L = 1.26; % switch with V_B? -% V_B = 1; -% Q = 0.71; -% -% b(1) = V_L * Omega^2 + V_B*Omega/Q + V_H; -% b(2) = 2*(V_L*Omega^2 - V_H); -% b(3) = V_L*Omega^2 - V_B*Omega/Q + V_H; -% a(1) = Omega^2 + Omega/Q + 1; -% a(2) = 2*(Omega^2 - 1); -% a(3) = Omega^2 - Omega/Q + 1; -% -% b = b /a(1); -% a = a /a(1); - -% f = 1682; % Hz -% S = 1; % steep without noticeable notches/peaks -% A = 10^(gain/40); -% w0 =2*pi*f/fs; -% alpha = sin(w0)/2 * sqrt( (A+ 1/A)*(1/S - 1) + 2 ); -% -% % filter coefficients -% b(1)= A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha ); -% b(2) = -2*A*( (A-1) + (A+1)*cos(w0) ); -% b(3) = A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha ); -% a(1) = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha; -% a(2) = 2*( (A-1) - (A+1)*cos(w0) ); -% a(3) = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha; -% - - -% DEBUG -%fvtool(b,a,'Fs',fs); - -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aux/loudness.m Tue Apr 26 14:54:32 2016 +0200 @@ -0,0 +1,102 @@ +function integratedloudness = loudness(signal, fs) +%INTEGRATEDLOUDNESS returns loudness level (scalar) according to EBU R 128 +% specification and accepts an audio file vector (vector) and a sampling +% rate (fs). +% +% by Brecht De Man on Monday 25 April 2016 + + nrSamples = size(signal,1); + nrChannels = size(signal,2); + + % loudness prefilters (functions below this one) + [b1, a1] = loudnessprefilter1(fs); + [b2, a2] = loudnessprefilter2(fs); + + % Weighting coefficients with channel format [L, R, C, Ls, Rs] + G = [1.0 1.0 1.0 1.41 1.41 0.0 0.0]; % temporary + + % Apply pre-filter + signal_intermediate = filter(b1, a1, signal); + signal_filtered = filter(b2, a2, signal_intermediate); + + % Gating block interval duration + T_g = .4; % seconds + Gamma_a = -70.0; % absolute threshold: -70 LKFS + overlap = 0.75; % relative overlap (0.0 - 1.0) + step = 1 - overlap; + + T = nrSamples/fs; % length of measurement interval in seconds + j_range = 1:floor((T-T_g)/(T_g*step)+1); + z = zeros(nrChannels, max(size(j_range))); + for i = 1:nrChannels % for each channel i + for j=j_range % for each window j + lbound = floor(fs*T_g*(j-1)*step+1); + hbound = floor(fs*T_g*((j-1)*step+1)); + z(i,j) = (1/(T_g*fs))*sum(signal_filtered(lbound:hbound, i).^2); + end + end + + G_current = G(1:nrChannels); % discard weighting coefficients G_i unused channels + l = zeros(size(j_range,1), 1); + for j=j_range % for each window j + l(j) = -.691 + 10.0*log10(sum(G_current*z(:,j))); + end + + % throw out anything below absolute threshold: + z_avg = mean(z(:,l>Gamma_a),2); + Gamma_r = -.691 + 10.0*log10(G_current*z_avg) - 10.0; + % throw out anything below relative threshold: + z_avg = mean(z(:,l>Gamma_r),2); + integratedloudness = -.691 + 10.0*log10(G_current*z_avg); + +end + +function [b, a] = loudnessprefilter1(fs) +% LOUDNESSPREFILTER1 calculates coefficients for the first prefilter +% specified in EBU R 128. + + % pre-filter 1 coefficients + f0 = 1681.9744509555319; + G = 3.99984385397; + Q = 0.7071752369554193; + K = tan(pi * f0 / fs); + Vh = 10.0^(G / 20.0); % TODO: precompute + Vb = Vh^0.499666774155; % TODO: precompute + a0_ = 1.0 + K / Q + K * K; + b0 = (Vh + Vb * K / Q + K * K) / a0_; + b1 = 2.0 * (K * K - Vh) / a0_; + b2 = (Vh - Vb * K / Q + K * K) / a0_; + a0 = 1.0; + a1 = 2.0 * (K * K - 1.0) / a0_; + a2 = (1.0 - K / Q + K * K) / a0_; + + b = [b0, b1, b2]; + a = [a0, a1, a2]; + + % DEBUG + %fvtool(b,a,'fs',fs); + +end + +function [b, a] = loudnessprefilter2(fs) +% LOUDNESSPREFILTER2 calculates coefficients for the second prefilter +% specified in EBU R 128. + + % pre-filter 2 coefficients + f0 = 38.13547087613982; + Q = 0.5003270373253953; + K = tan(pi * f0 / fs); + a0 = 1.0; + a1 = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K); + a2 = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K); + b0 = 1.0; + b1 = -2.0; + b2 = 1.0; + + b = [b0, b1, b2]; + a = [a0, a1, a2]; + + % DEBUG + %fvtool(b,a,'fs',fs); + +end
--- a/aux/loudness_itu.m Fri Jun 26 20:56:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -function lkfs = loudness_itu(x, fs) -%LOUDNESS_ITU compute loudness (LKFS) based on ITU-R BS.1770-2 -% LOUDNESS_ITU(x, fs, mode) compute loudness based on ITU-R BS.1770-2 -% specification. x is an input signal (mono/stereo/5.1ch) with sampling -% frequency fs. -% -% Input signal has to be either in mono (M), stereo (L and R), or -% 5.1ch(L, R, C, LFE, Ls, and Rs) in respective channel order. -% -% Example: loudness calculation -% [x,fs] = wavread('soundfile.wav'); -% lkfs = LOUDNESS_ITU(x, fs); -% -% 2012-01-06 MARUI Atsushi - -% constants -blockSize = 400; % in ms -overlapSize = 0.75; % in percentage -channelWeights = [1 1 1 0 sqrt(2) sqrt(2)]; % in L, R, C, LFE, Ls, Rs order -absoluteThreshold = -70; % in dB -relativeThreshold = -10; % in dB - -% preparation -if size(x,1)~=length(x) - x = x'; -end -numch = size(x,2); - -if fs~=48000 - x = resample(x, 48000, fs); - fs = 48000; -end - -switch(numch) - case 5 - chwat = channelWeights([1 2 3 5 6]); - otherwise - chwat = channelWeights(1:numch); -end - -% K-filter -B1 = [ - 1.53512485958697 - -2.69169618940638 - 1.19839281085285 - ]; -A1 = [ - 1.0 - -1.69065929318241 - 0.73248077421585 - ]; -B2 = [ - 1.0 - -2.0 - 1.0 - ]; -A2 = [ - 1.0 - -1.99004745483398 - 0.99007225036621 - ]; -y = filter(B2,A2,filter(B1,A1,x)); - -% Mean square -numBlock = ceil(length(y)/ blockSize) + 1; -yy = zeros(numBlock * blockSize, numch); -yy(1:length(y),:) = y; -j = 0:(length(y) - blockSize)/(blockSize * (1-overlapSize)); -z = zeros(length(j), numch); -for n1 = 1:length(j) - yyy = yy(blockSize*j(n1)*(1-overlapSize)+1:blockSize*(j(n1)*(1-overlapSize)+1)+1,:); - z(n1,:) = sum(yyy .^ 2) / blockSize; -end -l = -0.691 + 10*log10(sum(repmat(chwat,length(z),1) .* z, 2)); - -% Gating (absolute) -Jg = l > absoluteThreshold; -zz = repmat(channelWeights(1:numch),length(z),1) .* z; -L_KG = -0.691 + 10*log10(chwat * sum(zz(Jg,:), 1)' / sum(Jg)); - -% Gating (relative) -Gamma_r = L_KG + relativeThreshold; -Jg = l > Gamma_r; -L_KG = -0.691 + 10*log10(chwat * sum(zz(Jg,:), 1)' / sum(Jg)); - -% OPTIONAL: draw pretty figure -if false - t = (blockSize*(j*(1-overlapSize)+1)+1)/fs; - h = plot(t, l, 'color', [.5 .5 .5]); - hold on; - h = line([t(1) t(end)], [L_KG L_KG]); - set(h, 'Color', 'b'); - set(h, 'LineStyle', '--'); - set(h, 'LineWidth', 1); - h = line([t(1) t(end)], [Gamma_r Gamma_r]); - set(h, 'Color', 'b'); - set(h, 'LineStyle', ':'); - set(gca, 'Xlim', [t(1) t(end)]); - hold off; - legend({'momentary', 'integrated', 'relative gate'}); -end - -% output -lkfs = L_KG; \ No newline at end of file
--- a/aux/loudness_match.m Fri Jun 26 20:56:42 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -function factor = loudness_match (X, fs, lkfs) -%LOUDNESS_MATCH -% LOUDNESS_MATCH (X, fs, lkfs) calculates an amplitude multiplication factor -% which equalizes a sound to match the specified loudness (in LKFS). -% -% 2010-02-23 by MARUI Atsushi - -factor = 1.0; -factorHigh = 10^(+60/20); -factorLow = 10^(-60/20); -i = 1; - -while i - s = loudness_itu(factor * X, fs); - k = (s - lkfs) / lkfs; - - fprintf('%3d: Factor %7.5f LKFS %7.3f (%6.2f%% difference)\n', i, factor, s, k*100); - i = i + 1; - - if abs(k) < 0.001 - return; - end - - if k < 0.0 - factorOld = factor; - factor = (factorLow + factor) / 2.0; - factorHigh = factorOld; - elseif k > 0.0 - factorOld = factor; - factor = (factorHigh + factor) / 2.0; - factorLow = factorOld; - end -end \ No newline at end of file
--- a/aux/loudnesstest.m Fri Jun 26 20:56:42 2015 +0100 +++ b/aux/loudnesstest.m Tue Apr 26 14:54:32 2016 +0200 @@ -1,27 +1,15 @@ -% test loudness mod +% test loudness.m -tic; +testfolder = '/Users/Brecht/Google Drive/Writings/ebur128-scripts/ebu-loudness-test-setv04/'; -% target loudness and test file -target_loudness = -23; % dBLU -filename = 'W.wav'; +files = dir([testfolder '*.wav']); -% import sound file -[audio, fs] = audioread(filename); - -% measure and display loudness -initial_loudness = getloudness(audio, fs, 'ITU', 0); -disp(['Initial loudness: ' num2str(initial_loudness)]); - -% apply gain -difference_loudness = target_loudness - initial_loudness; -disp(['Difference in loudness: ' num2str(difference_loudness)]); -audio = 10^(difference_loudness/20) .* audio; -disp(['Gain: ' num2str(10^(difference_loudness/20))]); - -% measure and display loudness (should be equal to target loudness) -resulting_loudness = getloudness(audio, fs, 'ITU', 0); -disp(['Resulting loudness: ' num2str(resulting_loudness)]); - -elapsed_time = toc; -disp(['Elapsed time: ' num2str(elapsed_time)]); \ No newline at end of file +tTotal = tic; +for file = files' + [signal, fs] = audioread([testfolder file.name]); + tic; + IL = loudness(signal,fs); % calculate integrated loudness + tCurrent = toc; + fprintf('%s:\t%4.10f\t%d\t(%4.2f s)\n', file.name, IL, fs, tCurrent); +end +fprintf('Testing completed: %4.2f seconds elapsed\n', toc(tTotal)); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/aux/resample Tue Apr 26 14:54:32 2016 +0200 @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in *.wav; do + sox -G $i -b 24 temp.wav rate -v 96k; + mv temp.wav $i; +done \ No newline at end of file
--- a/aux/stereo2mono.m Fri Jun 26 20:56:42 2015 +0100 +++ b/aux/stereo2mono.m Tue Apr 26 14:54:32 2016 +0200 @@ -25,8 +25,8 @@ [audio,fs] = audioread(files(k).name); % read audio % check if stereo; if so, get channels and save as separate wavfile if size(audio,2)==2 - audiowrite([files(k).name(1:end-4) '_L.wav'],audio(:,1),fs, 'BitsPerSample', 24); - audiowrite([files(k).name(1:end-4) '_R.wav'],audio(:,2),fs, 'BitsPerSample', 24); + audiowrite([files(k).name(1:end-4) '.L.wav'],audio(:,1),fs, 'BitsPerSample', 24); + audiowrite([files(k).name(1:end-4) '.R.wav'],audio(:,2),fs, 'BitsPerSample', 24); end end cd(currentfolder); % go back to original folder