Franck E Franck E - 3 months ago 29
C# Question

UWP XAML ToggleSwitch to set Speech Synthesis voice to either male or female

I am trying to set the voice.gender to either male or female via a ToggleSwitch within the setting page in Template10 UWP app.

I declare the TG:

<ToggleSwitch x:Name="VoiceSelection" Header="Select Voice"
IsOn="{Binding VoiceChoice, Mode=TwoWay}"
OffContent="Male Voice" OnContent="Female Voice" />


That should be fine.

I then set a boolean, that will be use to select male or female later

public event PropertyChangedEventHandler PropertyChanged;
public static bool _voiceChoice = true;
public bool VoiceChoice
{
get
{
return _voiceChoice;
}
set
{
_voiceChoice = value;
OnPropertyChanged("VoiceChoice");
}
}

protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}


For info, here is the code that later assign the voice. That works fine too.

...
if (_voiceChoice == true)
{
VoiceInformation voiceInfo =
(
from voice in SpeechSynthesizer.AllVoices
where voice.Gender == VoiceGender.Female
select voice
).FirstOrDefault() ?? SpeechSynthesizer.DefaultVoice;
synthesizer.Voice = voiceInfo;
stream = await synthesizer.SynthesizeTextToStreamAsync(text);
}
else
...


Problem i have is I can select the voice by manually setting the boolean _voiceChoice, but I cannot set via the ToggleSwitch.

I also realize that this solution is not very clean, and I am open to any suggestions. Any help is greatly appreciated. Thanks in advance.

Answer

Actually, I was looking at this completely wrongly.
Here is what is needed to make a working ToggleSwitch to switch between male/female voice in Template10. May be cleaner solutions, but this works.

In SettingsPage.xaml, add:

<ToggleSwitch x:Name="VoiceSelection" Header="Select Voice"
    IsOn="{Binding UseVoiceSelection, Mode=TwoWay}"
    OffContent="Male Voice" OnContent="Female Voice" />

In SettingsService.cs, add:

public bool UseVoiceSelection
    {
        get { return _helper.Read<bool>(nameof(UseVoiceSelection), true); }
        set
        {
            _helper.Write(nameof(UseVoiceSelection), value);
        }
    }

In the class SettingsPartViewModel : ViewModelBase, add:

public bool UseVoiceSelection
    {
        get { return _settings.UseVoiceSelection; }
        set { _settings.UseVoiceSelection = value; base.RaisePropertyChanged(); }
    }

Finally, in a separate class, set the bool value and perform the speech synthesis:

public class ReadSpeech
{
    public static bool _voiceChoice = true;

    // Performs synthesis
    async Task<IRandomAccessStream> SynthesizeTextToSpeechAsync(string text)
    {
        IRandomAccessStream stream = null;
        using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
        {
            if (temp.SettingsPartViewModel.UseVoiceSelection == true)
            {
                VoiceInformation voiceInfo =
                  (
                    from voice in SpeechSynthesizer.AllVoices
                    where voice.Gender == VoiceGender.Female
                    select voice
                  ).FirstOrDefault() ?? SpeechSynthesizer.DefaultVoice;
                synthesizer.Voice = voiceInfo;
                stream = await synthesizer.SynthesizeTextToStreamAsync(text);
            }
            else
            {
                VoiceInformation voiceInfo =
                  (
                    from voice in SpeechSynthesizer.AllVoices
                    where voice.Gender == VoiceGender.Male
                    select voice
                  ).FirstOrDefault() ?? SpeechSynthesizer.DefaultVoice;
                synthesizer.Voice = voiceInfo;
                stream = await synthesizer.SynthesizeTextToStreamAsync(text);
            }
        }
        return (stream);
    }
Comments