1 |
|
---|
2 |
|
---|
3 | // FFT based on dsp.js
|
---|
4 |
|
---|
5 | // 1. Cutdown to just what is needed
|
---|
6 | // 2. Messed around with => added in array for the powerSpectrum
|
---|
7 |
|
---|
8 |
|
---|
9 | var FFTCustom = function(bufferSize, sampleRate) {
|
---|
10 | this.bufferSize = bufferSize;
|
---|
11 | this.sampleRate = sampleRate;
|
---|
12 | this.powerSpectrum = new Float32Array(bufferSize/2);
|
---|
13 | this.spectrum = new Float32Array(bufferSize/2);
|
---|
14 | this.real = new Float32Array(bufferSize);
|
---|
15 | this.imag = new Float32Array(bufferSize);
|
---|
16 | this.reverseTable = new Uint32Array(bufferSize);
|
---|
17 | this.sinTable = new Float32Array(bufferSize);
|
---|
18 | this.cosTable = new Float32Array(bufferSize);
|
---|
19 |
|
---|
20 | var limit = 1,
|
---|
21 | bit = bufferSize >> 1;
|
---|
22 |
|
---|
23 | while ( limit < bufferSize ) {
|
---|
24 | for ( var i = 0; i < limit; i++ ) {
|
---|
25 | this.reverseTable[i + limit] = this.reverseTable[i] + bit;
|
---|
26 | }
|
---|
27 |
|
---|
28 | limit = limit << 1;
|
---|
29 | bit = bit >> 1;
|
---|
30 | }
|
---|
31 |
|
---|
32 | for ( var i = 0; i < bufferSize; i++ ) {
|
---|
33 | this.sinTable[i] = Math.sin(-Math.PI/i);
|
---|
34 | this.cosTable[i] = Math.cos(-Math.PI/i);
|
---|
35 | }
|
---|
36 | };
|
---|
37 |
|
---|
38 | FFTCustom.prototype.forward = function(buffer) {
|
---|
39 | var bufferSize = this.bufferSize,
|
---|
40 | cosTable = this.cosTable,
|
---|
41 | sinTable = this.sinTable,
|
---|
42 | reverseTable = this.reverseTable,
|
---|
43 | real = this.real,
|
---|
44 | imag = this.imag,
|
---|
45 | spectrum = this.spectrum;
|
---|
46 | powerSpectrum = this.powerSpectrum;
|
---|
47 |
|
---|
48 | if ( bufferSize !== buffer.length ) {
|
---|
49 | throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length;
|
---|
50 | }
|
---|
51 |
|
---|
52 | if (_dspdebug) {
|
---|
53 | var line = "sample: [";
|
---|
54 | for (var ii=0; ii<500; ii+=100) {
|
---|
55 | line += buffer[ii] + " ";
|
---|
56 | }
|
---|
57 | line += "]";
|
---|
58 | console.log(line);
|
---|
59 | }
|
---|
60 |
|
---|
61 | for ( var i = 0; i < bufferSize; i++ ) {
|
---|
62 | real[i] = buffer[reverseTable[i]];
|
---|
63 | imag[i] = 0;
|
---|
64 | }
|
---|
65 |
|
---|
66 | var halfSize = 1,
|
---|
67 | phaseShiftStepReal,
|
---|
68 | phaseShiftStepImag,
|
---|
69 | currentPhaseShiftReal,
|
---|
70 | currentPhaseShiftImag,
|
---|
71 | off,
|
---|
72 | tr,
|
---|
73 | ti,
|
---|
74 | tmpReal,
|
---|
75 | i;
|
---|
76 |
|
---|
77 | while ( halfSize < bufferSize ) {
|
---|
78 | phaseShiftStepReal = cosTable[halfSize];
|
---|
79 | phaseShiftStepImag = sinTable[halfSize];
|
---|
80 | currentPhaseShiftReal = 1.0;
|
---|
81 | currentPhaseShiftImag = 0.0;
|
---|
82 |
|
---|
83 | for ( var fftStep = 0; fftStep < halfSize; fftStep++ ) {
|
---|
84 | i = fftStep;
|
---|
85 |
|
---|
86 | while ( i < bufferSize ) {
|
---|
87 | off = i + halfSize;
|
---|
88 | tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]);
|
---|
89 | ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]);
|
---|
90 |
|
---|
91 | real[off] = real[i] - tr;
|
---|
92 | imag[off] = imag[i] - ti;
|
---|
93 | real[i] += tr;
|
---|
94 | imag[i] += ti;
|
---|
95 |
|
---|
96 | i += halfSize << 1;
|
---|
97 | }
|
---|
98 |
|
---|
99 | tmpReal = currentPhaseShiftReal;
|
---|
100 | currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag);
|
---|
101 | currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal);
|
---|
102 | }
|
---|
103 |
|
---|
104 | halfSize = halfSize << 1;
|
---|
105 | }
|
---|
106 |
|
---|
107 | i = bufferSize/2;
|
---|
108 | while(i--) {
|
---|
109 | spectrum[i] = 2 * Math.sqrt(real[i] * real[i] + imag[i] * imag[i]) / bufferSize;
|
---|
110 | powerSpectrum[i] = 2 * (real[i] * real[i] + imag[i] * imag[i]) / bufferSize; // done to match fftExtract
|
---|
111 | }
|
---|
112 |
|
---|
113 |
|
---|
114 | if (_dspdebug) {
|
---|
115 | for (i=0; i<bufferSize/2; i+=80) {
|
---|
116 | console.log("{re: " + real[i] + ", im:" + imag[i] + "}");
|
---|
117 | }
|
---|
118 | console.log("-----");
|
---|
119 | }
|
---|
120 |
|
---|
121 | };
|
---|
122 |
|
---|