annotate src/stateful.c @ 214:f28f66faa016

Add "stateful" feature type with initial feature "last n" Stateful feature extraction functions are functions that require state to be maintained between successive calls. This is necessary, for example when an accumulation of values is required, or changes need to be measured over time. The initial xtract_last_n() function accumulates the last N (single) values from *data and writes them to *result
author Jamie Bullock <jamie@jamiebullock.com>
date Tue, 03 Jun 2014 21:17:07 +0100
parents
children d2453f55c470
rev   line source
jamie@214 1 /*
jamie@214 2 * Copyright (C) 2012 Jamie Bullock
jamie@214 3 *
jamie@214 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
jamie@214 5 * of this software and associated documentation files (the "Software"), to
jamie@214 6 * deal in the Software without restriction, including without limitation the
jamie@214 7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
jamie@214 8 * sell copies of the Software, and to permit persons to whom the Software is
jamie@214 9 * furnished to do so, subject to the following conditions:
jamie@214 10 *
jamie@214 11 * The above copyright notice and this permission notice shall be included in
jamie@214 12 * all copies or substantial portions of the Software.
jamie@214 13 *
jamie@214 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jamie@214 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jamie@214 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jamie@214 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jamie@214 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
jamie@214 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
jamie@214 20 * IN THE SOFTWARE.
jamie@214 21 *
jamie@214 22 */
jamie@214 23
jamie@214 24 /* stateful.c: declares functions that extract features that require stateful data to be retained between frames */
jamie@214 25
jamie@214 26 #include "../xtract/xtract_stateful.h"
jamie@214 27 #include "../xtract/libxtract.h"
jamie@214 28
jamie@214 29 #include "c-ringbuf/ringbuf.h"
jamie@214 30
jamie@214 31 #include <stdlib.h>
jamie@214 32 #include <stdio.h>
jamie@214 33 #include <float.h>
jamie@214 34
jamie@214 35 struct xtract_last_n_state_
jamie@214 36 {
jamie@214 37 ringbuf_t ringbuf;
jamie@214 38 };
jamie@214 39
jamie@214 40
jamie@214 41 xtract_last_n_state *xtract_last_n_state_new(size_t N)
jamie@214 42 {
jamie@214 43 xtract_last_n_state *last_n_state = malloc(sizeof(xtract_last_n_state));
jamie@214 44
jamie@214 45 if (last_n_state == NULL)
jamie@214 46 {
jamie@214 47 perror("could not allocate memory for xtract_last_n_state");
jamie@214 48 return NULL;
jamie@214 49 }
jamie@214 50
jamie@214 51 last_n_state->ringbuf = ringbuf_new(N * sizeof(double));
jamie@214 52
jamie@214 53 if (last_n_state->ringbuf)
jamie@214 54 {
jamie@214 55 perror("could not allocate memory for xtract_last_n_state->ringbuf");
jamie@214 56 }
jamie@214 57
jamie@214 58 return last_n_state;
jamie@214 59 }
jamie@214 60
jamie@214 61 void xtract_last_n_state_delete(xtract_last_n_state *last_n_state)
jamie@214 62 {
jamie@214 63 ringbuf_free(&last_n_state->ringbuf);
jamie@214 64 free(last_n_state);
jamie@214 65 }
jamie@214 66
jamie@214 67 int xtract_last_n(const xtract_last_n_state *state, const double *data, const int N, const void *argv, double *result)
jamie@214 68 {
jamie@214 69 double *current = (double *)argv;
jamie@214 70 size_t N_bytes = N * sizeof(double);
jamie@214 71
jamie@214 72 if (N_bytes != ringbuf_capacity(state->ringbuf))
jamie@214 73 {
jamie@214 74 fprintf(stderr, "libxtract: error: xtract_last_n(): inconsitent size");
jamie@214 75 return XTRACT_BAD_STATE;
jamie@214 76 }
jamie@214 77
jamie@214 78 ringbuf_memcpy_into(state->ringbuf, current, sizeof(double));
jamie@214 79 size_t used = ringbuf_bytes_used(state->ringbuf);
jamie@214 80 ringbuf_memcpy_from(result, state->ringbuf, used, false);
jamie@214 81
jamie@214 82 if (used < N_bytes)
jamie@214 83 {
jamie@214 84 /* zero pad */
jamie@214 85 for (size_t n = used / sizeof(double); n < N; ++n)
jamie@214 86 {
jamie@214 87 result[n] = 0.0;
jamie@214 88 }
jamie@214 89 }
jamie@214 90
jamie@214 91 return XTRACT_SUCCESS;
jamie@214 92 }
jamie@214 93