diff --git a/Virtual Sensing/Remote Microphone Technique/MATLAB/Functions/obsFiltEstTD.m b/Virtual Sensing/Remote Microphone Technique/MATLAB/Functions/obsFiltEstTD.m new file mode 100644 index 0000000000000000000000000000000000000000..dcd0f6bcf2854612c350c8412872c67e5af1ca4e --- /dev/null +++ b/Virtual Sensing/Remote Microphone Technique/MATLAB/Functions/obsFiltEstTD.m @@ -0,0 +1,131 @@ +%% Perform estimation with observation filters in the Time-Domain +% -------------------------------------------------- +% Author: Achilles Kappis +% e-mail: axilleaz@protonmail.com +% +% Date: 12/09/2024 (DD/MM/YYYY) +% +% Copyright: MIT +% -------------------------------------------------- +% Functionality: Perform estimation with observation filters in the +% Time-Domain. +% -------------------------------------------------- +% Input +% +% m [numeric]: The measurement(s) at the monitoring microphone position(s). +% This must be an KxMxJ matrix with K representing the length +% of the measurements in samples, M the number of monitoring +% microphones and J the number of trials/sound field +% realisations. +% +% O [numeric]: The observation filters. This must be an NxIxMxJ array, +% where N is the number of virtual microphones and I the +% length of the observation filters (in samples). Here J can +% either be equal to the third dimension of "m", or 1 in +% which case a single set of observation filters will be +% applied to all trials/realisations of the sound field. +% +% +% e [numeric] (Optional): The measurement(s) at the virtual microphone(s) +% position(s). This must be a KxNxJ array. If this +% argument is not provided, the output argument +% "err" is an empty array. +% +% -------------------------------------------------- +% Output +% +% estPerMic [numeric]: This array holds the monitoring microphone signals +% filtered by the corresponding observation filters. +% It is a KxNxMxJ array. +% +% est [numeric]: The estimated signals at the virtual microphone positions. +% This is an KxNxJ array and corresponds to the sum of +% "estPerMic" output argument over its third dimension. +% +% err [numeric]: The error signals at the virtual microphone positions. +% This corresponds to the difference between the true, "e" +% and the estimated, "est", signals. If "e" is not provided +% this argument is an empty array. +% +% estMean [numeric]: These are the estimated virtual microphone signals +% averaged over the trials/sound field realisations. +% +% errMean [numeric]: These are the error signals averaged over the +% trials/sound field realisations. If "e" is not +% provided this argument is an empty array. +% +% -------------------------------------------------- +% Notes +% +% -------------------------------------------------- +function [estPerMic, est, err, estMean, errMean] = obsFiltEstTD(m, O, e) + % ==================================================== + % Check for number of arguments + % ==================================================== + narginchk(2, 3); + nargoutchk(0, 5); + + % ==================================================== + % Validate input arguments + % ==================================================== + % Validate mandatory arguments + validateattributes(m, "numeric", {'3d', 'real', 'nonnan', 'nonempty', 'finite'}, mfilename, "Monitoring microphone measurements", 1); + validateattributes(O, "numeric", {'real', 'nonnan', 'nonempty', 'finite'}, mfilename, "Observation filters", 2); + + % Check for observation filter size + if ismatrix(O) || ndims(O) > 4 + error("Observation filter must be either a three- or four-dimensional array. See documentation (at the top of the function file) for more information."); + elseif size(O, 4) ~= size(m, 3) && size(O, 4) ~= 1 + error("The number of observation filter sets must be either equal to the trials/sound field realisations, or 1.") + end + + % Validate optional arguments + if nargin > 2 && ~isempty(e) + validateattributes(e, "numeric", {'3d', 'real', 'nonnan', 'nonempty', 'finite', 'size', [size(m, 1), NaN, size(m, 3)]}, mfilename, "Virtual microphone measurements", 3); + else + err = []; + end + + + % ==================================================== + % Pre-process the data + % ==================================================== + % Replicate observation filters if only one set is provided + if size(O, 4) ~= size(m, 3) + O = repmat(O, size(O, 1), size(O, 2), size(O, 3), size(m, 3)); + end + + % ==================================================== + % Filter signals to perform estimation + % ==================================================== + % Go through the trials/sound field realisations + for jIdx = size(m, 3):-1:1 + % Go through the virtual microphone positions + for eIdx = size(O, 1):-1:1 + % Go through the monitoring microphone positions + for mIdx = size(O, 3):-1:1 + estPerMic(:, eIdx, mIdx, jIdx) = filter(O(eIdx, :, mIdx, jIdx), 1, m(:, mIdx, jIdx)); + end + end + end + + % Sum the estimates of each monitoring microphone to get the estimated virtual microphone signals + if nargout > 1 + est = squeeze(sum(estPerMic, 3)); + end + + % Calculate the error signals + if nargout > 2 && ~exist("err", "var") + err = e - est; + end + + % Average of estimated signals + if nargout > 3 + estMean = mean(est, 3); + end + + % Mean error signal + if nargout > 4 + errMean = mean(err, 3); + end +end \ No newline at end of file