missing commit in generator.h
[galan.git] / plugins / libiir_generic.c
blob5d1849c500b913210d8654f856db6b2b1422725d
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
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <stddef.h>
24 #include <gdk/gdk.h>
25 #include <gtk/gtk.h>
27 #include "global.h"
28 #include "generator.h"
29 #include "comp.h"
30 #include "control.h"
31 #include "gencomp.h"
33 #define GENERATOR_CLASS_NAME "iir"
34 #define GENERATOR_CLASS_PATH "Filter/Generic IIR Filter"
36 #define SIG_INPUT 0
37 #define SIG_OUTPUT 0
39 #define EVT_COEFFS 0
40 #define EVT_RESET 1
41 #define NUM_EVENT_INPUTS 2
43 #define NUM_EVENT_OUTPUTS 0
45 typedef struct Data {
46 int len;
47 gdouble *coeffs;
48 gdouble *zcoeffs;
49 gdouble *state;
50 } Data;
52 PRIVATE int init_instance(Generator *g) {
53 Data *data = safe_malloc(sizeof(Data));
54 g->data = data;
56 data->len = 1;
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;
63 return 1;
66 PRIVATE void destroy_instance(Generator *g) {
68 Data *data = g->data;
70 free(data->coeffs);
71 free(data->zcoeffs);
72 if( data->len > 1 )
73 free(data->state);
74 free(data);
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" );
82 int i;
84 g->data = data;
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 );
91 if( data->len > 1 )
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++ )
97 if( zcoeffs != NULL)
98 data->zcoeffs[i] = objectstore_datum_double_value( objectstore_datum_array_get( zcoeffs, i ) );
99 else
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 );
111 int i;
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;
128 int i,j;
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];
149 if( data->len > 1 )
150 data->state[0] = tmp;
152 return TRUE;
155 PRIVATE void evt_coeffs_handler(Generator *g, AEvent *event) {
156 Data *data = g->data;
157 int i,len;
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 ) {
165 if( data->len > 1 )
166 free( data->state );
167 free( data->coeffs );
168 free( data->zcoeffs );
170 data->len = len;
172 data->coeffs = safe_malloc( sizeof( double ) * data->len );
173 data->zcoeffs = safe_malloc( sizeof( double ) * data->len );
174 if( data->len > 1 )
175 data->state = safe_malloc( sizeof( double ) * (data->len-1) );
176 for( i=0; i<data->len-1; i++ )
177 data->state[i] = 0;
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;
187 int i;
189 for( i=0; i<data->len-1; i++ )
190 data->state[i] = 0;
192 PRIVATE InputSignalDescriptor input_sigs[] = {
193 { "Input", SIG_FLAG_REALTIME },
194 { NULL, }
197 PRIVATE OutputSignalDescriptor output_sigs[] = {
198 { "Output", SIG_FLAG_REALTIME, { output_generator, } },
199 { NULL, }
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) {
222 setup_class();