function [dx, mod_func] = calculateModulationFunction(mod_amp, n_points, func)
    % Default value for func if not provided
    if nargin < 3
        func = 'arccos';
    end
    
    % Generate modulation function based on func type
    switch func
        case 'sin'
            phi = linspace(0, 2*pi, n_points);
            mod_func = mod_amp * sin(phi);
            
        case 'arccos'
            phi = linspace(0, 2*pi, floor(n_points/2));
            tmp_1 = 2/pi * acos(phi/pi - 1) - 1;
            tmp_2 = flip(tmp_1);
            mod_func = mod_amp * [tmp_1, tmp_2];
            
        case 'triangle'
            phi = linspace(0, 2*pi, n_points);
            mod_func = mod_amp * sawtooth(phi, 0.5); % Symmetric rising triangle
            
        case 'square'
            phi = linspace(0, 1.99*pi, n_points);
            mod_func = mod_amp * square(phi, 0.5);
            
        otherwise
            mod_func = [];
    end
    
    % Calculate dx if mod_func exists
    if ~isempty(mod_func)
        dx = (max(mod_func) - min(mod_func)) / (2 * n_points);
    else
        dx = [];
    end
end
