Skip to content

Commit 4932580

Browse files
Fix VFO reactivity and mode change detection
Co-authored-by: alexthemitchell <[email protected]>
1 parent fa45ce4 commit 4932580

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/hooks/useMultiVfoProcessor.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { createAudioContext, playAudioBuffer } from "../utils/webAudioUtils";
1313
import type { IQSample } from "../models/SDRDevice";
1414
import type { DemodulatorPlugin } from "../types/plugin";
1515
import type { VfoState } from "../types/vfo";
16+
import { VfoStatus } from "../types/vfo";
1617

1718
interface UseMultiVfoProcessorOptions {
1819
/** Hardware center frequency in Hz */
@@ -65,7 +66,7 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
6566
isReady: boolean;
6667
} {
6768
const { centerFrequencyHz, sampleRate, enableAudio } = options;
68-
const { getAllVfos, updateVfoState } = useVfo();
69+
const { vfos, getAllVfos, updateVfoState } = useVfo();
6970

7071
const processorRef = useRef<MultiVfoProcessor | null>(null);
7172
const audioContextRef = useRef<AudioContext | null>(null);
@@ -120,6 +121,9 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
120121
};
121122
}, [centerFrequencyHz, sampleRate, enableAudio]);
122123

124+
// Track VFO modes to detect changes
125+
const vfoModes = useRef<Map<string, string>>(new Map());
126+
123127
// Sync VFOs from store to processor
124128
useEffect(() => {
125129
const processor = processorRef.current;
@@ -132,6 +136,20 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
132136
// Add or update VFOs in processor
133137
const initializeVfos = async (): Promise<void> => {
134138
for (const vfo of vfoList) {
139+
// Check if mode has changed for existing VFO
140+
const existingMode = vfoModes.current.get(vfo.id);
141+
if (existingMode && existingMode !== vfo.modeId) {
142+
// Mode changed - dispose old demodulator and create new one
143+
const oldDemod = vfoDemodulators.current.get(vfo.id);
144+
if (oldDemod) {
145+
void oldDemod.dispose();
146+
vfoDemodulators.current.delete(vfo.id);
147+
}
148+
// Remove from processor so it can be re-added with new demodulator
149+
processor.removeVfo(vfo.id);
150+
addedVfoIds.current.delete(vfo.id);
151+
}
152+
135153
// Create demodulator if needed
136154
if (!vfoDemodulators.current.has(vfo.id)) {
137155
const demod = createDemodulatorForMode(vfo.modeId);
@@ -140,6 +158,7 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
140158
await demod.initialize();
141159
await demod.activate();
142160
vfoDemodulators.current.set(vfo.id, demod);
161+
vfoModes.current.set(vfo.id, vfo.modeId);
143162
} catch (error) {
144163
console.error(
145164
`Failed to initialize demodulator for VFO ${vfo.id}:`,
@@ -161,7 +180,7 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
161180
...vfo,
162181
demodulator,
163182
audioNode: null, // Web Audio API node will be created when playing
164-
status: "ACTIVE",
183+
status: VfoStatus.ACTIVE,
165184
};
166185

167186
// Only add VFO if we haven't added it yet
@@ -177,14 +196,15 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
177196
if (!vfoIds.has(id)) {
178197
processor.removeVfo(id);
179198
addedVfoIds.current.delete(id);
199+
vfoModes.current.delete(id);
180200
void demod.dispose();
181201
vfoDemodulators.current.delete(id);
182202
}
183203
}
184204
};
185205

186206
void initializeVfos();
187-
}, [getAllVfos]); // Re-run when VFO map changes
207+
}, [vfos, getAllVfos]); // Re-run when VFO map changes
188208

189209
/**
190210
* Process IQ samples through all active VFOs
@@ -216,7 +236,7 @@ export function useMultiVfoProcessor(options: UseMultiVfoProcessorOptions): {
216236
...vfo,
217237
demodulator,
218238
audioNode: null,
219-
status: "ACTIVE" as const,
239+
status: VfoStatus.ACTIVE,
220240
};
221241
})
222242
.filter((v): v is VfoState => v !== null);

0 commit comments

Comments
 (0)