view yetilab/signal/window.yeti @ 296:ec6a36d88f57

Move complex tests to complex package
author Chris Cannam
date Fri, 31 May 2013 22:02:03 +0100
parents 240eb77ee2e8
children f8089ccb686d
line wrap: on
line source

module yetilab.signal.window;

vec = load yetilab.vector;
bf = load yetilab.vector.blockfuncs;

cosineWindowSymmetric a0 a1 a2 a3 n =
   (n1 = n - 1;
    vec.fromList
       (map do i:
            a0
            - a1 * cos(2 * pi * i / n1)
            + a2 * cos(4 * pi * i / n1)
            - a3 * cos(6 * pi * i / n1)
            done [0..n1]));

cosineWindowPeriodic a0 a1 a2 a3 n =
   (vec.fromList
       (map do i:
            a0
            - a1 * cos(2 * pi * i / n)
            + a2 * cos(4 * pi * i / n)
            - a3 * cos(6 * pi * i / n)
            done [0..n-1]));
                  
cosineWindow a0 a1 a2 a3 sampling n =
    if n < 2 then vec.ones n
    else
        case sampling of 
        Symmetric (): cosineWindowSymmetric;
        Periodic (): cosineWindowPeriodic;
        esac a0 a1 a2 a3 n;
    fi;

bartlettSymmetric n =
    if n < 2 then vec.ones n
    else
        vec.fromList
           (n1 = n - 1;
            h = int (n1 / 2);
            concat [
                map do i:
                    2 * i / n1
                    done [0..h],
                map do i:
                    2 - (2 * i / n1)
                    done [h+1..n1]
                ]);
    fi;

bartlettPeriodic n = 
    if n < 2 then vec.ones n
    else
        vec.slice (bartlettSymmetric (n+1)) 0 n;
    fi;

bartlett sampling =
    case sampling of
    Symmetric (): bartlettSymmetric;
    Periodic (): bartlettPeriodic;
    esac;

hann = cosineWindow 0.5 0.5 0.0 0.0;
hamming = cosineWindow 0.54 0.46 0.0 0.0;
blackman = cosineWindow 0.42 0.50 0.08 0.0;
nuttall = cosineWindow 0.355768 0.487396 0.144232 0.012604;
blackmanNuttall = cosineWindow 0.3635819 0.4891775 0.1365995 0.0106411;
blackmanHarris = cosineWindow 0.35875 0.48829 0.14128 0.01168;

boxcar n = vec.ones n;

windowFunction type options =
   (var sampling = Periodic ();
    for options \case of
        Symmetric s: if s then sampling := Symmetric () fi
        esac;
    case type of
    Hann (): hann sampling;
    Hamming (): hamming sampling;
    Blackman (): blackman sampling;
    Nuttall (): nuttall sampling;
    BlackmanNuttall (): blackmanNuttall sampling;
    BlackmanHarris (): blackmanHarris sampling;
    Boxcar (): boxcar;
    Bartlett (): bartlett sampling;
    esac);

//!!! should use vector. but does anyone use this function anyway? would we use it in framer if it used vector?
windowed windowFunc frames =
    case frames of
        []: frames;
         _: (first = head frames;
             window = windowFunc (vec.length first);
             map (bf.multiply window) frames);
    esac;

{
cosineWindow,
hann = hann (Periodic ()),
hamming = hamming (Periodic ()), 
blackman = blackman (Periodic ()), 
nuttall = nuttall (Periodic ()), 
blackmanNuttall = blackmanNuttall (Periodic ()), 
blackmanHarris = blackmanHarris (Periodic ()),
boxcar,
bartlett = bartlett (Periodic ()), 
windowFunction,
windowed
};