|
| 1 | +function [f, m_db, b] = mls_calc_resp(csv_fn, ref_wfn, meas_wfn, t_tot, np, f_lo, f_hi) |
| 2 | + |
| 3 | +%% Calculate frequency response from MLS recordings |
| 4 | +% |
| 5 | +% [f, m, b] = calc_freq_resp(csv_fn, ref_fn, meas_fn, t_tot, np, f_lo, f_hi) |
| 6 | +% |
| 7 | +% Inputs parameters: |
| 8 | +% csv_fn - File name for CSV format response output |
| 9 | +% ref_fn - Reference MLS wave file |
| 10 | +% meas_fn - Captured MSL wave file |
| 11 | +% t_tot - Time window of MLS analysis in s, e.g. 5 - 10 ms |
| 12 | +% np - Number of frequency points |
| 13 | +% f_lo - Lower frequency limit for analysis |
| 14 | +% f_hi - Upper frequency limit for analysis |
| 15 | + |
| 16 | +%% |
| 17 | +% Copyright (c) 2018, Intel Corporation |
| 18 | +% All rights reserved. |
| 19 | +% |
| 20 | +% Redistribution and use in source and binary forms, with or without |
| 21 | +% modification, are permitted provided that the following conditions are met: |
| 22 | +% * Redistributions of source code must retain the above copyright |
| 23 | +% notice, this list of conditions and the following disclaimer. |
| 24 | +% * Redistributions in binary form must reproduce the above copyright |
| 25 | +% notice, this list of conditions and the following disclaimer in the |
| 26 | +% documentation and/or other materials provided with the distribution. |
| 27 | +% * Neither the name of the Intel Corporation nor the |
| 28 | +% names of its contributors may be used to endorse or promote products |
| 29 | +% derived from this software without specific prior written permission. |
| 30 | +% |
| 31 | +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 32 | +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 33 | +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 34 | +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 35 | +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 36 | +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 37 | +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 38 | +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 39 | +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 40 | +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 41 | +% POSSIBILITY OF SUCH DAMAGE. |
| 42 | +% |
| 43 | +% Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com> |
| 44 | +% |
| 45 | + |
| 46 | + %% Read audio files |
| 47 | + [xr, fs] = audioread(ref_wfn); |
| 48 | + [xm, fsm] = audioread(meas_wfn); |
| 49 | + sm = size(xm); |
| 50 | + nch = sm(2); |
| 51 | + |
| 52 | + if (fs ~= fsm) |
| 53 | + error('Reference and measured sample rates do not match.'); |
| 54 | + end |
| 55 | + |
| 56 | + ind_imp = zeros(1, nch); |
| 57 | + for ch=1:nch |
| 58 | + [acor(:,ch),lag] = xcorr(xm(:,ch), xr, 'coeff'); |
| 59 | + [~,I] = max(abs(acor(:,ch))); |
| 60 | + timeDiff = lag(I); |
| 61 | + % Crosscorrelation maximum points to max of impulse response. |
| 62 | + % Use it beginning of impulse response |
| 63 | + ind_imp(ch) = find(lag == timeDiff); |
| 64 | + end |
| 65 | + % Keep the channels time aligned by using average of max as reference |
| 66 | + ind_imp_avg = round(sum(ind_imp)/nch); |
| 67 | + |
| 68 | + b = []; |
| 69 | + nwin_half = round(t_tot*fs); |
| 70 | + nwin_tot = 2*nwin_half; |
| 71 | + win = hanning(nwin_tot); |
| 72 | + for ch = 1:nch |
| 73 | + % All channels are windowed from the same location |
| 74 | + p1 = ind_imp_avg-nwin_half; |
| 75 | + p2 = p1 + nwin_tot-1; |
| 76 | + acor_windowed = acor(p1:p2,ch) .* win; |
| 77 | + b(:,ch) = acor_windowed; |
| 78 | + end |
| 79 | + |
| 80 | + |
| 81 | + %% Compute frequency response |
| 82 | + f = logspace(log10(f_lo),log10(f_hi),np); |
| 83 | + for ch=1:nch |
| 84 | + h(:,ch) = freqz(b(:,ch), 1, f, fs); |
| 85 | + end |
| 86 | + m_db = 20*log10(abs(h)); |
| 87 | + |
| 88 | + fh = fopen(csv_fn, 'w'); |
| 89 | + for i = 1:np |
| 90 | + fprintf(fh, '%10.3f', f(i)); |
| 91 | + for j = 1:nch |
| 92 | + fprintf(fh, ', %8.3f', m_db(i, j)); |
| 93 | + end |
| 94 | + fprintf(fh, '\n'); |
| 95 | + end |
| 96 | + fclose(fh); |
| 97 | + |
| 98 | +end |
0 commit comments