@@ -13,6 +13,7 @@ import { createAudioContext, playAudioBuffer } from "../utils/webAudioUtils";
1313import type { IQSample } from "../models/SDRDevice" ;
1414import type { DemodulatorPlugin } from "../types/plugin" ;
1515import type { VfoState } from "../types/vfo" ;
16+ import { VfoStatus } from "../types/vfo" ;
1617
1718interface 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