summaryrefslogtreecommitdiff
path: root/macros/fir1.sci
blob: 05532db38a262aeb08d8fbddfb6f0e89e280d9a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
function b = fir1(n, w, varargin)

    funcprot(0);
    if argn(2) < 2 | argn(2) > 5
        error("Wrong Number of input arguments");
    end

    // Assign default window, filter type and scale.
    // If single band edge, the first band defaults to a pass band to
    // create a lowpass filter.  If multiple band edges, the first band
    // defaults to a stop band so that the two band case defaults to a
    // band pass filter.  Ick.

    window_in  = [];
    scale   = 1;
    ftype   = bool2s(length(w)==1);


    for i=1:length(varargin)
        arg = varargin(i);
        if (type(arg)==10)
            arg=convstr(arg,"l");
        end
        if isempty(arg)
            continue;
        end

        select arg
        case 'low' then ftype  = 1; case 'stop' then ftype  = 1; case 'dc-1' then ftype  = 1;
        case 'high' then ftype  = 0; case 'pass' then ftype  = 0; case 'bandpass' then ftype  = 0; case 'dc-0' then ftype  = 0;
        case 'scale' then scale=1;
        case 'noscale' then scale=0;
        else window_in=arg;
        end
    end

    // build response function according to fir2 requirements
    bands = length(w)+1;
    f = zeros(1,2*bands);
    f(2*bands)=1;
    f(2:2:2*bands-1) = w;
    f(3:2:2*bands-1) = w;
    m = zeros(1,2*bands);
    m(1:2:2*bands) = modulo([1:bands]-(1-ftype),2);
    m(2:2:2*bands) = m(1:2:2*bands);




    //Increment the order if the final band is a pass band.  Something
    // about having a nyquist frequency of zero causing problems.
    //
    if modulo(n,2)==1 & m(2*bands)==1,
        warning("n must be even for highpass and bandstop filters. Incrementing.");
        n = n+1;
        if isvector(window_in) & isreal(window_in) & ~(type(window_in)==10)
            // Extend the window using interpolation
            M = length(window_in);
            if M == 1,
                window_in = [window_in; window_in];
            elseif M < 4
                window_in = interp1(linspace(0,1,M),window_in,linspace(0,1,M+1),'linear');
            else
                window_in = interp1(linspace(0,1,M),window_in,linspace(0,1,M+1),'spline');
            end
        end
    end

    // compute the filter
    b = fir2(n, f, m, [], 2, window_in);

    // normalize filter magnitude
    if scale == 1
        // find the middle of the first band edge
        // find the frequency of the normalizing gain
        if m(1) == 1
            // if the first band is a passband, use DC gain
            w_o = 0;
        elseif f(4) == 1
            // for a highpass filter,
            // use the gain at half the sample frequency
            w_o = 1;
        else
            // otherwise, use the gain at the center
            // frequency of the first passband
            w_o = f(3) + (f(4)-f(3))/2;
        end

        // compute |h(w_o)|^-1

        if ~(isvector(b) | isempty(b))  // Check input is a vector
            error('Invalid');
        end

        x=exp(-1*%i*%pi*w_o)
//        z=[1 -exp(-1*%i*%pi*w_o)];
        disp(x)
        nc = length(b);
       if(isscalar(x) &  nc>0 & (x~=%inf) & or(b(:)~=%inf))
            // Make it scream for scalar x.  Polynomial evaluation can be
            // implemented as a recursive digital filter.
            q=b;
            k = filter(1,[1 -real(x)],q);
            k=k(nc);
        end
        k=abs(k);
        renorm = 1/k


    // normalize the filter
    b = renorm*b;
end

endfunction