Rychlý start: Vytvoření vlastního hlasového asistent
V tomto rychlém startu použijete sadu Speech SDK k vytvoření vlastní hlasové asistent aplikace, která se připojí k robotovi, který jste už vytvořili a nakonfigurovali. Pokud potřebujete vytvořit robota, podívejte se na související kurz , kde najdete podrobnějšího průvodce.
Po splnění několika požadavků trvá připojení vlastního hlasového asistent jen několik kroků:
- Vytvořte
BotFrameworkConfig
objekt z klíče a oblasti předplatného. - Vytvořte
DialogServiceConnector
objekt pomocí objektuBotFrameworkConfig
shora. - Pomocí objektu
DialogServiceConnector
spusťte proces naslouchání jedné promluvě. - Zkontrolujte vrácenou adresu
ActivityReceivedEventArgs
.
Poznámka
Sada Speech SDK pro C++, JavaScript, Objective-C, Python a Swift podporují vlastní hlasové asistenty, ale zatím jsme sem nezahrnuli průvodce.
Na GitHubu můžete zobrazit nebo stáhnout všechny ukázky jazyka C# sady Speech SDK .
Požadavky
Než začnete, nezapomeňte:
- Vytvoření prostředku služby Speech
- Nastavení vývojového prostředí a vytvoření prázdného projektu
- Vytvoření robota připojeného ke kanálu Direct Line Speech
- Ujistěte se, že máte přístup k mikrofonu pro záznam zvuku.
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
Otevření projektu v sadě Visual Studio
Prvním krokem je ujistit se, že máte projekt otevřený v sadě Visual Studio.
Začněte s nějakým často používaným kódem.
Pojďme přidat kód, který funguje jako kostra pro náš projekt.
V Průzkumník řešení otevřete
MainPage.xaml
.V zobrazení XAML návrháře nahraďte celý obsah následujícím fragmentem kódu, který definuje základní uživatelské rozhraní:
<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>
Návrhové zobrazení se aktualizuje tak, aby zobrazovala uživatelské rozhraní aplikace.
- V Průzkumník řešení otevřete zdrojový soubor
MainPage.xaml.cs
kódu na pozadí . (Je seskupený podMainPage.xaml
.) Obsah tohoto souboru nahraďte následujícími položkami, mezi které patří:
using
příkazy pro oborySpeech
názvů aSpeech.Dialog
Jednoduchá implementace pro zajištění přístupu k mikrofonu, připojená k obslužné rutině tlačítka
Základní pomocné rutiny uživatelského rozhraní k zobrazení zpráv a chyb v aplikaci
Cílový bod pro cestu inicializačního kódu, která bude vyplněna později
Pomocník pro přehrávání textu na řeč (bez podpory streamování)
Prázdná obslužná rutina tlačítka pro zahájení naslouchání, která se vyplní později
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 } } }
Do těla
InitializeDialogServiceConnector
metody přidejte následující fragment kódu . Tento kód vytvoří sDialogServiceConnector
informacemi o vašem předplatném.// 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);
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
Poznámka
Informace o konfiguraci robota najdete v dokumentaci k bot Frameworku pro kanál Direct Line Speech.
Nahraďte řetězce
YourSpeechSubscriptionKey
aYourServiceRegion
vlastními hodnotami pro vaše předplatné a oblast služby Speech.Na konec těla
InitializeDialogServiceConnector
metody připojte následující fragment kódu . Tento kód nastaví obslužné rutiny pro události, na kteréDialogServiceConnector
se spoléhá při komunikaci aktivit robota, výsledků rozpoznávání řeči a dalších informací.// 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}"); };
Do těla
ListenButton_ButtonClicked
metody veMainPage
třídě přidejte následující fragment kódu. Tento kód nastavíDialogServiceConnector
naslouchání, protože jste již vytvořili konfiguraci a zaregistrovali obslužné rutiny událostí.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); }
Sestavit a spustit aplikaci
Teď jste připraveni sestavit aplikaci a otestovat vlastní hlasovou asistent pomocí služby Speech.
V řádku nabídek zvolte Sestavit>řešení sestavení a sestavte aplikaci. Kód by se teď měl zkompilovat bez chyb.
Zvolte Ladit>Spustit ladění (nebo stiskněte klávesu F5) a spusťte aplikaci. Zobrazí se okno helloworld .
Vyberte Povolit mikrofon a až se zobrazí žádost o oprávnění k přístupu, vyberte Ano.
Vyberte Mluvit se svým robotem a vyslovte do mikrofonu zařízení anglickou frázi nebo větu. Vaše řeč se přenese do kanálu Direct Line Speech a přepíše na text, který se zobrazí v okně.
Další kroky
Na GitHubu můžete zobrazit nebo stáhnout všechny ukázky v Javě sady Speech SDK .
Volba cílového prostředí
Požadavky
Než začnete, nezapomeňte:
- Vytvoření prostředku služby Speech
- Nastavení vývojového prostředí a vytvoření prázdného projektu
- Vytvoření robota připojeného ke kanálu Direct Line Speech
- Ujistěte se, že máte přístup k mikrofonu pro záznam zvuku.
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
Vytvoření a konfigurace projektu
Vytvořte projekt Eclipse a nainstalujte sadu Speech SDK.
Pokud chcete povolit protokolování, aktualizujte souborpom.xml tak, aby zahrnoval následující závislost:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
Přidání ukázkového kódu
Pokud chcete do projektu Java přidat novou prázdnou třídu, vyberte Soubor>nová>třída.
V okně Nová třída Javy zadejte speechsdk.quickstart do pole Package (Balíček) a Main (Hlavní) do pole Name (Název).
Otevřete nově vytvořenou
Main
třídu a nahraďte obsahMain.java
souboru následujícím počátečním kódem: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(); } } }
V metodě
main
nejprve nakonfigurujete a použijeteDialogServiceConfig
ji k vytvořeníDialogServiceConnector
instance. Tato instance se připojí ke kanálu Direct Line Speech a bude moct komunikovat s vaším robotem. InstanceAudioConfig
se také používá k určení zdroje pro zvukový vstup. V tomto příkladu se používá výchozí mikrofon sAudioConfig.fromDefaultMicrophoneInput()
.- Nahraďte řetězec
YourSubscriptionKey
klíčem prostředku speech, který můžete získat z Azure Portal. - Nahraďte řetězec
YourServiceRegion
oblastí přidruženou k vašemu prostředku Speech.
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
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);
- Nahraďte řetězec
Konektor
DialogServiceConnector
spoléhá při komunikaci aktivit robota, výsledků rozpoznávání řeči a dalších informací na několik událostí. Přidejte tyto naslouchací procesy událostí jako další.// 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()); } });
Připojte
DialogServiceConnector
se k Direct Line Speech vyvolánímconnectAsync()
metody. Pokud chcete robota otestovat, můžete vyvolat metodu pro odeslání zvukovéholistenOnceAsync
vstupu z mikrofonu. Kromě toho můžete také použít metodusendActivityAsync
k odeslání vlastní aktivity jako serializovaného řetězce. Tyto vlastní aktivity můžou poskytovat další data, která robot používá v konverzaci.connector.connectAsync(); // Start listening. System.out.println("Say something ..."); connector.listenOnceAsync(); // connector.sendActivityAsync(...)
Uložte změny souboru
Main
.Pro podporu přehrávání odpovědí přidejte další třídu, která transformuje pullAudioOutputStream objekt vrácený z rozhraní GETAudio() API na Java InputStream pro usnadnění zpracování. Toto
ActivityAudioStream
je specializovaná třída, která zpracovává zvukovou odezvu z kanálu Direct Line Speech. Poskytuje příslušenství pro načtení informací o formátu zvuku, které jsou potřeba pro zpracování přehrávání. V takovém případě vyberte Soubor>nová>třída.V okně Nová třída Java zadejte speechsdk.quickstart do pole Package a ActivityAudioStream do pole Název .
Otevřete nově vytvořenou
ActivityAudioStream
třídu a nahraďte ji následujícím kódem: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; } } }
Uložte změny souboru
ActivityAudioStream
.
Sestavte a spusťte aplikaci.
Vyberte F11 nebo spustit>ladění.
Konzola zobrazí zprávu "Řekněte něco". V tuto chvíli vyslovte anglickou frázi nebo větu, které robot rozumí. Vaše řeč se do robota přenáší přes kanál Direct Line Speech, kde ji robot rozpozná a zpracuje. Odpověď se vrátí jako aktivita. Pokud robot vrací řeč jako odpověď, zvuk se přehraje AudioPlayer
pomocí třídy .
Další kroky
Všechny ukázky sady Speech SDK Go si můžete zobrazit nebo stáhnout na GitHubu.
Požadavky
Než začnete:
- Vytvoření prostředku služby Speech
- Nastavení vývojového prostředí a vytvoření prázdného projektu
- Vytvoření robota připojeného ke kanálu Direct Line Speech
- Ujistěte se, že máte přístup k mikrofonu pro záznam zvuku.
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
Nastavení vašeho prostředí
Přidáním tohoto řádku aktualizujte soubor go.mod na nejnovější verzi sady SDK.
require (
github.com/Microsoft/cognitive-services-speech-sdk-go v1.15.0
)
Začněte s určitým často používaným kódem.
Nahraďte obsah zdrojového souboru (např. quickstart.go
) následujícím kódem, mezi které patří:
- Definice "hlavního" balíčku
- import potřebných modulů ze sady Speech SDK
- Proměnné pro ukládání informací o robotovi, které budou nahrazeny později v tomto rychlém startu
- jednoduchá implementace pomocí mikrofonu pro zvukový vstup
- obslužné rutiny událostí pro různé události, ke kterým dochází během hlasové interakce
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
Nahraďte hodnoty a YOUR_BOT_REGION
skutečnými hodnotami z prostředku služby Speech.
Přejděte do Azure Portal a otevřete prostředek služby Speech.
V části Klíče a Koncový bod na levé straně jsou dva dostupné klíče předplatného.
- Jako nahrazení hodnoty použijte kteroukoli z nich
YOUR_SUBSCRIPTION_KEY
.
- Jako nahrazení hodnoty použijte kteroukoli z nich
V části Přehled na levé straně si poznamenejte oblast a namapujte ji na identifikátor oblasti.
- Jako náhradu
YOUR_BOT_REGION
hodnoty použijte identifikátor oblasti, například pro USA – západ."westus"
Poznámka
Projděte si seznam podporovaných oblastí pro hlasové asistenty a ujistěte se, že jsou vaše prostředky nasazené v jedné z těchto oblastí.
Poznámka
Informace o konfiguraci robota najdete v dokumentaci ke službě Bot Framework pro kanál Direct Line Speech.
- Jako náhradu
Vysvětlení kódu
K vytvoření objektu konfigurace řeči se vyžaduje klíč předplatného a oblast předplatného služby Speech. Objekt konfigurace je potřeba k vytvoření instance objektu rozpoznávání řeči.
Instance rozpoznávání zveřejňuje několik způsobů rozpoznávání řeči. V tomto příkladu je rozpoznávání řeči nepřetržitě rozpoznáno. Tato funkce dává službě Speech vědět, že odesíláte mnoho frází k rozpoznávání, a když se program ukončí, aby přestal rozpoznávat řeč. Po získání výsledků je kód zapíše do konzoly.
Sestavení a spuštění
Teď jste připraveni sestavit projekt a otestovat vlastní hlasovou asistent pomocí služby Speech.
- Sestavení projektu, například "go build"
- Spusťte modul a vyslovte frázi nebo větu do mikrofonu zařízení. Vaše řeč se přenese do kanálu Direct Line Speech a přepíše na text, který se zobrazí jako výstup.
Poznámka
Sada Speech SDK ve výchozím nastavení rozpozná jazyk pomocí en-us. Informace o výběru zdrojového jazyka najdete v tématu Rozpoznávání řeči .
Další kroky
Podpora dalších jazyků a platforem
Pokud jste klikli na tuto kartu, pravděpodobně jste ve svém oblíbeném programovacím jazyce neviděli rychlý start. Nemějte obavy, další materiály pro rychlý start a ukázky kódu jsou k dispozici na GitHubu. Pomocí tabulky vyhledejte vhodnou ukázku pro vaši kombinaci programovacího jazyka a platformy a operačního systému.
Jazyk | Ukázky kódů |
---|---|
C# | .NET Framework, .NET Core, UPW, Unity, Xamarin |
C++ | Windows, Linux, macOS |
Java | Android, JRE |
JavaScript | Prohlížeč, Node.js |
Objective-C | iOS, macOS |
Python | Windows, Linux, macOS |
Swift | iOS, macOS |