EQ Tool: Add calibration data import

This patch adds capability to apply for capture microphone calibration
data (ASCII text lines with Hz, dB values). The calibration data file
name needs to be edited into configuration file mls_rec_config.txt. Such
calibration data is provided by several inexpensive USB measurement
microphones manufacturers.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This commit is contained in:
Seppo Ingalsuo 2018-10-19 19:27:34 +03:00
parent b5eb15516c
commit fa0735572b
2 changed files with 128 additions and 11 deletions

View File

@ -169,6 +169,8 @@ fprintf('Done.\n');
[f, m_db, b] = mls_calc_resp(csvfn, mlsfn, measfn, t_tot, np, f_lo, f_hi);
[f, m_db] = apply_mic_calibration(f, m_db, rec_cfg);
figure
idx = find(f>1e3, 1, 'first') - 1;
m_db_align = m_db - m_db(idx);
@ -273,12 +275,89 @@ function rec = meas_remote_rec_config(fs, fmt)
rec.nch, fmt, fs);
fprintf('\nThe setttings for remote capture are\n');
fprintf('Use ssh : %d\n', rec.ssh);
fprintf('User : %s\n', rec.user);
fprintf('Directory : %s\n', rec.dir);
fprintf('Device : %s\n', rec.dev);
fprintf('format : %s\n', rec.fmt);
fprintf('Channels : %d\n', rec.nch);
fprintf('Use ssh : %d\n', rec.ssh);
fprintf('User : %s\n', rec.user);
fprintf('Directory : %s\n', rec.dir);
fprintf('Device : %s\n', rec.dev);
fprintf('format : %s\n', rec.fmt);
fprintf('Channels : %d\n', rec.nch);
fprintf('Calibration Data : %s\n', rec.cal);
if length(rec.cal) > 0
if exist(rec.cal, 'file')
[rec.cf, rec.cm, rec.sens, rec.cs] = get_calibration(rec.cal);
else
error('The calibration file does not exist');
end
else
rec.cf = [];
rec.cm = [];
rec.sens = [];
rec.cs = '';
end
end
% The syntax of ASCII text calibration data is such that first line is
% text string sometimes within "" or text line about Sensitivity. Such
% lines are read and stored to description text. The sensitivty is extracted
% and printed if success but currently it is not utilized by the code.
%
% The next lines are <frequency Hz> <magnitude decibels> for
% measurement data for microphone. If there are more than two numbers
% per line the other than two first columns are ignored. This code
% applies inverse of calibration data for measured response calibration.
function [f, m, sens, desc] = get_calibration(fn)
fh = fopen(fn, 'r');
if fh < 0
error('Cannot open calibration data file');
end
n = 1;
f = [];
m = [];
sens =[];
desc = '';
str = fgets(fh);
idx = findstr(str, '"');
while length(idx) > 0
line = str(idx(1)+1:idx(2)-1);
desc = sprintf('%s%s ', desc, line);
str = fgets(fh);
idx = findstr(str, '"');
end
if length(strfind(str, 'Sens'))
desc = str;
str = fgets(fh);
end
while str ~= -1
d=sscanf(str,'%f');
f(n) = d(1);
m(n) = d(2);
n = n + 1;
str = fgets(fh);
end
% Strip possible linefeed from description end
if double(desc(end)) == 10
desc = desc(1:end-1);
end
fprintf('Calibration Info : %s\n', desc);
i1 = strfind(desc, 'Sens Factor =');
i2 = strfind(desc, 'dB');
if length(i1) == 1 && length(i2) == 1
sens = sscanf(desc(i1+13:i2-1), '%f');
fprintf('Calibration Sens : %6.2f dB\n', sens);
end
fprintf('Calibration range: %.2f .. %.2f Hz\n', min(f), max(f));
fprintf('Calibration range: %.2f .. %.2f dB\n', min(m), max(m));
figure;
semilogx(f, m);
grid on;
title(desc);
xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
end
function [x, seed] = mlsp12(seed, n)
@ -304,3 +383,30 @@ function [x, seed] = mlsp12(seed, n)
end
end
end
%% Calibration apply function
% Resample microphone calibration data into used grid and
% then subtract calibration response from measured
% response.
function [cal_f, cal_m_db] = apply_mic_calibration(f, m_db, rec)
if length(rec.cm) > 0
if ~isvector(rec.cm)
error('Calibration can be for one channel only');
end
mic_m_db = interp1(rec.cf, rec.cm, f, 'linear');
nans = isnan(mic_m_db);
idx = find(nans == 0);
cal_f = f(idx);
cal_db = mic_m_db(idx);
s = size(m_db);
for i = 1:s(2)
cal_m_db(:,i) = m_db(idx,i) - cal_db(:);
end
else
cal_m_db = m_db;
cal_f = f;
end
end

View File

@ -1,5 +1,16 @@
rec.ssh = 0; % Set to 1 for remote capture
rec.user = ''; % Set to user@domain for ssh
rec.dir = '/tmp'; % Directory for temporary files
rec.dev = 'hw:0,0'; % Audio capture device
rec.nch = 2; % Number audio capture channels to use
%% Recording device configuration
rec.ssh = 0; % Set to 1 for remote capture
rec.user = ''; % Set to user@domain for ssh
rec.dir = '/tmp'; % Directory for temporary files
rec.dev = 'hw:0,0'; % Audio capture device
rec.nch = 2; % Number audio capture channels to use
% Use '' if calibration is not needed. Otherwise set to
% e.g. '1234567.txt'. Such calibration data format is supported for
% some reasonably priced measurement microphones. The ASCII text
% calibration data file is the measured frequency response of the used
% microphone. Lines in the beginning those start with character " are
% treated as comment. The successive lines should be <frequency>
% <magnitude> number pairs. Their unit must be Hz and dB.
rec.cal = '';