You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/id/6-consumer/lessons/1-speech-recognition/wio-terminal-speech-to-text.md

22 KiB

Ucapan ke Teks - Wio Terminal

Dalam bagian pelajaran ini, Anda akan menulis kode untuk mengubah ucapan dalam audio yang ditangkap menjadi teks menggunakan layanan ucapan.

Kirim audio ke layanan ucapan

Audio dapat dikirim ke layanan ucapan menggunakan REST API. Untuk menggunakan layanan ucapan, pertama-tama Anda perlu meminta token akses, lalu gunakan token tersebut untuk mengakses REST API. Token akses ini akan kedaluwarsa setelah 10 menit, jadi kode Anda harus memintanya secara berkala untuk memastikan token selalu diperbarui.

Tugas - mendapatkan token akses

  1. Buka proyek smart-timer jika belum terbuka.

  2. Tambahkan dependensi pustaka berikut ke file platformio.ini untuk mengakses WiFi dan menangani JSON:

    seeed-studio/Seeed Arduino rpcWiFi @ 1.0.5
    seeed-studio/Seeed Arduino rpcUnified @ 2.1.3
    seeed-studio/Seeed_Arduino_mbedtls @ 3.0.1
    seeed-studio/Seeed Arduino RTC @ 2.0.0
    bblanchon/ArduinoJson @ 6.17.3
    
  3. Tambahkan kode berikut ke file header config.h:

    const char *SSID = "<SSID>";
    const char *PASSWORD = "<PASSWORD>";
    
    const char *SPEECH_API_KEY = "<API_KEY>";
    const char *SPEECH_LOCATION = "<LOCATION>";
    const char *LANGUAGE = "<LANGUAGE>";
    
    const char *TOKEN_URL = "https://%s.api.cognitive.microsoft.com/sts/v1.0/issuetoken";
    

    Ganti <SSID> dan <PASSWORD> dengan nilai yang relevan untuk WiFi Anda.

    Ganti <API_KEY> dengan kunci API untuk sumber daya layanan ucapan Anda. Ganti <LOCATION> dengan lokasi yang Anda gunakan saat membuat sumber daya layanan ucapan.

    Ganti <LANGUAGE> dengan nama lokal untuk bahasa yang akan Anda gunakan, misalnya en-GB untuk Bahasa Inggris, atau zn-HK untuk Bahasa Kanton. Anda dapat menemukan daftar bahasa yang didukung dan nama lokalnya di dokumentasi dukungan bahasa dan suara di Microsoft Docs.

    Konstanta TOKEN_URL adalah URL penerbit token tanpa lokasi. URL ini akan digabungkan dengan lokasi nanti untuk mendapatkan URL lengkap.

  4. Sama seperti saat menghubungkan ke Custom Vision, Anda perlu menggunakan koneksi HTTPS untuk terhubung ke layanan penerbit token. Tambahkan kode berikut ke akhir config.h:

    const char *TOKEN_CERTIFICATE =
        "-----BEGIN CERTIFICATE-----\r\n"
        "MIIF8zCCBNugAwIBAgIQAueRcfuAIek/4tmDg0xQwDANBgkqhkiG9w0BAQwFADBh\r\n"
        "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n"
        "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\r\n"
        "MjAeFw0yMDA3MjkxMjMwMDBaFw0yNDA2MjcyMzU5NTlaMFkxCzAJBgNVBAYTAlVT\r\n"
        "MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKjAoBgNVBAMTIU1pY3Jv\r\n"
        "c29mdCBBenVyZSBUTFMgSXNzdWluZyBDQSAwNjCCAiIwDQYJKoZIhvcNAQEBBQAD\r\n"
        "ggIPADCCAgoCggIBALVGARl56bx3KBUSGuPc4H5uoNFkFH4e7pvTCxRi4j/+z+Xb\r\n"
        "wjEz+5CipDOqjx9/jWjskL5dk7PaQkzItidsAAnDCW1leZBOIi68Lff1bjTeZgMY\r\n"
        "iwdRd3Y39b/lcGpiuP2d23W95YHkMMT8IlWosYIX0f4kYb62rphyfnAjYb/4Od99\r\n"
        "ThnhlAxGtfvSbXcBVIKCYfZgqRvV+5lReUnd1aNjRYVzPOoifgSx2fRyy1+pO1Uz\r\n"
        "aMMNnIOE71bVYW0A1hr19w7kOb0KkJXoALTDDj1ukUEDqQuBfBxReL5mXiu1O7WG\r\n"
        "0vltg0VZ/SZzctBsdBlx1BkmWYBW261KZgBivrql5ELTKKd8qgtHcLQA5fl6JB0Q\r\n"
        "gs5XDaWehN86Gps5JW8ArjGtjcWAIP+X8CQaWfaCnuRm6Bk/03PQWhgdi84qwA0s\r\n"
        "sRfFJwHUPTNSnE8EiGVk2frt0u8PG1pwSQsFuNJfcYIHEv1vOzP7uEOuDydsmCjh\r\n"
        "lxuoK2n5/2aVR3BMTu+p4+gl8alXoBycyLmj3J/PUgqD8SL5fTCUegGsdia/Sa60\r\n"
        "N2oV7vQ17wjMN+LXa2rjj/b4ZlZgXVojDmAjDwIRdDUujQu0RVsJqFLMzSIHpp2C\r\n"
        "Zp7mIoLrySay2YYBu7SiNwL95X6He2kS8eefBBHjzwW/9FxGqry57i71c2cDAgMB\r\n"
        "AAGjggGtMIIBqTAdBgNVHQ4EFgQU1cFnOsKjnfR3UltZEjgp5lVou6UwHwYDVR0j\r\n"
        "BBgwFoAUTiJUIBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1Ud\r\n"
        "JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMHYG\r\n"
        "CCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu\r\n"
        "Y29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln\r\n"
        "aUNlcnRHbG9iYWxSb290RzIuY3J0MHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9j\r\n"
        "cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RHMi5jcmwwN6A1oDOG\r\n"
        "MWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RHMi5j\r\n"
        "cmwwHQYDVR0gBBYwFDAIBgZngQwBAgEwCAYGZ4EMAQICMBAGCSsGAQQBgjcVAQQD\r\n"
        "AgEAMA0GCSqGSIb3DQEBDAUAA4IBAQB2oWc93fB8esci/8esixj++N22meiGDjgF\r\n"
        "+rA2LUK5IOQOgcUSTGKSqF9lYfAxPjrqPjDCUPHCURv+26ad5P/BYtXtbmtxJWu+\r\n"
        "cS5BhMDPPeG3oPZwXRHBJFAkY4O4AF7RIAAUW6EzDflUoDHKv83zOiPfYGcpHc9s\r\n"
        "kxAInCedk7QSgXvMARjjOqdakor21DTmNIUotxo8kHv5hwRlGhBJwps6fEVi1Bt0\r\n"
        "trpM/3wYxlr473WSPUFZPgP1j519kLpWOJ8z09wxay+Br29irPcBYv0GMXlHqThy\r\n"
        "8y4m/HyTQeI2IMvMrQnwqPpY+rLIXyviI2vLoI+4xKE4Rn38ZZ8m\r\n"
        "-----END CERTIFICATE-----\r\n";
    

    Ini adalah sertifikat yang sama yang Anda gunakan saat menghubungkan ke Custom Vision.

  5. Tambahkan include untuk file header WiFi dan file header config ke bagian atas file main.cpp:

    #include <rpcWiFi.h>
    
    #include "config.h"
    
  6. Tambahkan kode untuk menghubungkan ke WiFi di main.cpp di atas fungsi setup:

    void connectWiFi()
    {
        while (WiFi.status() != WL_CONNECTED)
        {
            Serial.println("Connecting to WiFi..");
            WiFi.begin(SSID, PASSWORD);
            delay(500);
        }
    
        Serial.println("Connected!");
    }
    
  7. Panggil fungsi ini dari fungsi setup setelah koneksi serial telah dibuat:

    connectWiFi();
    
  8. Buat file header baru di folder src bernama speech_to_text.h. Dalam file header ini, tambahkan kode berikut:

    #pragma once
    
    #include <Arduino.h>
    #include <ArduinoJson.h>
    #include <HTTPClient.h>
    #include <WiFiClientSecure.h>
    
    #include "config.h"
    #include "mic.h"
    
    class SpeechToText
    {
    public:
    
    private:
    
    };
    
    SpeechToText speechToText;
    

    Ini mencakup beberapa file header yang diperlukan untuk koneksi HTTP, konfigurasi, dan file header mic.h, serta mendefinisikan kelas bernama SpeechToText, sebelum mendeklarasikan instance dari kelas tersebut yang dapat digunakan nanti.

  9. Tambahkan 2 field berikut ke bagian private dari kelas ini:

    WiFiClientSecure _token_client;
    String _access_token;
    

    _token_client adalah WiFi Client yang menggunakan HTTPS dan akan digunakan untuk mendapatkan token akses. Token ini kemudian akan disimpan di _access_token.

  10. Tambahkan metode berikut ke bagian private:

    String getAccessToken()
    {
        char url[128];
        sprintf(url, TOKEN_URL, SPEECH_LOCATION);
    
        HTTPClient httpClient;
        httpClient.begin(_token_client, url);
    
        httpClient.addHeader("Ocp-Apim-Subscription-Key", SPEECH_API_KEY);
        int httpResultCode = httpClient.POST("{}");
    
        if (httpResultCode != 200)
        {
            Serial.println("Error getting access token, trying again...");
            delay(10000);
            return getAccessToken();
        }
    
        Serial.println("Got access token.");
        String result = httpClient.getString();
    
        httpClient.end();
    
        return result;
    }
    

    Kode ini membangun URL untuk API penerbit token menggunakan lokasi sumber daya ucapan. Kemudian membuat HTTPClient untuk melakukan permintaan web, mengaturnya untuk menggunakan klien WiFi yang dikonfigurasi dengan sertifikat endpoint token. Kode ini menetapkan kunci API sebagai header untuk panggilan. Kemudian melakukan permintaan POST untuk mendapatkan sertifikat, mencoba ulang jika terjadi kesalahan. Akhirnya token akses dikembalikan.

  11. Ke bagian public, tambahkan metode untuk mendapatkan token akses. Metode ini akan diperlukan dalam pelajaran berikutnya untuk mengubah teks menjadi ucapan.

    String AccessToken()
    {
        return _access_token;
    }
    
  12. Ke bagian public, tambahkan metode init yang mengatur klien token:

    void init()
    {
        _token_client.setCACert(TOKEN_CERTIFICATE);
        _access_token = getAccessToken();
    }
    

    Metode ini menetapkan sertifikat pada klien WiFi, lalu mendapatkan token akses.

  13. Di main.cpp, tambahkan file header baru ini ke direktif include:

    #include "speech_to_text.h"
    
  14. Inisialisasi kelas SpeechToText di akhir fungsi setup, setelah panggilan mic.init tetapi sebelum Ready ditulis ke monitor serial:

    speechToText.init();
    

Tugas - membaca audio dari memori flash

  1. Pada bagian sebelumnya dari pelajaran ini, audio direkam ke memori flash. Audio ini perlu dikirim ke REST API Layanan Ucapan, sehingga perlu dibaca dari memori flash. Audio tidak dapat dimuat ke buffer dalam memori karena ukurannya terlalu besar. Kelas HTTPClient yang membuat panggilan REST dapat melakukan streaming data menggunakan Arduino Stream - sebuah kelas yang dapat memuat data dalam potongan kecil, mengirimkan potongan satu per satu sebagai bagian dari permintaan. Setiap kali Anda memanggil read pada stream, stream akan mengembalikan blok data berikutnya. Stream Arduino dapat dibuat untuk membaca dari memori flash. Buat file baru bernama flash_stream.h di folder src, dan tambahkan kode berikut ke dalamnya:

    #pragma once
    
    #include <Arduino.h>
    #include <HTTPClient.h>
    #include <sfud.h>
    
    #include "config.h"
    
    class FlashStream : public Stream
    {
    public:
        virtual size_t write(uint8_t val)
        {    
        }
    
        virtual int available()
        {
        }
    
        virtual int read()
        {
        }
    
        virtual int peek()
        {
        }
    private:
    
    };
    

    Ini mendeklarasikan kelas FlashStream, yang diturunkan dari kelas Stream Arduino. Ini adalah kelas abstrak - kelas turunan harus mengimplementasikan beberapa metode sebelum kelas dapat diinstansiasi, dan metode-metode ini didefinisikan dalam kelas ini.

    Baca lebih lanjut tentang Arduino Streams di dokumentasi Stream Arduino

  2. Tambahkan field berikut ke bagian private:

    size_t _pos;
    size_t _flash_address;
    const sfud_flash *_flash;
    
    byte _buffer[HTTP_TCP_BUFFER_SIZE];
    

    Ini mendefinisikan buffer sementara untuk menyimpan data yang dibaca dari memori flash, bersama dengan field untuk menyimpan posisi saat ini saat membaca dari buffer, alamat saat ini untuk membaca dari memori flash, dan perangkat memori flash.

  3. Di bagian private, tambahkan metode berikut:

    void populateBuffer()
    {
        sfud_read(_flash, _flash_address, HTTP_TCP_BUFFER_SIZE, _buffer);
        _flash_address += HTTP_TCP_BUFFER_SIZE;
        _pos = 0;
    }
    

    Kode ini membaca dari memori flash di alamat saat ini dan menyimpan data dalam buffer. Kemudian meningkatkan alamat, sehingga panggilan berikutnya membaca blok memori berikutnya. Buffer berukuran berdasarkan potongan terbesar yang akan dikirim oleh HTTPClient ke REST API dalam satu waktu.

    💁 Menghapus memori flash harus dilakukan menggunakan ukuran butir, sedangkan membaca tidak.

  4. Di bagian public dari kelas ini, tambahkan konstruktor:

    FlashStream()
    {
        _pos = 0;
        _flash_address = 0;
        _flash = sfud_get_device_table() + 0;
    
        populateBuffer();
    }
    

    Konstruktor ini mengatur semua field untuk mulai membaca dari awal blok memori flash, dan memuat potongan data pertama ke dalam buffer.

  5. Implementasikan metode write. Stream ini hanya akan membaca data, jadi metode ini tidak melakukan apa-apa dan mengembalikan 0:

    virtual size_t write(uint8_t val)
    {
        return 0;
    }
    
  6. Implementasikan metode peek. Metode ini mengembalikan data di posisi saat ini tanpa menggerakkan stream. Memanggil peek beberapa kali akan selalu mengembalikan data yang sama selama tidak ada data yang dibaca dari stream.

    virtual int peek()
    {
        return _buffer[_pos];
    }
    
  7. Implementasikan fungsi available. Fungsi ini mengembalikan berapa banyak byte yang dapat dibaca dari stream, atau -1 jika stream selesai. Untuk kelas ini, maksimum yang tersedia tidak akan lebih dari ukuran potongan HTTPClient. Saat stream ini digunakan dalam HTTP client, HTTP client memanggil fungsi ini untuk melihat berapa banyak data yang tersedia, lalu meminta data sebanyak itu untuk dikirim ke REST API. Kita tidak ingin setiap potongan lebih besar dari ukuran potongan HTTP client, jadi jika lebih dari itu tersedia, ukuran potongan dikembalikan. Jika kurang, maka yang tersedia dikembalikan. Setelah semua data telah di-streaming, -1 dikembalikan.

    virtual int available()
    {
        int remaining = BUFFER_SIZE - ((_flash_address - HTTP_TCP_BUFFER_SIZE) + _pos);
        int bytes_available = min(HTTP_TCP_BUFFER_SIZE, remaining);
    
        if (bytes_available == 0)
        {
            bytes_available = -1;
        }
    
        return bytes_available;
    }
    
  8. Implementasikan metode read untuk mengembalikan byte berikutnya dari buffer, meningkatkan posisi. Jika posisi melebihi ukuran buffer, buffer diisi dengan blok berikutnya dari memori flash dan posisi diatur ulang.

    virtual int read()
    {
        int retVal = _buffer[_pos++];
    
        if (_pos == HTTP_TCP_BUFFER_SIZE)
        {
            populateBuffer();
        }
    
        return retVal;
    }
    
  9. Di file header speech_to_text.h, tambahkan direktif include untuk file header baru ini:

    #include "flash_stream.h"
    

Tugas - mengubah ucapan menjadi teks

  1. Ucapan dapat diubah menjadi teks dengan mengirimkan audio ke Layanan Ucapan melalui REST API. REST API ini memiliki sertifikat yang berbeda dari penerbit token, jadi tambahkan kode berikut ke file header config.h untuk mendefinisikan sertifikat ini:

    const char *SPEECH_CERTIFICATE =
        "-----BEGIN CERTIFICATE-----\r\n"
        "MIIF8zCCBNugAwIBAgIQCq+mxcpjxFFB6jvh98dTFzANBgkqhkiG9w0BAQwFADBh\r\n"
        "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n"
        "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\r\n"
        "MjAeFw0yMDA3MjkxMjMwMDBaFw0yNDA2MjcyMzU5NTlaMFkxCzAJBgNVBAYTAlVT\r\n"
        "MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKjAoBgNVBAMTIU1pY3Jv\r\n"
        "c29mdCBBenVyZSBUTFMgSXNzdWluZyBDQSAwMTCCAiIwDQYJKoZIhvcNAQEBBQAD\r\n"
        "ggIPADCCAgoCggIBAMedcDrkXufP7pxVm1FHLDNA9IjwHaMoaY8arqqZ4Gff4xyr\r\n"
        "RygnavXL7g12MPAx8Q6Dd9hfBzrfWxkF0Br2wIvlvkzW01naNVSkHp+OS3hL3W6n\r\n"
        "l/jYvZnVeJXjtsKYcXIf/6WtspcF5awlQ9LZJcjwaH7KoZuK+THpXCMtzD8XNVdm\r\n"
        "GW/JI0C/7U/E7evXn9XDio8SYkGSM63aLO5BtLCv092+1d4GGBSQYolRq+7Pd1kR\r\n"
        "EkWBPm0ywZ2Vb8GIS5DLrjelEkBnKCyy3B0yQud9dpVsiUeE7F5sY8Me96WVxQcb\r\n"
        "OyYdEY/j/9UpDlOG+vA+YgOvBhkKEjiqygVpP8EZoMMijephzg43b5Qi9r5UrvYo\r\n"
        "o19oR/8pf4HJNDPF0/FJwFVMW8PmCBLGstin3NE1+NeWTkGt0TzpHjgKyfaDP2tO\r\n"
        "4bCk1G7pP2kDFT7SYfc8xbgCkFQ2UCEXsaH/f5YmpLn4YPiNFCeeIida7xnfTvc4\r\n"
        "7IxyVccHHq1FzGygOqemrxEETKh8hvDR6eBdrBwmCHVgZrnAqnn93JtGyPLi6+cj\r\n"
        "WGVGtMZHwzVvX1HvSFG771sskcEjJxiQNQDQRWHEh3NxvNb7kFlAXnVdRkkvhjpR\r\n"
        "GchFhTAzqmwltdWhWDEyCMKC2x/mSZvZtlZGY+g37Y72qHzidwtyW7rBetZJAgMB\r\n"
        "AAGjggGtMIIBqTAdBgNVHQ4EFgQUDyBd16FXlduSzyvQx8J3BM5ygHYwHwYDVR0j\r\n"
        "BBgwFoAUTiJUIBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1Ud\r\n"
        "JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMHYG\r\n"
        "CCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu\r\n"
        "Y29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln\r\n"
        "aUNlcnRHbG9iYWxSb290RzIuY3J0MHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9j\r\n"
        "cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RHMi5jcmwwN6A1oDOG\r\n"
        "MWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RHMi5j\r\n"
        "cmwwHQYDVR0gBBYwFDAIBgZngQwBAgEwCAYGZ4EMAQICMBAGCSsGAQQBgjcVAQQD\r\n"
        "AgEAMA0GCSqGSIb3DQEBDAUAA4IBAQAlFvNh7QgXVLAZSsNR2XRmIn9iS8OHFCBA\r\n"
        "WxKJoi8YYQafpMTkMqeuzoL3HWb1pYEipsDkhiMnrpfeYZEA7Lz7yqEEtfgHcEBs\r\n"
        "K9KcStQGGZRfmWU07hPXHnFz+5gTXqzCE2PBMlRgVUYJiA25mJPXfB00gDvGhtYa\r\n"
        "+mENwM9Bq1B9YYLyLjRtUz8cyGsdyTIG/bBM/Q9jcV8JGqMU/UjAdh1pFyTnnHEl\r\n"
        "Y59Npi7F87ZqYYJEHJM2LGD+le8VsHjgeWX2CJQko7klXvcizuZvUEDTjHaQcs2J\r\n"
        "+kPgfyMIOY1DMJ21NxOJ2xPRC/wAh/hzSBRVtoAnyuxtkZ4VjIOh\r\n"
        "-----END CERTIFICATE-----\r\n";
    
  2. Tambahkan konstanta ke file ini untuk URL ucapan tanpa lokasi. URL ini akan digabungkan dengan lokasi dan bahasa nanti untuk mendapatkan URL lengkap.

    const char *SPEECH_URL = "https://%s.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=%s";
    
  3. Di file header speech_to_text.h, di bagian private dari kelas SpeechToText, definisikan field untuk WiFi Client menggunakan sertifikat ucapan:

    WiFiClientSecure _speech_client;
    
  4. Di metode init, tetapkan sertifikat pada WiFi Client ini:

    _speech_client.setCACert(SPEECH_CERTIFICATE);
    
  5. Tambahkan kode berikut ke bagian public dari kelas SpeechToText untuk mendefinisikan metode untuk mengubah ucapan menjadi teks:

    String convertSpeechToText()
    {
    
    }
    
  6. Tambahkan kode berikut ke metode ini untuk membuat HTTP client menggunakan WiFi client yang dikonfigurasi dengan sertifikat ucapan, dan menggunakan URL ucapan yang diatur dengan lokasi dan bahasa:

    char url[128];
    sprintf(url, SPEECH_URL, SPEECH_LOCATION, LANGUAGE);
    
    HTTPClient httpClient;
    httpClient.begin(_speech_client, url);
    
  7. Beberapa header perlu diatur pada koneksi:

    httpClient.addHeader("Authorization", String("Bearer ") + _access_token);
    httpClient.addHeader("Content-Type", String("audio/wav; codecs=audio/pcm; samplerate=") + String(RATE));
    httpClient.addHeader("Accept", "application/json;text/xml");
    

    Header ini menetapkan otorisasi menggunakan token akses, format audio menggunakan sample rate, dan menetapkan bahwa klien mengharapkan hasil sebagai JSON.

  8. Setelah ini, tambahkan kode berikut untuk melakukan panggilan REST API:

    Serial.println("Sending speech...");
    
    FlashStream stream;
    int httpResponseCode = httpClient.sendRequest("POST", &stream, BUFFER_SIZE);
    
    Serial.println("Speech sent!");
    

    Ini membuat FlashStream dan menggunakannya untuk melakukan streaming data ke REST API.

  9. Di bawah ini, tambahkan kode berikut:

    String text = "";
    
    if (httpResponseCode == 200)
    {
        String result = httpClient.getString();
        Serial.println(result);
    
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, result.c_str());
    
        JsonObject obj = doc.as<JsonObject>();
        text = obj["DisplayText"].as<String>();
    }
    else if (httpResponseCode == 401)
    {
        Serial.println("Access token expired, trying again with a new token");
        _access_token = getAccessToken();
        return convertSpeechToText();
    }
    else
    {
        Serial.print("Failed to convert text to speech - error ");
        Serial.println(httpResponseCode);
    }
    

    Kode ini memeriksa kode respons.

    Jika kode respons adalah 200, kode untuk keberhasilan, maka hasilnya diambil, didekode dari JSON, dan properti DisplayText diatur ke variabel text. Properti ini adalah tempat teks versi ucapan dikembalikan.

    Jika kode respons adalah 401, maka token akses telah kedaluwarsa (token ini hanya bertahan 10 menit). Token akses baru diminta, dan panggilan dilakukan lagi.

    Jika tidak, kesalahan dikirim ke monitor serial, dan text dibiarkan kosong.

  10. Tambahkan kode berikut ke akhir metode ini untuk menutup HTTP client dan mengembalikan teks:

    httpClient.end();
    
    return text;
    
  11. Di main.cpp, panggil metode baru convertSpeechToText ini di fungsi processAudio, lalu log ucapan ke monitor serial:

    String text = speechToText.convertSpeechToText();
    Serial.println(text);
    
  12. Bangun kode ini, unggah ke Wio Terminal Anda, dan uji melalui monitor serial. Setelah Anda melihat Ready di monitor serial, tekan tombol C (yang ada di sisi kiri, paling dekat dengan sakelar daya), dan berbicaralah. Audio selama 4 detik akan ditangkap, lalu diubah menjadi teks.

    --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
    --- More details at http://bit.ly/pio-monitor-filters
    --- Miniterm on /dev/cu.usbmodem1101  9600,8,N,1 ---
    --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
    Connecting to WiFi..
    Connected!
    Got access token.
    Ready.
    Starting recording...
    Finished recording
    Sending speech...
    Speech sent!
    {"RecognitionStatus":"Success","DisplayText":"Set a 2 minute and 27 second timer.","Offset":4700000,"Duration":35300000}
    Set a 2 minute and 27 second timer.
    

💁 Anda dapat menemukan kode ini di folder code-speech-to-text/wio-terminal.

😀 Program ucapan ke teks Anda berhasil!


Penafian:
Dokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI Co-op Translator. Meskipun kami berusaha untuk memberikan hasil yang akurat, harap diingat bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang otoritatif. Untuk informasi yang bersifat kritis, disarankan menggunakan jasa penerjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.