Skip to content

Commit a00ce19

Browse files
committed
FFt calculation improved
1 parent 7d409b9 commit a00ce19

File tree

4 files changed

+67
-52
lines changed

4 files changed

+67
-52
lines changed

package-lock.json

Lines changed: 27 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"html2canvas": "^1.4.1",
4242
"jszip": "^3.10.1",
4343
"lucide-react": "^0.460.0",
44-
"next": "14.2.21",
44+
"next": "^14.2.21",
4545
"next-pwa": "^5.6.0",
4646
"next-themes": "^0.3.0",
4747
"react": "^18",

src/components/BandPowerGraph.tsx

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -55,49 +55,56 @@ const Graph: React.FC<GraphProps> = ({
5555

5656
const FREQ_RESOLUTION = samplingRate / 256;
5757

58-
function calculateBandPower(fftMagnitudes: number[], freqRange: number[]) {
59-
const [startFreq, endFreq] = freqRange;
60-
const startIndex = Math.max(1, Math.floor(startFreq / FREQ_RESOLUTION));
61-
const endIndex = Math.min(Math.floor(endFreq / FREQ_RESOLUTION), fftMagnitudes.length - 1);
62-
let power = 0;
63-
for (let i = startIndex; i <= endIndex; i++) {
64-
power += fftMagnitudes[i] * fftMagnitudes[i];
65-
}
66-
return power;
67-
}
68-
58+
const calculateBandPower = useCallback(
59+
(fftMagnitudes: number[], freqRange: number[]) => {
60+
const [startFreq, endFreq] = freqRange;
61+
const startIndex = Math.max(1, Math.floor(startFreq / FREQ_RESOLUTION));
62+
const endIndex = Math.min(Math.floor(endFreq / FREQ_RESOLUTION), fftMagnitudes.length - 1);
63+
let power = 0;
64+
for (let i = startIndex; i <= endIndex; i++) {
65+
power += fftMagnitudes[i] * fftMagnitudes[i];
66+
}
67+
return power;
68+
},
69+
[FREQ_RESOLUTION]
70+
);
71+
6972
useEffect(() => {
7073
if (fftData.length > 0 && fftData[0].length > 0) {
7174
const channelData = fftData[0];
72-
75+
7376
const deltaPower = calculateBandPower(channelData, DELTA_RANGE);
7477
const thetaPower = calculateBandPower(channelData, THETA_RANGE);
7578
const alphaPower = calculateBandPower(channelData, ALPHA_RANGE);
7679
const betaPower = calculateBandPower(channelData, BETA_RANGE);
7780
const gammaPower = calculateBandPower(channelData, GAMMA_RANGE);
7881
const total = deltaPower + thetaPower + alphaPower + betaPower + gammaPower;
79-
82+
8083
const newBandPowerData = [
8184
(deltaPower / total) * 100,
8285
(thetaPower / total) * 100,
8386
(alphaPower / total) * 100,
8487
(betaPower / total) * 100,
8588
(gammaPower / total) * 100,
8689
];
87-
90+
8891
if (
8992
newBandPowerData.some((value) => !isNaN(value) && value > -Infinity)
9093
) {
91-
setBandPowerData(newBandPowerData);
92-
93-
// Send smoothed beta value to parent
94+
setBandPowerData((prev) => {
95+
if (JSON.stringify(prev) !== JSON.stringify(newBandPowerData)) {
96+
return newBandPowerData;
97+
}
98+
return prev;
99+
});
100+
94101
if (onBetaUpdate) {
95102
onBetaUpdate(newBandPowerData[3]);
96103
}
97104
}
98105
}
99-
}, [fftData, calculateBandPower, onBetaUpdate]);
100-
106+
}, [fftData, calculateBandPower, onBetaUpdate && onBetaUpdate.toString()]); // Memoized dependencies
107+
101108

102109
const drawGraph = useCallback(
103110
(currentBandPowerData: number[]) => {
@@ -131,8 +138,8 @@ const Graph: React.FC<GraphProps> = ({
131138
const barWidth = (width - leftMargin - rightMargin) / bandNames.length;
132139
const barSpacing = barWidth * 0.2; // Space between bars
133140

134-
let minPower = Math.min(...currentBandPowerData);
135-
let maxPower = Math.max(...currentBandPowerData);
141+
let minPower = 0;
142+
let maxPower = 100;
136143

137144
if (maxPower - minPower < 1) {
138145
maxPower = minPower + 1;
@@ -151,8 +158,9 @@ const Graph: React.FC<GraphProps> = ({
151158
// Draw bars
152159
currentBandPowerData.forEach((power, index) => {
153160
const x = leftMargin + index * barWidth;
154-
const normalizedHeight = (power - minPower) / (maxPower - minPower);
155-
const barHeight = normalizedHeight * (height - bottomMargin - 10);
161+
const normalizedHeight = Math.max(0, (power - minPower) / (maxPower - minPower));
162+
const barHeight = Math.max(0,normalizedHeight * (height - bottomMargin - 10));
163+
156164
ctx.fillStyle = bandColors[index];
157165
ctx.fillRect(x + barSpacing / 2, height - bottomMargin - barHeight, barWidth - barSpacing, barHeight);
158166
});

src/components/FFT.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ const FFT = forwardRef(
3333
const fftBufferRef = useRef<number[][]>(Array.from({ length: 16 }, () => []));
3434
const [fftData, setFftData] = useState<number[][]>(Array.from({ length: 16 }, () => []));
3535
const fftSize = Math.pow(2, Math.round(Math.log2(currentSamplingRate / 2)));
36+
const sampleupdateref = useRef<number>(50);
37+
sampleupdateref.current=currentSamplingRate/10;
3638
const canvasRef = useRef<HTMLCanvasElement>(null);
3739
const containerRef = useRef<HTMLDivElement>(null);
3840
const { theme } = useTheme();
@@ -54,7 +56,6 @@ const FFT = forwardRef(
5456
: 'border rounded-xl bg-gray-600 text-primary-foreground'}
5557
`;
5658

57-
5859
let samplesReceived = 0;
5960
class SmoothingFilter {
6061
private bufferSize: number;
@@ -111,7 +112,6 @@ const FFT = forwardRef(
111112
const freqStep = currentSamplingRate / fftSize;
112113
const startIndex = Math.max(1, Math.floor(startFreq / freqStep));
113114
const endIndex = Math.min(Math.floor(endFreq / freqStep), magnitudes.length - 1);
114-
115115
let power = 0;
116116
for (let i = startIndex; i <= endIndex; i++) {
117117
power += magnitudes[i] * magnitudes[i];
@@ -161,7 +161,7 @@ const FFT = forwardRef(
161161
);
162162
}
163163
};
164-
const filter = new SmoothingFilter(128, 1);
164+
const filter = new SmoothingFilter((currentSamplingRate/ sampleupdateref.current)*2,1);
165165

166166
useImperativeHandle(
167167
ref,
@@ -178,7 +178,7 @@ const FFT = forwardRef(
178178
samplesReceived++;
179179

180180
// Trigger FFT computation more frequently
181-
if (samplesReceived % 15 === 0) { // Changed from 25 to 5
181+
if (samplesReceived % sampleupdateref.current === 0) { // Changed from 25 to 5
182182
const processedBuffer = fftBufferRef.current[i].slice(0, fftSize);
183183
const floatInput = new Float32Array(processedBuffer);
184184
const fftMags = fftProcessor.computeMagnitudes(floatInput);
@@ -299,7 +299,6 @@ const FFT = forwardRef(
299299

300300
try {
301301
const wglp = new WebglPlot(canvas);
302-
console.log("WebglPlot created:", wglp);
303302
wglp.gScaleY = Zoom;
304303
const lineColor = theme === "dark" ? new ColorRGBA(1, 2, 2, 1) : new ColorRGBA(0, 0, 0, 1); // Adjust colors as needed
305304

@@ -308,7 +307,6 @@ const FFT = forwardRef(
308307
line.lineSpaceX(-1, 2 / dataPointCountRef.current);
309308
wglp.addLine(line);
310309
newWglPlots.push(wglp);
311-
console.log(newWglPlots)
312310
linesRef.current = [line];
313311
wglPlotsref.current = [wglp];
314312
} catch (error) {
@@ -328,8 +326,6 @@ const FFT = forwardRef(
328326

329327
const updatePlot = useCallback((data: number, Zoom: number) => {
330328
if (!wglPlotsref.current[0] || !linesRef.current[0]) {
331-
console.log(linesRef.current[0]);
332-
console.log(wglPlotsref.current[0]);
333329
return;
334330
}
335331
const line = linesRef.current[0];
@@ -391,13 +387,8 @@ const FFT = forwardRef(
391387

392388
const xScale = (width - leftMargin - 10) / displayPoints;
393389

394-
let yMax = 1; // Default to prevent division by zero
395-
yMax = Math.max(...fftData[0]);
396-
// fftData.forEach((channelData) => {
397-
// if (channelData.length > 0) {
398-
// yMax = Math.max(yMax, ...channelData.slice(0, displayPoints));
399-
// }
400-
// });
390+
let yMax = 1;//Default to prevent division by zero
391+
yMax = Math.max(...fftData.flat());
401392

402393
const yScale = (height - bottomMargin - 10) / yMax;
403394

@@ -408,8 +399,7 @@ const FFT = forwardRef(
408399
const x = leftMargin + i * xScale;
409400
const y = height - bottomMargin - channelData[i] * yScale;
410401

411-
if (i === 0) ctx.moveTo(x, y);
412-
else ctx.lineTo(x, y);
402+
ctx.lineTo(x, y);
413403
}
414404
ctx.stroke();
415405
});
@@ -422,7 +412,7 @@ const FFT = forwardRef(
422412
for (let i = 0; i <= 5; i++) {
423413
const labelY =
424414
height - bottomMargin - (i / 5) * (height - bottomMargin - 10);
425-
ctx.fillText(((yMax * i) / 5).toFixed(1), leftMargin - 5, labelY);
415+
ctx.fillText(((yMax * i) / 5).toFixed(3), leftMargin - 5, labelY);
426416
}
427417

428418
ctx.textAlign = "center";

0 commit comments

Comments
 (0)