-
Notifications
You must be signed in to change notification settings - Fork 50
/
fft.c
69 lines (54 loc) · 1.31 KB
/
fft.c
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
/* $Revision$ */
#include <libintl.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <fftw3.h>
#include "error.h"
double *pin = NULL;
fftw_complex *pout = NULL;
fftw_plan plan;
int sample_rate = 44100;
void fft_init(int sample_rate_in)
{
sample_rate = sample_rate_in;
pin = (double *)malloc(sizeof(double) * sample_rate_in);
if (!pin)
error_exit(gettext("failed allocating memory for fft (1)"));
pout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * sample_rate_in + 1);
if (!pout)
error_exit(gettext("failed allocating memory for fft (2)"));
/* init fftw */
plan = fftw_plan_dft_r2c_1d(sample_rate_in, pin, pout, FFTW_ESTIMATE);
if (!plan)
error_exit(gettext("failed calculating plan for fft"));
}
void fft_free(void)
{
if (pin)
{
fftw_free(pout);
free(pin);
}
fftw_destroy_plan(plan);
}
void fft_stop(void)
{
fftw_cleanup();
}
void fft_do(double *in, double *output_mag, double *output_phase)
{
int loop = 0;
memcpy(pin, in, sizeof(double) * sample_rate);
/* calc fft */
fftw_execute(plan);
for(loop=0; loop<(sample_rate / 2) + 1; loop++)
{
double real = pout[loop][0];
double img = pout[loop][1];
/* magnitude */
output_mag[loop] = sqrt(pow(real, 2.0) + pow(img, 2.0));
/* phase */
output_phase[loop] = (real == 0 && img == 0) ? 0 : atan2(real, img);
}
}