## 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.