#include #include #include #include #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; }