Mulai cepat: Membuat asisten suara kustom

Dalam mulai cepat ini, Anda akan menggunakan SDK Ucapan untuk membuat aplikasi asisten suara kustom yang tersambung ke bot yang telah Anda tulis dan konfigurasi. Jika Anda perlu membuat bot, lihat tutorial terkait untuk panduan yang lebih komprehensif.

Setelah memenuhi beberapa prasyarat, menghubungkan asisten suara kustom Anda hanya memerlukan beberapa langkah:

  • Buat objek BotFrameworkConfig dari kunci dan wilayah langganan Anda.
  • Membuat objek DialogServiceConnector menggunakan objek BotFrameworkConfig dari atas.
  • Dengan menggunakan objek DialogServiceConnector, mulai proses mendengarkan untuk satu ucapan.
  • Periksa ActivityReceivedEventArgs yang dikembalikan.

Catatan

Speech SDK untuk C++, JavaScript, Objective-C, Python, dan Swift mendukung asisten suara kustom, tetapi kami belum menyertakan panduannya di sini.

Anda dapat melihat atau mengunduh semua Sampel C# SDK Ucapan di GitHub.

Prasyarat

Sebelum memulai, pastikan untuk:

Catatan

Lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

Membuka proyek Anda di Visual Studio

Langkah pertama adalah memastikan proyek Anda terbuka di Visual Studio.

Mulai dengan beberapa kode boilerplate

Mari tambahkan beberapa kode yang berfungsi sebagai kerangka untuk proyek kita.

  1. Di Penjelajah Solusi, buka MainPage.xaml.

  2. Dalam tampilan XAML desainer, ganti seluruh konten dengan cuplikan berikut yang mendefinisikan antarmuka pengguna yang belum sempurna:

    <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>
    

Tampilan Desain diperbarui untuk menampilkan antarmuka pengguna aplikasi.

  1. Di Penjelajah Solusi, buka file sumber di belakang kode MainPage.xaml.cs. (Ini dikelompokkan di MainPage.xaml.) Ganti konten file ini dengan di bawah ini, yang meliputi:
  • using pernyataan untuk namespace layanan Speech dan Speech.Dialog

  • Implementasi sederhana untuk memastikan akses mikrofon, tersambung dengan kabel ke penangan tombol

  • Pendukung antarmuka pengguna dasar untuk menyampaikan pesan dan kesalahan dalam aplikasi

  • Titik awal untuk jalur kode inisialisasi yang akan diisi nanti

  • Pembantu untuk memutar kembali teks ke ucapan (tanpa dukungan streaming)

  • Penangan tombol kosong untuk mulai mendengarkan yang akan diisi nanti

    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. Tambahkan cuplikan kode berikut ke isi metode InitializeDialogServiceConnector. Kode ini membuat DialogServiceConnector dengan informasi langganan Anda.

    // 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);
    

    Catatan

    Harap lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

    Catatan

    Untuk informasi tentang mengonfigurasi bot, lihat dokumentasi Bot Framework untuk saluran Direct Line Speech.

  2. Ganti untai (karakter) YourSpeechSubscriptionKey dan YourServiceRegion dengan nilai Anda sendiri untuk langganan ucapan dan kawasan Anda.

  3. Tambahkan cuplikan kode berikut ke akhir isi metode InitializeDialogServiceConnector. Kode ini menyiapkan penangan untuk aktivitas yang diandalkan oleh DialogServiceConnector untuk mengomunikasikan aktivitas bot, hasil pengenalan ucapan, dan informasi lainnya.

    // 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. Tambahkan cuplikan kode berikut ke isi metode ListenButton_ButtonClicked di kelas MainPage. Kode ini menyiapkan DialogServiceConnector untuk mendengarkan, karena Anda telah menetapkan konfigurasi dan mendaftarkan penanganan aktivitas.

    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);
    }
    

Membuat dan menjalankan aplikasi Anda

Sekarang Anda siap untuk membuat aplikasi dan menguji asisten suara kustom menggunakan layanan Speech.

  1. Dari bilah menu, pilih Build>Solusi Build untuk membuat aplikasi. Sekarang kode harus dikompilasi tanpa kesalahan.

  2. Pilih Debug>Mulai Penelusuran Kesalahan (atau tekan F5) untuk memulai aplikasi. Jendela helloworld akan muncul.

    Contoh aplikasi asisten suara UWP di C# - mulai cepat

  3. Pilih Aktifkan Mikrofon, dan saat permintaan izin akses muncul, pilih Ya.

    Permintaan izin akses mikrofon

  4. Pilih Bicara dengan bot, lalu ucapkan frasa atau kalimat bahasa Inggris di mikrofon perangkat Anda. Pidato Anda dikirimkan ke saluran Direct Line Speech dan ditranskripsikan menjadi teks, yang muncul di jendela.

Langkah berikutnya


Anda dapat melihat atau mengunduh semua Sampel Java SDK Ucapan di GitHub.

Memilih target lingkungan Anda

Prasyarat

Sebelum memulai, pastikan untuk:

Catatan

Silakan lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

Membuat dan mengonfigurasi proyek

Membuat proyek Eclipse dan menginstal Speech SDK.

Selain itu, untuk mengaktifkan pembuatan log, perbarui file pom.xml agar menyertakan dependensi berikut:

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

Menambahkan kode sampel

  1. Untuk menambahkan kelas kosong baru ke proyek Java, pilih File>Baru>Kelas.

  2. Di jendela Kelas Java Baru, masukkan speechsdk.quickstart di bidang Paket dan Utama di bidang Nama.

    Cuplikan layar jendela Kelas Java Baru

  3. Buka kelas Main yang baru dibuat, dan ganti konten file Main.java dengan kode awal berikut:

    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. Dalam metode main ini, Anda terlebih dahulu mengonfigurasi DialogServiceConfig dan menggunakannya untuk membuat instans DialogServiceConnector. Instans ini tersambung ke saluran Direct Line Speech untuk berinteraksi dengan bot Anda. Instans AudioConfig juga digunakan untuk menentukan sumber input audio. Dalam contoh ini, mikrofon default digunakan dengan AudioConfig.fromDefaultMicrophoneInput().

    • Ganti string YourSubscriptionKey dengan kunci sumber daya Ucapan, yang bisa Anda dapatkan dari portal Azure.
    • Ganti string YourServiceRegion dengan wilayah yang terkait dengan sumber daya Ucapan Anda.

    Catatan

    Silakan lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

    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. DialogServiceConnector konektor bergantung pada beberapa peristiwa untuk mengomunikasikan kegiatan bot, hasil pengenalan suara, dan informasi lainnya. Selanjutnya tambahkan pendengar peristiwa ini.

    // 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. Sambungkan DialogServiceConnector ke Direct Line Speech dengan memanggil metode connectAsync(). Untuk menguji bot, Anda dapat memanggil metode listenOnceAsync untuk mengirim input audio dari mikrofon Anda. Selain itu, Anda juga dapat menggunakan metode sendActivityAsync untuk mengirim aktivitas kustom sebagai string berseri. Aktivitas kustom ini dapat menyediakan data tambahan yang digunakan bot Anda dalam percakapan.

    connector.connectAsync();
    // Start listening.
    System.out.println("Say something ...");
    connector.listenOnceAsync();
    
    // connector.sendActivityAsync(...)
    
  7. Simpan perubahan pada file Main.

  8. Untuk mendukung pemutaran respons, tambahkan kelas tambahan yang mengubah objek PullAudioOutputStream yang dikembalikan dari GETAudio() API ke Java InputStream untuk kemudahan penanganan. ActivityAudioStream ini adalah kelas khusus yang menangani respons audio dari saluran Direct Line Speech. Ini menyediakan pengakses untuk mengambil informasi format audio yang diperlukan untuk menangani pemutaran. Untuk itu, pilih File>Baru>Kelas.

  9. Di jendela Kelas Java Baru, masukkan speechsdk.quickstart di bidang Paket dan ActivityAudioStream di bidang Nama.

  10. Buka kelas ActivityAudioStream yang baru dibuat, dan ganti dengan kode berikut:

    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. Simpan perubahan pada file ActivityAudioStream.

Membangun dan menjalankan aplikasi

Pilih F11, atau pilih Jalankan>Debug. Konsol menampilkan pesan "Katakan sesuatu". Pada bagian ini, ucapkan frasa atau kalimat bahasa Inggris yang dapat dipahami bot Anda. Ucapan Anda ditransmisikan ke bot Anda melalui saluran Direct Line Speech di mana ucapan tersebut dikenali dan diproses oleh bot Anda. Respons dekembalikan sebagai kegiatan. Jika bot mengembalikan ucapan sebagai respons, audio akan diputar kembali menggunakan kelas AudioPlayer.

Cuplikan layar output konsol setelah pengenalan berhasil

Langkah berikutnya

Anda dapat melihat atau mengunduh semua Sampel Go SDK Ucapan di GitHub.

Prasyarat

Sebelum Anda memulai:

Catatan

Harap lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

Menyiapkan lingkungan Anda

Perbarui file go.mod dengan versi SDK terbaru dengan menambahkan baris ini

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

Mulai dengan beberapa kode boilerplate

Ganti konten file sumber Anda (mis. quickstart.go) dengan yang di bawah, yang meliputi:

  • Definisi paket "utama"
  • mengimpor modul yang diperlukan dari SDK Speech
  • variabel untuk menyimpan informasi bot yang akan digantikan nanti di mulai cepat ini
  • implementasi sederhana menggunakan mikrofon untuk input audio
  • penanganan aktivitas untuk berbagai acara yang berlangsung selama interaksi ucapan
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)
}

Ganti nilai YOUR_SUBSCRIPTION_KEY dan YOUR_BOT_REGION dengan nilai aktual dari sumber daya Speech.

  • Buka portal Azure, dan buka sumber daya Speech Anda

  • Pada Tombol dan Titik Akhir di sebelah kiri, terdapat dua kunci langganan yang tersedia

    • Gunakan salah satu sebagai pengganti nilai YOUR_SUBSCRIPTION_KEY
  • Pada Ringkasan di sebelah kiri, perhatikan wilayah dan petakan ke pengidentifikasi wilayah

    • Gunakan Pengidentifikasi wilayah sebagai pengganti nilai YOUR_BOT_REGION, misalnya: "westus" untuk AS Barat

    Catatan

    Harap lihat daftar wilayah yang didukung untuk asisten suara dan pastikan sumber daya Anda disebarkan di salah satu wilayah tersebut.

    Catatan

    Untuk informasi tentang mengonfigurasi bot, lihat dokumentasi Bot Framework untuk saluran Direct Line Speech.

Penjelasan kode

Kunci dan wilayah langganan Speech diperlukan untuk membuat objek konfigurasi ucapan. Objek konfigurasi diperlukan untuk membuat objek pengenal ucapan.

Instans pengenal memaparkan beberapa cara untuk mengenali ucapan. Dalam contoh ini, ucapan terus dikenali. Fungsi ini memungkinkan layanan Speech mengetahui bahwa Anda mengirim banyak frasa untuk dikenali, dan kapan program berakhir untuk berhenti mengenali ucapan. Karena hasilnya sudah ada, kode akan menulisnya ke konsol.

Membangun dan menjalankan

Sekarang Anda siap untuk membangun proyek dan menguji asisten suara kustom Anda menggunakan layanan Speech.

  1. Bangun proyek Anda, misalnya "bangun"
  2. Jalankan modul dan ucapkan frasa atau kalimat ke mikrofon perangkat Anda. Ucapan Anda akan ditransmisikan ke saluran Direct Line Speech dan ditranskripsikan ke teks, yang muncul sebagai output.

Catatan

SDK Speech secara default akan mengenali menggunakan bahasa en-us, lihat Cara mengenali ucapan untuk mendapatkan informasi terkait pemilihan bahasa sumber.

Langkah berikutnya

Dukungan bahasa dan platform tambahan

Jika telah mengklik tab ini, Anda mungkin tidak melihat mulai cepat dalam bahasa pemrograman favorit Anda. Jangan khawatir, kami memiliki bahan mulai cepat tambahan dan sampel kode yang tersedia di GitHub. Gunakan tabel untuk menemukan sampel yang tepat untuk kombinasi bahasa dan platform/OS pemrograman Anda.

Bahasa Sampel kode
C# .NET Framework, .NET Core, UWP, Unity, Xamarin
C++ Windows, Linux, macOS
Java Android, JRE
JavaScript Browser, Node.js
Objective-C iOS, macOS
Python Windows, Linux, macOS
Swift iOS, macOS