@@ -28,7 +28,7 @@ internal string currentVoice
2828 }
2929 }
3030
31- public SystemSpeechSynthesizer ( ref HashSet < VoiceDetails > voiceStore )
31+ public void Initialize ( HashSet < VoiceDetails > voiceStore )
3232 {
3333 bool TrySystemVoice ( VoiceDetails voiceDetails )
3434 {
@@ -57,76 +57,87 @@ bool TrySystemVoice ( VoiceDetails voiceDetails )
5757 systemSpeechVoices = synth
5858 . GetInstalledVoices ( )
5959 . Where ( v => v . Enabled &&
60- ! v . VoiceInfo . Name . Contains ( "Microsoft Server Speech Text to Speech Voice" ) &&
60+ ! v . VoiceInfo . Name . Contains ( "Microsoft Server Speech Text to Speech Voice" ) &&
6161 ! v . VoiceInfo . Name . Contains ( "eSpeak" ) )
6262 . ToList ( ) ;
6363 }
6464
65- foreach ( var voice in systemSpeechVoices )
65+ try
6666 {
67- try
67+ foreach ( var voice in systemSpeechVoices )
6868 {
69- Logging . Debug ( $ "Found voice: { voice . VoiceInfo . Name } ", voice . VoiceInfo ) ;
69+ try
70+ {
71+ Logging . Debug ( $ "Found voice: { voice . VoiceInfo . Name } ", voice . VoiceInfo ) ;
7072
71- var voiceDetails = new VoiceDetails ( voice . VoiceInfo . Name , voice . VoiceInfo . Gender . ToString ( ) ,
73+ var voiceDetails = new VoiceDetails ( voice . VoiceInfo . Name , voice . VoiceInfo . Gender . ToString ( ) ,
7274 voice . VoiceInfo . Culture ?? CultureInfo . InvariantCulture , nameof ( System ) ) ;
7375
74- // Skip duplicates of voices already added from Windows.Media.SpeechSynthesis
75- // (for example, if OneCore voices have been added to System.Speech with a registry edit)
76- if ( voiceStore . Any ( v => v . name == voiceDetails . name ) )
77- {
78- Logging . Debug (
79- $ "{ voice . VoiceInfo . Name } has already been added to the voice list, skipping." ) ;
80- continue ;
81- }
76+ // Skip duplicates of voices already added from Windows.Media.SpeechSynthesis
77+ // (for example, if OneCore voices have been added to System.Speech with a registry edit)
78+ if ( voiceStore . Any ( v => v . name == voiceDetails . name ) )
79+ {
80+ Logging . Debug (
81+ $ "{ voice . VoiceInfo . Name } has already been added to the voice list, skipping." ) ;
82+ continue ;
83+ }
8284
83- // Skip voices which are not selectable
84- if ( ! TrySystemVoice ( voiceDetails ) )
85- {
86- Logging . Debug ( $ " { voice . VoiceInfo . Name } is not selectable, skipping." ) ;
87- continue ;
88- }
85+ // Suppress voices "Desktop" variant voices from System.Speech.Synthesis
86+ // where we already have a (newer) OneCore version (without disabling manual invocation of those voices )
87+ if ( voiceStore . Any ( v => $ " { v . name } Desktop" == voiceDetails . name ) )
88+ {
89+ voiceDetails . hideVoice = true ;
90+ }
8991
90- // Suppress voices "Desktop" variant voices from System.Speech.Synthesis
91- // where we already have a (newer) OneCore version (without disabling manual invocation of those voices)
92- if ( voiceStore . Any ( v => $ "{ v . name } Desktop" == voiceDetails . name ) )
93- {
94- voiceDetails . hideVoice = true ;
95- }
92+ // Skip Amazon Polly voices - these tend to throw various internal errors (cause unknown)
93+ // and are not currently reliable, particularly in VoiceAttack.
94+ if ( ! string . IsNullOrEmpty ( voiceDetails . name ) &&
95+ voiceDetails . name . StartsWith ( "Amazon Polly" ) )
96+ {
97+ continue ;
98+ }
99+
100+ // Skip voices which are not selectable
101+ if ( ! TrySystemVoice ( voiceDetails ) )
102+ {
103+ Logging . Debug ( $ "{ voice . VoiceInfo . Name } is not selectable, skipping." ) ;
104+ continue ;
105+ }
96106
97- // Skip Amazon Polly voices - these tend to throw various internal errors (cause unknown)
98- // and are not currently reliable, particularly in VoiceAttack.
99- if ( ! string . IsNullOrEmpty ( voiceDetails . name ) &&
100- voiceDetails . name . StartsWith ( "Amazon Polly" ) )
107+ voiceStore . Add ( voiceDetails ) ;
108+ Logging . Debug ( $ "Loaded voice: { voice . VoiceInfo . Name } " , voiceDetails ) ;
109+ }
110+ catch ( Exception e )
101111 {
112+ if ( voice . VoiceInfo . Culture is null )
113+ {
114+ Logging . Warn ( $ "Failed to load { voice . VoiceInfo . Name } , voice culture is not set.", e ) ;
115+ }
116+ else
117+ {
118+ Logging . Error ( $ "Failed to load { voice . VoiceInfo . Name } ", e ) ;
119+ }
102120 continue ;
103121 }
104-
105- voiceStore . Add ( voiceDetails ) ;
106- Logging . Debug ( $ "Loaded voice: { voice . VoiceInfo . Name } ", voiceDetails ) ;
107122 }
108- catch ( Exception e )
123+ }
124+ finally
125+ {
126+ if ( selectedVoice != null )
109127 {
110- if ( voice . VoiceInfo . Culture is null )
128+ try
111129 {
112- Logging . Warn ( $ "Failed to load { voice . VoiceInfo . Name } , voice culture is not set.", e ) ;
130+ lock ( synthLock )
131+ {
132+ synth . SelectVoice ( selectedVoice . Name ) ;
133+ }
113134 }
114- else
135+ catch ( Exception e )
115136 {
116- Logging . Error ( $ "Failed to load { voice . VoiceInfo . Name } ", e ) ;
137+ Logging . Warn ( $ "Failed to restore selected voice { selectedVoice . Name } during initialization. ", e ) ;
117138 }
118139 }
119140 }
120-
121- if ( selectedVoice == null )
122- {
123- return ;
124- }
125-
126- lock ( synthLock )
127- {
128- synth . SelectVoice ( selectedVoice . Name ) ;
129- }
130141 }
131142
132143 internal Stream Speak ( VoiceDetails voiceDetails , string speech , SpeechServiceConfiguration Configuration )
0 commit comments