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