~ubuntu-branches/ubuntu/utopic/glame/utopic

« back to all changes in this revision

Viewing changes to src/plugins/iir.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-09 17:14:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020409171412-jzpnov7mbz2w6zsr
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * iir.c
 
3
 * $Id: iir.c,v 1.21 2001/12/16 17:39:17 mag Exp $
 
4
 *
 
5
 * Copyright (C) 2000 Alexander Ehlert
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 *
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include <config.h>
 
25
#endif
 
26
 
 
27
#include <sys/time.h>
 
28
#include <sys/types.h>
 
29
#include <unistd.h>
 
30
#include <stdlib.h>
 
31
#include "filter.h"
 
32
#include "util.h"
 
33
#include "glplugin.h"
 
34
 
 
35
 
 
36
PLUGIN_SET(iir, "highpass lowpass bandpass bandpass_a")
 
37
 
 
38
#define GLAME_IIR_LOWPASS    0
 
39
#define GLAME_IIR_HIGHPASS   1
 
40
#define GLAME_IIR_BANDPASS   2
 
41
#define GLAME_IIR_BANDPASS_A 3
 
42
 
 
43
/* Just query the name of the plugin we get called from
 
44
 * to identify the right filter mode
 
45
 * returns the filter mode or -1 on error
 
46
 */
 
47
 
 
48
int identify_plugin(filter_t *n){
 
49
        const char *name = plugin_name(n->plugin);
 
50
 
 
51
        DPRINTF("plugin name = %s filter name = %s\n", name, n->name);
 
52
        if (name == NULL)
 
53
                return -1;
 
54
 
 
55
        
 
56
        if (strcmp(name,"lowpass")==0)
 
57
                return GLAME_IIR_LOWPASS;
 
58
        else if (strcmp(name,"highpass")==0)
 
59
                return GLAME_IIR_HIGHPASS;
 
60
        else if (strcmp(name,"bandpass")==0)
 
61
                return GLAME_IIR_BANDPASS;
 
62
        else if (strcmp(name,"bandpass_a")==0)
 
63
                return GLAME_IIR_BANDPASS_A;
 
64
        else
 
65
                return -1;
 
66
}
 
67
        
 
68
/* To get better filter accuracy I decided to compute the single
 
69
 * stages of the filter seperatly and apply them one by one 
 
70
 * to the sample data. According to the DSPGUIDE chapter 20 pp339
 
71
 * filters are more stable when applied in stages.
 
72
 * Who doesn't like that can still combine
 
73
 * all stages to one stage by just convoluting the single stages. 
 
74
 * But in the moment it's up to the user that he knows what he's doing. 
 
75
 * float accuracy can't be enough for certain parameters.
 
76
 */
 
77
 
 
78
#define gliirt double
 
79
#define CLAMP(x,mi,ma) ( (x < mi) ? mi : ( (x>ma) ? ma : x))
 
80
 
 
81
/* (hopefully) generic description of an iir filter */
 
82
 
 
83
typedef struct glame_iir glame_iir_t;
 
84
struct glame_iir {
 
85
        int np;         /* Number of poles */
 
86
        int mode;       /* Filter mode low/high/bandpass... */
 
87
        int nstages;    /* Number of filterstages */
 
88
        int na;         /* number of a coefficients per stage */
 
89
        int nb;         /* number of b coefficients per stage */
 
90
        gliirt fc;      /* cutoff/center frequency */
 
91
        gliirt bw;      /* bandwidth for bandpass */
 
92
        gliirt ppr;     /* percent of ripple in passband */
 
93
        gliirt spr;     /* percent of ripple in stopband */
 
94
        gliirt **coeff; /* Actual filter coefficients */
 
95
};
 
96
 
 
97
glame_iir_t *init_glame_iir(int mode, int nstages, int na, int nb){
 
98
        glame_iir_t *dum=NULL;
 
99
        int i;
 
100
        if ((dum=ALLOCN(1,glame_iir_t))){
 
101
                dum->mode=mode;
 
102
                dum->nstages=nstages;
 
103
                dum->na=na;
 
104
                dum->nb=nb;
 
105
                dum->coeff=(gliirt **)malloc(nstages*sizeof(gliirt *));
 
106
                for(i=0;i<nstages;i++)
 
107
                        dum->coeff[i]=(gliirt *)malloc((na+nb)*sizeof(gliirt));
 
108
        }
 
109
        return dum;
 
110
}
 
111
 
 
112
glame_iir_t *combine_iir_stages(int mode, glame_iir_t *first, glame_iir_t *second){
 
113
        int stages, i, j, cnt;
 
114
        glame_iir_t *gt;
 
115
        
 
116
        stages = first->nstages + second->nstages;
 
117
        
 
118
        if ((first->na != second->na) || (first->nb != second->nb))
 
119
                return NULL;
 
120
        
 
121
        if ((gt = init_glame_iir(mode, stages, first->na, first->nb))==NULL)
 
122
                return NULL;
 
123
        
 
124
        cnt = first->na + first->nb;
 
125
        
 
126
        /* copy coefficients */
 
127
        for(i=0; i<first->nstages; i++)
 
128
                for(j=0; j<cnt; j++)
 
129
                        gt->coeff[i][j]=first->coeff[i][j];
 
130
 
 
131
        for(i=first->nstages; i<stages; i++)
 
132
                for(j=0; j<cnt; j++)
 
133
                        gt->coeff[i][j]=second->coeff[i-first->nstages][j];
 
134
 
 
135
        return gt;
 
136
}
 
137
 
 
138
void free_glame_iir(glame_iir_t *gt){
 
139
        int i;
 
140
        for(i=0;i<gt->nstages;i++)
 
141
                free(gt->coeff[i]);
 
142
        free(gt->coeff);
 
143
        free(gt);
 
144
}
 
145
 
 
146
/* center: frequency already normalized between 0 and 0.5 of sampling
 
147
 * bandwidth given in octaves between lower and upper -3dB point
 
148
 */
 
149
 
 
150
glame_iir_t *calc_2polebandpass(float center, float bandwidth)
 
151
{
 
152
        glame_iir_t     *gt;
 
153
        double omega, alpha, gain;
 
154
        int i;
 
155
        
 
156
        if ((gt=init_glame_iir(GLAME_IIR_BANDPASS, 1, 3, 2))==NULL)
 
157
                return NULL;
 
158
        
 
159
        omega = 2.0*M_PI*center;
 
160
        DPRINTF("omega=%f\n", omega);
 
161
        alpha = sin(omega)*sinh(log(2.0)/2.0*bandwidth*omega/sin(omega));
 
162
        /*alpha=sin(omega)/2.0;*/
 
163
        DPRINTF("alpha=%f\n", alpha);
 
164
        gt->coeff[0][0] = alpha;
 
165
        gt->coeff[0][1] = 0.0;
 
166
        gt->coeff[0][2] = -alpha;
 
167
        gt->coeff[0][3] = 2.0 * cos(omega);
 
168
        gt->coeff[0][4] = alpha - 1.0;
 
169
        gain = 1.0 + alpha;
 
170
        for(i=0;i<5;i++)
 
171
                gt->coeff[0][i]/=gain;
 
172
        return gt;
 
173
}
 
174
 
 
175
/* chebyshev calculates coefficients for a chebyshev filter
 
176
 * a,b coefficients
 
177
 * n   number of poles(2,4,6,...)
 
178
 * m   0..lowpass, 1..highpass
 
179
 * fc  cutoff frequency in percent of samplerate
 
180
 * pr  percent ripple in passband (0.5 is optimal)
 
181
 *
 
182
 * Code from DSPGUIDE Chapter 20, pp341 
 
183
 * online version http://www.dspguide.com
 
184
 */
 
185
 
 
186
#define chebtype double
 
187
 
 
188
int chebyshev_stage(glame_iir_t *gt, int n){
 
189
        chebtype h,rp,ip,es,kx,vx,t,w,m,d,k,gain;
 
190
        chebtype *x=NULL, *y=NULL, *a=NULL, *b=NULL;
 
191
        int res=-1,i;
 
192
        
 
193
        if (n>gt->nstages)
 
194
                goto _error;
 
195
        if (gt->na+gt->nb!=5)
 
196
                goto _error;
 
197
 
 
198
        if (!(x=ALLOCN(3,chebtype)))
 
199
                goto _error;
 
200
        if (!(y=ALLOCN(2,chebtype)))
 
201
                goto _error;
 
202
        if (!(a=ALLOCN(3,chebtype)))
 
203
                goto _error;
 
204
        if (!(b=ALLOCN(2,chebtype)))
 
205
                goto _error;
 
206
        
 
207
        h=M_PI/((chebtype)gt->np*2.0)+n*M_PI/(chebtype)gt->np;
 
208
        rp=-cos(h);
 
209
        ip=sin(h);
 
210
/*      
 
211
        DPRINTF("rp=%f ip=%f np=%d h=%f ppr=%f\n",rp,ip,gt->np,h,gt->ppr);
 
212
*/      
 
213
        if(gt->ppr>0.0) {
 
214
                h=100.0/(100.0-gt->ppr);
 
215
                es=sqrt(h*h-1.0);
 
216
                h=1.0/es;
 
217
                vx=1.0/(chebtype)gt->np*log(h+sqrt(h*h+1.0));
 
218
                kx=1.0/(chebtype)gt->np*log(h+sqrt(h*h-1.0));
 
219
                kx=(exp(kx)+exp(-kx))/2.0;
 
220
                h=exp(vx);
 
221
                rp*=(h-1.0/h)*0.5/kx;
 
222
                ip*=(h+1.0/h)*0.5/kx;
 
223
        }
 
224
/*
 
225
        DPRINTF("rp=%f ip=%f es=%f kx=%f vx=%f h=%f\n",rp,ip,es,kx,vx,h);
 
226
*/
 
227
        t=2.0*tan(0.5);
 
228
        w=2.0*M_PI*gt->fc;
 
229
        m=rp*rp+ip*ip;
 
230
        d=4.0-4.0*rp*t+m*t*t;
 
231
        x[0]=t*t/d;
 
232
        x[1]=2*x[0];
 
233
        x[2]=x[0];
 
234
        y[0]=(8.0-2.0*m*t*t)/d;
 
235
        y[1]=(-4.0-4.0*rp*t-m*t*t)/d;
 
236
/*
 
237
        DPRINTF("\nt=%f\nw=%f\nm=%f\nd=%f\n",t,w,m,d);
 
238
        DPRINTF("\nx0=%f\nx1=%f\nx2=%f\ny1=%f\ny2=%f\n",x[0],x[1],x[2],y[0],y[1]);
 
239
*/
 
240
        if (gt->mode==GLAME_IIR_HIGHPASS)
 
241
                k=-cos(w*0.5+0.5)/cos(w*0.5-0.5);
 
242
        else
 
243
                k=sin(0.5-w*0.5)/sin(0.5+w*0.5);
 
244
        d=1+y[0]*k-y[1]*k*k;
 
245
        a[0]=(x[0]-x[1]*k+x[2]*k*k)/d;
 
246
        a[1]=(-2.0*x[0]*k+x[1]+x[1]*k*k-2.0*x[2]*k)/d;
 
247
        a[2]=(x[0]*k*k-x[1]*k+x[2])/d;
 
248
        b[0]=(2.0*k+y[0]+y[0]*k*k-2.0*y[1]*k)/d;
 
249
        b[1]=(-k*k-y[0]*k+y[1])/d;
 
250
        if(gt->mode==GLAME_IIR_HIGHPASS){
 
251
                a[1]=-a[1];
 
252
                b[0]=-b[0];
 
253
        }
 
254
/*      
 
255
        DPRINTF("n=%d a0=%e a1=%e a2=%e b1=%e b2=%e\n",n,a[0],a[1],a[2],b[0],b[1]);
 
256
*/
 
257
        /* FIXME gain correction for every stage is probably wrong */
 
258
 
 
259
        if(gt->mode==GLAME_IIR_HIGHPASS)
 
260
                gain=(a[0]-a[1]+a[2])/(1.0+b[0]-b[1]);
 
261
        else
 
262
                gain=(a[0]+a[1]+a[2])/(1.0-b[0]-b[1]);
 
263
        for(i=0;i<3;i++) a[i]/=gain;
 
264
 
 
265
 
 
266
        DPRINTF("n=%d a0=%e a1=%e a2=%e b1=%e b2=%e gain=%e\n",n,a[0],a[1],a[2],b[0],b[1],gain);
 
267
        
 
268
        gt->coeff[n][0]=(gliirt)(a[0]);
 
269
        gt->coeff[n][1]=(gliirt)(a[1]);
 
270
        gt->coeff[n][2]=(gliirt)(a[2]);
 
271
        gt->coeff[n][3]=(gliirt)(b[0]);
 
272
        gt->coeff[n][4]=(gliirt)(b[1]);
 
273
        
 
274
        res=0;
 
275
_error:
 
276
        free(x);
 
277
        free(y);
 
278
        free(a);
 
279
        free(b);
 
280
        return res;
 
281
}
 
282
 
 
283
glame_iir_t *chebyshev(int n, int mode, float fc, float pr){
 
284
        glame_iir_t *gt;
 
285
        int i;
 
286
        
 
287
        if (n%2!=0){
 
288
                DPRINTF("number of poles must be even.\n");
 
289
                return NULL;
 
290
        }
 
291
        
 
292
        if ((mode!=0) && (mode!=1)){
 
293
                DPRINTF("Mode %d not supported.\n",mode);
 
294
                return NULL;
 
295
        }
 
296
        
 
297
        if ((fc<0.0) || (fc>0.5)){
 
298
                DPRINTF("Invalid range for cutoff frequency(0-0.5)\n");
 
299
                return NULL;
 
300
        }
 
301
 
 
302
        if ((gt=init_glame_iir(mode,n/2,3,2))){
 
303
                DPRINTF("init_glame_iir done!\n");
 
304
                gt->ppr=pr;
 
305
                gt->fc=fc;
 
306
                gt->np=n;
 
307
                for(i=0;i<n/2;i++)
 
308
                        chebyshev_stage(gt,i);
 
309
                DPRINTF("Filter setup done!\n");
 
310
        }
 
311
        return gt;      
 
312
}
 
313
        
 
314
static int iir_f(filter_t *n)
 
315
{
 
316
        typedef struct {
 
317
                gliirt *iring;
 
318
                gliirt *oring;
 
319
                int     ipos;
 
320
                int     opos;
 
321
        } iirf_t;
 
322
        
 
323
        filter_pipe_t *in, *out;
 
324
        filter_buffer_t *inb;
 
325
        glame_iir_t *gt, *first, *second;
 
326
        iirf_t *iirf;
 
327
        int i,pos,j,nb,nt,z;
 
328
        int stages, mode, rate;
 
329
        float ripple, fc, ufc, lfc, bw;
 
330
 
 
331
        if (!(in = filterport_get_pipe(filterportdb_get_port(filter_portdb(n), PORTNAME_IN)))
 
332
            || !(out = filterport_get_pipe(filterportdb_get_port(filter_portdb(n), PORTNAME_OUT))))
 
333
                FILTER_ERROR_RETURN("no in- or output");
 
334
 
 
335
 
 
336
        rate = filterpipe_sample_rate(in);
 
337
 
 
338
        /* identify the filter mode */
 
339
 
 
340
        if ((mode=identify_plugin(n))==-1)
 
341
                FILTER_ERROR_RETURN("Doh! Filter mode not recognized\n");
 
342
        
 
343
        
 
344
        if (mode < GLAME_IIR_BANDPASS) {
 
345
                stages = filterparam_val_int(filterparamdb_get_param(filter_paramdb(n), "stages"));
 
346
                fc = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "cutoff"))/(float)rate;
 
347
                fc = CLAMP(fc, 0.0, 0.5);
 
348
                
 
349
                ripple = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "ripple"));
 
350
                
 
351
                DPRINTF("poles=%d mode=%d fc=%f ripple=%f\n", stages*2,mode,fc,ripple);
 
352
                
 
353
                if (!(gt=chebyshev(stages*2, mode, fc, ripple)))
 
354
                        FILTER_ERROR_RETURN("chebyshev failed");
 
355
                
 
356
        } else if (mode == GLAME_IIR_BANDPASS) {
 
357
                stages = filterparam_val_int(filterparamdb_get_param(filter_paramdb(n), "stages"));
 
358
                
 
359
                fc = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "center"))/(float)rate;
 
360
                fc = CLAMP(fc, 0.0, 0.5);
 
361
                
 
362
                bw = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "width"))/(float)rate;
 
363
                bw = CLAMP(bw, 0.0, 0.5);
 
364
 
 
365
                ufc = fc + bw*0.5;
 
366
                lfc = fc - bw*0.5;
 
367
                ufc = CLAMP(ufc, 0.0, 0.5);
 
368
                lfc = CLAMP(lfc, 0.0, 0.5);
 
369
                
 
370
                ripple=filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "ripple"));
 
371
                
 
372
                if (!(first=chebyshev(stages*2,GLAME_IIR_LOWPASS,ufc,ripple)))
 
373
                        FILTER_ERROR_RETURN("chebyshev failed");
 
374
                
 
375
                if (!(second=chebyshev(stages*2,GLAME_IIR_HIGHPASS,lfc,ripple)))
 
376
                        FILTER_ERROR_RETURN("chebyshev failed");
 
377
                
 
378
                if (!(gt = combine_iir_stages(mode, first, second)))
 
379
                        FILTER_ERROR_RETURN("combine stages failed");
 
380
                
 
381
                free_glame_iir(first);
 
382
                free_glame_iir(second);
 
383
 
 
384
        } else if (mode == GLAME_IIR_BANDPASS_A) {
 
385
                float nfc;
 
386
                fc = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "center"));
 
387
                /* normalize center frequency */
 
388
                nfc= CLAMP(fc/(float)rate, 0.0, 0.5);
 
389
                
 
390
                bw = filterparam_val_float(filterparamdb_get_param(filter_paramdb(n), "width"));
 
391
                if (fc <= bw*0.5)
 
392
                        bw = fc*2.0;
 
393
                
 
394
                DPRINTF("bandwidth(HZ)=%f\n", bw);
 
395
                /* calculate width in octaves log_2(x) = log(x)/log(2) */
 
396
                bw = log((fc+bw*0.5)/(fc-bw*0.5+1.0))/log(2.0);
 
397
 
 
398
                DPRINTF("center = %f, width in octaves = %f\n", nfc, bw);
 
399
 
 
400
                if (!(gt=calc_2polebandpass(nfc, bw)))
 
401
                        FILTER_ERROR_RETURN("bandpass failed");
 
402
 
 
403
        }
 
404
        
 
405
        /* here follows the generic code */
 
406
        
 
407
        if (gt->nstages==0)
 
408
                FILTER_ERROR_RETURN("iir filter needs at least one stage");
 
409
                        
 
410
        if (!(iirf=ALLOCN(gt->nstages,iirf_t)))
 
411
                FILTER_ERROR_RETURN("memory allocation error");
 
412
 
 
413
        for(i=0;i<gt->nstages;i++){
 
414
                DPRINTF("Stage %d\n",i);
 
415
                for(j=0;j<gt->na;j++)
 
416
                        DPRINTF("a[%d]=%f\n",j,gt->coeff[i][j]);
 
417
                for(;j<gt->na+gt->nb;j++)
 
418
                        DPRINTF("b[%d]=%f\n",j-gt->nb,gt->coeff[i][j]);
 
419
                if (!(iirf[i].iring=ALLOCN(gt->na,gliirt)))
 
420
                        FILTER_ERROR_CLEANUP("memory allocation error");
 
421
                if (!(iirf[i].oring=ALLOCN(gt->nb+1,gliirt)))
 
422
                        FILTER_ERROR_CLEANUP("memory allocation error");
 
423
                iirf[i].ipos=0;
 
424
                iirf[i].opos=0;
 
425
        }
 
426
        
 
427
        nb=gt->nb+1;
 
428
        nt=gt->na+gt->nb;
 
429
        
 
430
        FILTER_AFTER_INIT;
 
431
        
 
432
        /* Yes I know that this code is very ugly and possibly quite slow, but it's my first try :) */
 
433
        goto entry;
 
434
        do{
 
435
                FILTER_CHECK_STOP;
 
436
 
 
437
                while(pos<sbuf_size(inb)){
 
438
                        for(i=0;i<gt->nstages;i++){
 
439
                                if (i==0)
 
440
                                        iirf[0].iring[iirf[0].ipos]=sbuf_buf(inb)[pos];
 
441
                                else
 
442
                                        iirf[i].iring[iirf[i].ipos]=iirf[i-1].oring[iirf[i-1].opos];
 
443
                                iirf[i].oring[iirf[i].opos]=0.0;
 
444
                                /* y[n]=a0*x[n]+a1*x[n-1]+... */
 
445
                                z=iirf[i].ipos;
 
446
                                for(j=0;j<gt->na;j++){
 
447
                                        if(z==-1)
 
448
                                                z=gt->na-1;
 
449
                                        iirf[i].oring[iirf[i].opos]+=gt->coeff[i][j]*iirf[i].iring[z--];
 
450
                                }
 
451
                                /* y[n]=y[n]+b1*y[n-1]+b2*y[n-2]+... */
 
452
                                z=iirf[i].opos-1;
 
453
                                for(j=gt->na;j<nt;j++){
 
454
                                        if (z==-1)
 
455
                                                z=gt->nb;
 
456
                                        iirf[i].oring[iirf[i].opos]+=gt->coeff[i][j]*iirf[i].oring[z--];
 
457
                                }
 
458
                        }
 
459
                        /* At least I process it in place :) */
 
460
                        sbuf_buf(inb)[pos++]=(SAMPLE)iirf[gt->nstages-1].oring[iirf[gt->nstages-1].opos];
 
461
                        /* Adjust ringbuffers */
 
462
                        for(i=0;i<gt->nstages;i++){
 
463
                                iirf[i].ipos++;
 
464
                                if (iirf[i].ipos==gt->na)
 
465
                                        iirf[i].ipos=0;
 
466
                                iirf[i].opos++;
 
467
                                if (iirf[i].opos==nb)
 
468
                                        iirf[i].opos=0;
 
469
                        }
 
470
                }
 
471
                sbuf_queue(out,inb);
 
472
entry:
 
473
                inb=sbuf_get(in);
 
474
                inb=sbuf_make_private(inb);
 
475
                pos=0;
 
476
        }
 
477
        while(inb);
 
478
 
 
479
        sbuf_queue(out,inb);
 
480
 
 
481
        FILTER_BEFORE_STOPCLEANUP;
 
482
        FILTER_BEFORE_CLEANUP;
 
483
 
 
484
        for(i=0;i<gt->nstages;i++){
 
485
                free(iirf[i].iring);
 
486
                free(iirf[i].oring);
 
487
        }
 
488
        free(iirf);
 
489
 
 
490
        /* Later on this should be done by the calling filter */
 
491
 
 
492
        free_glame_iir(gt);
 
493
 
 
494
        FILTER_RETURN;
 
495
}
 
496
 
 
497
int highpass_register(plugin_t *p)
 
498
{
 
499
        filter_t *f;
 
500
        
 
501
        if (!(f = filter_creat(NULL)))
 
502
                        return -1;
 
503
        f->f = iir_f;
 
504
 
 
505
        filterportdb_add_port(filter_portdb(f), PORTNAME_OUT,
 
506
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_OUTPUT,
 
507
                              FILTERPORT_DESCRIPTION, "output channel",
 
508
                              FILTERPORT_END);
 
509
        filterportdb_add_port(filter_portdb(f), PORTNAME_IN,
 
510
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_INPUT,
 
511
                              FILTERPORT_DESCRIPTION, "input channel",
 
512
                              FILTERPORT_END);
 
513
        
 
514
        filterparamdb_add_param_int(filter_paramdb(f),"stages",
 
515
                                FILTER_PARAMTYPE_INT,1,
 
516
                                FILTERPARAM_DESCRIPTION,"number of stages",
 
517
                                FILTERPARAM_END);
 
518
        
 
519
        filterparamdb_add_param_float(filter_paramdb(f),"cutoff",
 
520
                            FILTER_PARAMTYPE_FLOAT, 1000,
 
521
                            FILTERPARAM_DESCRIPTION,"cutoff frequency",
 
522
                            FILTERPARAM_END);
 
523
 
 
524
        filterparamdb_add_param_float(filter_paramdb(f),"ripple",
 
525
                            FILTER_PARAMTYPE_FLOAT,0.5,
 
526
                            FILTERPARAM_DESCRIPTION,"percent ripple",
 
527
                            FILTERPARAM_END);
 
528
        
 
529
        plugin_set(p, PLUGIN_DESCRIPTION, "Chebyshev Lowpass");
 
530
        plugin_set(p, PLUGIN_PIXMAP, "iir.png");
 
531
        plugin_set(p, PLUGIN_CATEGORY, "Spectrum");
 
532
        plugin_set(p, PLUGIN_GUI_HELP_PATH, "highpass");
 
533
        
 
534
        filter_register(f, p);
 
535
 
 
536
        return 0;
 
537
}
 
538
 
 
539
int lowpass_register(plugin_t *p)
 
540
{
 
541
        filter_t *f;
 
542
        
 
543
        if (!(f = filter_creat(NULL)))
 
544
                        return -1;
 
545
        f->f = iir_f;
 
546
 
 
547
        filterportdb_add_port(filter_portdb(f), PORTNAME_OUT,
 
548
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_OUTPUT,
 
549
                              FILTERPORT_DESCRIPTION, "output channel",
 
550
                              FILTERPORT_END);
 
551
        filterportdb_add_port(filter_portdb(f), PORTNAME_IN,
 
552
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_INPUT,
 
553
                              FILTERPORT_DESCRIPTION, "input channel",
 
554
                              FILTERPORT_END);
 
555
        
 
556
        filterparamdb_add_param_int(filter_paramdb(f),"stages",
 
557
                                FILTER_PARAMTYPE_INT,1,
 
558
                                FILTERPARAM_DESCRIPTION,"number of stages",
 
559
                                FILTERPARAM_END);
 
560
        
 
561
        filterparamdb_add_param_float(filter_paramdb(f),"cutoff",
 
562
                            FILTER_PARAMTYPE_FLOAT, 1000,
 
563
                            FILTERPARAM_DESCRIPTION,"cutoff frequency",
 
564
                            FILTERPARAM_END);
 
565
 
 
566
        filterparamdb_add_param_float(filter_paramdb(f),"ripple",
 
567
                            FILTER_PARAMTYPE_FLOAT,0.5,
 
568
                            FILTERPARAM_DESCRIPTION,"percent ripple",
 
569
                            FILTERPARAM_END);
 
570
        
 
571
        plugin_set(p, PLUGIN_DESCRIPTION, "Chebyshev Highpass");
 
572
        plugin_set(p, PLUGIN_PIXMAP, "iir.png");
 
573
        plugin_set(p, PLUGIN_CATEGORY, "Spectrum");
 
574
        plugin_set(p, PLUGIN_GUI_HELP_PATH, "lowpass");
 
575
        
 
576
        filter_register(f, p);
 
577
 
 
578
        return 0;
 
579
}
 
580
 
 
581
int bandpass_register(plugin_t *p)
 
582
{
 
583
        filter_t *f;
 
584
 
 
585
        if (!(f = filter_creat(NULL)))
 
586
                return -1;
 
587
 
 
588
        f->f = iir_f;
 
589
 
 
590
        filterportdb_add_port(filter_portdb(f), PORTNAME_OUT,
 
591
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_OUTPUT,
 
592
                              FILTERPORT_DESCRIPTION, "output channel",
 
593
                              FILTERPORT_END);
 
594
        filterportdb_add_port(filter_portdb(f), PORTNAME_IN,
 
595
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_INPUT,
 
596
                              FILTERPORT_DESCRIPTION, "input channel",
 
597
                              FILTERPORT_END);
 
598
 
 
599
        filterparamdb_add_param_int(filter_paramdb(f),"stages",
 
600
                                FILTER_PARAMTYPE_INT,1,
 
601
                                FILTERPARAM_DESCRIPTION,"number of stages",
 
602
                                FILTERPARAM_END);
 
603
        
 
604
        filterparamdb_add_param_float(filter_paramdb(f),"center",
 
605
                            FILTER_PARAMTYPE_FLOAT, 1000,
 
606
                            FILTERPARAM_DESCRIPTION,"center frequency",
 
607
                            FILTERPARAM_END);
 
608
 
 
609
        filterparamdb_add_param_float(filter_paramdb(f),"width",
 
610
                            FILTER_PARAMTYPE_FLOAT,500,
 
611
                            FILTERPARAM_DESCRIPTION,"bandwidth around center",
 
612
                            FILTERPARAM_END);
 
613
        
 
614
        filterparamdb_add_param_float(filter_paramdb(f),"ripple",
 
615
                            FILTER_PARAMTYPE_FLOAT,0.5,
 
616
                            FILTERPARAM_DESCRIPTION,"percent ripple",
 
617
                            FILTERPARAM_END);
 
618
        
 
619
        plugin_set(p, PLUGIN_DESCRIPTION, "Chebyshev 2-stage Bandpass");
 
620
        plugin_set(p, PLUGIN_PIXMAP, "bandpass.png");
 
621
        plugin_set(p, PLUGIN_CATEGORY, "Spectrum");
 
622
        plugin_set(p, PLUGIN_GUI_HELP_PATH, "bandpass");
 
623
        
 
624
        filter_register(f, p);
 
625
 
 
626
        return 0;
 
627
}
 
628
 
 
629
int bandpass_a_register(plugin_t *p)
 
630
{
 
631
        filter_t *f;
 
632
 
 
633
        if (!(f = filter_creat(NULL)))
 
634
                return -1;
 
635
 
 
636
        f->f = iir_f;
 
637
 
 
638
        filterportdb_add_port(filter_portdb(f), PORTNAME_OUT,
 
639
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_OUTPUT,
 
640
                              FILTERPORT_DESCRIPTION, "output channel",
 
641
                              FILTERPORT_END);
 
642
        filterportdb_add_port(filter_portdb(f), PORTNAME_IN,
 
643
                              FILTER_PORTTYPE_SAMPLE, FILTER_PORTFLAG_INPUT,
 
644
                              FILTERPORT_DESCRIPTION, "input channel",
 
645
                              FILTERPORT_END);
 
646
 
 
647
        filterparamdb_add_param_float(filter_paramdb(f),"center",
 
648
                            FILTER_PARAMTYPE_FLOAT, 1000,
 
649
                            FILTERPARAM_DESCRIPTION,"center frequency",
 
650
                            FILTERPARAM_END);
 
651
 
 
652
        filterparamdb_add_param_float(filter_paramdb(f),"width",
 
653
                            FILTER_PARAMTYPE_FLOAT,500,
 
654
                            FILTERPARAM_DESCRIPTION,"bandwidth around center",
 
655
                            FILTERPARAM_END);
 
656
        
 
657
        plugin_set(p, PLUGIN_DESCRIPTION, "Biquad Bandpass (analog modelled bandpass)");
 
658
        plugin_set(p, PLUGIN_PIXMAP, "bandpass.png");
 
659
        plugin_set(p, PLUGIN_CATEGORY, "Spectrum");
 
660
        plugin_set(p, PLUGIN_GUI_HELP_PATH, "bandpass_a");
 
661
        
 
662
        filter_register(f, p);
 
663
 
 
664
        return 0;
 
665
}