1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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;
}
|