Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Essentials/samples/Samples/View/TextToSpeechPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<Label Text="{Binding Pitch}" HorizontalOptions="Center" IsVisible="{Binding AdvancedOptions}"/>
<Slider Value="{Binding Pitch}" Minimum="0.0" Maximum="2.0" IsVisible="{Binding AdvancedOptions}"/>

<Label Text="Rate" HorizontalOptions="Start" IsVisible="{Binding AdvancedOptions}"/>
<Label Text="{Binding Rate}" HorizontalOptions="Center" IsVisible="{Binding AdvancedOptions}"/>
<Slider Value="{Binding Rate}" Minimum="0.1" Maximum="2.0" IsVisible="{Binding AdvancedOptions}"/>

<Button Text="Pick Locale" Command="{Binding PickLocaleCommand}" IsVisible="{Binding AdvancedOptions}"/>
<Label Text="{Binding Locale}" IsVisible="{Binding AdvancedOptions}"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class TextToSpeechViewModel : BaseViewModel
bool advancedOptions;
float volume;
float pitch;
float rate;
string locale = "Default";
Locale selectedLocale;

Expand All @@ -30,6 +31,7 @@ public TextToSpeechViewModel()
AdvancedOptions = false;
Volume = 1.0f;
Pitch = 1.0f;
Rate = 1.0f;
}

public override void OnDisappearing()
Expand All @@ -55,7 +57,8 @@ void OnSpeak(bool multiple)
{
Volume = Volume,
Pitch = Pitch,
Locale = selectedLocale
Locale = selectedLocale,
Rate=Rate
};
}

Expand Down Expand Up @@ -141,6 +144,12 @@ public float Pitch
set => SetProperty(ref pitch, value);
}

public float Rate
{
get => rate;
set => SetProperty(ref rate, value);
}

public string Locale
{
get => locale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
2 changes: 2 additions & 0 deletions src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
2 changes: 2 additions & 0 deletions src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Get(string! key, System.DateTimeOffset defaultValue) -> System.DateTimeOffset
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value, string? sharedName) -> void
static Microsoft.Maui.Storage.Preferences.Set(string! key, System.DateTimeOffset value) -> void
Microsoft.Maui.Media.SpeechOptions.Rate.get -> float?
Microsoft.Maui.Media.SpeechOptions.Rate.set -> void
5 changes: 4 additions & 1 deletion src/Essentials/src/TextToSpeech/TextToSpeech.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ public async Task SpeakAsync(string text, int max, SpeechOptions options, Cancel
else
tts.SetPitch(TextToSpeechImplementation.PitchDefault);

tts.SetSpeechRate(1.0f);
if (options?.Rate.HasValue ?? false)
tts.SetSpeechRate((float)options.Rate);
else
tts.SetSpeechRate(1.0f);

var parts = TextToSpeech.SplitSpeak(text, max);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ static AVSpeechUtterance GetSpeechUtterance(string text, SpeechOptions options)

if (options.Volume.HasValue)
speechUtterance.Volume = options.Volume.Value;

if (options.Rate.HasValue)
speechUtterance.Rate = options.Rate.Value;
}

return speechUtterance;
Expand Down
3 changes: 3 additions & 0 deletions src/Essentials/src/TextToSpeech/TextToSpeech.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ async Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationTo

if (options.Locale != null)
ss.Voice = options.Locale.Id;

if (options.Rate.HasValue)
ss.Rate = options.Rate.Value;
}

ssd.FinishedSpeaking += OnFinishedSpeaking;
Expand Down
16 changes: 16 additions & 0 deletions src/Essentials/src/TextToSpeech/TextToSpeech.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ partial class TextToSpeechImplementation : ITextToSpeech
internal const float VolumeDefault = 0.5f;
internal const float VolumeMin = 0.0f;

internal const float RateMax = 2.0f;
internal const float RateDefault = 1.0f;
internal const float RateMin = 0.1f;

SemaphoreSlim? semaphore;

public Task<IEnumerable<Locale>> GetLocalesAsync() =>
Expand All @@ -170,6 +174,12 @@ public async Task SpeakAsync(string text, SpeechOptions? options = default, Canc
throw new ArgumentOutOfRangeException($"Pitch must be >= {PitchMin} and <= {PitchMin}");
}

if (options?.Rate.HasValue ?? false)
{
if (options.Rate.Value < RateMin || options.Rate.Value > RateMax)
throw new ArgumentOutOfRangeException($"Rate must be >= {RateMin} and <= {RateMin}");
}

if (semaphore == null)
semaphore = new SemaphoreSlim(1, 1);

Expand Down Expand Up @@ -245,5 +255,11 @@ public class SpeechOptions
/// </summary>
/// <remarks>This value should be between <c>0f</c> and <c>1.0f</c>.</remarks>
public float? Volume { get; set; }

/// <summary>
/// The speech rate to use when speaking.
/// </summary>
/// <remarks>This value should be between <c>0.1f</c> and <c>2.0f</c>.</remarks>
public float? Rate { get; set; }
}
}
8 changes: 4 additions & 4 deletions src/Essentials/src/TextToSpeech/TextToSpeech.tizen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ async Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationTo
}
}

var pitch = 0;
if (options?.Pitch.HasValue ?? false)
pitch = (int)Math.Round(options.Pitch.Value / PitchMax * tts.GetSpeedRange().Max, MidpointRounding.AwayFromZero);
var rate = 0;
if (options?.Rate.HasValue ?? false)
rate = (int)Math.Round(options.Rate.Value / RateMax * tts.GetSpeedRange().Max, MidpointRounding.AwayFromZero);

tts.AddText(text, language, (int)voiceType, pitch);
tts.AddText(text, language, (int)voiceType, rate);
tts.Play();

await tcsUtterances.Task;
Expand Down
5 changes: 4 additions & 1 deletion src/Essentials/src/TextToSpeech/TextToSpeech.uwp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static string GetSpeakParametersSSMLProsody(string text, SpeechOptions options)
{
var volume = "default";
var pitch = "default";
var rate = "default";
var rate = "medium";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit unrelated but perhaps this is a good opportunity to rename:

src/Essentials/src/TextToSpeech/TextToSpeech.uwp.cs
->
src/Essentials/src/TextToSpeech/TextToSpeech.Windows.cs

as that is the preferred name here. See https://github.com/search?q=repo%3Adotnet%2Fmaui%20.windows.cs&type=code.


// Look for the specified language, otherwise the default voice
var locale = options?.Locale?.Language ?? SpeechSynthesizer.DefaultVoice.Language;
Expand All @@ -82,6 +82,9 @@ static string GetSpeakParametersSSMLProsody(string text, SpeechOptions options)
if (options?.Pitch.HasValue ?? false)
pitch = ProsodyPitch(options.Pitch);

if (options?.Rate.HasValue ?? false)
rate = (options.Rate.Value * 100f).ToString(CultureInfo.InvariantCulture)+"%";

// SSML generation
var ssml = new StringBuilder();
ssml.AppendLine($"<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='{locale}'>");
Expand Down