3333CONFIG_PATH = os .path .join (now_dir , "assets" , "config.json" )
3434
3535
36- def save_realtime_settings (input_device , output_device , monitor_device , model_file , index_file ):
36+ def save_realtime_settings (
37+ input_device , output_device , monitor_device , model_file , index_file
38+ ):
3739 """Save realtime settings to config.json"""
3840 try :
3941 if os .path .exists (CONFIG_PATH ):
40- with open (CONFIG_PATH , 'r' , encoding = ' utf-8' ) as f :
42+ with open (CONFIG_PATH , "r" , encoding = " utf-8" ) as f :
4143 config = json .load (f )
4244 else :
4345 config = {}
44-
45- if ' realtime' not in config :
46- config [' realtime' ] = {}
47-
46+
47+ if " realtime" not in config :
48+ config [" realtime" ] = {}
49+
4850 # Only save non-None values, preserve existing values for None inputs
4951 if input_device is not None :
50- config [' realtime' ][ ' input_device' ] = input_device or ""
52+ config [" realtime" ][ " input_device" ] = input_device or ""
5153 if output_device is not None :
52- config [' realtime' ][ ' output_device' ] = output_device or ""
54+ config [" realtime" ][ " output_device" ] = output_device or ""
5355 if monitor_device is not None :
54- config [' realtime' ][ ' monitor_device' ] = monitor_device or ""
56+ config [" realtime" ][ " monitor_device" ] = monitor_device or ""
5557 if model_file is not None :
56- config [' realtime' ][ ' model_file' ] = model_file or ""
58+ config [" realtime" ][ " model_file" ] = model_file or ""
5759 if index_file is not None :
58- config [' realtime' ][ ' index_file' ] = index_file or ""
59-
60- with open (CONFIG_PATH , 'w' , encoding = ' utf-8' ) as f :
60+ config [" realtime" ][ " index_file" ] = index_file or ""
61+
62+ with open (CONFIG_PATH , "w" , encoding = " utf-8" ) as f :
6163 json .dump (config , f , indent = 2 , ensure_ascii = False )
6264 except Exception as e :
6365 print (f"Error saving realtime settings: { e } " )
@@ -67,25 +69,25 @@ def load_realtime_settings():
6769 """Load realtime settings from config.json"""
6870 try :
6971 if os .path .exists (CONFIG_PATH ):
70- with open (CONFIG_PATH , 'r' , encoding = ' utf-8' ) as f :
72+ with open (CONFIG_PATH , "r" , encoding = " utf-8" ) as f :
7173 config = json .load (f )
72- realtime_config = config .get (' realtime' , {})
74+ realtime_config = config .get (" realtime" , {})
7375 return {
74- ' input_device' : realtime_config .get (' input_device' , '' ),
75- ' output_device' : realtime_config .get (' output_device' , '' ),
76- ' monitor_device' : realtime_config .get (' monitor_device' , '' ),
77- ' model_file' : realtime_config .get (' model_file' , '' ),
78- ' index_file' : realtime_config .get (' index_file' , '' )
76+ " input_device" : realtime_config .get (" input_device" , "" ),
77+ " output_device" : realtime_config .get (" output_device" , "" ),
78+ " monitor_device" : realtime_config .get (" monitor_device" , "" ),
79+ " model_file" : realtime_config .get (" model_file" , "" ),
80+ " index_file" : realtime_config .get (" index_file" , "" ),
7981 }
8082 except Exception as e :
8183 print (f"Error loading realtime settings: { e } " )
82-
84+
8385 return {
84- ' input_device' : '' ,
85- ' output_device' : '' ,
86- ' monitor_device' : '' ,
87- ' model_file' : '' ,
88- ' index_file' : ''
86+ " input_device" : "" ,
87+ " output_device" : "" ,
88+ " monitor_device" : "" ,
89+ " model_file" : "" ,
90+ " index_file" : "" ,
8991 }
9092
9193
@@ -111,17 +113,17 @@ def get_safe_index_value(saved_value, choices, fallback_value=None):
111113 return choices [0 ]
112114 else :
113115 return None
114-
116+
115117 # Check exact match first
116118 if saved_value in choices :
117119 return saved_value
118-
120+
119121 # Check if saved value is a filename that matches any choice
120122 saved_filename = os .path .basename (saved_value )
121123 for choice in choices :
122124 if os .path .basename (choice ) == saved_filename :
123125 return choice
124-
126+
125127 # Fallback to default or first choice
126128 if fallback_value and fallback_value in choices :
127129 return fallback_value
@@ -302,7 +304,7 @@ def priority(name: str) -> int:
302304def realtime_tab ():
303305 gr .Markdown ("## Realtime Voice Changer" )
304306 input_devices , output_devices = get_audio_devices_formatted ()
305-
307+
306308 # Load saved settings
307309 saved_settings = load_realtime_settings ()
308310
@@ -323,7 +325,9 @@ def realtime_tab():
323325 label = "Input Device" ,
324326 info = "Select the microphone or audio interface you will be speaking into." ,
325327 choices = input_devices ,
326- value = get_safe_dropdown_value (saved_settings ['input_device' ], input_devices ),
328+ value = get_safe_dropdown_value (
329+ saved_settings ["input_device" ], input_devices
330+ ),
327331 interactive = True ,
328332 )
329333 input_audio_gain = gr .Slider (
@@ -349,7 +353,9 @@ def realtime_tab():
349353 label = "Output Device" ,
350354 info = "Select the device where the final converted voice will be sent (e.g., a virtual cable)." ,
351355 choices = output_devices ,
352- value = get_safe_dropdown_value (saved_settings ['output_device' ], output_devices ),
356+ value = get_safe_dropdown_value (
357+ saved_settings ["output_device" ], output_devices
358+ ),
353359 interactive = True ,
354360 )
355361 output_audio_gain = gr .Slider (
@@ -378,7 +384,9 @@ def realtime_tab():
378384 label = "Monitor Device" ,
379385 info = "Select the device for monitoring your voice (e.g., your headphones)." ,
380386 choices = output_devices ,
381- value = get_safe_dropdown_value (saved_settings ['monitor_device' ], output_devices ),
387+ value = get_safe_dropdown_value (
388+ saved_settings ["monitor_device" ], output_devices
389+ ),
382390 interactive = True ,
383391 )
384392 monitor_audio_gain = gr .Slider (
@@ -414,18 +422,26 @@ def realtime_tab():
414422
415423 with gr .TabItem ("Model Settings" ):
416424 with gr .Row ():
417- model_choices = sorted (names , key = extract_model_and_epoch ) if names else []
425+ model_choices = (
426+ sorted (names , key = extract_model_and_epoch ) if names else []
427+ )
418428 model_file = gr .Dropdown (
419429 label = i18n ("Voice Model" ),
420430 choices = model_choices ,
421431 interactive = True ,
422- value = get_safe_dropdown_value (saved_settings ['model_file' ], model_choices , default_weight ),
432+ value = get_safe_dropdown_value (
433+ saved_settings ["model_file" ], model_choices , default_weight
434+ ),
423435 )
424436 index_choices = get_indexes ()
425437 index_file = gr .Dropdown (
426438 label = i18n ("Index File" ),
427439 choices = index_choices ,
428- value = get_safe_index_value (saved_settings ['index_file' ], index_choices , match_index (default_weight ) if default_weight else None ),
440+ value = get_safe_index_value (
441+ saved_settings ["index_file" ],
442+ index_choices ,
443+ match_index (default_weight ) if default_weight else None ,
444+ ),
429445 interactive = True ,
430446 )
431447
@@ -615,17 +631,19 @@ def realtime_tab():
615631 def update_on_model_change (model_path ):
616632 new_index = match_index (model_path )
617633 new_sids = get_speakers_id (model_path )
618-
634+
619635 # Get updated index choices
620636 new_index_choices = get_indexes ()
621637 # Use the matched index as fallback, but handle empty strings
622638 fallback_index = new_index if new_index and new_index .strip () else None
623- safe_index_value = get_safe_index_value ("" , new_index_choices , fallback_index )
624-
625- return gr .update (choices = new_index_choices , value = safe_index_value ), gr .update (
626- choices = new_sids , value = 0 if new_sids else None
639+ safe_index_value = get_safe_index_value (
640+ "" , new_index_choices , fallback_index
627641 )
628642
643+ return gr .update (
644+ choices = new_index_choices , value = safe_index_value
645+ ), gr .update (choices = new_sids , value = 0 if new_sids else None )
646+
629647 def refresh_devices ():
630648 input_choices , output_choices = get_audio_devices_formatted ()
631649 return (
@@ -735,60 +753,46 @@ def toggle_visible_embedder_custom(embedder_model):
735753 model_file .select (
736754 fn = update_on_model_change , inputs = [model_file ], outputs = [index_file , sid ]
737755 )
738-
756+
739757 # Save settings when devices or model change
740758 def save_input_device (input_device ):
741759 if input_device :
742760 save_realtime_settings (input_device , None , None , None , None )
743-
761+
744762 def save_output_device (output_device ):
745763 if output_device :
746764 save_realtime_settings (None , output_device , None , None , None )
747-
765+
748766 def save_monitor_device (monitor_device ):
749767 if monitor_device :
750768 save_realtime_settings (None , None , monitor_device , None , None )
751-
769+
752770 def save_model_file (model_file ):
753771 if model_file :
754772 save_realtime_settings (None , None , None , model_file , None )
755-
773+
756774 def save_index_file (index_file ):
757775 # Only save if index_file is not None and not empty
758776 if index_file :
759777 save_realtime_settings (None , None , None , None , index_file )
760-
778+
761779 # Add event handlers to save settings
762780 input_audio_device .change (
763- fn = save_input_device ,
764- inputs = [input_audio_device ],
765- outputs = []
781+ fn = save_input_device , inputs = [input_audio_device ], outputs = []
766782 )
767-
783+
768784 output_audio_device .change (
769- fn = save_output_device ,
770- inputs = [output_audio_device ],
771- outputs = []
785+ fn = save_output_device , inputs = [output_audio_device ], outputs = []
772786 )
773-
787+
774788 monitor_output_device .change (
775- fn = save_monitor_device ,
776- inputs = [monitor_output_device ],
777- outputs = []
778- )
779-
780- model_file .change (
781- fn = save_model_file ,
782- inputs = [model_file ],
783- outputs = []
784- )
785-
786- index_file .change (
787- fn = save_index_file ,
788- inputs = [index_file ],
789- outputs = []
789+ fn = save_monitor_device , inputs = [monitor_output_device ], outputs = []
790790 )
791791
792+ model_file .change (fn = save_model_file , inputs = [model_file ], outputs = [])
793+
794+ index_file .change (fn = save_index_file , inputs = [index_file ], outputs = [])
795+
792796 def refresh_all ():
793797 new_names = [
794798 os .path .join (root , file )
0 commit comments