B.3 Reference algorithm
26.1323GPPRelease 18Speech and video telephony terminal acoustic test specificationTS
B.3.1 Main algorithm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% processedData: processed samples
% originalData: near-end-only samples
% downlinkData: down-link (loudspeaker) samples
% processedSegmentSet: set of indices to processed data segments
% originalSegmentSet: set of indices to original data segments
% PROC_FILE: name shown in diagrams
% downlinkSystemDelayInMs: delay in DL signal from data to acoustic out
% sampleRate: sampling frequency of the data
% resultsFile: output file
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function ecEvaluation(…
processedData, …
nearendData, …
downlinkData, …
indexProcessed, …
indexNearend, …
PROC_FILE, …
downlinkSystemDelayInMs, …
sampleRate, …
resultFile)
fid = fopen(resultFile, ‘a’);
% Define the categories
global D1 D2 D3 D4 L1 L2 L3;
D1 = 25;
D2 = 150;
D3 = 25;
D4 = 150;
L1 = 4;
L2 = -4;
L3 = -15;
global FRAME_LENGTH_MS …
MAX_DURATION_MS …
MAX_DURATION_FRAMES …
MAX_LEVEL_DIFFERENCE …
MIN_LEVEL_DIFFERENCE …
HISTOGRAM_RESOLUTION_MS
FRAME_LENGTH_MS = 5;
MAX_DURATION_MS = 200;
MAX_DURATION_FRAMES = MAX_DURATION_MS/FRAME_LENGTH_MS;
MAX_LEVEL_DIFFERENCE = 40;
MIN_LEVEL_DIFFERENCE = -40;
HISTOGRAM_RESOLUTION_MS = FRAME_LENGTH_MS;
% Main processing loop
frameLengthInSamples = FRAME_LENGTH_MS*sampleRate/1000; % 5ms frames
for segment = 1:length(indexProcessed)
% Get the data samples for the segment
segmentDataProcessed = cell2mat(indexProcessed(segment));
segmentDataNearend = cell2mat(indexNearend(segment));
index = (sampleRate*segmentDataProcessed(1)+1):sampleRate*segmentDataProcessed(2);
x = processedData(index);
z = downlinkData(index);
index = (sampleRate*segmentDataNearend(1)+1):sampleRate*segmentDataNearend(2);
y = nearendData(index);
% Estimate and compensate for delay between processed and near end
[x, y, z, delay] = compensateDelay(x, y, z, 0.5*sampleRate);
% Compute the signal levels and classify the frames
[Rx, Ry, Rz, doubleTalkFrames, singleTalkFrames] = …
computeSignalLevels(x, y, z, …
sampleRate, frameLengthInSamples, …
downlinkSystemDelayInMs, …
PROC_FILE, segment, fid);
% Evaluate double-talk performance
numberOfDoubleTalkFrames =0;
% Iterate over blocks of consecutive indices
H_dt = [];
doubleTalkFramesBlocks = findConsecutiveBlocks(doubleTalkFrames);
for i = 1:size(doubleTalkFramesBlocks,1)
IdxFrom = doubleTalkFramesBlocks(i,1);
IdxTo = doubleTalkFramesBlocks(i,2);
currentBlockLength = IdxTo – IdxFrom;
if currentBlockLength > 1
[H_dt_Tmp, ld_ax_dt, dur_ax_dt] = levelTimeStatistics(Rx(IdxFrom:IdxTo), Ry(IdxFrom:IdxTo));
if isempty(H_dt)
H_dt = H_dt_Tmp;
else
H_dt = H_dt + H_dt_Tmp;
end
numberOfDoubleTalkFrames = numberOfDoubleTalkFrames + currentBlockLength;
end
end
[C_dt, L_dt] = evaluateHistogram(H_dt, ld_ax_dt, dur_ax_dt, …
numberOfDoubleTalkFrames);
activityFactorDoubleTalk = numberOfDoubleTalkFrames/length(Rx);
% Evaluate single-talk performance
numberOfSingleTalkFrames = 0;
% Iterate over blocks of consecutive indices
H_st = [];
singleTalkFramesBlocks = findConsecutiveBlocks(singleTalkFrames);
for i = 1:size(singleTalkFramesBlocks,1)
IdxFrom = singleTalkFramesBlocks(i,1);
IdxTo = singleTalkFramesBlocks(i,2);
currentBlockLength = IdxTo – IdxFrom;
if currentBlockLength > 1
[H_st_Tmp, ld_ax_st, dur_ax_st] = levelTimeStatistics(Rx(IdxFrom:IdxTo), Ry(IdxFrom:IdxTo));
if isempty(H_st)
H_st = H_st_Tmp;
else
H_st = H_st + H_st_Tmp;
end
numberOfSingleTalkFrames = numberOfSingleTalkFrames + currentBlockLength;
end
end
[C_st, L_st] = evaluateHistogram(H_st, ld_ax_st, dur_ax_st, …
numberOfSingleTalkFrames);
activityFactorSingleTalk = numberOfSingleTalkFrames/length(Rx);
% Save to result file
writeResultsToFile(fid, …
PROC_FILE, …
segment, …
delay, …
round(downlinkSystemDelayInMs), …
activityFactorDoubleTalk, …
activityFactorSingleTalk, …
C_dt, …
C_st, …
L_dt, …
L_st);
end
fclose(fid);
B.3.2 Delay compensation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Compensate for delay in processed file
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x, y, z, delay] = …
compensateDelay(…
x, …
y, …
z, …
maxLag)
ii = 1:min(1000000, length(x));
r = xcorr(x(ii), y(ii), maxLag);
[~, delay] = max(abs(r));
delay = delay-maxLag-1;
if (delay > 0)
x = x((delay+1):end);
z = z((delay+1):end);
y = y(1:(end-delay));
elseif (delay < 0)
y = y((-delay+1):end);
x = x(1:(end+delay));
z = z(1:(end+delay));
end;
B.3.3 Signal level computation and frame classification
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Determine speech activity and signal levels
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Rx, Ry, Rz, doubleTalkFrames, singleTalkFrames] = …
computeSignalLevels(x, y, z, …
sampleRate, frameLengthInSamples, …
downlinkSystemDelayInMs, …
PROC_FILE, segment, fid)
LEVEL_METER_INIT_TIME_MS = 100;
DOWNLINK_HANGOVER_FRAMES = 40;
NEAREND_HANGOVER_FRAMES = 40;
levelMeterInitTime = LEVEL_METER_INIT_TIME_MS*sampleRate/1000;
% Level according to IEC61672
Rx = IEC61672(x, sampleRate, 12.5);
Ry = IEC61672(y, sampleRate, 12.5);
Rz = IEC61672(z, sampleRate, 12.5);
% Correct for system delay
nRz = length(Rz);
minRz = min(Rz(levelMeterInitTime:end));
Rz = [minRz*ones(floor(downlinkSystemDelayInMs*sampleRate/1000), 1); Rz];
Rz = Rz(1:nRz);
% Sub-sample and avoid initialization period of level meter
Rx = Rx(levelMeterInitTime:frameLengthInSamples:end);
Ry = Ry(levelMeterInitTime:frameLengthInSamples:end);
Rz = Rz(levelMeterInitTime:frameLengthInSamples:end);
% Active speech level according to P.56
[activeSpeechLevelProcessed, …
longTermLevelProcessed, …
activityFactorProcessed] = …
speechLevelMeter(x, sampleRate);
[activeSpeechLevelNearend, …
longTermLevelNearend, …
activityFactorNearend] = …
speechLevelMeter(y, sampleRate);
[activeSpeechLevelDownlink, …
longTermLevelDownlink, …
activityFactorDownlink] = …
speechLevelMeter(z, sampleRate);
% Write active speech levels to file
writeSpeechLevelsToFile(PROC_FILE, segment, fid, …
activeSpeechLevelProcessed, …
activeSpeechLevelNearend, …
activeSpeechLevelDownlink, …
longTermLevelProcessed, …
longTermLevelNearend, …
longTermLevelDownlink, …
activityFactorProcessed, …
activityFactorNearend, …
activityFactorDownlink);
%
% Only evaluate for active downlink/near-end speech including hang-over
%
activeRyFrames = find(Ry > activeSpeechLevelNearend-15.9);
activeRzFrames = find(Rz > activeSpeechLevelDownlink-15.9);
% Downlink with added hangover
activeDownlinkSpeechFrames = zeros(size(Rz));
activeDownlinkSpeechFrames(activeRzFrames) = ones(size(activeRzFrames));
activeDownlinkSpeechFrames = conv(activeDownlinkSpeechFrames, …
ones(DOWNLINK_HANGOVER_FRAMES, 1));
activeDownlinkSpeechFrames = activeDownlinkSpeechFrames(1:length(Rz));
% Near-end
activeNearEndSpeechFrames = zeros(size(Ry));
activeNearEndSpeechFrames(activeRyFrames) = ones(size(activeRyFrames));
activeNearEndSpeechHtFrames = conv(activeNearEndSpeechFrames, …
ones(NEAREND_HANGOVER_FRAMES, 1));
activeNearEndSpeechHtFrames = activeNearEndSpeechHtFrames(1:length(Rz));
% Only evaluate double talk when both rx+hangover and near-end
doubleTalkSpeechFrames = (activeDownlinkSpeechFrames & …
activeNearEndSpeechFrames);
doubleTalkFrames = find(doubleTalkSpeechFrames > 0);
% Single talk defined as rx and no near-end including 200 ms hangover
singleTalkSpeechFrames = (activeDownlinkSpeechFrames & …
~activeNearEndSpeechHtFrames);
singleTalkFrames = find(singleTalkSpeechFrames > 0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Average speech and noise levels
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function […
activeSpeechLevel, …
longTermLevel, …
activityFactor …
] = …
speechLevelMeter(x, sampleRate)
SPEECH_LEVEL_HANGOVER_TIME_IN_MS = 200;
% Filter data
g = exp(-1/(0.03*sampleRate));
p = filter((1-g), [1, -g], abs(x));
q = filter((1-g), [1, -g], abs(p));
% Add 200ms hangover
hTimeInSamples = SPEECH_LEVEL_HANGOVER_TIME_IN_MS*sampleRate/1000;
qht = q;
for loop = 1:hTimeInSamples
qht = max(qht, [zeros(loop, 1); q(1:end-loop)]);
end
% Compute cumulative histogram of signal power with hangover
nData = length(x);
cBins = 2.0.^(0:14)’;
histogramCsum = zeros(size(cBins));
for loop = 1:length(cBins)
histogramCsum(loop) = length(find(qht>cBins(loop)));
end
% Get the levels
sumSquare = sum(x.^2);
refdB = 20*log10(32768);
longTermLevel = 10*log10(sumSquare/nData) – refdB;
A = 10*log10(sumSquare./histogramCsum) – refdB;
C = 20*log10(cBins) – refdB;
Diff = A-C;
if ((A(1) == 0) || ((A(1) – C(1)) <= 15.9))
activeSpeechLevel = -100;
else
index = find(Diff <= 15.9, 1, ‘first’);
if (Diff(index) == 15.9)
activeSpeechLevel = A(index);
else
C_level = C(index) + …
(15.9 – Diff(index))* …
(C(index)-C(index-1))/(Diff(index)-Diff(index-1));
activeSpeechLevel = A(index) + …
(C_level – C(index))* …
(A(index)-A(index-1))/(C(index)-C(index-1));
end
end
activityFactor = 10.0^((longTermLevel-activeSpeechLevel)/10);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Speech level meter according to IEC61672
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Rx = IEC61672(x, sampleRate, tc)
%
%
% This functions computes the power of a sampled signal
% using a discrete filter with time constant equivalent to a first order
% continous time exponential averaging circuit,
%
% 1/tc
% Rx = ———- x^2
% s + 1/tc
%
% according to IEC 61672 (1993, section 7.2).
%
T = 1/sampleRate;
tc = tc/1000;
%
% Design H by sampling of Hc
%
la = exp(-T/tc);
B = 1-la;
A = [1, -la];
Rx = filter(B, A, x.^2);
%
% Transform Rx to dBov (square wave),
%
% 0 dBov <=> power of maximum square wave signal, 32768
%
% 10^0 = 32768^2/X => X = 32768^2
%
% Avoid log(0) by using log(max(eps, Rx))
%
Rx = 10*log10(max(eps, Rx)/32768/32768);
B.3.4 Level vs time computation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Computation of level and time statistics
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function […
levelVsDurationHistogram, …
levelDifferenceAxis, …
durationAxis] = …
levelTimeStatistics(processedLevel, nearEndLevel)
global MAX_DURATION_FRAMES MAX_LEVEL_DIFFERENCE MIN_LEVEL_DIFFERENCE
FIRST_OCCURENCE = 1;
%
% Compute level difference
%
levelDifference = processedLevel – nearEndLevel;
%
% Only evaluate in integers (rounded towards 0) of dB and limit to max/min difference
%
levelDifference = fix(levelDifference);
levelDifference = min(levelDifference, MAX_LEVEL_DIFFERENCE);
levelDifference = max(levelDifference, MIN_LEVEL_DIFFERENCE);
%
% Produce axis
%
levelDifferenceAxis = MIN_LEVEL_DIFFERENCE:MAX_LEVEL_DIFFERENCE;
durationAxis = 1:(MAX_DURATION_FRAMES+1);
%
% Set initial values for computations and loop through all frames
%
numberOfEvaluatedFrames = length(levelDifference);
levelIncludedInEvaluation = (MAX_LEVEL_DIFFERENCE+1)*…
ones(numberOfEvaluatedFrames, 1);
levelAndRunLength = zeros(numberOfEvaluatedFrames, 4);
levelVsDurationHistogram = zeros(MAX_LEVEL_DIFFERENCE+ …
(-MIN_LEVEL_DIFFERENCE)+1, …
MAX_DURATION_FRAMES+1);
previousLevelDifference = 0;
for frame = 1:numberOfEvaluatedFrames-1;
currentLevelDifference = levelDifference(frame);
%
% Evaluate all levels from the previous level up to the current level
%
if currentLevelDifference <= 0
firstEvaluatedLevelDifference = max(min(0, previousLevelDifference), …
currentLevelDifference);
step = -1;
else
firstEvaluatedLevelDifference = min(max(0, previousLevelDifference), …
currentLevelDifference);
step = 1;
end
%
% Loop the levels to be evaluated
%
for evaluatedLevelDifference = …
firstEvaluatedLevelDifference:step:currentLevelDifference
%
% Check that the current frame is not already included
% in evaluation for earlier frames
%
if (evaluatedLevelDifference ~= levelIncludedInEvaluation(frame))
if (evaluatedLevelDifference > 0)
duration = find(levelDifference(frame+1:end) < …
evaluatedLevelDifference, FIRST_OCCURENCE);
else
duration = find(levelDifference(frame+1:end) > …
evaluatedLevelDifference, FIRST_OCCURENCE);
end
if (isempty(duration))
duration = numberOfEvaluatedFrames-frame+1;
end
%
% Set the frames during duration of the level difference
% as being evaluated
%
if (duration > 1)
levelIncludedInEvaluation(frame:(frame+duration-1)) = …
evaluatedLevelDifference*ones(duration, 1);
end;
%
% Add the number of frames in the duration that have
% absolute level diff greater or equal to evalutedLevel
%
durationIndex = min(duration, MAX_DURATION_FRAMES);
levelIndex = evaluatedLevelDifference+(-MIN_LEVEL_DIFFERENCE)+1;
levelVsDurationHistogram(levelIndex, durationIndex) = …
levelVsDurationHistogram(levelIndex, durationIndex) + duration;
end
end
previousLevelDifference = currentLevelDifference;
end
B.3.5 Categorization
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Evaluate the histogram data
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [categories, averageLevelsInCategories] = …
evaluateHistogram(…
histogramData, …
levelDiff_ax, …
duration_ax, …
numberOfFrames)
global D1 D2 D3 D4 L1 L2 L3 HISTOGRAM_RESOLUTION_MS;
D1_scaled = D1/HISTOGRAM_RESOLUTION_MS;
D2_scaled = D2/HISTOGRAM_RESOLUTION_MS;
D3_scaled = D3/HISTOGRAM_RESOLUTION_MS;
D4_scaled = D4/HISTOGRAM_RESOLUTION_MS;
levelIndex_L1 = find(levelDiff_ax == L1);
levelIndex_L2 = levelDiff_ax == L2;
levelIndex_L3 = find(levelDiff_ax == L3);
duration_A2 = duration_ax;
duration_B = duration_ax<=D1_scaled;
duration_C = (D1_scaled<duration_ax)&(duration_ax<=D2_scaled);
duration_D = duration_ax>D2_scaled;
duration_E = duration_ax<=D3_scaled;
duration_F = (D3_scaled<duration_ax)&(duration_ax<=D4_scaled);
duration_G = duration_ax>D4_scaled;
framesInCategoryB = sum(histogramData(levelIndex_L3, duration_B));
framesInCategoryC = sum(histogramData(levelIndex_L3, duration_C));
framesInCategoryD = sum(histogramData(levelIndex_L3, duration_D));
framesInCategoryE = sum(histogramData(levelIndex_L1, duration_E));
framesInCategoryF = sum(histogramData(levelIndex_L1, duration_F));
framesInCategoryG = sum(histogramData(levelIndex_L1, duration_G));
framesInCategoryA2 = sum(histogramData(levelIndex_L2, duration_A2));
framesInCategoryA2 = framesInCategoryA2 – …
framesInCategoryB – …
framesInCategoryC – …
framesInCategoryD;
framesInCategoryA1 = numberOfFrames – …
framesInCategoryA2 – …
framesInCategoryB – …
framesInCategoryC – …
framesInCategoryD – …
framesInCategoryE – …
framesInCategoryF – …
framesInCategoryG;
categories = [framesInCategoryA1;
framesInCategoryA2;
framesInCategoryB;
framesInCategoryC;
framesInCategoryD;
framesInCategoryE;
framesInCategoryF;
framesInCategoryG]/numberOfFrames;
averageLevelsInCategories = zeros(8, 1);
% Category A1
index = levelDiff_ax < L1;
index = levelDiff_ax(index) > L2;
weight = levelDiff_ax(index);
duration = duration_ax;
levelTimesDuration = (weight*histogramData(index, duration)).*duration;
nData = sum(histogramData(index, duration)*duration’);
if (framesInCategoryA1 > 0)
averageLevelsInCategories(1) = sum(levelTimesDuration)/nData;
end
% Category A2
index = levelDiff_ax <= L2;
index = levelDiff_ax(index) > L3;
weight = levelDiff_ax(index);
duration = duration_ax;
levelTimesDuration = (weight*histogramData(index, duration)).*duration;
nData = sum(histogramData(index, duration)*duration’);
if (framesInCategoryA2 > 0)
averageLevelsInCategories(2) = sum(levelTimesDuration)/nData;
end
% Category B, C, D
index = find(levelDiff_ax <= L3);
weight = levelDiff_ax(index);
duration = duration_ax(duration_B);
levelTimesDuration = (weight*histogramData(index, duration_B)).*duration;
nData = sum(histogramData(index, duration_B)*duration’);
if (framesInCategoryB > 0)
averageLevelsInCategories(3) = sum(levelTimesDuration)/nData;
end
duration = duration_ax(duration_C);
levelTimesDuration = (weight*histogramData(index, duration_C)).*duration;
nData = sum(histogramData(index, duration_C)*duration’);
if (framesInCategoryC > 0)
averageLevelsInCategories(4) = sum(levelTimesDuration)/nData;
end
duration = duration_ax(duration_D);
levelTimesDuration = (weight*histogramData(index, duration_D)).*duration;
nData = sum(histogramData(index, duration_D)*duration’);
if (framesInCategoryD > 0)
averageLevelsInCategories(5) = sum(levelTimesDuration)/nData;
end
% Category E, F, G
index = find(levelDiff_ax >= L1);
weight = levelDiff_ax(index);
duration = duration_ax(duration_E);
levelTimesDuration = (weight*histogramData(index, duration_E)).*duration;
nData = sum(histogramData(index, duration_E)*duration’);
if (framesInCategoryE > 0)
averageLevelsInCategories(6) = sum(levelTimesDuration)/nData;
end
duration = duration_ax(duration_F);
levelTimesDuration = (weight*histogramData(index, duration_F)).*duration;
nData = sum(histogramData(index, duration_F)*duration’);
if (framesInCategoryF > 0)
averageLevelsInCategories(7) = sum(levelTimesDuration)/nData;
end
duration = duration_ax(duration_G);
levelTimesDuration = (weight*histogramData(index, duration_G)).*duration;
nData = sum(histogramData(index, duration_G)*duration’);
if (framesInCategoryC > 0)
averageLevelsInCategories(8) = sum(levelTimesDuration)/nData;
end
B.3.6 Auxiliary functions for reporting data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Write the classification to file
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function writeResultsToFile(fid, …
PROC_FILE, …
segment, …
delay, …
downlinkSystemDelay, …
activityFactorDoubleTalk, …
activityFactorSingleTalk, …
C_dt, …
C_st, …
L_dt, …
L_st)
str = sprintf(‘%s; segm. %d; delay %d; DL delay %d; DT activity %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f;’, …
PROC_FILE, segment, delay, downlinkSystemDelay, activityFactorDoubleTalk, …
C_dt(1), C_dt(2), C_dt(3), C_dt(4), …
C_dt(5), C_dt(6), C_dt(7), C_dt(8));
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
str = sprintf(‘%s; segm. %d; delay %d; DL delay %d; DT level diff; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f;’, …
PROC_FILE, segment, delay, downlinkSystemDelay, …
L_dt(1), L_dt(2), L_dt(3), L_dt(4), L_dt(5), L_dt(6), L_dt(7), L_dt(8));
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
str = sprintf(‘%s; segm. %d; delay %d; DL delay %d; ST activity %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f; %1.3f;’, …
PROC_FILE, segment, delay, downlinkSystemDelay, activityFactorSingleTalk, …
C_st(1), C_st(2), C_st(3), C_st(4), …
C_st(5), C_st(6), C_st(7), C_st(8));
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
str = sprintf(‘%s; segm. %d; delay %d; DL delay %d; ST level diff; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f; %1.1f;’, …
PROC_FILE, segment, delay, downlinkSystemDelay, …
L_st(1), L_st(2), L_st(3), L_st(4), L_st(5), L_st(6), L_st(7), L_st(8));
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Write the signal levels to file
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function writeSpeechLevelsToFile(PROC_FILE, segment, fid, …
activeSpeechLevelProcessed, …
activeSpeechLevelNearend, …
activeSpeechLevelDownlink, …
longTermLevelProcessed, …
longTermLevelNearend, …
longTermLevelDownlink, …
activityFactorProcessed, …
activityFactorNearend, …
activityFactorDownlink)
str = sprintf(‘%s; segm. %d; Processed signal; active speech level [dBovl]; %3.1f; RMS level [dBovl]; %3.1f; speech activity; %1.3f’, …
PROC_FILE, segment, activeSpeechLevelProcessed, …
longTermLevelProcessed, activityFactorProcessed);
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
str = sprintf(‘%s; segm. %d; Near end signal; active speech level [dBovl]; %3.1f; RMS level [dBovl]; %3.1f; speech activity; %1.3f’, …
PROC_FILE, segment, activeSpeechLevelNearend, …
longTermLevelNearend, activityFactorNearend);
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
str = sprintf(‘%s; segm. %d; Downlink signal; active speech level [dBovl]; %3.1f; RMS level [dBovl]; %3.1f; speech activity; %1.3f’, …
PROC_FILE, segment, activeSpeechLevelDownlink, …
longTermLevelDownlink, activityFactorDownlink);
disp(str);
if (fid > -1)
fprintf(fid, [str, ‘\n’]);
end;
B.3.7 Other helper functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Find & separate blocks with consecutive indices
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ConsecutiveBlocks] = findConsecutiveBlocks(FrameIndices)
D = diff(FrameIndices);
Changes = find(D > 1);
ConsecutiveBlocks = zeros(length(Changes)+1,2);
ConsecutiveBlocks(1,1) = FrameIndices(1);
for i = 1:length(Changes)
ConsecutiveBlocks(i,2) = FrameIndices(Changes(i));
if i <= length(Changes)
ConsecutiveBlocks(i+1,1) = FrameIndices(Changes(i)+1);
end
end
if ConsecutiveBlocks(end,2) == 0
ConsecutiveBlocks(end,2) = FrameIndices(end);
end
Annex C (informative):
Measurement method for determining the one way radio delays of LTE radio network simulators
The method decribed in this Annex can be used to determine or verify the delay introduced by a LTE radio network simulator.
NOTE. There is an inherent uncertainty in the method due the unknown delay of the modem delay (software stack in the modem). If this delay is known the measurement uncertainty can be reduced.