use opaque pointers
[sddekit.git] / src / sk_out.c
blobffa36451f7402d7198f7753647572fee370d9ba4
1 /* Apache 2.0 INS-AMU 2015 */
3 #include <stdlib.h>
4 #include <string.h>
6 #include "sk_out.h"
7 #include "sk_util.h"
8 #include "sk_malloc.h"
10 /* write data to file */
12 struct sk_out_file_data {
13 FILE *fd;
14 int isstd;
17 sk_out_file_data *sk_out_file_alloc() {
18 return sk_malloc (sizeof(sk_out_file_data));
21 int sk_out_file_is_std(sk_out_file_data *d) {
22 return d->isstd;
25 int sk_out_file_from_fname(sk_out_file_data *d, char *fname) {
26 d->fd = fopen(fname, "w");
27 d->isstd = 0;
28 return d->fd==NULL;
31 int sk_out_file_from_std(sk_out_file_data *d, FILE *std) {
32 d->fd = std;
33 d->isstd = 1;
34 return 0;
37 SK_DEFOUT(sk_out_file) {
38 int i;
39 sk_out_file_data *d = data;
40 fprintf(d->fd, "%f %d ", t, nx);
41 for (i=0; i<nx; i++) fprintf(d->fd, "%f ", x[i]);
42 fprintf(d->fd, "%d ", nc);
43 for (i=0; i<nc; i++) fprintf(d->fd, "%f ", c[i]);
44 fprintf(d->fd, "\n");
45 return 1;
48 void sk_out_file_free(sk_out_file_data *d) {
49 if (!(d->isstd))
50 fclose(d->fd);
51 sk_free(d);
54 /* auto-allocating array */
55 struct sk_out_mem_data {
56 int n_sample, capacity, nx, nc;
57 double *xs, *cs;
60 sk_out_mem_data *sk_out_mem_alloc() {
61 return sk_malloc (sizeof(sk_out_mem_data));
64 int sk_out_mem_get_n_sample(sk_out_mem_data *d) {
65 return d->n_sample;
68 int sk_out_mem_get_nx(sk_out_mem_data *d) {
69 return d->nx;
72 int sk_out_mem_get_nc(sk_out_mem_data *d) {
73 return d->nc;
76 double *sk_out_mem_get_xs(sk_out_mem_data *d) {
77 return d->xs;
80 double *sk_out_mem_get_cs(sk_out_mem_data *d) {
81 return d->cs;
84 int sk_out_mem_init(sk_out_mem_data *d) {
85 d->xs = NULL;
86 d->cs = NULL;
87 d->n_sample = 0;
88 d->capacity = 0;
89 return 0;
92 SK_DEFOUT(sk_out_mem) {
93 sk_out_mem_data *d = data;
94 (void) t;
95 if (d->capacity==0) {
96 /* first alloc */
97 d->nx = nx;
98 d->nc = nc;
99 d->xs = sk_malloc (sizeof(double)*nx);
100 d->cs = sk_malloc (sizeof(double)*nc);
101 d->capacity = 1;
103 memcpy(d->xs + d->n_sample*nx, x, sizeof(double)*nx);
104 memcpy(d->cs + d->n_sample*nc, c, sizeof(double)*nc);
105 d->n_sample++;
106 if (d->n_sample==d->capacity) {
107 double *x_, *c_;
108 /* expand buffer */
109 x_ = sk_realloc (d->xs, sizeof(double)*nx*2*d->capacity);
110 if (x_==NULL)
111 return 0;
112 c_ = sk_realloc (d->cs, sizeof(double)*nc*2*d->capacity);
113 if (c_==NULL)
114 return 0;
115 d->capacity *= 2;
116 d->xs = x_;
117 d->cs = c_;
119 return 1;
122 void sk_out_mem_free(sk_out_mem_data *d) {
123 if (d->xs!=NULL)
124 sk_free(d->xs);
125 if (d->cs!=NULL)
126 sk_free(d->cs);
127 sk_free(d);
130 /* split n-ways */
132 struct sk_out_tee_data {
133 int nout;
134 sk_out *outs;
135 void **outd;
138 sk_out_tee_data *sk_out_tee_alloc() {
139 return sk_malloc (sizeof(sk_out_tee_data));
142 int sk_out_tee_init(sk_out_tee_data *d, int nout) {
143 d->nout = nout;
144 d->outs = sk_malloc (sizeof(sk_out) * nout);
145 d->outd = sk_malloc (sizeof(void*) * nout);
146 return 0;
149 int sk_out_tee_set_out(sk_out_tee_data *d, int i, sk_out out, void *data) {
150 if (i < d->nout) {
151 d->outs[i] = out;
152 d->outd[i] = data;
153 return 0;
155 return 1;
158 SK_DEFOUT(sk_out_tee) {
159 int i, flag;
160 sk_out_tee_data *d = data;
161 flag = 1;
162 for (i=0; i<d->nout; i++)
163 flag &= (*(d->outs[i]))(d->outd[i], t, nx, x, nc, c);
164 return flag;
167 void sk_out_tee_free(sk_out_tee_data *d) {
168 sk_free(d->outs);
169 sk_free(d->outd);
170 sk_free(d);
173 /* temporal average / downsample */
175 struct sk_out_tavg_data {
176 int pos, len;
177 double *x, *c, t;
178 sk_out out;
179 void *outd;
182 sk_out_tavg_data *sk_out_tavg_alloc() {
183 return sk_malloc (sizeof(sk_out_tavg_data));
186 int sk_out_tavg_init(sk_out_tavg_data *d, int len, sk_out out, void *outd) {
187 d->len = len;
188 d->pos = 0;
189 d->t = 0.0;
190 d->out = out;
191 d->outd = outd;
192 d->x = NULL;
193 d->c = NULL;
194 return 0;
197 SK_DEFOUT(sk_out_tavg) {
198 int i;
199 int flag;
200 sk_out_tavg_data *d;
201 d = data;
202 #define ALL(lim) for(i=0;i<(lim);i++)
203 if (d->x==NULL) {
204 d->x = sk_malloc (sizeof(double) * nx);
205 d->c = sk_malloc (sizeof(double) * nc);
206 ALL(nx) d->x[i] = 0.0;
207 ALL(nc) d->c[i] = 0.0;
209 flag = 1;
210 ALL(nx) d->x[i] += x[i];
211 ALL(nc) d->c[i] += c[i];
212 d->t += t;
213 d->pos++;
214 if (d->pos==d->len) {
215 ALL(nx) d->x[i] /= d->len;
216 ALL(nc) d->c[i] /= d->len;
217 d->t /= d->len;
218 flag = (*(d->out))(d->outd, d->t, nx, d->x, nc, d->c);
219 d->pos = 0;
220 ALL(nx) d->x[i] = 0.0;
221 ALL(nc) d->c[i] = 0.0;
222 d->t = 0.0;
224 #undef ALL
225 return flag;
228 void sk_out_tavg_free(sk_out_tavg_data *d) {
229 if (d->x!=NULL) sk_free(d->x);
230 if (d->c!=NULL) sk_free(d->c);
231 sk_free(d);
234 /* spatial filter (bank)
236 * xfilts laid out as filter per row, i.e. shape [nfilt nx] & [nfilt nc]
239 struct sk_out_sfilt_data {
240 int nfilt, filtlen;
241 double *xfilts, *cfilts, *x, *c;
242 sk_out out;
243 void *outd;
246 sk_out_sfilt_data *sk_out_sfilt_alloc() {
247 return sk_malloc (sizeof(sk_out_sfilt_data));
250 int sk_out_sfilt_init(sk_out_sfilt_data *d, int nfilt, int filtlen,
251 double *xfilts, double *cfilts, sk_out out, void *outd) {
252 int nb;
253 d->nfilt = nfilt;
254 d->filtlen = filtlen;
255 nb = nfilt * filtlen * sizeof(double);
256 d->xfilts = sk_malloc(nb);
257 d->cfilts = sk_malloc(nb);
258 d->x = sk_malloc (sizeof(double) * nfilt);
259 d->c = sk_malloc (sizeof(double) * nfilt);
260 memcpy(d->xfilts, xfilts, nb);
261 memcpy(d->cfilts, cfilts, nb);
262 d->out = out;
263 d->outd = outd;
264 return 0;
267 SK_DEFOUT(sk_out_sfilt) {
268 int i, j;
269 sk_out_sfilt_data *d = data;
270 /* unused */ (void) nx; (void) nc;
271 for (i=0; i<d->nfilt; i++) {
272 d->x[i] = d->c[i] = 0.0;
273 for (j=0; j<d->filtlen; j++) {
274 d->x[i] += d->xfilts[i*d->filtlen+j] * x[j];
275 d->c[i] += d->cfilts[i*d->filtlen+j] * c[j];
278 return (*(d->out))(d->outd, t, d->nfilt, d->x, d->nfilt, d->c);
281 void sk_out_sfilt_free(sk_out_sfilt_data *d) {
282 sk_free(d->xfilts);
283 sk_free(d->cfilts);
284 sk_free(d->x);
285 sk_free(d->c);
286 sk_free(d);
289 FILE *sk_out_file_get_fd(sk_out_file_data *d) { return d->fd; }
290 int sk_out_mem_get_capacity(sk_out_mem_data *d) { return d->capacity; }
291 int sk_out_tee_get_nout(sk_out_tee_data *d) { return d->nout; }
292 int sk_out_tee_outs_is_null(sk_out_tee_data *d) { return d->outs == NULL; }
293 int sk_out_tee_outd_is_null(sk_out_tee_data *d) { return d->outd == NULL; }
294 sk_out sk_out_tee_get_out_i(sk_out_tee_data *d, int i) { return d->outs[i]; }
295 void *sk_out_tee_get_outd_i(sk_out_tee_data *d, int i) { return d->outd[i]; }
296 int sk_out_tavg_get_len(sk_out_tavg_data *d) { return d->len; }
297 int sk_out_tavg_get_pos(sk_out_tavg_data *d) { return d->pos; }
298 double sk_out_tavg_get_t(sk_out_tavg_data *d) { return d->t; }
299 sk_out sk_out_tavg_get_out(sk_out_tavg_data *d) { return d->out; }
300 void *sk_out_tavg_get_outd(sk_out_tavg_data *d) { return d->outd; }
301 double *sk_out_tavg_get_x(sk_out_tavg_data *d) { return d->x; }
302 double *sk_out_tavg_get_c(sk_out_tavg_data *d) { return d->c; }
303 int sk_out_sfilt_get_nfilt(sk_out_sfilt_data *d) { return d->nfilt; }
304 int sk_out_sfilt_get_filtlen(sk_out_sfilt_data *d) { return d->filtlen; }
305 double *sk_out_sfilt_get_xfilts(sk_out_sfilt_data *d) { return d->xfilts; }
306 double *sk_out_sfilt_get_cfilts(sk_out_sfilt_data *d) { return d->cfilts; }
307 double *sk_out_sfilt_get_x(sk_out_sfilt_data *d) { return d->x; }
308 double *sk_out_sfilt_get_c(sk_out_sfilt_data *d) { return d->c; }
309 sk_out sk_out_sfilt_get_out(sk_out_sfilt_data *d) { return d->out; }
310 void *sk_out_sfilt_get_outd(sk_out_sfilt_data *d) { return d->outd; }