Snabbstart: Skapa en anpassad röstassistent

I den här snabbstarten använder du Speech SDK för att skapa ett anpassat röstassistentprogram som ansluter till en robot som du redan har skapat och konfigurerat. Om du behöver skapa en robot kan du läsa den relaterade självstudien för en mer omfattande guide.

När du har uppfyllt några krav tar det bara några steg att ansluta din anpassade röstassistent:

  • Skapa ett BotFrameworkConfig objekt från din prenumerationsnyckel och region.
  • Skapa ett DialogServiceConnector objekt med hjälp av objektet BotFrameworkConfig ovan.
  • DialogServiceConnector Starta lyssningsprocessen för ett enda yttrande med hjälp av objektet.
  • Inspektera den ActivityReceivedEventArgs returnerade.

Kommentar

Speech SDK för C++, JavaScript, Objective-C, Python och Swift stöder anpassade röstassistenter, men vi har ännu inte inkluderat någon guide här.

Du kan visa eller ladda ned alla C#-exempel för Speech SDK på GitHub.

Förutsättningar

Innan du kommer igång måste du:

Kommentar

Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

Öppna projektet i Visual Studio

Det första steget är att se till att projektet är öppet i Visual Studio.

Börja med lite pannplåtskod

Nu ska vi lägga till kod som fungerar som ett skelett för vårt projekt.

  1. Öppna i Solution ExplorerMainPage.xaml.

  2. I designerns XAML-vy ersätter du hela innehållet med följande kodfragment som definierar ett rudimentärt användargränssnitt:

    <Page
        x:Class="helloworld.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:helloworld"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    
        <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="ListenButton" Content="Talk to your bot" 
                        Margin="0,10,10,0" Click="ListenButton_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>
            <MediaElement x:Name="mediaElement"/>
        </Grid>
    </Page>
    

Designvyn uppdateras för att visa programmets användargränssnitt.

  1. Öppna källfilen MainPage.xaml.csbakom koden i Solution Explorer. (Den är grupperad under MainPage.xaml.) Ersätt innehållet i den här filen med nedanstående, som innehåller:
  • using-instruktioner för Speech namnrymderna och Speech.Dialog

  • En enkel implementering för att säkerställa mikrofonåtkomst, kabelansluten till en knapphanterare

  • Grundläggande användargränssnittshjälp för att presentera meddelanden och fel i programmet

  • En landningsplats för initieringskodsökvägen som ska fyllas i senare

  • En hjälp för att spela upp text till tal (utan stöd för direktuppspelning)

  • En tom knapphanterare för att börja lyssna som fylls i senare

    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Dialog;
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using Windows.Foundation;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;
    
    namespace helloworld
    {
        public sealed partial class MainPage : Page
        {
            private DialogServiceConnector connector;
    
            private enum NotifyType
            {
                StatusMessage,
                ErrorMessage
            };
    
            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 void NotifyUser(
                string strMessage, NotifyType type = NotifyType.StatusMessage)
            {
                // 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;
    
                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);
                }
            }
    
            // Waits for and accumulates all audio associated with a given 
            // PullAudioOutputStream and then plays it to the MediaElement. Long spoken 
            // audio will create extra latency and a streaming playback solution 
            // (that plays audio while it continues to be received) should be used -- 
            // see the samples for examples of this.
            private void SynchronouslyPlayActivityAudio(
                PullAudioOutputStream activityAudio)
            {
                var playbackStreamWithHeader = new MemoryStream();
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4); // ChunkID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(UInt32.MaxValue), 0, 4); // ChunkSize: max
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4); // Format
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4); // Subchunk1ID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16), 0, 4); // Subchunk1Size: PCM
                playbackStreamWithHeader.Write(BitConverter.GetBytes(1), 0, 2); // AudioFormat: PCM
                playbackStreamWithHeader.Write(BitConverter.GetBytes(1), 0, 2); // NumChannels: mono
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16000), 0, 4); // SampleRate: 16kHz
                playbackStreamWithHeader.Write(BitConverter.GetBytes(32000), 0, 4); // ByteRate
                playbackStreamWithHeader.Write(BitConverter.GetBytes(2), 0, 2); // BlockAlign
                playbackStreamWithHeader.Write(BitConverter.GetBytes(16), 0, 2); // BitsPerSample: 16-bit
                playbackStreamWithHeader.Write(Encoding.ASCII.GetBytes("data"), 0, 4); // Subchunk2ID
                playbackStreamWithHeader.Write(BitConverter.GetBytes(UInt32.MaxValue), 0, 4); // Subchunk2Size
    
                byte[] pullBuffer = new byte[2056];
    
                uint lastRead = 0;
                do
                {
                    lastRead = activityAudio.Read(pullBuffer);
                    playbackStreamWithHeader.Write(pullBuffer, 0, (int)lastRead);
                }
                while (lastRead == pullBuffer.Length);
    
                var task = Dispatcher.RunAsync(
                    Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.SetSource(
                        playbackStreamWithHeader.AsRandomAccessStream(), "audio/wav");
                    mediaElement.Play();
                });
            }
    
            private void InitializeDialogServiceConnector()
            {
                // New code will go here
            }
    
            private async void ListenButton_ButtonClicked(
                object sender, RoutedEventArgs e)
            {
                // New code will go here
            }
        }
    }
    
  1. Lägg till följande kodfragment i metodtexten InitializeDialogServiceConnectori . Den här koden skapar DialogServiceConnector med din prenumerationsinformation.

    // Create a BotFrameworkConfig by providing a Speech service subscription key
    // the botConfig.Language property is optional (default en-US)
    const string speechSubscriptionKey = "YourSpeechSubscriptionKey"; // Your subscription key
    const string region = "YourServiceRegion"; // Your subscription service region.
    
    var botConfig = BotFrameworkConfig.FromSubscription(speechSubscriptionKey, region);
    botConfig.Language = "en-US";
    connector = new DialogServiceConnector(botConfig);
    

    Kommentar

    Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

    Kommentar

    Information om hur du konfigurerar din robot finns i Bot Framework-dokumentationen för Direct Line Speech-kanalen.

  2. Ersätt strängarna och YourServiceRegion med dina egna värden för din talprenumeration YourSpeechSubscriptionKey och region.

  3. Lägg till följande kodfragment i slutet av metodtexten InitializeDialogServiceConnectori . Den här koden konfigurerar hanterare för händelser som används för DialogServiceConnector att kommunicera robotaktiviteter, taligenkänningsresultat och annan information.

    // ActivityReceived is the main way your bot will communicate with the client 
    // and uses bot framework activities
    connector.ActivityReceived += (sender, activityReceivedEventArgs) =>
    {
        NotifyUser(
            $"Activity received, hasAudio={activityReceivedEventArgs.HasAudio} activity={activityReceivedEventArgs.Activity}");
    
        if (activityReceivedEventArgs.HasAudio)
        {
            SynchronouslyPlayActivityAudio(activityReceivedEventArgs.Audio);
        }
    };
    
    // Canceled will be signaled when a turn is aborted or experiences an error condition
    connector.Canceled += (sender, canceledEventArgs) =>
    {
        NotifyUser($"Canceled, reason={canceledEventArgs.Reason}");
        if (canceledEventArgs.Reason == CancellationReason.Error)
        {
            NotifyUser(
                $"Error: code={canceledEventArgs.ErrorCode}, details={canceledEventArgs.ErrorDetails}");
        }
    };
    
    // Recognizing (not 'Recognized') will provide the intermediate recognized text 
    // while an audio stream is being processed
    connector.Recognizing += (sender, recognitionEventArgs) =>
    {
        NotifyUser($"Recognizing! in-progress text={recognitionEventArgs.Result.Text}");
    };
    
    // Recognized (not 'Recognizing') will provide the final recognized text 
    // once audio capture is completed
    connector.Recognized += (sender, recognitionEventArgs) =>
    {
        NotifyUser($"Final speech to text result: '{recognitionEventArgs.Result.Text}'");
    };
    
    // SessionStarted will notify when audio begins flowing to the service for a turn
    connector.SessionStarted += (sender, sessionEventArgs) =>
    {
        NotifyUser($"Now Listening! Session started, id={sessionEventArgs.SessionId}");
    };
    
    // SessionStopped will notify when a turn is complete and 
    // it's safe to begin listening again
    connector.SessionStopped += (sender, sessionEventArgs) =>
    {
        NotifyUser($"Listening complete. Session ended, id={sessionEventArgs.SessionId}");
    };
    
  4. Lägg till följande kodfragment i brödtexten för ListenButton_ButtonClicked metoden i MainPage klassen. Den här koden konfigureras DialogServiceConnector för att lyssna eftersom du redan har upprättat konfigurationen och registrerat händelsehanterarna.

    if (connector == null)
    {
        InitializeDialogServiceConnector();
        // Optional step to speed up first interaction: if not called, 
        // connection happens automatically on first use
        var connectTask = connector.ConnectAsync();
    }
    
    try
    {
        // Start sending audio to your speech-enabled bot
        var listenTask = connector.ListenOnceAsync();
    
        // You can also send activities to your bot as JSON strings -- 
        // Microsoft.Bot.Schema can simplify this
        string speakActivity = 
            @"{""type"":""message"",""text"":""Greeting Message"", ""speak"":""Hello there!""}";
        await connector.SendActivityAsync(speakActivity);
    
    }
    catch (Exception ex)
    {
        NotifyUser($"Exception: {ex.ToString()}", NotifyType.ErrorMessage);
    }
    

Skapa och köra din app

Nu är du redo att skapa din app och testa din anpassade röstassistent med hjälp av Speech-tjänsten.

  1. I menyraden väljer du Skapa>bygglösning för att skapa programmet. Koden bör nu kompileras utan fel.

  2. Välj Felsök>Starta felsökning (eller tryck på F5) för att starta programmet. Fönstret helloworld visas.

    Exempel på UWP-röstassistentprogram i C# – snabbstart

  3. Välj Aktivera mikrofon och välj Ja när begäran om åtkomstbehörighet visas.

    Begäran om åtkomstbehörighet för mikrofon

  4. Välj Prata med din robot och tala en engelsk fras eller mening i enhetens mikrofon. Ditt tal överförs till direct line speech-kanalen och transkriberas till text, som visas i fönstret.

Nästa steg


Du kan visa eller ladda ned alla Java-exempel för Speech SDK på GitHub.

Välj målmiljö

Förutsättningar

Innan du kommer igång måste du:

Kommentar

Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

Skapa och konfigurera projektet

Skapa ett Eclipse-projekt och installera Speech SDK.

Om du vill aktivera loggning uppdaterar du dessutom pom.xml-filen så att den innehåller följande beroende:

 <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-simple</artifactId>
     <version>1.7.5</version>
 </dependency>

Lägga till exempelkod

  1. Du lägger till en ny tom klass i Java-projektet genom att välja Arkiv>Nytt>Klass.

  2. I fönstret Ny Java-klass anger du speechsdk.quickstart i fältet Paket och Main i fältet Namn .

    Skärmbild av fönstret New Java Class (Ny Java-klass)

  3. Öppna den nyligen skapade Main klassen och ersätt innehållet i Main.java filen med följande startkod:

    package speechsdk.quickstart;
    
    import com.microsoft.cognitiveservices.speech.audio.AudioConfig;
    import com.microsoft.cognitiveservices.speech.audio.PullAudioOutputStream;
    import com.microsoft.cognitiveservices.speech.dialog.BotFrameworkConfig;
    import com.microsoft.cognitiveservices.speech.dialog.DialogServiceConnector;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.SourceDataLine;
    import java.io.InputStream;
    
    public class Main {
        final Logger log = LoggerFactory.getLogger(Main.class);
    
        public static void main(String[] args) {
            // New code will go here
        }
    
        private void playAudioStream(PullAudioOutputStream audio) {
            ActivityAudioStream stream = new ActivityAudioStream(audio);
            final ActivityAudioStream.ActivityAudioFormat audioFormat = stream.getActivityAudioFormat();
            final AudioFormat format = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    audioFormat.getSamplesPerSecond(),
                    audioFormat.getBitsPerSample(),
                    audioFormat.getChannels(),
                    audioFormat.getFrameSize(),
                    audioFormat.getSamplesPerSecond(),
                    false);
            try {
                int bufferSize = format.getFrameSize();
                final byte[] data = new byte[bufferSize];
    
                SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(format);
    
                if (line != null) {
                    line.start();
                    int nBytesRead = 0;
                    while (nBytesRead != -1) {
                        nBytesRead = stream.read(data);
                        if (nBytesRead != -1) {
                            line.write(data, 0, nBytesRead);
                        }
                    }
                    line.drain();
                    line.stop();
                    line.close();
                }
                stream.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
  4. main I metoden konfigurerar du först och DialogServiceConfig använder den för att skapa en DialogServiceConnector instans. Den här instansen ansluter till Direct Line Speech-kanalen för att interagera med din robot. En AudioConfig instans används också för att ange källan för ljudindata. I det här exemplet används standardmikrofonen med AudioConfig.fromDefaultMicrophoneInput().

    • Ersätt strängen YourSubscriptionKey med din Speech-resursnyckel, som du kan hämta från Azure Portal.
    • Ersätt strängen YourServiceRegion med den region som är associerad med din Speech-resurs.

    Kommentar

    Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

    final String subscriptionKey = "YourSubscriptionKey"; // Your subscription key
    final String region = "YourServiceRegion"; // Your speech subscription service region
    final BotFrameworkConfig botConfig = BotFrameworkConfig.fromSubscription(subscriptionKey, region);
    
    // Configure audio input from a microphone.
    final AudioConfig audioConfig = AudioConfig.fromDefaultMicrophoneInput();
    
    // Create a DialogServiceConnector instance.
    final DialogServiceConnector connector = new DialogServiceConnector(botConfig, audioConfig);
    
  5. Anslutningsappen DialogServiceConnector förlitar sig på flera händelser för att kommunicera sina robotaktiviteter, taligenkänningsresultat och annan information. Lägg till dessa händelselyssnare härnäst.

    // Recognizing will provide the intermediate recognized text while an audio stream is being processed.
    connector.recognizing.addEventListener((o, speechRecognitionResultEventArgs) -> {
        log.info("Recognizing speech event text: {}", speechRecognitionResultEventArgs.getResult().getText());
    });
    
    // Recognized will provide the final recognized text once audio capture is completed.
    connector.recognized.addEventListener((o, speechRecognitionResultEventArgs) -> {
        log.info("Recognized speech event reason text: {}", speechRecognitionResultEventArgs.getResult().getText());
    });
    
    // SessionStarted will notify when audio begins flowing to the service for a turn.
    connector.sessionStarted.addEventListener((o, sessionEventArgs) -> {
        log.info("Session Started event id: {} ", sessionEventArgs.getSessionId());
    });
    
    // SessionStopped will notify when a turn is complete and it's safe to begin listening again.
    connector.sessionStopped.addEventListener((o, sessionEventArgs) -> {
        log.info("Session stopped event id: {}", sessionEventArgs.getSessionId());
    });
    
    // Canceled will be signaled when a turn is aborted or experiences an error condition.
    connector.canceled.addEventListener((o, canceledEventArgs) -> {
        log.info("Canceled event details: {}", canceledEventArgs.getErrorDetails());
        connector.disconnectAsync();
    });
    
    // ActivityReceived is the main way your bot will communicate with the client and uses Bot Framework activities.
    connector.activityReceived.addEventListener((o, activityEventArgs) -> {
        final String act = activityEventArgs.getActivity().serialize();
            log.info("Received activity {} audio", activityEventArgs.hasAudio() ? "with" : "without");
            if (activityEventArgs.hasAudio()) {
                playAudioStream(activityEventArgs.getAudio());
            }
        });
    
  6. Anslut DialogServiceConnector till Direct Line Speech genom att connectAsync() anropa metoden. Om du vill testa roboten listenOnceAsync kan du anropa metoden för att skicka ljudindata från mikrofonen. Du kan också använda sendActivityAsync metoden för att skicka en anpassad aktivitet som en serialiserad sträng. Dessa anpassade aktiviteter kan ge ytterligare data som din robot använder i konversationen.

    connector.connectAsync();
    // Start listening.
    System.out.println("Say something ...");
    connector.listenOnceAsync();
    
    // connector.sendActivityAsync(...)
    
  7. Spara ändringar i Main filen.

  8. Om du vill stödja svarsuppspelning lägger du till ytterligare en klass som transformerar PullAudioOutputStream-objektet som returneras från getAudio()-API:et till en Java InputStream för enkel hantering. Det här ActivityAudioStream är en specialiserad klass som hanterar ljudsvar från Direct Line Speech-kanalen. Det ger åtkomst till att hämta information om ljudformat som krävs för att hantera uppspelning. För det väljer du Arkiv>Ny>klass.

  9. I fönstret Ny Java-klass anger du speechsdk.quickstart i fältet Paket och ActivityAudioStream i fältet Namn .

  10. Öppna den nyligen skapade ActivityAudioStream klassen och ersätt den med följande kod:

    package com.speechsdk.quickstart;
    
    import com.microsoft.cognitiveservices.speech.audio.PullAudioOutputStream;
    
    import java.io.IOException;
    import java.io.InputStream;
    
     public final class ActivityAudioStream extends InputStream {
         /**
          * The number of samples played per second (16 kHz).
          */
         public static final long SAMPLE_RATE = 16000;
         /**
          * The number of bits in each sample of a sound that has this format (16 bits).
          */
         public static final int BITS_PER_SECOND = 16;
         /**
          * The number of audio channels in this format (1 for mono).
          */
         public static final int CHANNELS = 1;
         /**
          * The number of bytes in each frame of a sound that has this format (2).
          */
         public static final int FRAME_SIZE = 2;
    
         /**
          * Reads up to a specified maximum number of bytes of data from the audio
          * stream, putting them into the given byte array.
          *
          * @param b   the buffer into which the data is read
          * @param off the offset, from the beginning of array <code>b</code>, at which
          *            the data will be written
          * @param len the maximum number of bytes to read
          * @return the total number of bytes read into the buffer, or -1 if there
          * is no more data because the end of the stream has been reached
          */
         @Override
         public int read(byte[] b, int off, int len) {
             byte[] tempBuffer = new byte[len];
             int n = (int) this.pullStreamImpl.read(tempBuffer);
             for (int i = 0; i < n; i++) {
                 if (off + i > b.length) {
                     throw new ArrayIndexOutOfBoundsException(b.length);
                 }
                 b[off + i] = tempBuffer[i];
             }
             if (n == 0) {
                 return -1;
             }
             return n;
         }
    
         /**
          * Reads the next byte of data from the activity audio stream if available.
          *
          * @return the next byte of data, or -1 if the end of the stream is reached
          * @see #read(byte[], int, int)
          * @see #read(byte[])
          * @see #available
          * <p>
          */
         @Override
         public int read() {
             byte[] data = new byte[1];
             int temp = read(data);
             if (temp <= 0) {
                 // we have a weird situation if read(byte[]) returns 0!
                 return -1;
             }
             return data[0] & 0xFF;
         }
    
         /**
          * Reads up to a specified maximum number of bytes of data from the activity audio stream,
          * putting them into the given byte array.
          *
          * @param b the buffer into which the data is read
          * @return the total number of bytes read into the buffer, or -1 if there
          * is no more data because the end of the stream has been reached
          */
         @Override
         public int read(byte[] b) {
             int n = (int) pullStreamImpl.read(b);
             if (n == 0) {
                 return -1;
             }
             return n;
         }
    
         /**
          * Skips over and discards a specified number of bytes from this
          * audio input stream.
          *
          * @param n the requested number of bytes to be skipped
          * @return the actual number of bytes skipped
          * @throws IOException if an input or output error occurs
          * @see #read
          * @see #available
          */
         @Override
         public long skip(long n) {
             if (n <= 0) {
                 return 0;
             }
             if (n <= Integer.MAX_VALUE) {
                 byte[] tempBuffer = new byte[(int) n];
                 return read(tempBuffer);
             }
             long count = 0;
             for (long i = n; i > 0; i -= Integer.MAX_VALUE) {
                 int size = (int) Math.min(Integer.MAX_VALUE, i);
                 byte[] tempBuffer = new byte[size];
                 count += read(tempBuffer);
             }
             return count;
         }
    
         /**
          * Closes this audio input stream and releases any system resources associated
          * with the stream.
          */
         @Override
         public void close() {
             this.pullStreamImpl.close();
         }
    
         /**
          * Fetch the audio format for the ActivityAudioStream. The ActivityAudioFormat defines the sample rate, bits per sample, and the # channels.
          *
          * @return instance of the ActivityAudioFormat associated with the stream
          */
         public ActivityAudioStream.ActivityAudioFormat getActivityAudioFormat() {
             return activityAudioFormat;
         }
    
         /**
          * Returns the maximum number of bytes that can be read (or skipped over) from this
          * audio input stream without blocking.
          *
          * @return the number of bytes that can be read from this audio input stream without blocking.
          * As this implementation does not buffer, this will be defaulted to 0
          */
         @Override
         public int available() {
             return 0;
         }
    
         public ActivityAudioStream(final PullAudioOutputStream stream) {
             pullStreamImpl = stream;
             this.activityAudioFormat = new ActivityAudioStream.ActivityAudioFormat(SAMPLE_RATE, BITS_PER_SECOND, CHANNELS, FRAME_SIZE, AudioEncoding.PCM_SIGNED);
         }
    
         private PullAudioOutputStream pullStreamImpl;
    
         private ActivityAudioFormat activityAudioFormat;
    
         /**
          * ActivityAudioFormat is an internal format which contains metadata regarding the type of arrangement of
          * audio bits in this activity audio stream.
          */
         static class ActivityAudioFormat {
    
             private long samplesPerSecond;
             private int bitsPerSample;
             private int channels;
             private int frameSize;
             private AudioEncoding encoding;
    
             public ActivityAudioFormat(long samplesPerSecond, int bitsPerSample, int channels, int frameSize, AudioEncoding encoding) {
                 this.samplesPerSecond = samplesPerSecond;
                 this.bitsPerSample = bitsPerSample;
                 this.channels = channels;
                 this.encoding = encoding;
                 this.frameSize = frameSize;
             }
    
             /**
              * Fetch the number of samples played per second for the associated audio stream format.
              *
              * @return the number of samples played per second
              */
             public long getSamplesPerSecond() {
                 return samplesPerSecond;
             }
    
             /**
              * Fetch the number of bits in each sample of a sound that has this audio stream format.
              *
              * @return the number of bits per sample
              */
             public int getBitsPerSample() {
                 return bitsPerSample;
             }
    
             /**
              * Fetch the number of audio channels used by this audio stream format.
              *
              * @return the number of channels
              */
             public int getChannels() {
                 return channels;
             }
    
             /**
              * Fetch the default number of bytes in a frame required by this audio stream format.
              *
              * @return the number of bytes
              */
             public int getFrameSize() {
                 return frameSize;
             }
    
             /**
              * Fetch the audio encoding type associated with this audio stream format.
              *
              * @return the encoding associated
              */
             public AudioEncoding getEncoding() {
                 return encoding;
             }
         }
    
         /**
          * Enum defining the types of audio encoding supported by this stream.
          */
         public enum AudioEncoding {
             PCM_SIGNED("PCM_SIGNED");
    
             String value;
    
             AudioEncoding(String value) {
                 this.value = value;
             }
         }
     }
    
    
  11. Spara ändringar i ActivityAudioStream filen.

Kompilera och köra appen

Välj F11 eller kör >felsökning. Konsolen visar meddelandet "Säg något". Tala nu en engelsk fras eller mening som roboten kan förstå. Ditt tal överförs till roboten via Direct Line Speech-kanalen där det känns igen och bearbetas av roboten. Svaret returneras som en aktivitet. Om roboten returnerar tal som ett svar spelas ljudet upp med hjälp AudioPlayer av klassen .

Skärmbild av konsolutdata efter lyckad taligenkänning

Nästa steg

Du kan visa eller ladda ned alla Speech SDK Go-exempel på GitHub.

Förutsättningar

Innan du börjar:

Kommentar

Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

Konfigurera din miljö

Uppdatera go.mod-filen med den senaste SDK-versionen genom att lägga till den här raden

require (
    github.com/Microsoft/cognitive-services-speech-sdk-go v1.15.0
)

Börja med lite pannplåtskod

Ersätt innehållet i källfilen (t.ex. quickstart.go) med nedanstående, som innehåller:

  • Paketdefinitionen "main"
  • importera nödvändiga moduler från Speech SDK
  • variabler för att lagra robotinformationen som kommer att ersättas senare i den här snabbstarten
  • en enkel implementering med mikrofonen för ljudinmatning
  • händelsehanterare för olika händelser som äger rum under en talinteraktion
package main

import (
    "fmt"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/dialog"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func main() {
    subscription :=  "YOUR_SUBSCRIPTION_KEY"
    region := "YOUR_BOT_REGION"

    audioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    config, err := dialog.NewBotFrameworkConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    connector, err := dialog.NewDialogServiceConnectorFromConfig(config, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer connector.Close()
    activityReceivedHandler := func(event dialog.ActivityReceivedEventArgs) {
        defer event.Close()
        fmt.Println("Received an activity.")
    }
    connector.ActivityReceived(activityReceivedHandler)
    recognizedHandle := func(event speech.SpeechRecognitionEventArgs) {
        defer event.Close()
        fmt.Println("Recognized ", event.Result.Text)
    }
    connector.Recognized(recognizedHandle)
    recognizingHandler := func(event speech.SpeechRecognitionEventArgs) {
        defer event.Close()
        fmt.Println("Recognizing ", event.Result.Text)
    }
    connector.Recognizing(recognizingHandler)
    connector.ListenOnceAsync()
    <-time.After(10 * time.Second)
}

YOUR_SUBSCRIPTION_KEY Ersätt värdena och YOUR_BOT_REGION med faktiska värden från Speech-resursen.

  • Gå till Azure Portal och öppna din Speech-resurs

  • Under Nycklar och slutpunkt till vänster finns det två tillgängliga prenumerationsnycklar

    • Använd antingen en som YOUR_SUBSCRIPTION_KEY värdeersättning
  • Under Översikt till vänster noterar du regionen och mappar den till regionidentifieraren

    • Använd regionidentifieraren som YOUR_BOT_REGION värdeersättning, till exempel för "westus" USA, västra

    Kommentar

    Se listan över regioner som stöds för röstassistenter och se till att dina resurser distribueras i någon av dessa regioner.

    Kommentar

    Information om hur du konfigurerar din robot finns i Bot Framework-dokumentationen för Direct Line Speech-kanalen.

Kodförklaring

Talprenumerationsnyckeln och -regionen krävs för att skapa ett talkonfigurationsobjekt. Konfigurationsobjektet behövs för att instansiera ett taligenkänningsobjekt.

Identifierarinstansen exponerar flera sätt att känna igen tal. I det här exemplet identifieras tal kontinuerligt. Den här funktionen låter Speech-tjänsten veta att du skickar många fraser för igenkänning och när programmet avslutas för att sluta känna igen tal. När resultatet returneras skriver koden dem till konsolen.

Skapa och köra

Nu är du konfigurerad för att skapa projektet och testa din anpassade röstassistent med hjälp av Speech-tjänsten.

  1. Skapa projektet, t.ex. "go build"
  2. Kör modulen och tala en fras eller mening i enhetens mikrofon. Ditt tal överförs till direct line speech-kanalen och transkriberas till text, som visas som utdata.

Kommentar

Speech SDK kommer som standard att känna igen med hjälp av en-us för språket, se Så här känner du igen tal för information om hur du väljer källspråket.

Nästa steg

Ytterligare stöd för språk och plattform

Om du har klickat på den här fliken ser du förmodligen ingen snabbstart i ditt favoritprogrammeringsspråk. Oroa dig inte, vi har ytterligare snabbstartsmaterial och kodexempel tillgängliga på GitHub. Använd tabellen för att hitta rätt exempel för din kombination av programmeringsspråk och plattform/operativsystem.

Språk Kodexempel
C# .NET Framework, .NET Core, UWP, Unity
C++ Windows, Linux, macOS
Java Android, JRE
JavaScript Webbläsare, Node.js
Objective-C iOS, macOS
Python Windows, Linux, macOS
Swift iOS, macOS