roctave 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +33 -0
- data/ext/roctave/cu8_file_reader.c +331 -0
- data/ext/roctave/cu8_file_reader.h +30 -0
- data/ext/roctave/extconf.rb +6 -0
- data/ext/roctave/fir_filter.c +795 -0
- data/ext/roctave/fir_filter.h +29 -0
- data/ext/roctave/freq_shifter.c +410 -0
- data/ext/roctave/freq_shifter.h +29 -0
- data/ext/roctave/iir_filter.c +462 -0
- data/ext/roctave/iir_filter.h +29 -0
- data/ext/roctave/roctave.c +38 -0
- data/ext/roctave/roctave.h +27 -0
- data/lib/roctave.rb +168 -0
- data/lib/roctave/bilinear.rb +92 -0
- data/lib/roctave/butter.rb +87 -0
- data/lib/roctave/cheby.rb +180 -0
- data/lib/roctave/cu8_file_reader.rb +45 -0
- data/lib/roctave/dft.rb +280 -0
- data/lib/roctave/filter.rb +64 -0
- data/lib/roctave/finite_difference_coefficients.rb +73 -0
- data/lib/roctave/fir.rb +121 -0
- data/lib/roctave/fir1.rb +134 -0
- data/lib/roctave/fir2.rb +246 -0
- data/lib/roctave/fir_design.rb +311 -0
- data/lib/roctave/firls.rb +380 -0
- data/lib/roctave/firpm.rb +499 -0
- data/lib/roctave/freq_shifter.rb +47 -0
- data/lib/roctave/freqz.rb +233 -0
- data/lib/roctave/iir.rb +80 -0
- data/lib/roctave/interp1.rb +78 -0
- data/lib/roctave/plot.rb +748 -0
- data/lib/roctave/poly.rb +46 -0
- data/lib/roctave/roots.rb +73 -0
- data/lib/roctave/sftrans.rb +157 -0
- data/lib/roctave/version.rb +3 -0
- data/lib/roctave/window.rb +116 -0
- data/roctave.gemspec +79 -0
- data/samples/butter.rb +12 -0
- data/samples/cheby.rb +28 -0
- data/samples/dft.rb +18 -0
- data/samples/differentiator.rb +48 -0
- data/samples/differentiator_frequency_scaling.rb +52 -0
- data/samples/fft.rb +40 -0
- data/samples/finite_difference_coefficient.rb +53 -0
- data/samples/fir1.rb +13 -0
- data/samples/fir2.rb +14 -0
- data/samples/fir2_windows.rb +29 -0
- data/samples/fir2bank.rb +30 -0
- data/samples/fir_low_pass.rb +44 -0
- data/samples/firls.rb +77 -0
- data/samples/firpm.rb +78 -0
- data/samples/hilbert_transformer.rb +20 -0
- data/samples/hilbert_transformer_frequency_scaling.rb +47 -0
- data/samples/plot.rb +45 -0
- data/samples/stem.rb +8 -0
- data/samples/type1.rb +25 -0
- data/samples/type3.rb +24 -0
- data/samples/windows.rb +25 -0
- metadata +123 -0
@@ -0,0 +1,462 @@
|
|
1
|
+
/* Copyright (C) 2019 Théotime Bollengier <theotime.bollengier@gmail.com>
|
2
|
+
*
|
3
|
+
* This file is part of Roctave
|
4
|
+
*
|
5
|
+
* Roctave is free software: you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* Roctave is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License
|
16
|
+
* along with Roctave. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
|
20
|
+
#include <ruby.h>
|
21
|
+
#include "roctave.h"
|
22
|
+
#include "iir_filter.h"
|
23
|
+
|
24
|
+
VALUE c_IIR;
|
25
|
+
|
26
|
+
static ID id_real;
|
27
|
+
static ID id_imag;
|
28
|
+
|
29
|
+
|
30
|
+
struct iir_filter {
|
31
|
+
double *b;
|
32
|
+
double *a;
|
33
|
+
double *state;
|
34
|
+
double *stateim;
|
35
|
+
int nb_coefficients;
|
36
|
+
int state_length;
|
37
|
+
VALUE (*filter_one_sample_func)(struct iir_filter*, VALUE);
|
38
|
+
};
|
39
|
+
|
40
|
+
|
41
|
+
static void iir_filter_free(void *p)
|
42
|
+
{
|
43
|
+
struct iir_filter *flt = (struct iir_filter*)p;
|
44
|
+
|
45
|
+
if (flt->b)
|
46
|
+
free(flt->b);
|
47
|
+
|
48
|
+
if (flt->a)
|
49
|
+
free(flt->a);
|
50
|
+
|
51
|
+
if (flt->state)
|
52
|
+
free(flt->state);
|
53
|
+
|
54
|
+
if (flt->stateim)
|
55
|
+
free(flt->stateim);
|
56
|
+
|
57
|
+
xfree(flt);
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
static size_t iir_filter_size(const void* data)
|
62
|
+
{
|
63
|
+
const struct iir_filter *flt;
|
64
|
+
size_t res;
|
65
|
+
|
66
|
+
flt = (const struct iir_filter*)data;
|
67
|
+
|
68
|
+
res = sizeof(struct iir_filter);
|
69
|
+
res += 2*flt->nb_coefficients*sizeof(double);
|
70
|
+
res += flt->state_length*sizeof(double);
|
71
|
+
if (flt->stateim)
|
72
|
+
res += flt->state_length*sizeof(double);
|
73
|
+
|
74
|
+
return res;
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
static const rb_data_type_t iir_filter_type = {
|
79
|
+
.wrap_struct_name = "roctave_iir_filter_struct",
|
80
|
+
.function = {
|
81
|
+
.dmark = NULL,
|
82
|
+
.dfree = iir_filter_free,
|
83
|
+
.dsize = iir_filter_size,
|
84
|
+
},
|
85
|
+
.data = NULL,
|
86
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
87
|
+
};
|
88
|
+
|
89
|
+
|
90
|
+
/* @return [Integer] the filter order
|
91
|
+
*/
|
92
|
+
static VALUE iir_filter_order(VALUE self)
|
93
|
+
{
|
94
|
+
struct iir_filter *flt;
|
95
|
+
|
96
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
97
|
+
|
98
|
+
return INT2NUM(flt->nb_coefficients - 1);
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
/* Set a numerator coefficient.
|
103
|
+
* @param index [Integer] the coefficient index
|
104
|
+
* @param coef [Float] the coefficient value
|
105
|
+
* @return [Float, nil] the coefficient if the index is valid, or nil otherwise
|
106
|
+
*/
|
107
|
+
static VALUE iir_filter_set_b_coefficient_at(VALUE self, VALUE index, VALUE coef)
|
108
|
+
{
|
109
|
+
struct iir_filter *flt;
|
110
|
+
int ind;
|
111
|
+
double val;
|
112
|
+
VALUE res = Qnil;
|
113
|
+
|
114
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
115
|
+
|
116
|
+
ind = NUM2INT(index);
|
117
|
+
if (ind >= 0 && ind < flt->nb_coefficients) {
|
118
|
+
val = NUM2DBL(coef);
|
119
|
+
flt->b[ind] = val;
|
120
|
+
res = DBL2NUM(val);
|
121
|
+
}
|
122
|
+
|
123
|
+
return res;
|
124
|
+
}
|
125
|
+
|
126
|
+
|
127
|
+
/* Get a numerator coefficient.
|
128
|
+
* @param index [Integer] the coefficient index
|
129
|
+
* @return [Float] the coefficient at index
|
130
|
+
*/
|
131
|
+
static VALUE iir_filter_get_b_coefficient_at(VALUE self, VALUE index)
|
132
|
+
{
|
133
|
+
struct iir_filter *flt;
|
134
|
+
int ind;
|
135
|
+
VALUE res = Qnil;
|
136
|
+
|
137
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
138
|
+
|
139
|
+
ind = NUM2INT(index);
|
140
|
+
if (ind >= 0 && ind < flt->nb_coefficients)
|
141
|
+
res = DBL2NUM(flt->b[ind]);
|
142
|
+
else
|
143
|
+
res = DBL2NUM(0.0);
|
144
|
+
|
145
|
+
return res;
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
/* Set a denominator coefficient.
|
150
|
+
* @param index [Integer] the coefficient index, must be > 0
|
151
|
+
* @param coef [Float] the coefficient value
|
152
|
+
* @return [Float, nil] the coefficient if the index is valid, or nil otherwise
|
153
|
+
*/
|
154
|
+
static VALUE iir_filter_set_a_coefficient_at(VALUE self, VALUE index, VALUE coef)
|
155
|
+
{
|
156
|
+
struct iir_filter *flt;
|
157
|
+
int ind;
|
158
|
+
double val;
|
159
|
+
VALUE res = Qnil;
|
160
|
+
|
161
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
162
|
+
|
163
|
+
ind = NUM2INT(index);
|
164
|
+
if (ind > 0 && ind < flt->nb_coefficients) {
|
165
|
+
val = NUM2DBL(coef);
|
166
|
+
flt->a[ind] = val;
|
167
|
+
res = DBL2NUM(val);
|
168
|
+
}
|
169
|
+
|
170
|
+
return res;
|
171
|
+
}
|
172
|
+
|
173
|
+
|
174
|
+
/* Get a denominator coefficient.
|
175
|
+
* @param index [Integer] the coefficient index
|
176
|
+
* @return [Float] the coefficient at index
|
177
|
+
*/
|
178
|
+
static VALUE iir_filter_get_a_coefficient_at(VALUE self, VALUE index)
|
179
|
+
{
|
180
|
+
struct iir_filter *flt;
|
181
|
+
int ind;
|
182
|
+
VALUE res = Qnil;
|
183
|
+
|
184
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
185
|
+
|
186
|
+
ind = NUM2INT(index);
|
187
|
+
if (ind >= 0 && ind < flt->nb_coefficients)
|
188
|
+
res = DBL2NUM(flt->a[ind]);
|
189
|
+
else
|
190
|
+
res = DBL2NUM(0.0);
|
191
|
+
|
192
|
+
return res;
|
193
|
+
}
|
194
|
+
|
195
|
+
|
196
|
+
/* Return a copy of the numerator coefficients as an array.
|
197
|
+
* @return [Array<Float>] the filter +b+ coefficients
|
198
|
+
*/
|
199
|
+
static VALUE iir_filter_b_coefficients(VALUE self)
|
200
|
+
{
|
201
|
+
struct iir_filter *flt;
|
202
|
+
VALUE res;
|
203
|
+
int i;
|
204
|
+
|
205
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
206
|
+
|
207
|
+
res = rb_ary_new_capa(flt->nb_coefficients);
|
208
|
+
for (i = 0; i < flt->nb_coefficients; i++)
|
209
|
+
rb_ary_store(res, i, DBL2NUM(flt->b[i]));
|
210
|
+
|
211
|
+
return res;
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
/* Return a copy of the denominator coefficients as an array.
|
216
|
+
* @return [Array<Float>] the filter +a+ coefficients
|
217
|
+
*/
|
218
|
+
static VALUE iir_filter_a_coefficients(VALUE self)
|
219
|
+
{
|
220
|
+
struct iir_filter *flt;
|
221
|
+
VALUE res;
|
222
|
+
int i;
|
223
|
+
|
224
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
225
|
+
|
226
|
+
res = rb_ary_new_capa(flt->nb_coefficients);
|
227
|
+
for (i = 0; i < flt->nb_coefficients; i++)
|
228
|
+
rb_ary_store(res, i, DBL2NUM(flt->a[i]));
|
229
|
+
|
230
|
+
return res;
|
231
|
+
}
|
232
|
+
|
233
|
+
|
234
|
+
static VALUE filter_one_sample_complex(struct iir_filter *flt, VALUE samp)
|
235
|
+
{
|
236
|
+
const int flt_len = flt->nb_coefficients - 1;
|
237
|
+
double inr, ini, outr, outi;
|
238
|
+
int i;
|
239
|
+
|
240
|
+
inr = NUM2DBL(rb_funcallv(samp, id_real, 0, NULL));
|
241
|
+
ini = NUM2DBL(rb_funcallv(samp, id_imag, 0, NULL));
|
242
|
+
outr = flt->b[0] * inr + flt->state[0];
|
243
|
+
outi = flt->b[0] * ini + flt->stateim[0];
|
244
|
+
for (i = 1; i < flt_len; i++) {
|
245
|
+
flt->state[i-1] = flt->b[i] * inr - flt->a[i] * outr + flt->state[i];
|
246
|
+
flt->stateim[i-1] = flt->b[i] * ini - flt->a[i] * outi + flt->stateim[i];
|
247
|
+
}
|
248
|
+
flt->state[i-1] = flt->b[i] * inr - flt->a[i] * outr;
|
249
|
+
flt->stateim[i-1] = flt->b[i] * ini - flt->a[i] * outi;
|
250
|
+
|
251
|
+
return rb_complex_raw(DBL2NUM(outr), DBL2NUM(outi));
|
252
|
+
}
|
253
|
+
|
254
|
+
|
255
|
+
static void make_accept_complex(struct iir_filter *flt)
|
256
|
+
{
|
257
|
+
if (!flt->stateim)
|
258
|
+
flt->stateim = calloc(flt->state_length, sizeof(double));
|
259
|
+
if (!flt->stateim)
|
260
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate %lu bytes of state storage", flt->state_length*sizeof(double));
|
261
|
+
flt->filter_one_sample_func = &filter_one_sample_complex;
|
262
|
+
}
|
263
|
+
|
264
|
+
|
265
|
+
/* Not visible from the Ruby API.
|
266
|
+
* Process one Float sample, returning a Float sample.
|
267
|
+
* If the input sample is a Complex sample ane not a Float one,
|
268
|
+
* makes the filter accept Complex sample and returns filter_one_sample_complex().
|
269
|
+
* Once the filter has accepted one Complex, it will allways return complex samples.
|
270
|
+
*/
|
271
|
+
static VALUE filter_one_sample_float(struct iir_filter *flt, VALUE samp)
|
272
|
+
{
|
273
|
+
const int flt_len = flt->nb_coefficients - 1;
|
274
|
+
double in, out;
|
275
|
+
int i;
|
276
|
+
|
277
|
+
if (rb_class_of(samp) == rb_cComplex) {
|
278
|
+
make_accept_complex(flt);
|
279
|
+
return filter_one_sample_complex(flt, samp);
|
280
|
+
}
|
281
|
+
|
282
|
+
/* Transposed direct form 2 */
|
283
|
+
in = NUM2DBL(samp);
|
284
|
+
out = flt->b[0] * in + flt->state[0];
|
285
|
+
for (i = 1; i < flt_len; i++)
|
286
|
+
flt->state[i-1] = flt->b[i] * in - flt->a[i] * out + flt->state[i];
|
287
|
+
flt->state[i-1] = flt->b[i] * in - flt->a[i] * out;
|
288
|
+
|
289
|
+
return DBL2NUM(out);
|
290
|
+
}
|
291
|
+
|
292
|
+
|
293
|
+
/* @param sample [Float, Array<Float>] a single sample or an array of samples to process
|
294
|
+
* @return [Float, Array<Float>] a single or an array of processed samples
|
295
|
+
*/
|
296
|
+
static VALUE iir_filter_filter(VALUE self, VALUE sample)
|
297
|
+
{
|
298
|
+
struct iir_filter *flt;
|
299
|
+
VALUE res = Qnil;
|
300
|
+
int i, len;
|
301
|
+
|
302
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
303
|
+
|
304
|
+
if (RB_FLOAT_TYPE_P(sample) || rb_obj_is_kind_of(sample, rb_cNumeric))
|
305
|
+
res = (*flt->filter_one_sample_func)(flt, sample);
|
306
|
+
else if (rb_class_of(sample) == rb_cArray) {
|
307
|
+
len = rb_array_len(sample);
|
308
|
+
res = rb_ary_new_capa(len);
|
309
|
+
for (i = 0; i < len; i++)
|
310
|
+
rb_ary_store(res, i, (*flt->filter_one_sample_func)(flt, rb_ary_entry(sample, i)));
|
311
|
+
}
|
312
|
+
else
|
313
|
+
rb_raise(rb_eArgError, "Expecting a single Numeric or an Array of Numeric");
|
314
|
+
|
315
|
+
return res;
|
316
|
+
}
|
317
|
+
|
318
|
+
|
319
|
+
static VALUE iir_filter_alloc(VALUE klass)
|
320
|
+
{
|
321
|
+
VALUE obj;
|
322
|
+
struct iir_filter *flt;
|
323
|
+
|
324
|
+
flt = ZALLOC(struct iir_filter);
|
325
|
+
|
326
|
+
obj = TypedData_Wrap_Struct(klass, &iir_filter_type, flt);
|
327
|
+
|
328
|
+
flt->b = NULL;
|
329
|
+
flt->a = NULL;
|
330
|
+
flt->state = NULL;
|
331
|
+
flt->stateim = NULL;
|
332
|
+
flt->nb_coefficients = 0;
|
333
|
+
flt->state_length = 0;
|
334
|
+
flt->filter_one_sample_func = &filter_one_sample_float;
|
335
|
+
|
336
|
+
return obj;
|
337
|
+
}
|
338
|
+
|
339
|
+
|
340
|
+
/* Reset the filter state.
|
341
|
+
* @return self
|
342
|
+
*/
|
343
|
+
static VALUE iir_filter_reset(VALUE self)
|
344
|
+
{
|
345
|
+
struct iir_filter *flt;
|
346
|
+
int i;
|
347
|
+
|
348
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
349
|
+
|
350
|
+
for (i = 0; i < flt->state_length; i++)
|
351
|
+
flt->state[i] = 0.0f;
|
352
|
+
|
353
|
+
if (flt->stateim) {
|
354
|
+
for (i = 0; i < flt->state_length; i++)
|
355
|
+
flt->stateim[i] = 0.0f;
|
356
|
+
}
|
357
|
+
|
358
|
+
flt->filter_one_sample_func = &filter_one_sample_float;
|
359
|
+
|
360
|
+
return self;
|
361
|
+
}
|
362
|
+
|
363
|
+
|
364
|
+
/* @overload initialize(n)
|
365
|
+
* @param n [Integer] the filter order
|
366
|
+
* @overload initialize(b, a)
|
367
|
+
* @param b [Array<Float>] the array of numerator coefficients
|
368
|
+
* @param a [Array<Float>] the array of denominator coefficients
|
369
|
+
*/
|
370
|
+
static VALUE iir_filter_initialize(int argc, VALUE *argv, VALUE self)
|
371
|
+
{
|
372
|
+
struct iir_filter *flt;
|
373
|
+
VALUE b_or_n;
|
374
|
+
VALUE a;
|
375
|
+
double dv;
|
376
|
+
int i, lenb, lena = 0, len;
|
377
|
+
|
378
|
+
rb_scan_args(argc, argv, "11", &b_or_n, &a);
|
379
|
+
|
380
|
+
TypedData_Get_Struct(self, struct iir_filter, &iir_filter_type, flt);
|
381
|
+
|
382
|
+
if (rb_class_of(b_or_n) == rb_cInteger) {
|
383
|
+
if (argc > 1)
|
384
|
+
rb_raise(rb_eArgError, "If the order is given as the first argument, no other argument is expected");
|
385
|
+
flt->nb_coefficients = NUM2INT(b_or_n) + 1;
|
386
|
+
if (flt->nb_coefficients < 1)
|
387
|
+
rb_raise(rb_eArgError, "Order cannot be less than 0");
|
388
|
+
if (flt->nb_coefficients > 1048577)
|
389
|
+
rb_raise(rb_eArgError, "Order cannot be more than 1048576");
|
390
|
+
flt->b = calloc(flt->nb_coefficients, sizeof(double));
|
391
|
+
flt->a = calloc(flt->nb_coefficients, sizeof(double));
|
392
|
+
if (flt->b == NULL || flt->a == NULL)
|
393
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate memory for coefficient storage");
|
394
|
+
flt->a[0] = 1.0;
|
395
|
+
}
|
396
|
+
else if (rb_class_of(b_or_n) == rb_cArray) {
|
397
|
+
lenb = rb_array_len(b_or_n);
|
398
|
+
len = lenb;
|
399
|
+
if (argc > 1) {
|
400
|
+
if (rb_class_of(a) == rb_cArray)
|
401
|
+
lena = rb_array_len(a);
|
402
|
+
else
|
403
|
+
rb_raise(rb_eArgError, "Expecting denominator coefficients (Array<Float>) as second argument");
|
404
|
+
if (len < lena)
|
405
|
+
len = lena;
|
406
|
+
}
|
407
|
+
if (len > 1048577)
|
408
|
+
rb_raise(rb_eArgError, "Cannot be more than 1048577 coefficients");
|
409
|
+
if (len < 1)
|
410
|
+
rb_raise(rb_eArgError, "Coefficient arrays are empty");
|
411
|
+
flt->nb_coefficients = len;
|
412
|
+
flt->b = calloc(flt->nb_coefficients, sizeof(double));
|
413
|
+
flt->a = calloc(flt->nb_coefficients, sizeof(double));
|
414
|
+
if (flt->b == NULL || flt->a == NULL)
|
415
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate memory for coefficient storage");
|
416
|
+
flt->a[0] = 1.0;
|
417
|
+
if (lena > 1)
|
418
|
+
dv = NUM2DBL(rb_ary_entry(a, i));
|
419
|
+
else
|
420
|
+
dv = 1.0;
|
421
|
+
if (dv == 0.0)
|
422
|
+
rb_raise(rb_eArgError, "The first denominator coefficient may no be null");
|
423
|
+
for (i = 0; i < lenb; i++)
|
424
|
+
flt->b[i] = (double)(NUM2DBL(rb_ary_entry(b_or_n, i))) / dv;
|
425
|
+
for (i = 1; i < lena; i++)
|
426
|
+
flt->a[i] = (double)(NUM2DBL(rb_ary_entry(a, i))) / dv;
|
427
|
+
}
|
428
|
+
else
|
429
|
+
rb_raise(rb_eArgError, "Expecting the filter order (Integer) or the filter coefficients (two Array<Float>)");
|
430
|
+
|
431
|
+
flt->state_length = flt->nb_coefficients - 1;
|
432
|
+
flt->state = calloc(flt->state_length, sizeof(double));
|
433
|
+
if (!flt->state)
|
434
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate %lu bytes of state storage", flt->state_length*sizeof(double));
|
435
|
+
flt->stateim = NULL;
|
436
|
+
flt->filter_one_sample_func = &filter_one_sample_float;
|
437
|
+
|
438
|
+
return self;
|
439
|
+
}
|
440
|
+
|
441
|
+
|
442
|
+
void Init_iir_filter()
|
443
|
+
{
|
444
|
+
id_real = rb_intern("real");
|
445
|
+
id_imag = rb_intern("imag");
|
446
|
+
|
447
|
+
c_IIR = rb_define_class_under(m_Roctave, "IirFilter", rb_cData);
|
448
|
+
|
449
|
+
rb_define_alloc_func(c_IIR, iir_filter_alloc);
|
450
|
+
rb_define_method(c_IIR, "initialize", iir_filter_initialize, -1);
|
451
|
+
rb_define_method(c_IIR, "order", iir_filter_order, 0);
|
452
|
+
rb_define_method(c_IIR, "reset!", iir_filter_reset, 0);
|
453
|
+
rb_define_method(c_IIR, "get_num_coefficient_at", iir_filter_get_b_coefficient_at, 1);
|
454
|
+
rb_define_method(c_IIR, "set_num_coefficient_at", iir_filter_set_b_coefficient_at, 2);
|
455
|
+
rb_define_method(c_IIR, "get_den_coefficient_at", iir_filter_get_a_coefficient_at, 1);
|
456
|
+
rb_define_method(c_IIR, "set_den_coefficient_at", iir_filter_set_a_coefficient_at, 2);
|
457
|
+
rb_define_method(c_IIR, "numerator", iir_filter_b_coefficients, 0);
|
458
|
+
rb_define_method(c_IIR, "denominator", iir_filter_a_coefficients, 0);
|
459
|
+
rb_define_method(c_IIR, "filter", iir_filter_filter, 1);
|
460
|
+
}
|
461
|
+
|
462
|
+
|