Rövid útmutató: Egyéni hangsegéd létrehozása
Ebben a rövid útmutatóban a Speech SDK használatával fog létrehozni egy egyéni hangsegédalkalmazást, amely egy már létrehozott és konfigurált robothoz csatlakozik. Ha robotot kell létrehoznia, tekintse meg a kapcsolódó oktatóanyagot egy átfogóbb útmutatóhoz.
Néhány előfeltétel teljesítése után az egyéni hangsegéd csatlakoztatása csak néhány lépést tesz meg:
- Hozzon létre egy objektumot
BotFrameworkConfig
az előfizetési kulcsból és a régióból. - Hozzon létre egy
DialogServiceConnector
objektumot aBotFrameworkConfig
fenti objektum használatával. DialogServiceConnector
Az objektum használatával indítsa el a figyelési folyamatot egyetlen kimondott szöveghez.- Vizsgálja meg a
ActivityReceivedEventArgs
visszaadott adatokat.
Feljegyzés
A Speech SDK for C++, JavaScript, Objective-C, Python és Swift támogatja az egyéni hangsegédeket, de itt még nem tartalmaztunk útmutatót.
A GitHubon megtekintheti vagy letöltheti az összes Speech SDK C#-mintát .
Előfeltételek
Az első lépések előtt győződjön meg arról, hogy:
- Speech-erőforrás létrehozása
- A fejlesztési környezet beállítása és üres projekt létrehozása
- A Direct Line Speech csatornához csatlakoztatott robot létrehozása
- Győződjön meg arról, hogy rendelkezik hozzáféréssel egy mikrofonhoz a hangrögzítéshez
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
Projekt megnyitása a Visual Studióban
Első lépésként győződjön meg arról, hogy a projekt nyitva van a Visual Studióban.
Kezdje néhány sablonkóddal
Adjunk hozzá néhány olyan kódot, amely csontvázként működik a projektünkhöz.
Nyissa meg
MainPage.xaml
a Megoldáskezelő.A tervező XAML nézetében cserélje le a teljes tartalmat a következő kódrészletre, amely egy kezdetleges felhasználói felületet határoz meg:
<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>
A Tervező nézet frissül az alkalmazás felhasználói felületének megjelenítéséhez.
- A Megoldáskezelő nyissa meg a forrásfájl mögötti kódot
MainPage.xaml.cs
. (A csoport aMainPage.xaml
.) Cserélje le a fájl tartalmát az alábbira, amely a következőket tartalmazza:
using
a névterekre ésSpeech.Dialog
aSpeech
névterekre vonatkozó utasításokEgyszerű implementáció a mikrofonhoz való hozzáférés biztosításához, egy gombkezelőhöz kapcsolva
Egyszerű felhasználói felületi segítők az alkalmazás üzeneteinek és hibáinak megjelenítéséhez
Az inicializálási kód elérési útjának kezdőpontja, amely később lesz feltöltve
Segítő a szöveg visszajátszásához (streamelés támogatása nélkül)
Egy üres gombkezelő, amellyel elkezdhet figyelni, amely később fel lesz töltve
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 } } }
Adja hozzá a következő kódrészletet a metódus törzséhez
InitializeDialogServiceConnector
. Ez a kód létrehozza azDialogServiceConnector
előfizetés adatait.// 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);
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
Feljegyzés
A robot konfigurálásával kapcsolatos információkért tekintse meg a Bot Framework Direct Line Speech-csatorna dokumentációját.
Cserélje le a sztringeket
YourSpeechSubscriptionKey
ésYourServiceRegion
a saját értékeit a beszéd-előfizetéshez és a régióhoz.Fűzze hozzá a következő kódrészletet a metódus törzsének végéhez
InitializeDialogServiceConnector
. Ez a kód beállítja a robottevékenységek, a beszédfelismerési eredmények és egyéb információk közlése általDialogServiceConnector
hivatkozott események kezelőit.// 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}"); };
Adja hozzá a következő kódrészletet a
ListenButton_ButtonClicked
metódus törzséhez azMainPage
osztályban. Ez a kód beállítjaDialogServiceConnector
a figyelés beállításait, mivel már létrehozta a konfigurációt, és regisztrálta az eseménykezelőket.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); }
Az alkalmazás létrehozása és futtatása
Most már készen áll az alkalmazás összeállítására és az egyéni hangsegéd tesztelésére a Speech szolgáltatással.
A menüsávon válassza a Build Solution (Build Solution)>lehetőséget az alkalmazás létrehozásához. A kód fordításának hiba nélkül végbe kell mennie.
Az alkalmazás elindításához válassza a Hibakeresés indítása hibakeresés>(vagy az F5 billentyű lenyomása) lehetőséget. Megjelenik a helloworld ablak.
Válassza a Mikrofon engedélyezése lehetőséget, és amikor megjelenik a hozzáférési engedélykérés, válassza az Igen lehetőséget.
Válassza a Beszélgetés a robottal lehetőséget, és beszéljen egy angol kifejezéssel vagy mondattal az eszköz mikrofonjába. A beszéd a Direct Line Speech csatornára kerül, és át lesz írva a szövegre, amely megjelenik az ablakban.
Következő lépések
Megtekintheti vagy letöltheti az összes Speech SDK Java-mintát a GitHubon.
A célkörnyezet kiválasztása
Előfeltételek
Az első lépések előtt győződjön meg arról, hogy:
- Speech-erőforrás létrehozása
- A fejlesztési környezet beállítása és üres projekt létrehozása
- A Direct Line Speech csatornához csatlakoztatott robot létrehozása
- Győződjön meg arról, hogy rendelkezik hozzáféréssel egy mikrofonhoz a hangrögzítéshez
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
Projekt létrehozása és konfigurálása
Hozzon létre egy Eclipse-projektet, és telepítse a Speech SDK-t.
A naplózás engedélyezéséhez frissítse a pom.xml fájlt úgy, hogy az tartalmazza a következő függőséget:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
Mintakód hozzáadása
Ha új, üres osztályt szeretne hozzáadni a Java-projekthez, válassza a File>New>Class (Fájl, Új, Osztály) lehetőséget.
Az Új Java-osztály ablakban írja be a speechsdk.quickstart kifejezést a Csomag mezőbe, a Főt pedig a Név mezőbe.
Nyissa meg az újonnan létrehozott
Main
osztályt, és cserélje le aMain.java
fájl tartalmát a következő kezdőkódra: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(); } } }
A metódusban
main
először konfigurálja ésDialogServiceConfig
használja egy példány létrehozásáhozDialogServiceConnector
. Ez a példány a Direct Line Speech csatornához csatlakozik a robottal való interakcióhoz. EgyAudioConfig
példány a hangbemenet forrásának megadására is használható. Ebben a példában a rendszer az alapértelmezett mikrofontAudioConfig.fromDefaultMicrophoneInput()
használja.- Cserélje le a sztringet
YourSubscriptionKey
a Speech erőforráskulcsára, amelyet az Azure Portalról szerezhet be. - Cserélje le a sztringet
YourServiceRegion
a Speech-erőforráshoz társított régióra .
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
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);
- Cserélje le a sztringet
Az összekötő
DialogServiceConnector
számos eseményre támaszkodik a robottevékenységek, a beszédfelismerési eredmények és egyéb információk közléséhez. Ezután vegye fel ezeket az eseményfigyelőket.// 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()); } });
Csatlakozzon
DialogServiceConnector
a Direct Line Speechhez aconnectAsync()
metódus meghívásával. A robot teszteléséhez meghívhatja azt alistenOnceAsync
metódust, amely hangbemenetet küld a mikrofonból. Emellett asendActivityAsync
metódussal szerializált sztringként is küldhet egyéni tevékenységeket. Ezek az egyéni tevékenységek további adatokat biztosíthatnak, amelyeket a robot a beszélgetés során használ.connector.connectAsync(); // Start listening. System.out.println("Say something ..."); connector.listenOnceAsync(); // connector.sendActivityAsync(...)
Mentse a fájl módosításait
Main
.A válaszlejátszás támogatásához adjon hozzá egy további osztályt, amely átalakítja a getAudio() API-ból visszaadott PullAudioOutputStream objektumot egy Java InputStreambe a könnyű kezelhetőség érdekében. Ez
ActivityAudioStream
egy speciális osztály, amely a Direct Line Speech csatornáról érkező hangválaszokat kezeli. Tartozékokat biztosít a lejátszás kezeléséhez szükséges hangformátum-információk lekéréséhez. Ehhez válassza az Új>fájl osztály lehetőséget.>Az Új Java-osztály ablakban írja be a speechsdk.quickstart kifejezést a Csomag mezőbe, az ActivityAudioStreamet pedig a Név mezőbe.
Nyissa meg az újonnan létrehozott
ActivityAudioStream
osztályt, és cserélje le a következő kódra: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; } } }
Mentse a fájl módosításait
ActivityAudioStream
.
Készítsen buildet és futtassa az alkalmazást
Válassza az F11 lehetőséget, vagy válassza a Hibakeresés futtatása>lehetőséget.
A konzolon megjelenik a "Mondj valamit" üzenet. Ezen a ponton beszéljen egy angol kifejezést vagy mondatot, amelyet a robot megért. A beszédet a robot a Direct Line Speech csatornán keresztül továbbítja, ahol a robot felismeri és feldolgozta. A válasz tevékenységként lesz visszaadva. Ha a robot válaszként adja vissza a beszédet, a hang lejátszása az AudioPlayer
osztály használatával történik.
Következő lépések
Az összes Speech SDK Go-mintát megtekintheti vagy letöltheti a GitHubon.
Előfeltételek
A kezdés előtt:
- Speech-erőforrás létrehozása
- A fejlesztési környezet beállítása és egy üres projekt létrehozása
- A Direct Line Speech csatornához csatlakoztatott robot létrehozása
- Győződjön meg arról, hogy rendelkezik hozzáféréssel egy mikrofonhoz a hangrögzítéshez
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
A környezet beállítása
A go.mod fájl frissítése a legújabb SDK-verzióval a sor hozzáadásával
require (
github.com/Microsoft/cognitive-services-speech-sdk-go v1.15.0
)
Kezdje néhány sablonkóddal
Cserélje le a forrásfájl tartalmát (például quickstart.go
) az alábbira, amely a következőket tartalmazza:
- "fő" csomagdefiníció
- a szükséges modulok importálása a Speech SDK-ból
- változók a robot információinak tárolására, amelyeket a rövid útmutató későbbi részében lecserélünk
- egyszerű implementáció a mikrofonnal hangbemenethez
- eseménykezelők a beszédkezelés során zajló különböző eseményekhez
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)
}
Cserélje le az és YOUR_BOT_REGION
az YOUR_SUBSCRIPTION_KEY
értékeket a Speech erőforrás tényleges értékeire.
Lépjen az Azure Portalra, és nyissa meg a Speech-erőforrást
A bal oldali Kulcsok és végpont területen két elérhető előfizetési kulcs található
- Bármelyiket használja értékhelyettesítőként
YOUR_SUBSCRIPTION_KEY
- Bármelyiket használja értékhelyettesítőként
A bal oldali Áttekintés területen jegyezze fel a régiót, és képezze le a régióazonosítóra
- Használja a Régió azonosítót értékhelyettesítőként
YOUR_BOT_REGION
, például az"westus"
USA nyugati régiója esetében
Feljegyzés
Tekintse meg a hangsegédek támogatott régióinak listáját, és győződjön meg arról, hogy az erőforrások ezen régiók egyikében vannak üzembe helyezve.
Feljegyzés
A robot konfigurálásával kapcsolatos információkért tekintse meg a Bot Framework Direct Line Speech-csatorna dokumentációját.
- Használja a Régió azonosítót értékhelyettesítőként
Kód magyarázata
Beszédkonfigurációs objektum létrehozásához a Speech előfizetési kulcsára és régiójára van szükség. A konfigurációs objektumra szükség van egy beszédfelismerő objektum példányosításához.
A felismerő példány több módszert is kínál a beszéd felismerésére. Ebben a példában a beszéd folyamatosan felismerhető. Ez a funkció tudatja a Speech szolgáltatással, hogy számos kifejezést küld felismerésre, és amikor a program leáll, hogy leálljon a beszéd felismerése. Az eredmények eredményének megfelelően a kód a konzolra írja őket.
Buildelés és futtatás
Most már be van állítva, hogy elkészítse a projektet, és tesztelje az egyéni hangsegédet a Speech szolgáltatással.
- A projekt felépítése, például "go build"
- Futtassa a modult, és beszéljen egy kifejezést vagy mondatot az eszköz mikrofonjába. A beszéd továbbítása a Direct Line Speech csatornára történik, és át lesz írva a szövegre, amely kimenetként jelenik meg.
Feljegyzés
A Speech SDK alapértelmezés szerint felismeri az en-us nyelvet. A forrásnyelv kiválasztásával kapcsolatos információkért tekintse meg a Beszéd felismerése című témakört.
Következő lépések
További nyelvi és platformtámogatás
Ha erre a fülre kattintott, valószínűleg nem látott rövid útmutatót a kedvenc programozási nyelvében. Ne aggódjon, további gyorsútmutató anyagok és kódminták érhetők el a GitHubon. A táblázat segítségével megtalálhatja a programozási nyelv és a platform/operációs rendszer kombinációjának megfelelő mintát.
Nyelv | Kódminták |
---|---|
C# | .NET-keretrendszer, .NET Core, UWP, Unity |
C++ | Windows, Linux, macOS |
Java | Android, JRE |
JavaScript | Böngésző, Node.js |
Objective-C | iOS, macOS |
Python | Windows, Linux, macOS |
Swift | iOS, macOS |