View Raw SPL
/*****************************************************************************
*                                                                            *
*   GFLATTOP.SPL   Copyright (C) 2004-2010 DSP Development Corporation       *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Generates a Flattop window                                  *
*                                                                            *
*   Revisions:   22 Jan 2004  RRR  Creation                                  *
*                10 Jul 2008  RRR  4 point ISO 18431-1 standard              *
*                29 Jun 2010  RRR  alternate 4 point                         *
*                                                                            *
*****************************************************************************/


#if @HELP_GFLATTOP

    GFLATTOP

    Purpose: Generates a Flattop Window.

    Syntax:  GFLATTOP(N, spacing, type, "sym")

                    N  - Number of points to generate.

               spacing - Spacing between points.

                  type - Optional integer, generation mode.

                          0: ISO 18431-1 4 point method (default)
                          1: 2 point method
                          2: Alternate 4 point method
                          3: HP P301
                          4: HP 4 point formula
                          5: Modified HP P401 5 point formula
                          6: Rohde & Schwartz 4 point formula

                 "sym" - Optional. A string, the symmetry mode.

                          "symmetric" : Starting and ending points are equal.

                          "periodic"  : Periodically extended window. Conforms 
                                        to ISO standard (default).

                          "iso"       : Same as "periodic".

    Returns: A series.

    Example:
             gflattop(100, .01)

             Creates a periodic 100-point Flattop window with points
             spaced with an interval of 0.01 using the following 4
             point formula:

             w[k]  = 1.0 - 1.9330 * cos(2*pi*(k-1)/N)
                         + 1.2860 * cos(4*pi*(k-1)/N)
                         - 0.3880 * cos(6*pi*(k-1)/N)
                         + 0.0322 * cos(8*pi*(k-1)/N)

             where k is the kth point (1 <= k <= N) and N is 100, the number
             of points to generate. The spacing between points is set to 0.01.

    Example:
             gflattop(100, .01, "symmetric")

             Creates a symmetric 100-point Flattop window with points
             spaced with an interval of 0.01 using the following 4
             point formula:

             w[k]  = 1.0 - 1.9330 * cos(2*pi*(k-1)/N-1)
                         + 1.2860 * cos(4*pi*(k-1)/N-1)
                         - 0.3880 * cos(6*pi*(k-1)/N-1)
                         + 0.0322 * cos(8*pi*(k-1)/N-1)

             where k is the kth point (1 <= k <= N) and N is 100, the number
             of points to generate. The spacing between points is set to 0.01.

    Remarks:
             The Flattop window preserves the amplitude of a series
             at the expense of frequency resolution. It will accurately
             measure the amplitude of a series at any frequency, even
             if the frequency lies between FFT bins.

             The type parameter specifies the coefficients for the following
             periodic flattop window generation formula:

             w[k]  = a0 - a1 * cos(2*pi*(k-1)/N)
                        + a2 * cos(4*pi*(k-1)/N)
                        - a3 * cos(6*pi*(k-1)/N)
                        + a4 * cos(8*pi*(k-1)/N)

             The symmetric form can be constructed by setting N to N-1.

             The following flattop window types are supported:

             type 0, ISO 18431-1 (default):

             a0 = 1.0
             a1 = 1.9330
             a2 = 1.2860
             a3 = 0.3880
             a4 = 0.0322


             type 1, two point flattop window:
            
             a0 = 0.2810639
             a1 = 0.5208972
             a2 = 0.1980399
             a3 = 0.0
             a4 = 0.0


             type 2, alternate four point flattop window:

             a0 = 0.215578950
             a1 = 0.416631580
             a2 = 0.277263158
             a3 = 0.083578947
             a4 = 0.006947368

             
             type 3, three point HP P301 flattop window:

             a0 = 0.9994484 
             a1 = 2*0.955728 
             a2 = 2*0.538289 
             a3 = 2*0.091581


             type 4, HP four point window:

             a0 = 1.0
             a1 = 2 * 0.934516
             a2 = 2 * 0.597986
             a3 = 2 * 0.017964
             a4 = 2 * 0.015458

             
             type 5, modified HP P401 five point flattop window:

             a0 = 1.0
             a1 = 1.93774046310203
             a2 = 1.32530734987255
             a3 = 0.43206975880342
             a4 = 0.04359135851569
             a5 = 0.00015175580171


             type 6, Rohde & Schwartz four point flattop window:

             a0 = 0.1881999
             a1 = 0.3692300
             a2 = 0.2870200
             a3 = 0.1307700
             a4 = 0.0248800


             The "sym" flag controls the window symmetry as follows: 

             "Symmetric" sets the first and last points to be equal. 
             An N point symmetric window can be constructed by creating
             an N-1 point periodic window and setting the Nth point to
             the value of the first point.

             "Periodic" or "iso" (the default) creates a periodic
             window function useful in spectrum analysis applications
             where the starting zero is preserved and the trailing zero
             is removed.  "Periodic" or "iso" conforms to the ISO
             18431-1 standard for windowing functions.

             Because the ISO 18431-1 standard specifies a periodic flattop
             window, GFLATTOP uses "periodic" as the default for the
             symmetry flag.

             Use the Flattop function to automatically create and multiply
             a Flattop window with a series. For example:

               flattop(W2)

             multiplies Window 2 with a Flattop window calculated to the same
             length and spacing as the series in W2.

             Hamming, Hanning, Kaiser and Flattop windows are useful in
             creating FIR filters and in preprocessing series for FFT
             calculations.

    See Also:
             FFT
             GHAMMING
             GHANNING
             GKAISER
             PSD
             SPECTRUM
#endif



/* generate an N point Flattop window */
gflattop(n, dx, type, sym)
{
        local w, a, a0, a1, a2, a3, a4, a5, m;

        (n, dx, type, sym) = gflattop_parse_args(n, dx, type, sym);

        /* special cases */
        if (n == 0) return({});
        if (n == 1) return(ones(1, 1, dx));

        if (type == 1)
        {
                /* 2 point */
                a = {0.2810639, 0.5208972, 0.1980399};
        }
        else if (type == 3)
        {
                /* 4 point P301 */
                a0 = 0.9994484; 
                a1 = 2*0.955728; 
                a2 = 2*0.538289; 
                a3 = 2*0.0915810;

                a = {a0, a1, a2, a3};
        }
        else if (type == 5)
        {
                /* 5 point - HP P401 comparable */
                a0 = 1.0;
                a1 = 1.93774046310203;
                a2 = 1.32530734987255;
                a3 = 0.43206975880342;
                a4 = 0.04359135851569;
                a5 = 0.00015175580171;

                a = {a0, a1, a2, a3, a4, a5};
        }
        else
        {
                /* 4 point formulae */
                if (type == 2)
                {
                        /* alternative 4 point */
                        a0 = 0.215578950;
                        a1 = 0.416631580;
                        a2 = 0.277263158;
                        a3 = 0.083578947;
                        a4 = 0.006947368;
                }
                else if (type == 4)
                {
                        /* HP 4 point */
                        a0 = 1.0;
                        a1 = 2 * 0.934516;
                        a2 = 2 * 0.597986;
                        a3 = 2 * 0.017964;
                        a4 = 2 * 0.015458;
                }
                else if (type == 6)
                {
                        /* Rohde & Schwartz 4 point */
                        a0 = 0.1881999;
                        a1 = 0.3692300;
                        a2 = 0.2870200;
                        a3 = 0.1307700;
                        a4 = 0.0248800;
                }
                else
                {
                        /* ISO 4 point */
                        a0 = 1.0;
                        a1 = 1.933;
                        a2 = 1.286;
                        a3 = 0.388;
                        a4 = 0.0322;
                }

                a = {a0, a1, a2, a3, a4};
        }

        /* generate window */
        w = gcoswin(a, n, dx, sym);
        
        return(w);
}


gflattop_parse_args(n, dx, type, sym)
{
        local temp;

        if (argc < 4)
        {
                if (argc < 3)
                {
                        if (argc < 2)
                        {
                                if (argc < 1) error("gflattop - number of points required");
                                
                                dx = 1.0;
                        }
                        
                        /* use ISO four point algorithm */
                        type = 0;
                }
                
                sym = "periodic";
        }
        
        if (isstring(type))
        {
                temp = sym;
                sym = type;
                type = isstring(temp) ? 0 : temp;
        }

        return(n, dx, type, sym);
}