Implementing Text-to-Speech

Use DependencyService to call into each platform's native text-to-speech API

PDF for offline use
Interactive:
Sample Code:

Let us know how you feel about this

Translation Quality


0/250

last updated: 2017-09

This article will guide you as you create a cross-platform app that uses DependencyService to access native text-to-speech APIs:

The application using DependencyService will have the following structure:

Creating the Interface

First, create an interface in the shared code that expresses the functionality you plan to implement. For this example, the interface contains a single method, Speak:

public interface ITextToSpeech
{
    void Speak (string text);
}

Coding against this interface in the shared code will allow the Xamarin.Forms app to access the speech APIs on each platform.

Note: Classes implementing the interface must have a parameterless constructor to work with the DependencyService.

iOS Implementation

The interface must be implemented in each platform-specific application project. Note that the class has a parameterless constructor so that the DependencyService can create new instances.

[assembly: Dependency(typeof(TextToSpeechImplementation))]
namespace DependencyServiceSample.iOS
{

    public class TextToSpeechImplementation : ITextToSpeech
    {
        public TextToSpeechImplementation() { }

        public void Speak(string text)
        {
            var speechSynthesizer = new AVSpeechSynthesizer();
            var speechUtterance = new AVSpeechUtterance(text)
            {
                Rate = AVSpeechUtterance.MaximumSpeechRate / 4,
                Voice = AVSpeechSynthesisVoice.FromLanguage("en-US"),
                Volume = 0.5f,
                PitchMultiplier = 1.0f
            };

            speechSynthesizer.SpeakUtterance(speechUtterance);
        }
    }
}

The [assembly] attribute registers the class as an implementation of the ITextToSpeech interface, which means that DependencyService.Get<ITextToSpeech>() can be used in the shared code to create an instance of it.

Android Implementation

The Android code is more complex than the iOS version: it requires the implementing class to inherit from Android-specific Java.Lang.Object and to implement the IOnInitListener interface as well.

Xamarin.Forms also provides the Forms.Context object, which is an instance of the current Android context. Many Android SDK methods require this, a good example being the ability to call StartActivity().

[assembly: Dependency(typeof(TextToSpeechImplementation))]
namespace DependencyServiceSample.Droid
{

    public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
    {
        TextToSpeech speaker;
        string toSpeak;

        public void Speak(string text)
        {
            toSpeak = text;
            if (speaker == null)
            {
                speaker = new TextToSpeech(Forms.Context, this);
            }
            else
            {
                speaker.Speak(toSpeak, QueueMode.Flush, null, null);
            }
        }

        public void OnInit(OperationResult status)
        {
            if (status.Equals(OperationResult.Success))
            {
                speaker.Speak(toSpeak, QueueMode.Flush, null, null);
            }
        }
    }
}

The [assembly] attribute registers the class as an implementation of the ITextToSpeech interface, which means that DependencyService.Get<ITextToSpeech>() can be used in the shared code to create an instance of it.

Windows Phone and Universal Windows Platform Implementation

Windows Phone and the Universal Windows Platform have a speech API in the Windows.Media.SpeechSynthesis namespace. The only caveat is to remember to tick the Microphone capability in the manifest, otherwise access to the speech APIs are blocked.

[assembly:Dependency(typeof(TextToSpeechImplementation))]
public class TextToSpeechImplementation : ITextToSpeech
{
    public async void Speak(string text)
    {
        var mediaElement = new MediaElement();
        var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
        var stream = await synth.SynthesizeTextToStreamAsync(text);

        mediaElement.SetSource(stream, stream.ContentType);
        mediaElement.Play();
    }
}

The [assembly] attribute registers the class as an implementation of the ITextToSpeech interface, which means that DependencyService.Get<ITextToSpeech>() can be used in the shared code to create an instance of it.

Implementing in Shared Code

Now we can write and test shared code that accesses the text-to-speech interface. This simple page includes a button that triggers the speech functionality. It uses the DependencyService to get an instance of the ITextToSpeech interface – at runtime this instance will be the platform-specific implementation that has full access to the native SDK.

public MainPage ()
{
    var speak = new Button {
        Text = "Hello, Forms !",
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
    speak.Clicked += (sender, e) => {
        DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
    };
    Content = speak;
}

Running this application on iOS, Android, or the Windows platforms and pressing the button will result in the application speaking to you, using the native speech SDK on each platform.

iOS and Android text-to-speech button

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.