View Raw SPL
#include 


/* parse input args and set defaults */
welch_parse_args(x, y, win, olap, nfft, fs, detrend_in, zpad_in, frange_in, output_in, est_in, func)
{
        local lseg, dflag = 0;
        local frange = "", output = "", est = "";

        if (isunspecified(win))   win  = {};
        if (isunspecified(olap))  olap = {};
        if (isunspecified(nfft))  nfft = {};
        if (isunspecified(fs))    fs   = {};

        if (isunspecified(detrend_in)) detrend_in = "";
        if (isunspecified(zpad_in))    zpad_in    = "";
        if (isunspecified(frange_in))  frange_in  = "";
        if (isunspecified(output_in))  output_in  = "";
        if (isunspecified(est_in))     est_in     = "";

        /* series required */
        if (not(isarray(x)))
        {
                error(sprintf("%s - input series required", func));
        }

        /* check for strings */
        if (isstring(win))
        {
                (detrend_in, zpad_in, frange_in, output_in, est_in) = welch_assign_strings(win, detrend_in, zpad_in, frange_in, output_in, est_in);
                win = {};
        }

        if (isstring(olap))
        {
                (detrend_in, zpad_in, frange_in, output_in, est_in) = welch_assign_strings(olap, detrend_in, zpad_in, frange_in, output_in, est_in);
                olap = {};
        }

        if (isstring(nfft))
        {
                (detrend_in, zpad_in, frange_in, output_in, est_in) = welch_assign_strings(nfft, detrend_in, zpad_in, frange_in, output_in, est_in);
                nfft = {};
        }

        if (isstring(fs))
        {
                (detrend_in, zpad_in, frange_in, output_in, est_in) = welch_assign_strings(fs, detrend_in, zpad_in, frange_in, output_in, est_in);
                fs = {};
        }

        /* handle defaults */
        if (isempty(win))
        {
                win = int(2*max(length(x), length(y))/9);
        }

        if (isscalar(win))
        {
                if ((lseg = win) <= 0)
                {
                        error(sprintf("%s - at least 5 samples required", func));
                }

                win  = hamming(lseg);
        }
        else
        {
                lseg = length(win);
        }

        if (isempty(olap))
        {
                olap = int(lseg / 2);
        }

        if (lseg <= 0)
        {
                error(sprintf("%s - positive segment size required", func));
        }

        if (olap >= lseg)
        {
                error(sprintf("%s - overlap must be less than segment size", func));
        }

        if (isempty(nfft))
        {
                nfft = max(256, bestpow2(win));
        }

        if (isempty(fs))
        {
                fs = rate(x);
        }

        if (isstring(est_in))
        {
                (dflag, frange, output, est) = welch_parse_string(est_in, dflag, frange, output, est, func);
        }
        else
        {
                error(sprintf("%s - EST flag must be a string 'h1' or 'h2'", func));
        }

        if (isstring(output_in))
        {
                (dflag, frange, output, est) = welch_parse_string(output_in, dflag, frange, output, est, func);
        }
        else
        {
                error(sprintf("%s - OUTPUT flag must be a string 'complex' or 'magnitude' or 'mag2'", func));
        }

        if (isstring(frange_in))
        {
                (dflag, frange, output, est) = welch_parse_string(frange_in, dflag, frange, output, est, func);
        }
        else
        {
                error(sprintf("%s - RANGE flag must be a string 'onesided', 'twosided' or 'centered'", func));
        }

        if (isstring(zpad_in))
        {
                (dflag, frange, output, est) = welch_parse_string(zpad_in, dflag, frange, output, est, func);
        }
        else
        {
                error(sprintf("%s - ZEROPAD flag must be a string 'zeropad' or 'none'", func));
        }


        if (isstring(detrend_in))
        {
                (dflag, frange, output, est) = welch_parse_string(detrend_in, dflag, frange, output, est, func);
        }
        else
        {
                error(sprintf("%s - DETREND flag must be a string 'constant', 'linear' or 'none'", func));
        }

        if (strlen(frange) == 0)
        {
                frange = (iscomplex(x) || iscomplex(y)) ? "twosided" : "onesided";
        }

        if (strlen(output) == 0)
        {
                output = "mag2";
        }

        if (strlen(est) == 0)
        {
                est = "h1";
        }

        return(win, olap, nfft, fs, dflag, frange, output, est);
}


/* parse string options */
welch_parse_string(str, dflag, frange, output, est, func)
{
        if (isstring(str))
        {
                if (strlen(str) > 0)
                {
                        str = tolower(str);

                        switch (str)
                        {
                                case "constant":
                                case "mean":
                                        dflag |= WELCH_F_DEMEAN;
                                        break;

                                case "linear":
                                        dflag |= WELCH_F_DETREND;
                                        break;

                                case "none":
                                        dflag |= 0;
                                        break;

                                case "zeropad":
                                        dflag |= WELCH_F_ZPAD;
                                        break;
                        
                                case "onesided":
                                case "half":
                                case "single":
                                        frange = "onesided";
                                        break;

                                case "twosided":
                                case "whole":
                                case "double":
                                        frange = "twosided";
                                        break;

                                case "center":
                                case "centered":
                                case "centerdc":
                                case "shift":
                                        frange = tolower("centered");
                                        break;

                                case "complex":
                                        output = "complex";
                                        break;

                                case "mag":
                                case "magnitude":
                                        output = "magnitude";
                                        break;

                                case "mag2":
                                case "magsquared":
                                        output = "mag2";
                                        break;

                                case "h1":
                                case "h2":
                                        est = str;
                                        break;

                                default:
                                        error(sprintf("%s - unknown flag '%s'", func, str));
                        }
                }
        }

        return(dflag, frange, output, est);
}


/* sort out string args */
welch_assign_strings(arg, detrend, zpad, frange, output, est)
{
        if (isstring(detrend) && strlen(detrend) == 0)
        {
                detrend = arg;
        }
        else if (isstring(zpad) && strlen(zpad) == 0)
        {
                zpad = arg;
        }
        else if (isstring(frange) && strlen(frange) == 0)
        {
                frange = arg;
        }
        else if (isstring(output) && strlen(output) == 0)
        {
                output = arg;
        }
        else if (isstring(est) && strlen(est) == 0)
        {
                est = arg;
        }

        return(detrend, zpad, frange, output, est);
}