1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "generator.h"
33 #define GENERATOR_CLASS_NAME "iir"
34 #define GENERATOR_CLASS_PATH "Filter/Generic IIR Filter"
41 #define NUM_EVENT_INPUTS 2
43 #define NUM_EVENT_OUTPUTS 0
52 PRIVATE
int init_instance(Generator
*g
) {
53 Data
*data
= safe_malloc(sizeof(Data
));
57 data
->coeffs
= safe_malloc( sizeof( double ) * data
->len
);
58 data
->zcoeffs
= safe_malloc( sizeof( double ) * data
->len
);
59 //data->state = safe_malloc( sizeof( double ) * (data->len-1) );
61 data
->coeffs
[0] = 1.0;
66 PRIVATE
void destroy_instance(Generator
*g
) {
77 PRIVATE
void unpickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
78 Data
*data
= safe_malloc(sizeof(Data
));
79 ObjectStoreDatum
*coeffs
= objectstore_item_get( item
, "iir_coeffs" );
80 ObjectStoreDatum
*zcoeffs
= objectstore_item_get( item
, "iir_zcoeffs" );
81 ObjectStoreDatum
*state
= objectstore_item_get( item
, "iir_state" );
86 data
->len
= objectstore_item_get_integer( item
, "iir_len", 1 );
88 data
->coeffs
= safe_malloc( sizeof( double ) * data
->len
);
89 data
->zcoeffs
= safe_malloc( sizeof( double ) * data
->len
);
92 data
->state
= safe_malloc( sizeof( double ) * (data
->len
-1) );
94 for( i
=0; i
<data
->len
; i
++ )
95 data
->coeffs
[i
] = objectstore_datum_double_value( objectstore_datum_array_get( coeffs
, i
) );
96 for( i
=0; i
<data
->len
; i
++ )
98 data
->zcoeffs
[i
] = objectstore_datum_double_value( objectstore_datum_array_get( zcoeffs
, i
) );
100 data
->zcoeffs
[i
] = 0;
102 for( i
=0; i
< (data
->len
-1); i
++ )
103 data
->state
[i
] = objectstore_datum_double_value( objectstore_datum_array_get( state
, i
) );
106 PRIVATE
void pickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
107 Data
*data
= g
->data
;
108 ObjectStoreDatum
*coeffs
= objectstore_datum_new_array( data
->len
);
109 ObjectStoreDatum
*zcoeffs
= objectstore_datum_new_array( data
->len
);
110 ObjectStoreDatum
*state
= objectstore_datum_new_array( data
->len
- 1 );
113 for( i
=0; i
<data
->len
; i
++ )
114 objectstore_datum_array_set( coeffs
, i
, objectstore_datum_new_double( data
->coeffs
[i
] ) );
115 for( i
=0; i
<data
->len
; i
++ )
116 objectstore_datum_array_set( zcoeffs
, i
, objectstore_datum_new_double( data
->zcoeffs
[i
] ) );
117 for( i
=0; i
< (data
->len
-1); i
++ )
118 objectstore_datum_array_set( state
, i
, objectstore_datum_new_double( data
->state
[i
] ) );
120 objectstore_item_set_integer(item
, "iir_len", data
->len
);
121 objectstore_item_set(item
, "iir_coeffs", coeffs
);
122 objectstore_item_set(item
, "iir_zcoeffs", zcoeffs
);
123 objectstore_item_set(item
, "iir_state", state
);
126 PRIVATE gboolean
output_generator(Generator
*g
, SAMPLE
*buf
, int buflen
) {
127 Data
*data
= g
->data
;
130 if (!gen_read_realtime_input(g
, SIG_INPUT
, -1, buf
, buflen
))
131 memset(buf
, 0, buflen
* sizeof(SAMPLE
));
133 for (i
= 0; i
< buflen
; i
++) {
134 SAMPLE tmp
= buf
[i
] * data
->coeffs
[0]; // This is normally not in canonical form 2
135 // But i include this here for compatibility
136 // TODO: sort this out again.
138 for( j
=1; j
<data
->len
; j
++ )
139 tmp
+= data
->coeffs
[j
] * data
->state
[j
-1];
141 buf
[i
] = tmp
* data
->zcoeffs
[0];
143 for( j
=1; j
<data
->len
; j
++ )
144 buf
[i
] += data
->zcoeffs
[j
] * data
->state
[j
-1];
146 for( j
= data
->len
-2; j
>0; j
-- )
147 data
->state
[j
] = data
->state
[j
-1];
150 data
->state
[0] = tmp
;
155 PRIVATE
void evt_coeffs_handler(Generator
*g
, AEvent
*event
) {
156 Data
*data
= g
->data
;
159 RETURN_UNLESS( event
->kind
== AE_DBLARRAY
);
160 RETURN_UNLESS( (event
->d
.darray
.len
& 1) == 0 );
162 len
= event
->d
.darray
.len
/ 2;
164 if( len
!= data
->len
) {
167 free( data
->coeffs
);
168 free( data
->zcoeffs
);
172 data
->coeffs
= safe_malloc( sizeof( double ) * data
->len
);
173 data
->zcoeffs
= safe_malloc( sizeof( double ) * data
->len
);
175 data
->state
= safe_malloc( sizeof( double ) * (data
->len
-1) );
176 for( i
=0; i
<data
->len
-1; i
++ )
179 for( i
=0; i
<data
->len
; i
++ )
180 data
->coeffs
[i
] = event
->d
.darray
.numbers
[i
];
181 for( i
=0; i
<data
->len
; i
++ )
182 data
->zcoeffs
[i
] = event
->d
.darray
.numbers
[i
+data
->len
];
185 PRIVATE
void evt_reset_handler(Generator
*g
, AEvent
*event
) {
186 Data
*data
= g
->data
;
189 for( i
=0; i
<data
->len
-1; i
++ )
192 PRIVATE InputSignalDescriptor input_sigs
[] = {
193 { "Input", SIG_FLAG_REALTIME
},
197 PRIVATE OutputSignalDescriptor output_sigs
[] = {
198 { "Output", SIG_FLAG_REALTIME
, { output_generator
, } },
202 PRIVATE ControlDescriptor controls
[] = {
203 /* { kind, name, min,max,step,page, size,editable, is_dst,queue_number,
204 init,destroy,refresh,refresh_data }, */
205 { CONTROL_KIND_NONE
, },
208 PRIVATE
void setup_class(void) {
209 GeneratorClass
*k
= gen_new_generatorclass(GENERATOR_CLASS_NAME
, FALSE
,
210 NUM_EVENT_INPUTS
, NUM_EVENT_OUTPUTS
,
211 input_sigs
, output_sigs
, controls
,
212 init_instance
, destroy_instance
,
213 unpickle_instance
, pickle_instance
);
215 gen_configure_event_input(k
, EVT_COEFFS
, "Coefficients", evt_coeffs_handler
);
216 gen_configure_event_input(k
, EVT_RESET
, "Reset", evt_reset_handler
);
218 gencomp_register_generatorclass(k
, FALSE
, GENERATOR_CLASS_PATH
, NULL
, NULL
);
221 PUBLIC
void init_plugin(void) {