Add voice switcher for TTS - #77
Conversation
…gine throw error), so need to handle null engine
|
|
||
| public void UpdateVoice(IList<string> voices) | ||
| { | ||
| var currentVoice = voices.Contains(CurrentVoice) ? CurrentVoice : voices.First(); |
|
|
||
| public string[] GetVoices() => _voices; | ||
|
|
||
| public void SetVoice(string voice) => _voice = _voices.First(x => x.Equals(voice, StringComparison.OrdinalIgnoreCase)); |
There was a problem hiding this comment.
There is a bug, exception occurred when TTS with voice is selected, then user switch to another TTS. Need to set TtsConfiguration.CurrentVoice after(before) this update.
| public TtsConfiguration TtsSettings { get; set; } | ||
|
|
||
| // NOTE: wfp doesnt update combobox source for non-static propertions or properties from non-singletone class 💀, I cant find another workaround | ||
| public static ObservableCollection<string> AvailableVoices { get; } = new(); |
There was a problem hiding this comment.
There is some problem with VM instances... I will investigate it further and come back with update
There was a problem hiding this comment.
I got it. VM has scoped lifetime, but TtsFactory receives another VM instance (out of main scope), so UpdateVoice is called also on that wrong instance. Generally speaking, it the consequence of incorrect dependency (factory shouldn't update external component).
Let's get back to implementation with AvailableVoices in TTSConfiguration :) But with updating outside Factory (in ProcessingService). It's still not the best option though, but I have further plans for more global refactoring in that part VM <--> ProcessingService
|
Hi, sorry for such long delay with answer. Now I got back to development and left some comments |
Port the core improvements from ramjke/Translumo#77 (Add voice switcher for TTS) into the existing SelectedVoiceName architecture, without breaking the LLM enhancements: - WindowsTTSHelper.InjectOneCoreVoices: inject Win10/11 OneCore voices via reflection (SO/a/71198211) so they appear in GetInstalledVoices; GetAvailableVoicesForLanguage/IsLanguageTTSCapabilityInstalled call it. - ITTSEngine: add GetVoices()/SetVoice(string). - WindowsTTSEngine: use a _voices dictionary + InjectOneCoreVoices + GetVoices/SetVoice. - NoneTTSEngine: add empty implementations. - TranslationProcessingService: handle SelectedVoiceName changes by calling SetVoice (switch at runtime without rebuilding the engine); make Dispose null-safe. - LanguagesSettingsViewModel: use WindowsTTSHelper for the voice list, drop the duplicated private method. - Localize the Voices label (Str.LangSettings.Voice) in 5 languages. Verified: 0 error/0 warning, 54 tests pass (including LLM tests).
tts engines offer various voices, this change introduces the option to choose which voice to use