diff options
Diffstat (limited to 'gfft.c')
-rw-r--r-- | gfft.c | 100 |
1 files changed, 100 insertions, 0 deletions
@@ -0,0 +1,100 @@ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <ctype.h> + +#include "gfft.h" + +void window_hard(sample *in, double *out, size_t size, int ch, int nch) +{ + for (size_t i = 0; i < size; i++) { + sample val = in[i * nch + ch]; + out[i] = (1./32768.) * val; + } +} + +void window_hann(sample *in, double *out, size_t size, int ch, int nch) +{ + double cfac = 2. * M_PI / ((double) size - 1); + for (size_t i = 0; i < size; i++) { + sample val = in[i * nch + ch]; + out[i] = (1./32768.) * val + * 0.5 * (1. - cos (cfac * (double)i)); + } +} + +static gpointer fftrun_threadf(gpointer param) +{ + struct fft_runner *fftr = param; + fftw_plan p; + double *in; + fftw_complex *out; + struct qe *qe; + struct fe *fe; + int stopped = 0; + sample *hist; + size_t span = fftr->span; + size_t pktsize = fftr->dev->pktsize; + + hist = malloc(sizeof(sample) * pktsize * span * fftr->dev->chan); + in = fftw_malloc(sizeof(double) * pktsize * span); + out = fftw_malloc(sizeof(fftw_complex) * pktsize * span); + p = fftw_plan_dft_r2c_1d(pktsize * span, in, out, + FFTW_MEASURE | FFTW_DESTROY_INPUT); + free(out); + + while (!stopped) { + qe = g_async_queue_pop(fftr->dev->queue); + fe = calloc(sizeof(struct fe), 1); + + switch (qe->message) { + case QE_STOPPED: + fe->message = FE_STOPPED; + stopped = 1; + break; + + case QE_ERROR: + fe->message = FE_DEV_ERROR; + fe->errcode = qe->errcode; + fe->errp = qe->errp; + break; + + case QE_DATA: + memmove(hist, hist + pktsize, + pktsize * (span - 1) * fftr->dev->chan * sizeof(*hist)); + memmove(hist + pktsize * (span - 1), qe->samples, + pktsize * fftr->dev->chan * sizeof(*hist)); + + fe->message = FE_DATA; + fe->data = fftw_malloc(sizeof(fftw_complex) + * pktsize * span); + fe->size = pktsize * span; + fftr->winf(hist, in, pktsize * span, 0, fftr->dev->chan); + fftw_execute_dft_r2c(p, in, fe->data); + break; + } + free(qe); + + g_async_queue_push(fftr->queue, fe); + } + + free(in); + fftw_destroy_plan(p); + return NULL; +} + +struct fft_runner *fftrun_attach(struct device *device, + window_func *winf, size_t span) +{ + GError *error = NULL; + struct fft_runner *fftr; + + fftr = malloc(sizeof(*fftr)); + fftr->dev = device; + fftr->queue = g_async_queue_new(); + fftr->thread = g_thread_create(fftrun_threadf, fftr, 0, &error); + fftr->winf = winf; + fftr->span = span; + return fftr; +} + |