Skip to content

Commit bc3b2c2

Browse files
author
Ritika Mishra
committed
updated code to light candle
1 parent 889c933 commit bc3b2c2

File tree

3 files changed

+97
-35
lines changed

3 files changed

+97
-35
lines changed

src/components/BandPowerGraph.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const Graph: React.FC<GraphProps> = ({
6666

6767

6868
const FREQ_RESOLUTION = samplingRate / 256;
69+
6970
function calculateBandPower(fftMagnitudes: number[], freqRange: number[]) {
7071
const [startFreq, endFreq] = freqRange;
7172
const startIndex = Math.max(1, Math.floor(startFreq / FREQ_RESOLUTION));

src/components/CandleLit.tsx

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect } from 'react';
22

33
type FFTChannel = number[];
44
type FFTData = FFTChannel[];
@@ -14,11 +14,27 @@ interface CandleLitProps {
1414

1515
const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaPower }) => {
1616
const brightness = Math.max(0, betaPower / 100); // Normalize brightness
17-
17+
// Add smoothing and minimum brightness
18+
const [displayBrightness, setDisplayBrightness] = useState(0.1); // Start with small flame
19+
20+
useEffect(() => {
21+
// Always show at least a small flame (0.1) and cap at 1.0
22+
const target = Math.max(0.1, Math.min(1, betaPower / 100));
23+
24+
// Smooth transition
25+
const timer = setInterval(() => {
26+
setDisplayBrightness(prev => {
27+
const diff = target - prev;
28+
return Math.abs(diff) < 0.01 ? target : prev + diff * 0.1;
29+
});
30+
}, 16); // ~60fps
31+
32+
return () => clearInterval(timer);
33+
}, [betaPower]);
1834
// console.log("beta",betaPower);
1935

20-
// console.log(brightness);
21-
const flameColor = `rgba(255, 165, 0, ${brightness})`;
36+
// Use displayBrightness instead of raw betaPower for all visual elements
37+
const flameColor = `rgba(255, 165, 0, ${displayBrightness})`;
2238
// Calculate brightness from FFT data
2339
const calculateBrightness = (): number => {
2440
if (!Array.isArray(fftData) || fftData.length === 0) {
@@ -82,31 +98,32 @@ const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaP
8298
className="absolute top-0 left-1/2 transform -translate-x-1/2 w-full h-48 z-10 drop-shadow-xl"
8399
>
84100
<defs>
85-
{/* Outer Flame Gradient: bright yellow to orange */}
101+
{/* Outer Flame Gradient: Rich, Realistic Candle Flame Colors */}
86102
<linearGradient id="outerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
87-
<stop offset="0%" stopColor={`rgba(255,255,0, ${brightness * 0.5})`} />
88-
<stop offset="100%" stopColor={`rgba(255,165,0, ${brightness * 0.3})`} />
103+
<stop offset="0%" stopColor={`rgba(255,140,0, ${brightness * 0.6})`} />
104+
<stop offset="100%" stopColor={`rgba(255,69,0, ${brightness * 0.3})`} />
89105
</linearGradient>
90106

91-
{/* Inner Flame Gradient: pale yellow to gold */}
107+
{/* Inner Flame Gradient: Warm, Luminous Colors */}
92108
<linearGradient id="innerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
93-
<stop offset="0%" stopColor={`rgba(255,255,204, ${brightness * 0.7})`} />
94-
<stop offset="100%" stopColor={`rgba(255,215,0, ${brightness * 0.5})`} />
109+
<stop offset="0%" stopColor={`rgba(255,165,0, ${brightness * 0.8})`} />
110+
<stop offset="100%" stopColor={`rgba(255,99,71, ${brightness * 0.5})`} />
95111
</linearGradient>
96112

97-
{/* Filters for Blur and Glow */}
113+
{/* Filters for Enhanced Realism */}
98114
<filter id="flameBlur">
99-
<feGaussianBlur stdDeviation="5" />
115+
<feGaussianBlur stdDeviation="7" />
100116
</filter>
101117
<filter id="innerGlow">
102-
<feGaussianBlur stdDeviation="3" result="coloredBlur" />
118+
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
103119
<feMerge>
104120
<feMergeNode in="coloredBlur" />
105121
<feMergeNode in="SourceGraphic" />
106122
</feMerge>
107123
</filter>
108124
</defs>
109125

126+
110127
{/* Outer Flame Layer */}
111128
<path
112129
d={generateFlamePath()}
@@ -135,10 +152,6 @@ const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaP
135152
/>
136153
</svg>
137154

138-
{/* Wick with subtle flicker */}
139-
<div
140-
className="absolute top-12 left-1/2 transform -translate-x-1/2 w-0.5 h-8 bg-gray-400 dark:bg-gray-300 rounded-full z-20 shadow-lg animate-wickFlicker"
141-
></div>
142155

143156
{/* Energy Indicator */}
144157
<div className="absolute bottom-[-30px] left-1/2 transform -translate-x-1/2

src/components/FFT.tsx

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ const FFT = forwardRef(
3737
const containerRef = useRef<HTMLDivElement>(null);
3838
const { theme } = useTheme();
3939
const maxFreq = 60;
40-
const [betaPower, setBetaPower] = useState(0);
40+
const [betaPower, setBetaPower] = useState<number>(0);
41+
const betaPowerRef = useRef<number>(0);
4142
const channelColors = useMemo(() => ["red", "green", "blue", "purple", "orange", "yellow"], []);
4243
const canvasContainerRef = useRef<HTMLDivElement>(null);
4344
const dataPointCountRef = useRef<number>(1000);
@@ -92,65 +93,112 @@ const FFT = forwardRef(
9293
return smoothed;
9394
}
9495
}
96+
97+
// Add this useEffect to calculate initial beta power
98+
useEffect(() => {
99+
if (fftData.length > 0 && fftData[0].length > 0) {
100+
const channelData = fftData[0];
101+
const betaPower = calculateBandPower(channelData, [13, 32]); // Beta range
102+
const totalPower = calculateBandPower(channelData, [0.5, 100]); // Full range
103+
const normalizedBeta = (betaPower / totalPower) * 100;
104+
setBetaPower(normalizedBeta);
105+
betaPowerRef.current = normalizedBeta;
106+
}
107+
}, [fftData]);
108+
109+
// Add this calculateBandPower function to FFT.tsx
110+
const calculateBandPower = useCallback((magnitudes: number[], range: [number, number]) => {
111+
const [startFreq, endFreq] = range;
112+
const freqStep = currentSamplingRate / fftSize;
113+
const startIndex = Math.max(1, Math.floor(startFreq / freqStep));
114+
const endIndex = Math.min(Math.floor(endFreq / freqStep), magnitudes.length - 1);
115+
116+
let power = 0;
117+
for (let i = startIndex; i <= endIndex; i++) {
118+
power += magnitudes[i] * magnitudes[i];
119+
}
120+
return power;
121+
}, [currentSamplingRate, fftSize]);
122+
95123
const filter = new SmoothingFilter(32, fftSize / 2); // 5-point moving average
96124
// console.log("fft", betaPower);
97125
const renderBandPowerView = () => {
98126
switch (activeBandPowerView) {
99127
case 'bandpower':
100-
return <BandPowerGraph fftData={fftData} onBetaUpdate={setBetaPower} samplingRate={currentSamplingRate} />;
128+
return (
129+
<BandPowerGraph
130+
fftData={fftData}
131+
// Update both state and ref
132+
onBetaUpdate={(beta) => {
133+
betaPowerRef.current = beta;
134+
setBetaPower(beta);
135+
}}
136+
137+
samplingRate={currentSamplingRate}
138+
/>
139+
);
101140
case 'brightcandle':
102-
return <BrightCandleView betaPower={betaPower} fftData={fftData} />;
141+
return (
142+
<BrightCandleView
143+
betaPower={betaPower} // Use state value instead of ref
144+
fftData={fftData}
145+
/>
146+
);
103147
case 'moveup':
104148
return (
105149
<div className="w-full h-full flex items-center justify-center text-gray-400">
106150
Move Up View
107151
</div>
108152
);
109153
default:
110-
return <BandPowerGraph fftData={fftData} onBetaUpdate={setBetaPower} samplingRate={currentSamplingRate} />;
154+
return (
155+
<BandPowerGraph
156+
fftData={fftData}
157+
// Update both state and ref
158+
onBetaUpdate={(beta) => {
159+
betaPowerRef.current = beta;
160+
setBetaPower(beta);
161+
}}
162+
163+
samplingRate={currentSamplingRate}
164+
/>
165+
);
111166
}
112167
};
113168

114-
115169
useImperativeHandle(
116170
ref,
117171
() => ({
118172
updateData(data: number[]) {
119173
for (let i = 0; i < 1; i++) {
120174
const sensorValue = data[i + 1];
121-
// Add new sample to the buffer
122175
fftBufferRef.current[i].push(sensorValue);
123-
// Update the plot with the new sensor value
124176
updatePlot(sensorValue, Zoom);
125-
// Ensure the buffer does not exceed fftSize
177+
126178
if (fftBufferRef.current[i].length > fftSize) {
127-
fftBufferRef.current[i].shift(); // Remove the oldest sample
179+
fftBufferRef.current[i].shift();
128180
}
129181
samplesReceived++;
130182

131-
// Trigger FFT computation every 5 samples
132-
if (samplesReceived % 25 === 0) {
133-
const processedBuffer = fftBufferRef.current[i].slice(0, fftSize); // Ensure exact length
183+
// Trigger FFT computation more frequently
184+
if (samplesReceived % 5 === 0) { // Changed from 25 to 5
185+
const processedBuffer = fftBufferRef.current[i].slice(0, fftSize);
134186
const floatInput = new Float32Array(processedBuffer);
135-
136-
// Calculate frequencies for the FFT result
137187
const fftMags = fftProcessor.computeMagnitudes(floatInput);
138-
const magArray = Array.from(fftMags); // Convert Float32Array to regular array
188+
const magArray = Array.from(fftMags);
139189
const smoothedMags = filter.getSmoothedValues(magArray);
140-
// Update the FFT data state
190+
141191
setFftData((prevData) => {
142192
const newData = [...prevData];
143193
newData[i] = smoothedMags;
144194
return newData;
145195
});
146-
147196
}
148197
}
149198
},
150199
}),
151200
[Zoom, timeBase, canvasCount, fftSize, currentSamplingRate]
152201
);
153-
154202
////
155203
class FFT {
156204
private size: number;

0 commit comments

Comments
 (0)