Dear all,

Just in case somebody finds this useful, I'm attaching a proposal of a
modified version of the function window() which includes three new
window functions: Blackman, Blackman-Harris and one out of many
different flat-top windows. It also allows a new argument, opt, which
can be either "per" for periodic option or "sym" or any other value (or
no value) for triggering the default symmetric option.

If there were interest, several other windows could be easily added.

Regards,

Federico Miyara


On 11/02/2021 04:12, Federico Miyara wrote:

Dear All,

I wonder why windowing functions such as Hann, Hamming, etc., provided
by window(), are only symmetric.

When used for spectral analysis by subsequent use of fft(), the
periodic weighting is better than the symmetric one. The symmetric
window is mainly used in the design of FIR filters, which I guess is a
less frequent application than spectral analysis.

While it is true that an easy workaround to get a periodic window of
length n is, for instance

w = window("hn", n+1)(1:$-1);

a syntax such as this

w = window("hn", n, "per");

would be easier.Setting "sym" as the default option, no backward
compatibility issues would possibly arise.

Regards,

Federico Miyara

<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient>
        Libre de virus. www.avast.com
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient>


<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

_______________________________________________
users mailing list
users@lists.scilab.org
http://lists.scilab.org/mailman/listinfo/users



--
El software de antivirus Avast ha analizado este correo electrónico en busca de 
virus.
https://www.avast.com/antivirus
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) INRIA - 1988 - C. Bunks
//
// Copyright (C) 2012 - 2021 - Scilab Enterprises
//
// This file is hereby licensed under the terms of the GNU GPL v2.0,
// pursuant to article 5.3.4 of the CeCILL v.2.1.
// This file was originally licensed under the terms of the CeCILL v2.1,
// and continues to be available under such terms.
// For more information, see the COPYING file which you should have received
// along with this program.

function [win_l,cwp] = window(wtype,n,par,opt)
    //[win_l,cwp] = window(wtype,n,par)
    //macro that calculates symmetric window
    // wtype :window type (re,tr,hn,hm,kr,ch)
    // n     :window length
    // par   :parameter 2-vector (kaiser window: par(1)=beta>0)
    //       :                   (chebyshev window:par=[dp,df])
    //       :                   dp=main lobe width (0<dp<.5)
    //       :                   df=side lobe height (df>0)
    // opt   :window option: "sym" (symmetric)
    //                       "per" (periodic) 
    // win   :window
    // cwp   :unspecified Chebyshev window parameter
    //!
    WT = ["re","tr","hm","hn","kr","ch","bl","bh","ft"]

    if isdef("opt") then
        if opt=="per" then
            n = n+1;
        end
    end

    if and(wtype<>WT) then
        error(msprintf(_("%s: Wrong value for input argument #%d: Must be in 
the set {%s}.\n"),"window",1,strcat(WT,",")))
    end
    
    if type(n)<>1|size(n,"*")<>1|~isreal(n)|size(n,"*")<>1|int(n)<>n|n<1 then
        error(msprintf(_("%s: Wrong type for input argument #%d: A positive 
integer expected.\n"),"window",2))
    end

    if or(wtype==["kr","ch"]) then
        if type(par)<>1|~isreal(par) then
            error(msprintf(_("%s: Wrong type for input argument #%d: A %d-by-%d 
real vector expected.\n"),"window",3,1,2))
        end
        if wtype=="kr" then
            if size(par,"*")==0| size(par,"*")>2 then
                error(msprintf(_("%s: Wrong size for input argument #%d: A 
%d-by-%d real vector expected.\n"),"window",3,1,2))
            end
            Beta = par(1)
            if Beta<0 then
                error(msprintf(_("%s: Input argument #%d must be strictly 
positive.\n"),"window",3))
            end
        else //chebychev
            if size(par,"*")<>2 then
                error(msprintf(_("%s: Wrong size for input argument #%d: A 
%d-by-%d real vector expected.\n"),"window",3,1,2))
            end
            dp = par(1);df = par(2)
            if dp>0 then
                if df>0 then
                    error(msprintf(_("%s: Wrong value for input argument #%d: 
incorrect element #%d\n"),"window",3,2))
                end
                if dp>=0.5 then
                    error(msprintf(_("%s: Wrong value for input argument #%d: 
incorrect element #%d\n"),"window",3,1))
                end
                unknown = "df";
            else
                if df<=0 then
                    error(msprintf(_("%s: Wrong value for input argument #%d: 
incorrect element #%d\n"),"window",3,2))
                end
                unknown = "dp";
            end
        end
    end
    cwp = -1;

    //Pre-calculations

    no2 = (n-1)/2;
    xt = (-no2:no2);
    un = ones(1,n);

    //Design window according to window type

    select wtype
    case "re" then           //Rectangular window.
        win_l = un;
    case "tr" then           //Triangular window.
        win_l = un-2*abs(xt)/(n+1);
    case "hm" then           //Hamming window.
        win_l = 0.54*un+0.46*cos(2*%pi*xt/(n-1));
    case "hn" then           //Hann window.
        win_l = 0.5*un+0.5*cos(2*%pi*xt/(n-1));
    case "bl" then           //Blackman window 
        win_l = 0.42*un + 0.5*cos(2*%pi*xt/(n-1)) + 0.08*cos(4*%pi*xt/(n-1));
    case "bh" then           //Blackman-Harris window
        win_l = 0.35875*un - 0.48829*cos(2*%pi*xt/(n-1)) + ... 
                0.14128*cos(4*%pi*xt/(n-1)) - ...
                0.01168*cos(6*%pi*xt/(n-1));
    case "ft" then           //Flat-top HFT70 window
        
//https://pure.mpg.de/pubman/faces/ViewItemFullPage.jsp?itemId=item_152164_2
        win_l = un - 1.90796*cos(2*%pi*xt/(n-1)) + ...
                1.07349*cos(4*%pi*xt/(n-1)) - ...
                0.18199*cos(6*%pi*xt/(n-1));
    case "kr" then           //Kaiser window with parameter beta (n,beta)
        //http://en.wikipedia.org/wiki/Kaiser_window
        win_l = besseli(0,Beta*sqrt(1-(2*(0:n-1)/(n-1)-1).^2))/besseli(0,Beta);
    case "ch" then           //Chebyshev window
        m = (n-1)/2;
        select unknown
        case "dp" then
            dp = 1/cosh((n-1)*acosh(1/cos(%pi*df)));
            cwp = dp;
        case "df" then
            df = real(acos(1/cosh(acosh((1+dp)/dp)/(n-1)))/%pi)
            cwp = df;
        end

        //Pre-calculation

        np1 = int((n+1)/2);
        odd = modulo(n,2)==1

        x0 = (3-cos(2*%pi*df))/(1+cos(2*%pi*df));
        alpha = (x0+1)/2;
        Beta = (x0-1)/2;
        c2 = (n-1)/2;

        //Obtain the frequency values of the Chebyshev window
        f = (0:n-1)/n;
        xarg = alpha*cos(2*%pi*f)+Beta;

        //Evaluate Chebyshev polynomials
        //           / cos(n acos(x),    |x| <=  1
        //    p(x) = |
        //           \ cosh(n acosh(x),  |x| > 1
        pr = zeros(1,n);//real part
        pi = zeros(1,n); //imaginary part
        ind  =  find(xarg<=1); pr(ind) = dp*cos (c2*acos (xarg(ind)));
        ind  =  find(xarg>1);  pr(ind) = dp*cosh(c2*acosh(xarg(ind)));
        pr = real(pr);

        if ~odd then
            pr = pr.*cos(%pi*f);
            pi = -pr.*sin(%pi*f);
            antisym = [1*ones(1:int(n/2)+1),-1*ones(int(n/2)+2:n)];
            pr = pr.*antisym;
            pi = pi.*antisym;
        end

        //Calculate the window coefficients using the inverse DFT
        twn = 2*%pi/n;
        xj = (0:n-1);
        for i = 1:np1;
            arg = twn*(i-1)*xj
            w(i) = sum(pr.*cos(arg)+pi.*sin(arg));
        end,
        c1 = w(1);
        w = w/c1;
        if odd then
            win_l(np1:n) = w(1:np1);
            win_l(1:np1-1) = w(np1-1:-1:1);
        else,
            win_l(np1+1:n) = w(1:np1);
            win_l(1:np1) = w(np1:-1:1);
        end
        win_l = real(win_l');
    end
    if isdef("opt") then
        if opt=="per" then
            win_l = win_l(1:$-1);
        end
    end
endfunction
_______________________________________________
users mailing list
users@lists.scilab.org
http://lists.scilab.org/mailman/listinfo/users

Reply via email to