diff --git a/tools/test/audio/process_test.m b/tools/test/audio/process_test.m index aaefe76a80a8..ece4c70461f7 100644 --- a/tools/test/audio/process_test.m +++ b/tools/test/audio/process_test.m @@ -139,18 +139,15 @@ fprintf('Number of skipped tests = %d\n', r.n_skipped); fprintf('============================================================\n'); - n_fail = r.n_fail; - n_pass = r.n_pass; - n_na = r.n_na; - if r.n_fail < 1 && r.n_pass < 1 - fprintf('\nERROR: No test results.\n'); - n_fail = 1; - elseif r.n_fail > 0 + if r.n_fail > 0 || r.n_pass < 1 fprintf('\nERROR: TEST FAILED!!!\n'); else fprintf('\nTest passed.\n'); end + n_fail = r.n_fail; + n_pass = r.n_pass; + n_na = r.n_na; end %% ------------------------------------------------------------ @@ -350,7 +347,7 @@ test.f_start = 20; test.f_end = test.fs * 0.41667; % 20 kHz @ 48 kHz test.fu = test.fs * 0.41667; % 20 kHz @ 48 kHz - test.f_max = 0.999*t.fs/2; % Measure up to min. Nyquist frequency + test.f_max = 0.999*test.fs/2; % Measure up to min. Nyquist frequency test.fs1 = test.fs; test.fs2 = test.fs; diff --git a/tools/test/audio/sof_test_perf.m b/tools/test/audio/sof_test_perf.m index 613862c7397d..3b491746aec8 100644 --- a/tools/test/audio/sof_test_perf.m +++ b/tools/test/audio/sof_test_perf.m @@ -46,8 +46,6 @@ test = get_config(test); %% Run tests -fail = 0; -pass = 0; test.tf = []; % Check that the configuration has been edited @@ -68,6 +66,9 @@ %% Total harmonic distortion plus noise [tf(3), thdnf_low, thdnf_high] = thdnf_test(test); + + %% Dynamic range + [tf(4), dynamic_range]= dr_test(test); end %% Print results @@ -81,6 +82,7 @@ print_val(test, tf(2), fr_3db_hz / 1000, 'kHz', '-3 dB frequency'); print_val(test, tf(3), thdnf_low, 'dB', 'THD+N -20 dBFS'); print_val(test, tf(3), thdnf_high, 'dB', 'THD+N -1 dBFS'); + print_val(test, tf(4), dynamic_range, 'dB', 'dr_db_min'); else fprintf(1, '\n'); fprintf(1, 'Warning: The gain test must pass before other tests are executed.\n'); @@ -128,8 +130,8 @@ %% Reference: AES17 6.2.3 Frequency response c1 = 20/48; c2 = 23.9/48; -test.f_lo = 20; % Measure start at 20 Hz -test.f_hi = c1 * test.fs; % Measure end e.g. at 20 kHz +test.fr_lo = 20; % Measure start at 20 Hz +test.fr_hi = c1 * test.fs; % Measure end e.g. at 20 kHz test.f_max = c2 * test.fs; % Sweep max e.g. at 23.9 kHz %% Create input file @@ -144,7 +146,7 @@ fail = test.fail; fr_db = test.rp; -fr_hz = [test.f_lo test.f_hi]; +fr_hz = [test.fr_lo test.fr_hi]; fr_3db_hz = test.fr3db_hz; delete_check(test.files_delete, test.fn_in); delete_check(test.files_delete, test.fn_out); @@ -182,6 +184,28 @@ end +%% Reference: AES17 6.4.1 Dynamic range +function [fail, dr_db] = dr_test(t) + +test = test_defaults(t); + +% Create input file +test = dr_test_input(test); + +% Run test +% test = test_run_process(test, t); +test = remote_test_run(test); + +% Measure +test = dr_test_measure(test); + +% Get output parameters +fail = test.fail; +dr_db = test.dr_db; +delete_check(test.files_delete, test.fn_in); +delete_check(test.files_delete, test.fn_out); + +end %% %% Utilities %% diff --git a/tools/test/audio/sof_test_perf_config.m b/tools/test/audio/sof_test_perf_config.m index cd5d3796cf98..f67da719645c 100644 --- a/tools/test/audio/sof_test_perf_config.m +++ b/tools/test/audio/sof_test_perf_config.m @@ -6,7 +6,7 @@ %% %% Set user@domain for ssh, need to be set for playback test -play.user = 'user@host.domain'; +play.user = 'localhost'; % username@ip-address %% Other playback settings play.ssh = 1; % Set to 1 for for remote play @@ -41,6 +41,12 @@ test.fr_rp_max_db = 1.0; % Upper limit for p-p ripple in dB test.plot_fr_axis = [10 30e3 -4 1]; % Plot xmin, xmax, ymin, ymax +test.fr_mask_flo = []; +test.fr_mask_fhi = []; +test.fr_mask_mlo = []; +test.fr_mask_mhi = []; %% THD+N test case test.thdnf_max = -55; % Upper limit for THD+N test.plot_thdn_axis = [10 30e3 -90 -40]; % Plot xmin xmax ymin ymax +%% dynamic range test case +test.dr_db_min = 70; % Min. DR,80dB diff --git a/tools/test/audio/std_utils/dr_test_measure.m b/tools/test/audio/std_utils/dr_test_measure.m index 6e8634fb90d8..abb76cfef885 100644 --- a/tools/test/audio/std_utils/dr_test_measure.m +++ b/tools/test/audio/std_utils/dr_test_measure.m @@ -57,7 +57,7 @@ level_in = test.a_db; level_out = level_dbfs(y); level_final = level_dbfs(y_n); -test.dr_db = level_out-level_final-test.a_db; +test.dr_db = level_out - level_final - test.a_db; fprintf('DR = %5.1f dB\n', test.dr_db); if 0 plot(y); diff --git a/tools/test/audio/std_utils/fr_test_input.m b/tools/test/audio/std_utils/fr_test_input.m index c2ea782f701e..871e50ee9de8 100644 --- a/tools/test/audio/std_utils/fr_test_input.m +++ b/tools/test/audio/std_utils/fr_test_input.m @@ -88,7 +88,7 @@ test.tr = 10e-3; % Gain ramp time for tones test.sm = 3; % Seek start marker from 3s from start test.em = 3; % Seek end marker from 3s from end -test.mt = 0.1; % Error if marker positions delta is greater than 0.1s +test.mt = 2; % Error if marker positions delta is greater than 2s test.tc = 10; % Min. 10 cycles of sine wave for a frequency t_min = 0.1; % Use t_min or min cycles count as tone length diff --git a/tools/test/audio/std_utils/fr_test_measure.m b/tools/test/audio/std_utils/fr_test_measure.m index 90d5207058df..a2b8fde130cd 100644 --- a/tools/test/audio/std_utils/fr_test_measure.m +++ b/tools/test/audio/std_utils/fr_test_measure.m @@ -33,15 +33,17 @@ % Author: Seppo Ingalsuo %% Check if upper and lower mask is defined -if length(test.fr_mask_flo) || length(test.fr_mask_fhi) +if ~isempty(test.fr_mask_flo) || ~isempty(test.fr_mask_fhi) test.fr_lo = 0; test.fr_hi = 0; end if test.fr_lo > 0 || test.fr_hi > 0 - test.fr_mask_flo = []; - test.fr_mask_fhi = []; - test.fr_mask_mlo = []; - test.fr_mask_mhi = []; + test.fr_mask_fhi = [20 test.f_max]; + test.fr_mask_flo = [200 400 3500 3600 ]; + for i = 1:test.nch + test.fr_mask_mhi(:,i) = [ 1 1 ]; + test.fr_mask_mlo(:,i) = [-10 -1 -1 -10]; + end end test.ph = []; @@ -109,7 +111,7 @@ mask_hi = interp1(log(test.fr_mask_fhi), ... test.fr_mask_mhi(:,j), f_log, 'linear'); over_mask = test.m(:,j)-mask_hi'; - idx = find(isnan(over_mask) == 0); + idx = ~isnan(over_mask); [m_over_mask, io] = max(over_mask(idx)); if m_over_mask > 0 fprintf('Failed upper response mask around %.0f Hz\n', ... @@ -122,7 +124,7 @@ mask_lo = interp1(log(test.fr_mask_flo), ... test.fr_mask_mlo(:,j), f_log, 'linear'); under_mask = mask_lo'-test.m(:,j); - idx = find(isnan(under_mask) == 0); + idx = ~isnan(under_mask); [m_under_mask, iu] = max(under_mask(idx)); if m_under_mask > 0 fprintf('Failed lower response mask around %.0f Hz\n', ... diff --git a/tools/test/audio/std_utils/level_dbfs.m b/tools/test/audio/std_utils/level_dbfs.m index 8bca996648eb..62676335bfe7 100644 --- a/tools/test/audio/std_utils/level_dbfs.m +++ b/tools/test/audio/std_utils/level_dbfs.m @@ -6,7 +6,7 @@ % x - signal % % Output -% dbfs - sigmal level in dBFS +% dbfs - signal level in dBFS % % SPDX-License-Identifier: BSD-3-Clause @@ -14,7 +14,6 @@ % Author: Seppo Ingalsuo %% Reference AES 17 3.12.3 -level_ms = mean(x.^2); -dbfs = 10*log10(level_ms + 1e-20) + 20*log10(sqrt(2)); +dbfs = 20*log10(rms(x) * sqrt(2)); end diff --git a/tools/test/audio/std_utils/thdnf_test_input.m b/tools/test/audio/std_utils/thdnf_test_input.m index d833f16b8e5d..fc02a84b970d 100644 --- a/tools/test/audio/std_utils/thdnf_test_input.m +++ b/tools/test/audio/std_utils/thdnf_test_input.m @@ -59,7 +59,7 @@ test.tr = 10e-3; % Gain ramp time for tones test.sm = 3; % Seek start marker from 3s from start test.em = 3; % Seek end marker from 3s from end -test.mt = 0.1; % Error if marker positions delta is greater than 0.1s +test.mt = 2; % Error if marker positions delta is greater than 2s test.a_db = [-1 -20]; % -1 and -20 dBFS levels test.a = 10.^(test.a_db/20); test.tl = 4; % 3 seconds tone diff --git a/tools/test/audio/std_utils/thdnf_test_measure.m b/tools/test/audio/std_utils/thdnf_test_measure.m index a0bc35f1f856..9cccd76f0f56 100644 --- a/tools/test/audio/std_utils/thdnf_test_measure.m +++ b/tools/test/audio/std_utils/thdnf_test_measure.m @@ -7,18 +7,14 @@ 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 +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 +if isempty(test.thdnf_max) + error('Set either thdnf_max or thdnf_mask_f & thdnf_mask_hi but not both'); +elseif isempty(test.thdnf_mask_hi) + error('thdnf_mask_hi must be set when thdnf_mask_f is defined'); end %% Reference: AES17 6.3.2 THD+N ratio vs frequency @@ -76,16 +72,16 @@ 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 + fidx = find(test.thdnf(idx, 1) > mask_hi, 1); + if ~isempty(fidx) 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 + fidx = find(test.thdnf(idx, 2) > mask_hi, 1); + if ~isempty(fidx) fail_lo = 1; fprintf('Failed THD+N mask with low input.\n'); else diff --git a/tools/test/audio/test_utils/find_test_signal.m b/tools/test/audio/test_utils/find_test_signal.m index c4002bef8569..282e443e1cd0 100644 --- a/tools/test/audio/test_utils/find_test_signal.m +++ b/tools/test/audio/test_utils/find_test_signal.m @@ -21,7 +21,7 @@ nt = []; nt_use = []; nt_skip = []; - +trace_en = false; % Enable to trace algorithm -analysis %% Use channel with strongest signal ch = select_channel(x0); x = x0(:, ch); @@ -35,29 +35,59 @@ y = x(1:n); [r, lags] = xcorr(y, s); r2 = r.^2; -r2_thr = 0.1 * max(r2); +r2_thr = mean(abs(r2)) + std(abs(r2))*3; %1/3rd of Max value idx = find(r2 > r2_thr); d_start = lags(idx(1)); +fprintf('Finding test start marker.up\n'); + +if isequal(trace_en,true) + fprintf(['%20s|%20s|%20s|%20s|%20s|%20s|%20s|%20s|\n--------------------+--------------------+--------------------+----' ... + '----------------+--------------------+--------------------+--------------------+--------------------+\n'], ... + 'nx', 'n_seek', 'test.fs', 'test.idle_t', 'test.mark_t', 'test.sm', 'n','d_start'); + + fprintf('%20d|%20d|%20d|%20.6f|%20.6f|%20d|%20d|%20d|\n',nx, n_seek, test.fs, test.idle_t, test.mark_t, test.sm, n,d_start); +end + + %% Find end marker fprintf('Finding test end marker...\n'); s = sync_chirp(test.fs, 'down'); + +nx = length(x); n_seek = round(test.fs*(test.idle_t + test.mark_t)); n = min(max(round(test.fs*test.em),n_seek), nx); y = x(end-n+1:end); [r, lags] = xcorr(y, s); r2 = r.^2; -r2_thr = 0.1 * max(r2); + +r2_thr = mean(abs(r2)) + std(abs(r2))*3; %1/3rd of Max value idx = find(r2 > r2_thr); d_end = nx-n+lags(idx(end)); +fprintf('Finding test start marker.down\n'); +if isequal(trace_en,true) + fprintf(['%20s|%20s|%20s|%20s|%20s|%20s|%20s|%20s|%20s|\n--------------------+--------------------+--------------------+----' ... + '----------------+--------------------+--------------------+--------------------+--------------------+--------------------+\n'], ... + 'nx', 'n_seek', 'test.fs', 'test.idle_t', 'test.mark_t', 'test.sm', 'n','d_start','d_end'); + fprintf('%20d|%20d|%20d|%20.6f|%20.6f|%20d|%20d|%20d|%20d|\n',nx, n_seek, test.fs, test.idle_t, test.mark_t, test.sm, n,d_start,d_end); + +end + + %% Check correct length of signal len = d_end-d_start; len_s = len/test.fs; ref_s = test.mark_t+test.nf*test.na*test.tl; -if abs(len_s-ref_s) > test.mt - fprintf(1, 'Start and end markers were not found. Signal quality may be poor.\n'); - return + +if isequal(trace_en,true) + fprintf(['%20s|%20s|%20s|%20s|\n--------------------+--------------------+' ... + '--------------------+--------------------+\n'],'len_s', 'ref_s', 'test.mt','abs(len_s - ref_s)'); + fprintf('%20f|%20f|%20f|%20f|\n', len_s, ref_s, test.mt,abs(len_s - ref_s)); +end +if abs(len_s - ref_s) > test.mt %FR , THD, DR,Relaxation may be required. + fprintf(1, 'Start and end markers were not found. Signal quality may be poor.\n'); + return end %% Delay to first tone, length of tone in samples @@ -65,7 +95,6 @@ if (d < 0) fprintf(1, 'Invalid delay value. Signal quality may be poor.\n'); return - d = []; end nt = round(test.tl*test.fs); nt_use = nt -round(test.is*test.fs) -round(test.ie*test.fs); @@ -92,6 +121,6 @@ nch = s(2); rms_db = zeros(1, nch); for i = 1:nch - rms_db(i) = 20*log10(sqrt(mean(x(:,i).^2))); + rms_db(i) = 20*log10(rms(x(:,i)));% very small data end end diff --git a/tools/test/audio/test_utils/mix_sweep.m b/tools/test/audio/test_utils/mix_sweep.m index a171f99de008..41c67ef624b6 100644 --- a/tools/test/audio/test_utils/mix_sweep.m +++ b/tools/test/audio/test_utils/mix_sweep.m @@ -4,7 +4,7 @@ % Copyright(c) 2017 Intel Corporation. All rights reserved. % Author: Seppo Ingalsuo -%% Adjust tone lengt to integer number of samples +%% Adjust tone length to integer number of samples test.nt = round(test.tl*test.fs); % Make number of samples per tone test.tl = test.nt/test.fs; % an integer by adjusting tl. test.nf = length(test.f); % Number of frequencies diff --git a/tools/tune/common/alsactl_write.m b/tools/tune/common/alsactl_write.m index 4ecf4af9c56e..2430ecbef0c2 100644 --- a/tools/tune/common/alsactl_write.m +++ b/tools/tune/common/alsactl_write.m @@ -21,4 +21,4 @@ function alsactl_write(fn, blob8) end fprintf(fh, '%ld,\n', blob32(end)); fclose(fh); -endfunction +end diff --git a/tools/tune/crossover/crossover_build_blob.m b/tools/tune/crossover/crossover_build_blob.m index eb6e2879a825..d3df6e501ebe 100644 --- a/tools/tune/crossover/crossover_build_blob.m +++ b/tools/tune/crossover/crossover_build_blob.m @@ -6,7 +6,7 @@ if nargin < 2 endian = 'little' -endif +end %% Shift values for little/big endian switch lower(endian) @@ -49,7 +49,7 @@ j=j+4; end -endfunction +end function bytes = word2byte(word, sh) bytes = uint8(zeros(1,4)); diff --git a/tools/tune/crossover/crossover_coef_quant.m b/tools/tune/crossover/crossover_coef_quant.m index 1546845268db..ca403c0c3afd 100644 --- a/tools/tune/crossover/crossover_coef_quant.m +++ b/tools/tune/crossover/crossover_coef_quant.m @@ -5,7 +5,7 @@ addpath ./../eq -if length(lowpass) != length(highpass) +if length(lowpass) ~= length(highpass) error("length of lowpass and highpass array do not match"); end @@ -20,8 +20,8 @@ hp_a = eq_coef_quant(-hp.a(3:-1:2), bits_iir, qf_iir); hp_b = eq_coef_quant(hp.b(3:-1:1), bits_iir, qf_iir); - crossover_quant.lp_coef(i) = [lp_a lp_b 0 16384]; - crossover_quant.hp_coef(i) = [hp_a hp_b 0 16384]; + crossover_quant.lp_coef{i} = [lp_a lp_b 0 16384]; + crossover_quant.hp_coef{i} = [hp_a hp_b 0 16384]; end crossover_quant.lp_coef = cell2mat(crossover_quant.lp_coef); diff --git a/tools/tune/crossover/crossover_gen_coefs.m b/tools/tune/crossover/crossover_gen_coefs.m index 10e00bf04d63..73961e7fc129 100644 --- a/tools/tune/crossover/crossover_gen_coefs.m +++ b/tools/tune/crossover/crossover_gen_coefs.m @@ -11,8 +11,8 @@ end function crossover_2way = crossover_generate_2way(fs, fc); - crossover_2way.lp = [lp_iir(fs, fc, 0)]; - crossover_2way.hp = [hp_iir(fs, fc, 0)]; + crossover_2way.lp = lp_iir(fs, fc, 0); + crossover_2way.hp = hp_iir(fs, fc, 0); end function crossover_3way = crossover_generate_3way(fs, fc_low, fc_high); @@ -29,13 +29,13 @@ % Generate the a,b coefficients for a second order % low pass butterworth filter -function lp = lp_iir(fs, fc, gain_db) +function lp = lp_iir(fs, fc, ~) [lp.b, lp.a] = low_pass_2nd_resonance(fc, 0, fs); end % Generate the a,b coefficients for a second order % low pass butterworth filter -function hp = hp_iir(fs, fc, gain_db) +function hp = hp_iir(fs, fc, ~) [hp.b, hp.a] = high_pass_2nd_resonance(fc, 0, fs); end @@ -54,7 +54,7 @@ b = [1 - cutoff, 0, 0]; a = [1, 0, 0]; return; - endif + end % Compute biquad coefficients for highpass filter resonance = max(0.0, resonance); % can't go negative @@ -90,7 +90,7 @@ b = [cutoff, 0, 0]; a = [1, 0, 0]; return; - endif + end % Compute biquad coefficients for lowpass filter resonance = max(0.0, resonance); % can't go negative diff --git a/tools/tune/crossover/crossover_plot_freq.m b/tools/tune/crossover/crossover_plot_freq.m index c75e18536e8b..ca55e24b5784 100644 --- a/tools/tune/crossover/crossover_plot_freq.m +++ b/tools/tune/crossover/crossover_plot_freq.m @@ -78,13 +78,23 @@ function plot_phase_resp(f,varargin) n = length(varargin); -labels = cellstr(n); + +labels = cellstr(char(n)); + hold on grid on for i=1:n - h = varargin{i}; - semilogx(f, unwrap(arg(h)) * 180 / pi) - labels(i) = sprintf("out%d", i); + h = varargin{i}; + if exist('OCTAVE_VERSION', 'builtin') + semilogx(f, unwrap(arg(h)) * 180 / pi) + else + semilogx(f, unwrap(angle(h)) * 180 / pi); + end + if exist('OCTAVE_VERSION', 'builtin') + labels(i) = sprintf("out%d", i); + else + labels{i} = sprintf("out%d", i); + end end legend(labels, 'Location', 'NorthEast') xlabel('Frequency (Hz)'); @@ -95,13 +105,18 @@ function plot_phase_resp(f,varargin) function plot_mag_resp(f,varargin) n = length(varargin); -labels = cellstr(n); +labels = cellstr(char(n)); hold on grid on for i=1:n h = varargin{i}; - semilogx(f,20*log10(h)) - labels(i) = sprintf("out%d", i); + semilogx(f,20*log10(abs(h))); + if exist('OCTAVE_VERSION', 'builtin') + labels(i) = sprintf("out%d", i); + else + labels{i} = sprintf("out%d", i); + end + end legend(labels, 'Location', 'NorthEast') xlabel('Frequency (Hz)'); diff --git a/tools/tune/crossover/example_crossover.m b/tools/tune/crossover/example_crossover.m index d46be04a6f0b..8c86c795ace3 100644 --- a/tools/tune/crossover/example_crossover.m +++ b/tools/tune/crossover/example_crossover.m @@ -1,10 +1,10 @@ function example_crossover(); % Set the parameters here -tplg_fn = "../../topology/topology1/m4/crossover_coef_default.m4" % Control Bytes File +tplg_fn = "../../topology/topology1/m4/crossover_coef_default.m4"; % Control Bytes File % Use those files with sof-ctl to update the component's configuration -blob_fn = "../../ctl/crossover_coef.blob" % Blob binary file -alsa_fn = "../../ctl/crossover_coef.txt" % ALSA CSV format file +blob_fn = "../../ctl/crossover_coef.blob"; % Blob binary file +alsa_fn = "../../ctl/crossover_coef.txt"; % ALSA CSV format file endian = "little"; @@ -51,4 +51,4 @@ crossover_plot_freq(crossover.lp, crossover.hp, fs, num_sinks); rmpath ./../common -endfunction +end diff --git a/tools/tune/dcblock/dcblock_build_blob.m b/tools/tune/dcblock/dcblock_build_blob.m index 43fa67f5c915..6719d96f1ccb 100644 --- a/tools/tune/dcblock/dcblock_build_blob.m +++ b/tools/tune/dcblock/dcblock_build_blob.m @@ -6,7 +6,7 @@ if nargin < 2 endian = 'little' -endif +end %% Shift values for little/big endian switch lower(endian) @@ -40,7 +40,7 @@ j=j+4; end -endfunction +end function bytes = word2byte(word, sh) bytes = uint8(zeros(1,4)); diff --git a/tools/tune/dcblock/dcblock_plot_stepfn.m b/tools/tune/dcblock/dcblock_plot_stepfn.m index 724b4bcfcf40..6cc0cd40be35 100644 --- a/tools/tune/dcblock/dcblock_plot_stepfn.m +++ b/tools/tune/dcblock/dcblock_plot_stepfn.m @@ -13,4 +13,4 @@ tstr = sprintf("DC Blocking Filter Step Response, R = %i", R); title(tstr); -endfunction +end diff --git a/tools/tune/dcblock/dcblock_plot_transferfn.m b/tools/tune/dcblock/dcblock_plot_transferfn.m index 8237222014a6..006d9b1ec26f 100644 --- a/tools/tune/dcblock/dcblock_plot_transferfn.m +++ b/tools/tune/dcblock/dcblock_plot_transferfn.m @@ -1,4 +1,4 @@ -function dcblock_plot_transferfn(R, fs); +function dcblock_plot_transferfn(R, fs) % Plot the transfer function. % For a DC Blocking filter: H(z) = (1-1/z)/(1 - R/z) % Therefore the coefficients are b = [1 -1], a = [1 -R] @@ -6,12 +6,14 @@ a = [1 -R]; f = linspace(1, fs/2, 500); - -semilogx(f, 20*log10(freqz(b, a, f, fs))); +[h,w] = freqz(b, a, f, fs); +% semilogx(f, 20*log10(freqz(b, a, f, fs))); +semilogx(w, 20*log10(abs(h))); grid on -xlabel('Frequency (Hz)'); +% xlabel('Frequency (Hz)'); +xlabel('Normalized Frequency (\times\pi rad/sample)'); ylabel('Magnitude (dB)'); tstr = sprintf("DC Blocking Filter Frequency Response, R = %i", R); title(tstr); -endfunction +end diff --git a/tools/tune/dcblock/example_dcblock.m b/tools/tune/dcblock/example_dcblock.m index 74490e5ab159..b7ada48df66c 100644 --- a/tools/tune/dcblock/example_dcblock.m +++ b/tools/tune/dcblock/example_dcblock.m @@ -27,4 +27,4 @@ rmpath ./../common -endfunction +end diff --git a/tools/tune/dmic/dmic_fir.m b/tools/tune/dmic/dmic_fir.m index b82a3c0faafe..b70651c15526 100644 --- a/tools/tune/dmic/dmic_fir.m +++ b/tools/tune/dmic/dmic_fir.m @@ -46,7 +46,7 @@ %% Iterate order and passband width iterate = 1; -lo_ind = find(f < passhz/20); +lo_ind = f < passhz/20; pb_ind = find(f < passhz); sb_ind = find(f > stophz); pb_ripple_min = 1000; diff --git a/tools/tune/drc/drc_build_blob.m b/tools/tune/drc/drc_build_blob.m index 1599c7715b2e..e9433c9991fd 100644 --- a/tools/tune/drc/drc_build_blob.m +++ b/tools/tune/drc/drc_build_blob.m @@ -2,7 +2,7 @@ if nargin < 2 endian = 'little' -endif +end %% Shift values for little/big endian switch lower(endian) @@ -58,7 +58,7 @@ blob8(j:j+3) = word2byte(blob_struct.kD, sh); j=j+4; blob8(j:j+3) = word2byte(blob_struct.kE, sh); j=j+4; -endfunction +end function bytes = word2byte(word, sh) bytes = uint8(zeros(1,4)); diff --git a/tools/tune/drc/drc_gen_coefs.m b/tools/tune/drc/drc_gen_coefs.m index 632c5b5fc935..0edfa39d2513 100644 --- a/tools/tune/drc/drc_gen_coefs.m +++ b/tools/tune/drc/drc_gen_coefs.m @@ -2,7 +2,7 @@ if exist('OCTAVE_VERSION', 'builtin') pkg load control; -endif +end % Print out params params @@ -82,7 +82,7 @@ max_k = k; % k is too high else min_k = k; % k is too low - endif + end % Re-calculate based on geometric mean k = sqrt(min_k * max_k); @@ -103,7 +103,7 @@ y2_db = mag2db(knee_curve(linear_threshold, x2, k)); slope = (y2_db - y_db) / (x2_db - x_db); -endif +end end @@ -114,6 +114,6 @@ y = x; else y = linear_threshold + (1 - exp(-k * (x - linear_threshold))) / k; -endif +end end diff --git a/tools/tune/drc/drc_plot_db_curve.m b/tools/tune/drc/drc_plot_db_curve.m index ae3952973e4e..230b9049f8be 100644 --- a/tools/tune/drc/drc_plot_db_curve.m +++ b/tools/tune/drc/drc_plot_db_curve.m @@ -2,7 +2,7 @@ if exist('OCTAVE_VERSION', 'builtin') pkg load control; -endif +end db_thres = coefs.db_threshold; db_knee_thres = db_thres + coefs.db_knee; @@ -18,21 +18,27 @@ % Plot the x-y dB curve plot(db_xs, db_ys, "b"); +text(db_xs(end), db_ys(end), "dB curve"); hold on grid on % Plot the reference line: x = db_thres plot([db_thres, db_thres], [db_ys(1), db_knee_thres], "g"); +text([db_thres, db_thres], [db_ys(1), db_knee_thres], "reference line: x = db thres"); hold on % Plot the reference line: x = db_knee_thres plot([db_knee_thres, db_knee_thres], [db_ys(1), db_knee_thres], "g"); +text([db_knee_thres, db_knee_thres], [db_ys(1), db_knee_thres], "reference line: x = db knee thres"); hold on % Plot the reference line: y = x plot([db_xs(1), db_knee_thres], [db_xs(1), db_knee_thres], "r"); +text([db_xs(1), db_knee_thres] + 0.5, [db_xs(1), db_knee_thres], "reference line: y = x",'HorizontalAlignment', 'Center', 'VerticalAlignment', 'Bottom'); hold off +title('Single band DRC range of db(x) determined by thres(db) and knee thres(db)'); %pause(); end + function db_ys = db_curve(coefs, db_xs); db_thres = coefs.db_threshold; @@ -50,7 +56,7 @@ else % Among knee curve db_ys(i) = db_knee_curve(coefs, db_x); - endif + end end end diff --git a/tools/tune/drc/example_drc.m b/tools/tune/drc/example_drc.m index 580aede93d8f..773f3b19db49 100644 --- a/tools/tune/drc/example_drc.m +++ b/tools/tune/drc/example_drc.m @@ -53,4 +53,4 @@ rmpath ./../common -endfunction +end diff --git a/tools/tune/eq/eq_compute.m b/tools/tune/eq/eq_compute.m index f20863772261..266af9096422 100644 --- a/tools/tune/eq/eq_compute.m +++ b/tools/tune/eq/eq_compute.m @@ -41,7 +41,7 @@ %% Define target (e.g. speaker) response as parametric filter. This could also % be numerical data interpolated to the grid. -if length(eq.parametric_target_response) > 0 +if ~isempty(eq.parametric_target_response) [eq.t_z, eq.t_p, eq.t_k] = eq_define_parametric_eq( ... eq.parametric_target_response, eq.fs); eq.t_db = eq_compute_response(eq.t_z, eq.t_p, eq.t_k, eq.f, eq.fs); @@ -121,7 +121,7 @@ %% Smooth response with 1/N octave filter for plotting eq.m_db_s = logsmooth(eq.f, eq.m_db, eq.logsmooth_plot); -if length(eq.target_m_db) > 0 +if ~isempty(eq.target_m_db) % Use target_m_db as dummy group delay, ignore other than magnitude [f0, m0, ~] = fix_response_dcnyquist_mult(eq.target_f, ... eq.target_m_db, [], eq.fs); @@ -139,14 +139,14 @@ if min(f_hz) > 0 f_hz = [0 f_hz]; m_db = [m_db(1) m_db]; % DC the same as 1st measured point - if length(gd_s) > 0 + if ~isempty(gd_s) gd_s = [gd_s(1) gd_s]; % DC the same as 1st measured point end end if max(f_hz) < fs/2 f_hz = [f_hz fs/2]; m_db = [m_db m_db(end)]; % Fs/2 the same as last measured point - if length(gd_s) > 0 + if ~isempty(gd_s) gd_s = [gd_s gd_s(end)]; % Fs/2 the same as last measured point end end @@ -251,17 +251,17 @@ m_db = err2db - err2db(idx); if auto cf = [1e3 6e3]; - ind1 = find(fhz < cf(2)); + ind1 = fhz < cf(2); ind2 = find(fhz(ind1) > cf(1)); ipeak = find(m_db(ind2) == max(m_db(ind2))) + ind2(1); - ind1 = find(fhz < cf(1)); + ind1 = fhz < cf(1); ind2 = find(m_db(ind1) > m_db(ipeak)); - if length(ind2) > 0 + if ~isempty(ind2) fmin_fir = fhz(ind2(end)); end ind1 = find(fhz > cf(2)); ind2 = find(m_db(ind1) > m_db(ipeak)) + ind1(1); - if length(ind2) > 0 + if ~isempty(ind2) fmax_fir = fhz(ind2(1)); end end @@ -270,16 +270,16 @@ ind1 = find(fhz < fmin_fir); ind2 = find(fhz > fmax_fir); p1 = ind1(end)+1; -if length(ind2) > 0 +if ~isempty(ind2) p2 = ind2(1)-1; else p2 = length(fhz); end m_db(ind1) = m_db(p1); m_db(ind2) = m_db(p2); -ind = find(m_db > amax_fir); +ind = m_db > amax_fir; m_db(ind) = amax_fir; -ind = find(m_db < amin_fir); +ind = m_db < amin_fir; m_db(ind) = amin_fir; %% Smooth high frequency corner with spline @@ -342,13 +342,13 @@ %% Find zeros inside unit circle myeps = 1e-3; hdzeros = roots(blin); -ind1 = find( abs(hdzeros) < (1-myeps) ); +ind1 = abs(hdzeros) < (1-myeps) ; minzeros = hdzeros(ind1); %% Find double zeros at unit circle -ind2 = find( abs(hdzeros) > (1-myeps) ); +ind2 = abs(hdzeros) > (1-myeps) ; outzeros = hdzeros(ind2); -ind3 = find( abs(outzeros) < (1+myeps) ); +ind3 = abs(outzeros) < (1+myeps) ; circlezeros = outzeros(ind3); %% Get half of the unit circle zeros @@ -359,7 +359,7 @@ cangle = angle(circlezeros); [sorted_cangle, ind] = sort(cangle); sorted_czeros = circlezeros(ind); - pos = find(angle(sorted_czeros) > 0); + pos = angle(sorted_czeros) > 0; neg = find(angle(sorted_czeros) < 0); pos_czeros = sorted_czeros(pos); neg_czeros = sorted_czeros(neg(end:-1:1)); @@ -369,7 +369,7 @@ h1 = [h1' complex(cos(x),sin(x))]'; end h2 = []; - for i = 1:2:length(neg_czeros)-1; + for i = 1:2:length(neg_czeros)-1 x=mean(angle(neg_czeros(i:i+1))); h2 = [h2' complex(cos(x),sin(x))]'; end @@ -412,7 +412,7 @@ i1 = zeros(1,n1); i2 = zeros(1,n1); i1(1) = 1; - for i = 1:n1-1; + for i = 1:n1-1 if rem > 0 i2(i) = i1(i)+rpb; rem = rem-1; diff --git a/tools/tune/eq/eq_define_parametric_eq.m b/tools/tune/eq/eq_define_parametric_eq.m index 70a728e14c73..29e4684c5b82 100644 --- a/tools/tune/eq/eq_define_parametric_eq.m +++ b/tools/tune/eq/eq_define_parametric_eq.m @@ -73,10 +73,10 @@ otherwise error('Unknown parametric EQ type'); end - if length(a0) > 0 + if ~isempty(a0) [z0, p0, k0] = tf2zp(b0, a0); end - if length(k0) > 0 + if ~isempty(k0) z = [z ; z0(:)]; p = [p ; p0(:)]; k = k * k0; @@ -127,15 +127,15 @@ A = 10^(gdb/40); % Square root of linear gain wc = 2*pi*fhz/fs; - if Q <= 0 - % To fix gui edge cases, comment from CRAS code: - % When Q = 0, the above formulas have problems. If we - % look at the z-transform, we can see that the limit - % as Q->0 is A^2, so set the filter that way. - b = [A * A, 0, 0] - a = [1, 0, 0]; - return; - endif + if Q <= 0 + % To fix gui edge cases, comment from CRAS code: + % When Q = 0, the above formulas have problems. If we + % look at the z-transform, we can see that the limit + % as Q->0 is A^2, so set the filter that way. + b = [A * A, 0, 0]; + a = [1, 0, 0]; + return; + end alpha = sin(wc)/(2*Q); b0 = 1 + alpha * A; @@ -163,7 +163,7 @@ b = [1 - cutoff, 0, 0]; a = [1, 0, 0]; return; - endif + end % Compute biquad coefficients for highpass filter resonance = max(0.0, resonance); % can't go negative @@ -199,7 +199,7 @@ b = [cutoff, 0, 0]; a = [1, 0, 0]; return; - endif + end % Compute biquad coefficients for lowpass filter resonance = max(0.0, resonance); % can't go negative @@ -239,7 +239,7 @@ b = [0, 0, 0]; a = [1, 0, 0]; return; - endif + end if (Q <= 0) % When Q = 0, the above formulas have problems. If we % look at the z-transform, we can see that the limit @@ -247,7 +247,7 @@ b = [1, 0, 0]; a = [1, 0, 0]; return; - endif + end w0 = pi * frequency; alpha = sin(w0) / (2 * Q); @@ -271,20 +271,20 @@ % Don't let Q go negative, which causes an unstable filter. Q = max(0.0, Q); - if frequency <= 0 || frequency >= 1 - % When frequency is 0 or 1, the z-transform is 1. - b = [1, 0, 0]; - a = [1, 0, 0]; - return; - endif - if Q <= 0 - % When Q = 0, the above formulas have problems. If we - % look at the z-transform, we can see that the limit - % as Q->0 is 0, so set the filter that way. - b = [0, 0, 0]; - a = [1, 0, 0]; - return; - endif + if frequency <= 0 || frequency >= 1 + % When frequency is 0 or 1, the z-transform is 1. + b = [1, 0, 0]; + a = [1, 0, 0]; + return; + end + if Q <= 0 + % When Q = 0, the above formulas have problems. If we + % look at the z-transform, we can see that the limit + % as Q->0 is 0, so set the filter that way. + b = [0, 0, 0]; + a = [1, 0, 0]; + return; + end w0 = pi * frequency; alpha = sin(w0) / (2 * Q); @@ -313,13 +313,13 @@ b = [A * A, 0, 0]; a = [1, 0, 0]; return; - endif + end if (frequency <= 0) % When frequency is 0, the z-transform is 1. b = [1, 0, 0]; a = [1, 0, 0]; return; - endif + end w0 = pi * frequency; S = 1; % filter slope (1 is max value) @@ -353,13 +353,13 @@ b = [1, 0, 0]; a = [1, 0, 0]; return; - endif + end if (frequency <= 0) % When frequency = 0, the filter is just a gain, A^2. b = [A * A, 0, 0]; a = [1, 0, 0]; return; - endif + end w0 = pi * frequency; S = 1; % filter slope (1 is max value) diff --git a/tools/tune/eq/example_spk_eq.m b/tools/tune/eq/example_spk_eq.m index fdc1f096ac42..37b7f557098a 100644 --- a/tools/tune/eq/example_spk_eq.m +++ b/tools/tune/eq/example_spk_eq.m @@ -90,7 +90,7 @@ function example_spk_eq() % The lowest and highest frequeciens below and above speaker % capability are attenuated with high-pass and low-pass % filtering. -if eq.enable_iir; +if eq.enable_iir eq.peq = [ ... eq.PEQ_HP2 100 NaN NaN; ... eq.PEQ_PN2 1480 -7 2.0; ... @@ -102,12 +102,12 @@ function example_spk_eq() %% With FIR EQ try to flatten frequency response within % 1 - 13 kHz frequency band. if eq.enable_fir - eq.fir_minph = 1; - eq.fir_beta = 4; - eq.fir_length = 63; - eq.fir_autoband = 0; - eq.fmin_fir = 900; - eq.fmax_fir = 10700; + eq.fir_minph = 1; + eq.fir_beta = 4; + eq.fir_length = 63; + eq.fir_autoband = 0; + eq.fmin_fir = 900; + eq.fmax_fir = 10700; end %% Design EQ @@ -125,7 +125,7 @@ function example_spk_eq() bm_fir = eq_fir_blob_merge(channels_in_config, ... num_responses, ... assign_response, ... - [ bq_fir ]); + bq_fir ); bp_fir = eq_fir_blob_pack(bm_fir); eq_alsactl_write(fn_fir_sofctl, bp_fir); eq_blob_write(fn_fir_blob, bp_fir); @@ -138,7 +138,7 @@ function example_spk_eq() bm_iir = eq_iir_blob_merge(channels_in_config, ... num_responses, ... assign_response, ... - [ bq_iir ]); + ( bq_iir )); bp_iir = eq_iir_blob_pack(bm_iir); eq_alsactl_write(fn_iir_sofctl, bp_iir); eq_blob_write(fn_iir_blob, bp_iir); diff --git a/tools/tune/eq/mls_freq_resp.m b/tools/tune/eq/mls_freq_resp.m index a6fbdbdb0497..aabddc584aaf 100644 --- a/tools/tune/eq/mls_freq_resp.m +++ b/tools/tune/eq/mls_freq_resp.m @@ -57,8 +57,8 @@ else selftest = 0; end -measfn = sprintf('mls-%s.wav', id); -csvfn = sprintf('mls-%s.txt', id); +measfn = sprintf('mls-%d.wav', id); +csvfn = sprintf('mls-%d.txt', id); %% Paths addpath('../../test/audio/test_utils'); @@ -101,10 +101,10 @@ recfn = 'recch.wav'; y = []; if selftest - labels = cell(play_cfg.nch * rec_cfg.nch + 1, 1); + labels = cellstr(char(play_cfg.nch * rec_cfg.nch + 1, 1)); labels(end) = 'Reference'; else - labels = cell(play_cfg.nch * rec_cfg.nch, 1); + labels = cellstr(char(play_cfg.nch * rec_cfg.nch, 1)); end label_idx = 1; for i=1:play_cfg.nch @@ -130,7 +130,7 @@ r = get_recording(recfn, rec_cfg); end for j = 1:rec_cfg.nch - labels(label_idx) = sprintf('p%d-r%d', i, j); + labels{label_idx} = sprintf('p%d-r%d', i, j); label_idx = label_idx + 1; end [d, nt] = find_test_signal(r(:,1), fnd); @@ -200,7 +200,7 @@ legend(labels); if selftest - idx = find(f < f_hi); + idx = f < f_hi; idx = find(f(idx) > f_lo); m_lin = 10.^(m_db_align(idx)/20); ref_lin = 10.^(ref_db_align(idx)/20); @@ -330,14 +330,14 @@ function remote_capture(fn, cfg, t) sens =[]; desc = ''; str = fgets(fh); - idx = findstr(str, '"'); - while length(idx) > 0 + idx = strfind(str, '"'); + while ~isempty(idx) line = str(idx(1)+1:idx(2)-1); desc = sprintf('%s%s ', desc, line); str = fgets(fh); - idx = findstr(str, '"'); + idx = strfind(str, '"'); end - if length(strfind(str, 'Sens')) + if contains(str, 'Sens') desc = str; str = fgets(fh); end @@ -403,7 +403,7 @@ function remote_capture(fn, cfg, t) function [cal_f, cal_m_db] = apply_mic_calibration(f, m_db, rec) - if length(rec.cm) > 0 + if ~isempty(rec.cm) if ~isvector(rec.cm) error('Calibration can be for one channel only'); end diff --git a/tools/tune/multiband_drc/example_multiband_drc.m b/tools/tune/multiband_drc/example_multiband_drc.m index 2594c3b86682..a4772dc6caae 100644 --- a/tools/tune/multiband_drc/example_multiband_drc.m +++ b/tools/tune/multiband_drc/example_multiband_drc.m @@ -97,17 +97,17 @@ [emp_coefs, deemp_coefs] = iir_gen_quant_coefs(iir_params); % Generate Crossover quantized coefs struct from parameters -crossover_coefs = crossover_gen_quant_coefs(num_bands, sample_rate, - drc_params(2).band_lower_freq, - drc_params(3).band_lower_freq, +crossover_coefs = crossover_gen_quant_coefs(num_bands, sample_rate,... + drc_params(2).band_lower_freq, ... + drc_params(3).band_lower_freq, ... drc_params(4).band_lower_freq); % Generate DRC quantized coefs struct from parameters drc_coefs = drc_gen_quant_coefs(num_bands, sample_rate, drc_params); % Convert quantized coefs structs to binary blob -blob8 = multiband_drc_build_blob(num_bands, enable_emp_deemp, emp_coefs, - deemp_coefs, crossover_coefs, drc_coefs, +blob8 = multiband_drc_build_blob(num_bands, enable_emp_deemp, emp_coefs,... + deemp_coefs, crossover_coefs, drc_coefs,... endian); % Generate output files @@ -119,4 +119,4 @@ rmpath ../common -endfunction +end diff --git a/tools/tune/multiband_drc/iir_gen_quant_coefs.m b/tools/tune/multiband_drc/iir_gen_quant_coefs.m index 425a7513bba5..b67727f4a833 100644 --- a/tools/tune/multiband_drc/iir_gen_quant_coefs.m +++ b/tools/tune/multiband_drc/iir_gen_quant_coefs.m @@ -1,4 +1,4 @@ -function [emp_coefs, deemp_coefs] = iir_gen_quant_coefs(params); +function [emp_coefs, deemp_coefs] = iir_gen_quant_coefs(params) stage_gain = params.stage_gain; stage_ratio = params.stage_ratio; @@ -7,13 +7,13 @@ emp = cell(1, 2); deemp = cell(1, 2); % Generate the coefficients of (de)emphasis for the 1-st stage of biquads -[emp(1), deemp(1)] = emp_deemp_stage_biquad(stage_gain, anchor_freq, +[emp(1), deemp(1)] = emp_deemp_stage_biquad(stage_gain, anchor_freq,... anchor_freq / stage_ratio); anchor_freq = anchor_freq / (stage_ratio * stage_ratio); % Generate the coefficients of (de)emphasis for the 2-nd stage of biquads -[emp(2), deemp(2)] = emp_deemp_stage_biquad(stage_gain, anchor_freq, +[emp(2), deemp(2)] = emp_deemp_stage_biquad(stage_gain, anchor_freq,... anchor_freq / stage_ratio); % Adjust the stage gain (push gains to the last stage) of emphasis filter @@ -29,7 +29,7 @@ end -function [emp, deemp] = emp_deemp_stage_biquad(gain, f1, f2); +function [emp, deemp] = emp_deemp_stage_biquad(gain, f1, f2) [z1, p1] = emp_stage_roots(gain, f1); [z2, p2] = emp_stage_roots(gain, f2); @@ -58,7 +58,7 @@ end -function [zero, pole] = emp_stage_roots(gain, normalized_freq); +function [zero, pole] = emp_stage_roots(gain, normalized_freq) gk = 1 - gain / 20; f1 = normalized_freq * gk; @@ -68,7 +68,7 @@ end -function quant_coefs = iir_coef_quant(coefs); +function quant_coefs = iir_coef_quant(coefs) bits_iir = 32; % Q2.30 qf_iir = 30; @@ -92,7 +92,7 @@ end -function [bq1, bq2] = stage_gain_adjust(prev_bq1, prev_bq2); +function [bq1, bq2] = stage_gain_adjust(prev_bq1, prev_bq2) prev_bq1 = cell2mat(prev_bq1); prev_bq2 = cell2mat(prev_bq2); @@ -103,7 +103,7 @@ end -function [rshift, gain] = decompose_gain(prev_gain); +function [rshift, gain] = decompose_gain(prev_gain) max_abs_val = 2; % Q2.14 rshift = 0; @@ -111,7 +111,7 @@ while (abs(gain) >= max_abs_val) gain = gain / 2; - rshift--; % left-shift in shift stage -endwhile + rshift = rshift - 1;%left-shift in shift stage +end end