diff --git a/Utilities/Geometries/MATLAB/Functions/virtMicGeo.m b/Utilities/Geometries/MATLAB/Functions/virtMicGeo.m
index 564dfa39f7ed587750f32163456f71430b73b86b..b6947bea4181865388d190d9d660bc204e60f0d9 100644
--- a/Utilities/Geometries/MATLAB/Functions/virtMicGeo.m
+++ b/Utilities/Geometries/MATLAB/Functions/virtMicGeo.m
@@ -3,7 +3,7 @@
 % Author: Achilles Kappis
 % e-mail: axilleaz@protonmail.com
 %
-% Date: 16/07/2024 (DD/MM/YYYY)
+% Date: 18/09/2024 (DD/MM/YYYY)
 %
 % Copyright: MIT
 % --------------------------------------------------
@@ -13,17 +13,35 @@
 % Input
 % 
 % gType [char/string]: The type of the source geometry. At the moment the
-%                      available options are "Single", "Array", "Grid",
-%                      "Cube" and "Dual". The last is an arrangement with 2
-%                      sensors "xLen" apart that can be translated and
-%                      rotated.
+%                      available options are "Single", "Array", "Cube" and
+%                      "Dual". The last is an arrangement a distance apart
+%                      that can be translated and rotated.
 % 
+% geoDim [numeric] (Optional): The dimensions of the geometry. This is a
+%                              vector with three elements holding the
+%                              dimensions of the setup in each Cartesian
+%                              direction. Based on the "gType" some or all
+%                              of them are used. For "gType" set either as
+%                              "Array" or "Dual", the first value is used
+%                              as the length of the "Array" or distance
+%                              between the two position in "Dual". When
+%                              "gType" is "Single" this argument is
+%                              ignored. [Default: ones(3, 1)].
 % 
-% xLen [numeric] (Optional): The width of the "Array" geometry, the length
-%                            of the side of the "Grid" and "Cube geometries
-%                            and the distance between positions in "Dual"
-%                            geometry.
-%                            [Default: Array/Grid/Cube - 1, Dual - 0.2].
+% nSens [numeric]  (Optional): This can be either a real integer value
+%                              denoting the number of sensors in the array
+%                              or a vector with three elements denoting
+%                              the number of sensor along each Cartesian
+%                              dimension. If a dimension is equal to zero
+%                              the corresponding value is ignored. If this
+%                              is a scalar value the used must ensure that
+%                              it is correctly divisible over the non-zero
+%                              dimensions of the geometry uniformly (see
+%                              Notes for info). For the "Array" geometry,
+%                              only the first value (if "nSens" is a
+%                              vector) is used and for the "Single"
+%                              geometry the argument is ignored.
+%                              [Default: 10 * ones(3, 1)].
 % 
 % xOff [numeric] (Optional): X-axis offset. [Default: 0].
 % 
@@ -31,28 +49,10 @@
 % 
 % zOff [numeric] (Optional): Z-axis offset. [Default: 0].
 % 
-% nSens [numeric]  (Optional): The number of sensors in the array.
-%                              For the "Grid" geometry the square root of
-%                              "nSens" must be an integer value. For the
-%                              "Cube" geometry the cubic root of "nSens"
-%                              must be an integer value. This parameter is
-%                              ignored for the "Single" geometry.
-%                              [Default: Array/Grid - 100, Cube - 1000].
-% 
-% orient [char/string/numeric] (Optional): The orientation of the
-%                                          geometry. For the "Single" and
-%                                          "Cube" geometries this value is
-%                                          ignored. For the "Dual"
-%                                          configuration only numerical
-%                                          values are used to declare the
-%                                          rotation of the configuration
-%                                          with respect to the local z-axis
-%                                          in degrees. For the rest of the
-%                                          configurations, the string
-%                                          values allowed are "XY", "XZ"
-%                                          and "YZ" and declare the plane
-%                                          on which the configuration will
-%                                          be placed. [Default: "XY" | 0].
+% orient [numeric] (Optional): This is a real vector holding the rotation
+%                              for the geometry in degrees, along each
+%                              Cartesian axis. The rotations are performed
+%                              clockwise. [Default: zeros(3, 1)].
 % 
 % --------------------------------------------------
 % Output
@@ -62,24 +62,26 @@
 %                 number of sources and the other dimension correspond to
 %                 the x, y and z coodrinates.
 % 
-% vPosMesh [numeric]: The matrix has dimensions sqrt(N)xsqrt(N)x3 where N
-%                     is the number of sources. It contains the x, y and z
-%                     Cartesian coordinates for each position in a
-%                     rectangular grid with dimensions sqrt(N)xsqrt(N).
-%                     This is used only with the "Grid" geometry, otherwise
-%                     it is empty.
+% vPosMesh [numeric]: The matrix has dimensions nSens(1)xnSens(2)x3. It
+%                     holds the x, y and z Cartesian coordinates for each
+%                     position of the "Grid" geometry. If the geometry is 
+%                     otherwise not "Grid", this is an empty array.
 % 
 % --------------------------------------------------
 % Notes
 % 
-% - Dependencies: rotMat3d(): To rotate sources.
+% - Dependencies: rotMat3d(): To rotate the geometry.
+% 
+% - If the number of sources are provided as a single integer, the user
+%   must make sure that they can be uniformly distributed in the non-zero
+%   dimensions of the geometry. For example, for the "Cube" geometry with
+%   two non-zero dimensions, the square root of the number of sensors must
+%   be an integer and for three non-zero dimensions its third root must be
+%   an integer. For the "Array" configuration, there is not an issue as the
+%   setup is one dimensional.
 % 
-% - The position of the geometry is calculated like this: First the
-%   geometry is placed on the x-y plane, then rotated to match the
-%   orientation defined by the "orient" argument and finally, the offsets
-%   on each axis are applied.
 % --------------------------------------------------
-function [vPos, vPosMesh] = virtMicGeo(gType, xLen, xOff, yOff, zOff, nSens, orient)
+function [vPos, vPosMesh] = virtMicGeo(gType, geoDim, nSens, xOff, yOff, zOff, orient)
     % ====================================================
     % Check for number of arguments
     % ====================================================
@@ -91,81 +93,67 @@ function [vPos, vPosMesh] = virtMicGeo(gType, xLen, xOff, yOff, zOff, nSens, ori
     % ====================================================
     % Validate mandatory arguments
     validateattributes(gType, {'char', 'string'}, {'scalartext', 'nonempty'}, mfilename, "Geometry type", 1);
-    validatestring(gType, ["Single", "Dual", "Array", "Grid", "Cube"], mfilename, "Geometry type", 1);
+    validatestring(gType, ["Single", "Dual", "Array", "Cube"], mfilename, "Geometry type", 1);
 
     % Validate optional arguments
-    if nargin > 1 && ~isempty(xLen) && ~strcmpi(gType, "Single")
-        validateattributes(xLen, "numeric", {'scalar', 'real', 'nonnan', 'finite', 'positive'}, mfilename, "Width of the geometry, or distance between positions in Dual geometry", 2);
+    if nargin > 1 && ~isempty(geoDim) && ~strcmpi(gType, "Single")
+        validateattributes(geoDim, "numeric", {'vector', 'real', 'nonnan', 'finite', 'nonempty', 'positive'}, mfilename, "Geometry dimensions", 2);
+        
+        if numel(geoDim) > 3 || numel(geoDim) == 2
+            error("The dimensions argument must be either a scalar or a vector with three elements");
+        end
+
+        if isscalar(geoDim)
+            geoDim = geoDim * ones(3, 1);
+        end
     else
-        if strcmpi(gType, "Dual")
-            xLen = 0.2;
-        else
-            xLen = 1;
+        geoDim = ones(3, 1);
+    end
+
+    if nargin > 2 && ~isempty(nSens) && sum(strcmpi(gType, ["Single", "Dual"])) == 0
+        validateattributes(nSens, "numeric", {'vector', 'real', 'nonempty', 'nonnan', 'nonnegative', 'integer', 'finite'}, mfilename, "Number of sensors in the geometry", 3);
+
+        if numel(nSens) > 3 || numel(nSens) == 2
+            error("The number of sensors must be either a scalar or a vector with three elements");
+        end
+        
+        if isscalar(nSens) && strcmpi(gType, "Cube")
+            if mod(nthroot(nSens, sum(geoDim ~= 0)), 1) ~= 0
+                error("The number of sources is cannot be divided uniformly over the non-zero dimensions");
+            else
+                nSens = nthroot(nSens, sum(geoDim ~= 0)) * double(geoDim ~= 0);
+            end
         end
+    elseif strcmpi(gType, "Dual")
+        nSens = [2, 0, 0];
+    else
+        nSens = 10 * ones(3, 1);
     end
 
-    if nargin > 2 && ~isempty(xOff)
-        validateattributes(xOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "X-offset", 3);
+    if nargin > 3 && ~isempty(xOff)
+        validateattributes(xOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "X-offset", 4);
     else
         xOff = 0;
     end
 
-    if nargin > 3 && ~isempty(yOff)
-        validateattributes(yOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "Y-offset", 4);
+    if nargin > 4 && ~isempty(yOff)
+        validateattributes(yOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "Y-offset", 5);
     else
         yOff = 0;
     end
 
-    if nargin > 4 && ~isempty(zOff)
-        validateattributes(zOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "Z-offset", 5);
+    if nargin > 5 && ~isempty(zOff)
+        validateattributes(zOff, "numeric", {'scalar', 'real', 'nonnan', 'finite'}, mfilename, "Z-offset", 6);
     else
         zOff = 0;
     end
 
-    if nargin > 5 && ~isempty(nSens)
-        if ~strcmpi(gType, "Single")
-            validateattributes(nSens, "numeric", {'scalar', 'real', 'nonnegative', 'finite', 'nonnan'}, mfilename, "Number of sensors", 6);
-        end
-    else
-        if sum(strcmpi(gType, ["Array", "Grid"])) > 0
-            nSens = 1e2;
-        elseif strcmpi(gType, "Cube")
-            nSens = 1e3;
-        else
-            nSens = 0;
-        end
-    end
-
-    if nargin > 6 && ~isempty(orient)
-        if ischar(orient) || isstring(orient)
-            validateattributes(orient, {'char', 'string'}, {'scalartext', 'nonempty'}, mfilename, "Geometry orientation", 7);
-            validatestring(orient, ["XY", "XZ", "YZ"], mfilename, "Geometry orientation", 7);
-        else
-            if ~strcmpi(gType, "Dual")
-                error("Planes can be provided for the orientation of only the Array and Grid geometries.");
-            end
-
-            validateattributes(orient, {'numeric'}, {'scalar', 'nonempty', 'nonnan', 'finite', 'real'}, mfilename, "Geometry orientation", 7);
-        end
+    if nargin > 6 && ~isempty(orient) && ~strcmpi(gType, "Single")
+        validateattributes(orient, {'numeric'}, {'vector', 'nonempty', 'nonnan', 'finite', 'real', 'numel', 3}, mfilename, "Geometry rotation around the Cartesian axes", 7);
     else
-        if strcmpi(gType, "Dual")
-            orient = 0;
-        else
-            orient = "XY";
-        end
+        orient = zeros(3, 1);
     end
 
-    % ====================================================
-    % Check we have all needed parameters and they have
-    % acceptable values
-    % ====================================================
-
-    % For "Grid" geometry the square root of the number of sensors must be an integral value
-    if strcmpi(gType, "Grid") && mod(sqrt(nSens), 1) ~= 0
-        error("For the Grid geometry, the square root of the number of sensors must be an integer.");
-    elseif strcmpi(gType, "Cube") && mod(nthroot(nSens, 3), 1) ~= 0
-        error("For the Cube geometry, the cubic root of the number of sensors must be an integer (a tolerance of 1e-6 has been used for the calculation).");
-    end
 
     % ====================================================
     % Calculate virtual microphone positions
@@ -173,53 +161,49 @@ function [vPos, vPosMesh] = virtMicGeo(gType, xLen, xOff, yOff, zOff, nSens, ori
     switch lower(gType)
         case "single"
             % Create a single point at offset coordinates and return
-            vPos = [xOff, yOff, zOff];
-            vPosMesh = [];
-            return;
+            vPos = zeros(1, 3);
         case "dual"
-            vPos = [-xLen/2, 0, 0; ...
-                     xLen/2, 0, 0];
+            vPos = [-geoDim(1)/2, 0, 0; ...
+                     geoDim(1)/2, 0, 0];
         case "array"
-            vPos = linspace(-xLen/2, xLen/2, nSens);
+            vPos = linspace(-geoDim(1)/2, geoDim(1)/2, nSens(1));
             vPos = [vPos(:), zeros(numel(vPos), 2)];
-        case "grid"
-            vPos = linspace(-xLen/2, xLen/2, sqrt(nSens));
-            [x, y] = meshgrid(vPos, vPos);
-            vPos = [x(:), y(:), zeros(numel(x), 1)];
         case "cube"
-            vPos = linspace(-xLen/2, xLen/2, round(nSens^(1/3)));
-            [x, y, z] = meshgrid(vPos, vPos, vPos);
+            % Make we don't get empty arrays when dimensions are 0
+            if nSens(1) == 0
+                x = 0;
+            else
+                x = linspace(-geoDim(1)/2, geoDim(1)/2, nSens(1));
+            end
+
+            if nSens(2) == 0
+                y = 0;
+            else
+                y = linspace(-geoDim(2)/2, geoDim(2)/2, nSens(2));
+            end
+
+            if nSens(3) == 0
+                z = 0;
+            else
+                z = linspace(-geoDim(3)/2, geoDim(3)/2, nSens(3));
+            end
+
+            [x, y, z] = meshgrid(x, y, z);
             vPos = [x(:), y(:), z(:)];
         otherwise
             error("Oops... something went wrong here... not known geometry...!!!");
     end
 
     % Rotate
-    if ~strcmpi(gType, "Cube")
-        if isnumeric(orient)
-            vPos = vPos * rotMat3d(0, 0, -orient, "Degs");
-        elseif strcmpi(orient, "XZ")
-            if strcmpi(gType, "array")
-                vPos = vPos * rotMat3d(0, 0, 90, "Degs");
-            else
-                vPos = vPos * rotMat3d(90, 0, 0, "Degs");
-            end
-        elseif strcmpi(orient, "YZ")
-            vPos = vPos * rotMat3d(0, 90, 0, "Degs");
-        end
-    end
+    vPos = vPos * rotMat3d(-orient(1), -orient(2), -orient(3), "Degs");
 
     % Translate
-    if ~strcmpi(gType, "Cube")
-        vPos = vPos + [xOff, yOff, zOff];
-    end
+    vPos = vPos + [xOff, yOff, zOff];
 
-    % For "Grid" and "Cube" geometry provide the coordinates in a "mesh format"
-    if strcmpi(gType, "Grid")
-        vPosMesh = reshape(vPos, sqrt(nSens), [], 3);
-    elseif strcmpi(gType, "Cube")
-        vPosMesh = reshape(vPos, round(nSens^(1/3)), round(nSens^(1/3)), [], 3);
-    else
+    % For "Cube" geometry provide the coordinates in a "mesh format"
+    if nargout > 1 && strcmpi(gType, "Cube")
+        vPosMesh = cat(3, x, y, z);
+    elseif nargout > 1
         vPosMesh = [];
     end
 end
\ No newline at end of file