function test = thdnf_test_measure(test)

% SPDX-License-Identifier: BSD-3-Clause
% Copyright(c) 2017 Intel Corporation. All rights reserved.
% Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>

debug = 0;
test.ph = [];
test.fh = [];

if isempty(test.thdnf_mask_f)
	if ~isempty(test.thdnf_max)
		test.thdnf_mask_f = [1 test.fs/2]; % Start from 1 due to log()
		test.thdnf_mask_hi = test.thdnf_max * [1 1];
	end
else
	if ~isempty(test.thdnf_max)
		error('Set either thdnf_max or thdnf_mask_f & thdnf_mask_hi but not both');
	end
	if isempty(test.thdnf_mask_hi)
		error('thdnf_mask_hi must be set when thdnf_mask_f is defined');
	end
end

%% Reference: AES17 6.3.2 THD+N ratio vs frequency
%  http://www.aes.org/publications/standards/

default_result = NaN * ones(test.nf, length(test.ch));
test.thdnf_high = default_result;
test.thdnf_low = default_result;

%% Load output file
[x, nx] = load_test_output(test);
if nx == 0
	test.fail = 1;
	return
end

%% Standard low-pass
y0 = stdlpf(x, test.fu, test.fs);

%% Find sync
[d, nt, nt_use, nt_skip] = find_test_signal(y0, test);
if isempty(d)
	test.fail = 1;
	return
end

%% Interpolate THD+N mask
idx = find(test.f <= test.thdnf_mask_f(end));
idx = find(test.f(idx) >= test.thdnf_mask_f(1));
f_mask = test.f(idx);
f_log = log(f_mask);
mask_hi = interp1(log(test.thdnf_mask_f), test.thdnf_mask_hi, f_log, 'linear');
mask_hi = mask_hi(:);

%% Measure all test frequencies
test.fail = 0;
for i = 1:length(test.ch);
	ml = zeros(test.nf,test.na);
	mn = zeros(test.nf,test.na);
	n_notch_settle = round(test.fs*test.nst);
	nn = 1;
	for m=1:test.na
		for n=1:test.nf
			if debug
				fprintf('Measuring %.0f Hz ...\n', test.f(n));
			end
			i1 = d+(nn-1)*nt+nt_skip;
			i2 = i1+nt_use-1;
			nn = nn+1;
			y0n = stdnotch(y0(i1:i2, i), test.f(n), test.fs);
			ml(n,m) = level_dbfs(y0(i1:i2, i));
			mn(n,m) = level_dbfs(y0n(n_notch_settle:end));
		end
	end

	test.thdnf = mn - ml;
	test.thdnf_high(:,i) = test.thdnf(:,1);
	test.thdnf_low(:,i) = test.thdnf(:,2);

	fidx = find(test.thdnf(idx, 1) > mask_hi);
	if length(fidx) > 0
		fail_hi = 1;
		fprintf('Failed THD+N mask with high input.\n');
	else
		fail_hi = 0;
	end

	fidx = find(test.thdnf(idx, 2) > mask_hi);
	if length(fidx) > 0
		fail_lo = 1;
		fprintf('Failed THD+N mask with low input.\n');
	else
		fail_lo = 0;
	end

	if fail_hi && fail_lo
		test.fail = 1;
	end
end

%% Do plots
for i = 1:length(test.ch)
	test.fh(i) = figure('visible', test.plot_visible);
	test.ph(i) = subplot(1, 1, 1);

	if test.plot_channels_combine
		semilogx(test.f, test.thdnf_high, test.f, test.thdnf_low);
	else
		semilogx(test.f, test.thdnf_high(:,i), ...
			test.f, test.thdnf_low(:,i));
	end

	if ~isempty(test.thdnf_mask_f)
		hold on
		plot(f_mask, mask_hi, 'k--');
		hold off
	end

	grid on;
	if ~isempty(test.plot_thdn_axis)
		axis(test.plot_thdn_axis);
	end

	xlabel('Frequency (Hz)');
	ylabel('THD+N (dB)');

	if test.plot_channels_combine && (test.nch > 1)
		switch test.nch
			case 2
				ls1 = sprintf("ch%d  -1 dBFS", test.ch(1));
				ls2 = sprintf("ch%d  -1 dBFS", test.ch(2));
				ls3 = sprintf("ch%d -20 dBFS", test.ch(1));
				ls4 = sprintf("ch%d -20 dBFS", test.ch(2));
				legend(ls1, ls2, ls3, ls4, 'Location', 'NorthEast');
		end
	else
		ls1 = sprintf("ch%d  -1 dBFS", test.ch(i));
		ls2 = sprintf("ch%d -20 dBFS", test.ch(i));
		legend(ls1, ls2, 'Location', 'NorthEast');
	end

	if test.plot_channels_combine
		break
	end

end

end
