Quickstart: Translate speech with the Speech SDK for C# (UWP)

Quickstarts are also available for speech recognition, speech synthesis, and voice-first virtual assistant.

In this quickstart, you'll create a Universal Windows Platform (UWP) application that captures user speech from your computer's microphone, translates the speech, and transcribes the translated text to the command line in real time. This application is designed to run on 64-bit Windows, and it's built with the Speech SDK NuGet package and Microsoft Visual Studio 2019.

For a complete list of languages available for speech translation, see language support.

Note

UWP lets you develop apps that run on any device that supports Windows 10, including PCs, Xbox, Surface Hub, and other devices.

Prerequisites

This quickstart requires:

Create a Visual Studio project

To create a Visual Studio project for Universal Windows Platform (UWP) development, you need to set up Visual Studio development options, create the project, select the target architecture, set up audio capture, and install the Speech SDK.

Set up Visual Studio development options

To start, make sure you're set up correctly in Visual Studio for UWP development:

  1. Open Visual Studio 2019 to display the Start window.

    Start window - Visual Studio

  2. Select Continue without code to go to the Visual Studio IDE.

  3. From the Visual Studio menu bar, select Tools > Get Tools and Features to open Visual Studio Installer and view the Modifying dialog box.

    Workloads tab, Modifying dialog box, Visual Studio Installer

  4. In the Workloads tab, under Windows, find the Universal Windows Platform development workload. If the check box next to that workload is already selected, close the Modifying dialog box, and go to step 6.

  5. Select the Universal Windows Platform development check box, select Modify, and then in the Before we get started dialog box, select Continue to install the UWP development workload. Installation of the new feature may take a while.

  6. Close Visual Studio Installer.

Create the project and select the target architecture

Next, create your project:

  1. In the Visual Studio menu bar, choose File > New > Project to display the Create a new project window.

    Create a new project - Visual Studio

  2. Find and select Blank App (Universal Windows). Make sure that you select the C# version of this project type (as opposed to Visual Basic).

  3. Select Next to display the Configure your new project screen.

    Configure your new project - Visual Studio

  4. In Project name, enter helloworld.

  5. In Location, navigate to and select or create the folder to save your project in.

  6. Select Create to go to the New Universal Windows Platform Project window.

    New Universal Windows Platform Project dialog box - Visual Studio

  7. In Minimum version (the second drop-down box), choose Windows 10 Fall Creators Update (10.0; Build 16299), which is the minimum requirement for the Speech SDK.

  8. In Target version (the first drop-down box), choose a value identical to or later than the value in Minimum version.

  9. Select OK. You're returned to the Visual Studio IDE, with the new project created and visible in the Solution Explorer pane.

    helloworld project - Visual Studio

Now select your target platform architecture. In the Visual Studio toolbar, find the Solution Platforms drop-down box. (If you don't see it, choose View > Toolbars > Standard to display the toolbar containing Solution Platforms.) If you're running 64-bit Windows, choose x64 in the drop-down box. 64-bit Windows can also run 32-bit applications, so you can choose x86 if you prefer.

Note

The Speech SDK only supports Intel-compatible processors. ARM processors are currently not supported.

Set up audio capture

Then allow the project to capture audio input:

  1. In Solution Explorer, double-click Package.appxmanifest to open the package application manifest.

  2. Select the Capabilities tab.

    Capabilities tab, Package application manifest - Visual Studio

  3. Select the box for the Microphone capability.

  4. From the menu bar, choose File > Save Package.appxmanifest to save your changes.

Install the Speech SDK

Finally, install the Speech SDK NuGet package, and reference the Speech SDK in your project:

  1. In Solution Explorer, right-click your solution, and choose Manage NuGet Packages for Solution to go to the NuGet - Solution window.

  2. Select Browse.

    Screenshot of Manage Packages for Solution dialog box

  3. In Package source, choose nuget.org.

  4. In the Search box, enter Microsoft.CognitiveServices.Speech, and then choose that package after it appears in the search results.

    Screenshot of Manage Packages for Solution dialog box

  5. In the package status pane next to the search results, select your helloworld project.

  6. Select Install.

  7. In the Preview Changes dialog box, select OK.

  8. In the License Acceptance dialog box, view the license, and then select I Accept. The package installation begins, and when installation is complete, the Output pane displays a message similar to the following text: Successfully installed 'Microsoft.CognitiveServices.Speech 1.6.0' to helloworld.

Add sample code

Now add the XAML code that defines the user interface of the application, and add the C# code-behind implementation.

  1. In Solution Explorer, open MainPage.xaml.

  2. In the designer's XAML view, insert the following XAML snippet into the Grid tag (between <Grid> and </Grid>):

    <StackPanel Orientation="Vertical" HorizontalAlignment="Center"  Margin="20,50,0,0" VerticalAlignment="Center" Width="800">
        <Button x:Name="EnableMicrophoneButton" Content="Enable Microphone"  Margin="0,0,10,0" Click="EnableMicrophone_ButtonClicked" Height="35"/>
        <Button x:Name="SpeechRecognitionButton" Content="Translate speech from the microphone input" Margin="0,10,10,0" Click="SpeechTranslationFromMicrophone_ButtonClicked" Height="35"/>
        <StackPanel x:Name="StatusPanel" Orientation="Vertical" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignRightWithPanel="True" RelativePanel.AlignLeftWithPanel="True">
            <TextBlock x:Name="StatusLabel" Margin="0,10,10,0" TextWrapping="Wrap" Text="Status:" FontSize="20"/>
            <Border x:Name="StatusBorder" Margin="0,0,0,0">
                <ScrollViewer VerticalScrollMode="Auto"  VerticalScrollBarVisibility="Auto" MaxHeight="200">
                    <!-- Use LiveSetting to enable screen readers to announce the status update. -->
                    <TextBlock x:Name="StatusBlock" FontWeight="Bold" AutomationProperties.LiveSetting="Assertive"
    MaxWidth="{Binding ElementName=Splitter, Path=ActualWidth}" Margin="10,10,10,20" TextWrapping="Wrap"  />
                </ScrollViewer>
            </Border>
        </StackPanel>
    </StackPanel>
    
  3. In Solution Explorer, open the code-behind source file MainPage.xaml.cs. (It's grouped under MainPage.xaml.)

  4. Replace all the code in it with the following snippet:

    using System;
    using System.Threading.Tasks;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Translation;
    
    namespace helloworld
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void EnableMicrophone_ButtonClicked(object sender, RoutedEventArgs e)
            {
                bool isMicAvailable = true;
                try
                {
                    var mediaCapture = new Windows.Media.Capture.MediaCapture();
                    var settings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
                    settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Audio;
                    await mediaCapture.InitializeAsync(settings);
                }
                catch (Exception)
                {
                    isMicAvailable = false;
                }
                if (!isMicAvailable)
                {
                    await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-microphone"));
                }
                else
                {
                    NotifyUser("Microphone was enabled", NotifyType.StatusMessage);
                }
            }
    
            private async void SpeechTranslationFromMicrophone_ButtonClicked(object sender, RoutedEventArgs e)
            {
                // Creates an instance of a speech config with specified subscription key and service region.
                // Replace with your own subscription key and service region (e.g., "westus").
                var config = SpeechTranslationConfig.FromSubscription("YourSubscriptionKey", "YourServiceRegion");
    
                // Sets source and target languages.
                string fromLanguage = "en-US";
                config.SpeechRecognitionLanguage = fromLanguage;
                config.AddTargetLanguage("de");
    
                try
                {
                    // Creates a speech recognizer using microphone as audio input.
                    using (var recognizer = new TranslationRecognizer(config))
                    {
                        // The TaskCompletionSource to stop recognition.
                        var stopRecognition = new TaskCompletionSource<int>();
    
                        // Subscribes to events.
                        recognizer.Recognizing += (s, ee) =>
                        {
                            NotifyUser($"RECOGNIZING in '{fromLanguage}': Text={ee.Result.Text}", NotifyType.StatusMessage);
                            foreach (var element in ee.Result.Translations)
                            {
                                NotifyUser($"    TRANSLATING into '{element.Key}': {element.Value}", NotifyType.StatusMessage);
                            }
                        };
    
                        recognizer.Recognized += (s, ee) =>
                        {
                            if (ee.Result.Reason == ResultReason.TranslatedSpeech)
                            {
                                NotifyUser($"\nFinal result: Reason: {ee.Result.Reason.ToString()}, recognized text in {fromLanguage}: {ee.Result.Text}.", NotifyType.StatusMessage);
                                foreach (var element in ee.Result.Translations)
                                {
                                    NotifyUser($"    TRANSLATING into '{element.Key}': {element.Value}", NotifyType.StatusMessage);
                                }
                            }
                        };
    
                        recognizer.Canceled += (s, ee) =>
                        {
                            NotifyUser($"\nRecognition canceled. Reason: {ee.Reason}; ErrorDetails: {ee.ErrorDetails}", NotifyType.StatusMessage);
                        };
    
                        recognizer.SessionStarted += (s, ee) =>
                        {
                            NotifyUser("\nSession started event.", NotifyType.StatusMessage);
                        };
    
                        recognizer.SessionStopped += (s, ee) =>
                        {
                            NotifyUser("\nSession stopped event.", NotifyType.StatusMessage);
                            stopRecognition.TrySetResult(0);
                        };
    
                        // Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
                        await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
    
                        // Waits for completion.
                        // Use Task.WaitAny to keep the task rooted.
                        Task.WaitAny(new[] { stopRecognition.Task });
    
                        // Stops continuous recognition.
                        await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    NotifyUser($"{ex.ToString()}", NotifyType.ErrorMessage);
                }
            }
    
            private enum NotifyType
            {
                StatusMessage,
                ErrorMessage
            };
    
            private void NotifyUser(string strMessage, NotifyType type)
            {
                // If called from the UI thread, then update immediately.
                // Otherwise, schedule a task on the UI thread to perform the update.
                if (Dispatcher.HasThreadAccess)
                {
                    UpdateStatus(strMessage, type);
                }
                else
                {
                    var task = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => UpdateStatus(strMessage, type));
                }
            }
    
            private void UpdateStatus(string strMessage, NotifyType type)
            {
                switch (type)
                {
                    case NotifyType.StatusMessage:
                        StatusBorder.Background = new SolidColorBrush(Windows.UI.Colors.Green);
                        break;
                    case NotifyType.ErrorMessage:
                        StatusBorder.Background = new SolidColorBrush(Windows.UI.Colors.Red);
                        break;
                }
                StatusBlock.Text += string.IsNullOrEmpty(StatusBlock.Text) ? strMessage : "\n" + strMessage;
    
                // Collapse the StatusBlock if it has no text to conserve real estate.
                StatusBorder.Visibility = !string.IsNullOrEmpty(StatusBlock.Text) ? Visibility.Visible : Visibility.Collapsed;
                if (!string.IsNullOrEmpty(StatusBlock.Text))
                {
                    StatusBorder.Visibility = Visibility.Visible;
                    StatusPanel.Visibility = Visibility.Visible;
                }
                else
                {
                    StatusBorder.Visibility = Visibility.Collapsed;
                    StatusPanel.Visibility = Visibility.Collapsed;
                }
                // Raise an event if necessary to enable a screen reader to announce the status update.
                var peer = Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer.FromElement(StatusBlock);
                if (peer != null)
                {
                    peer.RaiseAutomationEvent(Windows.UI.Xaml.Automation.Peers.AutomationEvents.LiveRegionChanged);
                }
            }
        }
    }
    
  5. In the SpeechTranslationFromMicrophone_ButtonClicked handler in this file, find the string YourSubscriptionKey, and replace it with your subscription key.

  6. In the SpeechTranslationFromMicrophone_ButtonClicked handler, find the string YourServiceRegion, and replace it with the region associated with your subscription. (For example, use westus for the free trial subscription.)

  7. From the menu bar, choose File > Save All to save your changes.

Build and run the application

Now you are ready to build and test your application.

  1. From the menu bar, select Build > Build Solution to build the application. The code should compile without errors now.

  2. Choose Debug > Start Debugging (or press F5) to start the application. The helloworld window appears.

    Sample UWP translation application in C# - quickstart

  3. Select Enable Microphone, and when the access permission request pops up, select Yes.

    Microphone access permission request

  4. Select Translate speech from the microphone input, and speak an English phrase or sentence into your device's microphone. The application transmits your speech to the Speech service, which translates the speech into text in another language (in this case, German). The Speech service sends the translated text back to the application, which displays the translation in the window.

    Speech translation user interface

Next steps

See also