-
Notifications
You must be signed in to change notification settings - Fork 4
/
DataFFT.sc
77 lines (76 loc) · 1.91 KB
/
DataFFT.sc
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
//for performing fft on OpenBCI data
DataFFT {
var <board, table, imag, <fftSize, <fftSize2, <bw;
var result;
*new {|board, fftSize= 256, windowType|
^super.new.initDataFFT(board, fftSize, windowType);
}
initDataFFT {|argBoard, argSize, argWindowType|
board= argBoard;
if(argSize.isPowerOfTwo.not, {
argSize= argSize.nextPowerOfTwo;
"%: not power-of-two. setting fftSize to %".format(this.class.name, argSize).warn;
});
fftSize= argSize;
fftSize2= argSize.div(2);
table= switch(argWindowType,
\hamming, {
Signal.hammingWindow(fftSize2+2).copyToEnd(fftSize2.div(2)+1);
},
\hanning, {
Signal.hanningWindow(fftSize2+2).copyToEnd(fftSize2.div(2)+1);
},
\rect, {
Signal.rectWindow(fftSize2+2).copyToEnd(fftSize2.div(2)+1);
},
\welch, {
Signal.welchWindow(fftSize2+2).copyToEnd(fftSize2.div(2)+1);
},
{
Signal.fftCosTable(fftSize);
}
);
imag= Signal.newClear(fftSize);
bw= 2/fftSize*(board.currentSampleRate*0.5);
result= FloatArray.newClear(fftSize2+1);
}
fft {|data|
var complex;
if(data.size<fftSize, {
"%: data size must be >= fftSize. zeropadded % values".format(this.class.name, fftSize-data.size).warn;
data= 0.dup(fftSize-data.size)++data;
});
data= data.copyRange(data.size-fftSize, data.size-1);
data= data-(data.sum/data.size); //remove the mean
complex= fft(data.as(Signal), imag, table);
result.size.do{|i|
result[i]= complex.real[i].hypot(complex.imag[i])/fftSize;
if(i>0 and:{i<fftSize2}, {
result[i]= result[i]*2;
});
};
^result;
}
indexToFreq {|index|
if(index==0, {
^bw*0.25;
}, {
if(index==fftSize2, {
^board.currentSampleRate*0.5-(bw*0.5)+(bw*0.25);
}, {
^index*bw;
});
});
}
freqToIndex {|freq|
if(freq<(bw*0.5), {
^0;
}, {
if(freq>(board.currentSampleRate*0.5-(bw*0.5)), {
^fftSize2;
}, {
^(fftSize*(freq/board.currentSampleRate)).round.asInteger;
});
});
}
}