# വാചകം മുതൽ എഴുത്തു വരെ - Wio Terminal പാഠത്തിന്റെ ഈ ഭാഗത്ത്, ന capturedെടുത്തു കൊണ്ടിരിക്കുന്ന ഓഡിയോയുടെ ഭാഷയെ എഴുത്താക്കി മാറ്റാൻ നിങ്ങൾക്ക് കോഡ് എഴുതി വരുത്താം. ## ഓഡിയോ ഭാഷാ സേവനത്തിലേക്ക് അയയ്‌ക്കുക ഓഡിയോ REST API ഉപയോഗിച്ച് ഭാഷാ സേവനത്തിലേക്ക് അയയ്‌ക്കാവുന്നതാണ്. ഭാഷാ സേവനം ഉപയോഗിക്കാൻ, ആദ്യം നിങ്ങൾക്ക് ഒരു ആക്സസ് ടോക്കൺ അഭ്യർത്ഥിക്കേണ്ടതുണ്ട്, പിന്നീട് ആ ടോക്കൺ REST API-യിലേക്ക് പ്രവേശിക്കാൻ ഉപയോഗിക്കണം. ഈ ആക്സസ് ടോക്കണുകൾ 10 മിനിറ്റിനുള്ളിൽ കാലഹരണപ്പെടും, അതിനാൽ സെൻസാസിസ് ടോക്കണുകൾ നാളമടങ്ങെ അഭ്യർത്ഥിക്കേണ്ടതാണ് എപ്പോഴും അപ്‌ഡേറ്റ് ആയിരിക്കുമെന്ന് ഉറപ്പാക്കാൻ. ### പ്രവൃത്തി - ആക്സസ് ടോക്കൺ ലഭിക്കുക 1. `smart-timer` പ്രോജക്ട് ഇതിനകം തുറന്നിട്ടില്ലെങ്കിൽ തുറക്കുക. 1. WiFi ആക്സസ് ചെയ്യാനും JSON കൈകാര്യംചെയ്യാനും `platformio.ini` ഫയലിൽ താഴെയുള്ള ലൈബ്രറി ആശ്രിതങ്ങൾ ചേർക്കുക: ```ini 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 ``` 1. `config.h` ഹെഡർ ഫയലിൽ താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp const char *SSID = ""; const char *PASSWORD = ""; const char *SPEECH_API_KEY = ""; const char *SPEECH_LOCATION = ""; const char *LANGUAGE = ""; const char *TOKEN_URL = "https://%s.api.cognitive.microsoft.com/sts/v1.0/issuetoken"; ``` ``യും ``യും നിങ്ങളുടെ WiFi-യുടെ അനുയോജ്യമായ മൂല്യങ്ങളാൽ മാറ്റി സ്ഥാപിക്കുക. `` നിങ്ങളുടെ ഭാഷാ സേവന റിസോഴ്സിന്റെ API കീ ആണ്. `` നിങ്ങളുടെ ഭാഷാ സേവന റിസോഴ്സ് സൃഷ്ടിക്കുമ്പോൾ ഉപയോഗിച്ച സ്ഥലത്തിൻറെ പേര് ഉപയോഗിക്കുക. നിങ്ങൾ സംസാരിക്കുന്ന ഭാഷയ്ക്ക് അനുയോജ്യമായ പ്രാദേശിക നാമം `` എന്നതിൽ സജ്ജമാക്കുക. ഉദാഹരണത്തിന്, ഇംഗ്ലീഷ് ആയതിനായി `en-GB`, കാൻറോനീസ് ഭാഷക്ക് `zn-HK`. പിന്തുണയുള്ള ഭാഷകളുടെയും പ്രാദേശിക നാമങ്ങളുടെയും പട്ടികക്ക് [Language and voice support documentation on Microsoft docs](https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support?WT.mc_id=academic-17441-jabenn#speech-to-text) സന്ദർശിക്കുക. `TOKEN_URL` എന്ന സ്ഥിരം മൂല്യം ടോക്കൺ നൽകുന്ന സൈറ്റിന്റെ URL ആണ്, സ്ഥലത്തിന്റെ പേരില്ലാതെ. അതിന് ശേഷമുള്ള സന്ദേശത്തിൽ സ്ഥലം ചേർത്ത് പൂർണ്ണ URL തയ്യാറാക്കും. 1. Custom Vision-നുമാണ് പോലെ, ടോക്കൺ നൽകുന്ന സേവനവുമായി HTTPS ബന്ധം കൊണ്ടു ചേരേണ്ടതുണ്ട്. `config.h`യുടെ അവസാനം താഴെ കൊടുത്തിരിക്കുന്നത് ചേർക്കുക: ```cpp 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"; ``` ഇത് Custom Vision ഉപയോ​ഗിക്കുമ്പോഴേ ಬಳಸിയ സർട്ടിഫിക്കേറ്റാണ്. 1. `main.cpp` ഫയലിന്റെ മുകളിൽ WiFi ഹെഡർ ഫയലിനും config ഹെഡർ ഫയലിനും ഇൻക്ലൂഡ് ആയി ചേർക്കുക: ```cpp #include #include "config.h" ``` 1. `main.cpp`ലെ `setup` ഫംഗ്ഷന്റെ മുകളിൽ WiFi-യിലേക്ക് കണക്റ്റ് ചെയ്യാനുള്ള കോഡ് ചേർക്കുക: ```cpp void connectWiFi() { while (WiFi.status() != WL_CONNECTED) { Serial.println("Connecting to WiFi.."); WiFi.begin(SSID, PASSWORD); delay(500); } Serial.println("Connected!"); } ``` 1. സീരിയൽ ബന്ധം ആരംഭിച്ചതിനു ശേഷം `setup` ഫംഗ്ഷനിൽ ഈ ഫംഗ്ഷൻ വിളിക്കുക: ```cpp connectWiFi(); ``` 1. `src` ഫോൾഡറിൽ `speech_to_text.h` എന്ന പുതിയ ഹെഡർ ഫയൽ സൃഷ്ടിച്ച് ഇതിൽ താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp #pragma once #include #include #include #include #include "config.h" #include "mic.h" class SpeechToText { public: private: }; SpeechToText speechToText; ``` HTTP കണക്ഷനും കോൺഫിഗറേഷനും `mic.h` ഹെഡർ ഫയലും ഉൾപ്പെടുത്തി, `SpeechToText` എന്ന ക്ലാസ് നിർവചിക്കുകയും പിന്നീട് ഈ ക്ലാസിന്റെ ഒരു ഇൻസ്റ്റൻസ് പ്രഖ്യാപിക്കുകയും ചെയ്യുന്നു. 1. ഈ ക്ലാസിന്റെ `private` സെക്ഷനിൽ താഴെ കൊടുത്തിരിക്കുന്ന 2 ഫീൽഡുകൾ ചേർക്കുക: ```cpp WiFiClientSecure _token_client; String _access_token; ``` `_token_client` HTTPS ഉപയോഗിക്കുന്ന WiFi ക്ലയന്റാണ്, ആക്സസ് ടോക്കൺ ലഭിക്കാൻ ഉപയോ​ഗിക്കും. പിന്നീട് ആ ടോക്കൺ `_access_token` ലെ സസ്യപ്പെടുത്തിയിരിക്കും. 1. `private` സെക്ഷനിൽ താഴെ കൊടുത്തിരിക്കുന്ന മെത്തഡ് ചേർക്കുക: ```cpp 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; } ``` ഭാഷാ റിസോഴ്‌സ് സ്ഥലം ഉപയോഗിച്ച് ടോക്കൺ ഇഷ്യൂസ് ചെയ്യുന്ന API URL നിർമ്മിക്കുന്നു. പിന്നീട് `HTTPClient` സൃഷ്ടിച്ച് വെബ് അഭ്യർത്ഥന ചെയ്യുന്നു, ടോക്കൺ എൻഡ്‌പോയിന്റിന്റെ സർട്ടിഫിക്കറ്റ് സജ്ജീകരിച്ച WiFi ക്ലയന്റ് ഉപയോഗിച്ച്. API കീ ഹേഡർ ആയി പണിയുന്നു. പോസ്റ്റ് അഭ്യർത്ഥന കഴിഞ്ഞ് സർട്ടിഫിക്കേറ്റ് ലഭിക്കുന്നതുവരെ ആവർത്തിക്കുന്നു. അവസാനം ആക്സസ് ടോക്കൺ റിട്ടേൺ ചെയ്യുന്നു. 1. `public` സെക്ഷനിൽ ആക്സസ് ടോക്കൺ ലഭിക്കുന്ന ഒരു മെथഡ് ചേർക്കുക. പിന്‍തുടരുന്ന പാഠങ്ങളിൽ വാചകം മുതൽ ഭാഷയിലേക്ക് മാറ്റാനായാൽ ഇത് ആവശ്യമാണ്. ```cpp String AccessToken() { return _access_token; } ``` 1. `public` സെക്ഷനിൽ ടോക്കൺ ക്ലയന്റ് സജ്ജമാക്കുന്ന `init` മെത്തഡ് ചേർക്കുക: ```cpp void init() { _token_client.setCACert(TOKEN_CERTIFICATE); _access_token = getAccessToken(); } ``` WiFi ക്ലയന്റിൽ സർട്ടിഫിക്കറ്റ് സെറ്റ് ചെയ്‌ത ശേഷം ആക്സസ് ടോക്കൺ ലഭിക്കുന്നു. 1. `main.cpp`-ൽ പുതിയ ഹെഡർ ഫയൽ ഇൻക്ലൂഡ് നിർദേശങ്ങളിൽ ചേർക്കുക: ```cpp #include "speech_to_text.h" ``` 1. `setup` ഫംഗ്ഷന്റെ അവസാനം, `mic.init` കോൾ കഴിഞ്ഞു, സീരിയൽ മോനിറ്ററിൽ Ready എഴുതുന്നതിനു മുമ്പ് `SpeechToText` ക്ലാസ് ഇൻസ്റ്റൻസ് ആരംഭിക്കുക: ```cpp speechToText.init(); ``` ### പ്രവൃത്തി - ഓഡിയോ ഫ്ലാഷ് മെമ്മറിയിൽ നിന്ന് വായിക്കുക 1. മുകളിൽ പാഠത്തിലുണ്ടായപ്പോൾ, ഓഡിയോ ഫ്ലാഷ് മെമ്മറിയിലേക്ക് റെക്കോർഡ് ചെയ്തത്. ഈ ഓഡിയോ Speech Services REST API-യിലേക്ക് അയയ്ക്കേണ്ടതാണ്, അതിനാൽ ഫ്ലാഷ് മെമ്മറിയിൽ നിന്ന് വായിക്കേണ്ടതുണ്ട്. ഓഡിയോ ഒരു ഇൻ-മെമ്മറി ബഫറിൽ ലോഡ് ചെയ്യാൻ പറ്റില്ല കാരണം troppo വലുതായിരിക്കും. REST കോൾ ചെയ്യാൻ ഉപയോഗിക്കുന്ന `HTTPClient` ക്ലാസ് Arduino Stream ഉപയോഗിച്ച് ഡേറ്റ സ്റ്റ്രീമായായി അയയ്‌ക്കാം - ചെറിയChunkകളിൽ ഡേറ്റ വായിച്ച് ഓരോ തവണയും അയയ്ക്കുന്നു. ഓരോ തവണയും `read` വിളിക്കുന്നത് അടുത്ത ഡേറ്റാബ്ലോക്ക് തിരികെ നല്കും. Flash memory-യിൽ നിന്ന് ഡേറ്റ വായിക്കാൻ കഴിയുന്ന Arduino Stream സൃഷ്ടിക്കാം. `src` ഫോൾഡറിൽ `flash_stream.h` എന്ന പുതിയ ഫയൽ സൃഷ്ടിച്ച് താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp #pragma once #include #include #include #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: }; ``` Arduino `Stream` ക്ലാസിൽ നിന്നുണ്ടാകുന്ന FlashStream ക്ലാസ് പ്രഖ്യാപിക്കുന്നു. ഇത് ഒരു അബ്സ്ട്രാക്റ്റ് ക്ലാസ് ആണ് - ഉദാഹരണത്തിനായി ക്ലാസ് ഇൻസ്റ്റൻസ് സൃഷ്ടിക്കാനുമുമ്പ് ചില മെഥഡുകൾ നിർവഹിക്കേണ്ടതാണ്, അവ ഈ ക്ലാസിൽ നിർവചിച്ചിരിക്കുന്നു. ✅ Arduino Streams-ഇൽ പുതിയത് പഠിക്കാൻ [Arduino Stream documentation](https://www.arduino.cc/reference/en/language/functions/communication/stream/) സന്ദർശിക്കുക 1. `private` സെക്ഷനിൽ താഴെ കൊടുത്തിരിക്കുന്ന ഫീൽഡുകൾ ചേർക്കുക: ```cpp size_t _pos; size_t _flash_address; const sfud_flash *_flash; byte _buffer[HTTP_TCP_BUFFER_SIZE]; ``` Flash memory-യിൽ നിന്ന് വായിച്ച ഡേറ്റ സ്റ്റോർ ചെയ്യുന്നതിന് താൽക്കാലിക ബഫർ നിർവചിക്കുന്നു, അടക്കവെ പ്രത്യക്ഷപ്പെടുന്ന സ്ഥാനം, ഫ്ലാഷ് മെമ്മറിയിൽ നിലവിലെ തിരയാനുള്ള വിലാസം, മെമ്മറി ഉപകരണം എന്നിവയ്ക്കുള്ള ഫീൽഡുകളുമുണ്ട്. 1. `private` സെക്ഷനിൽ താഴെ കൊടുത്തിരിക്കുന്ന മെത്തഡ് ചേർക്കുക: ```cpp void populateBuffer() { sfud_read(_flash, _flash_address, HTTP_TCP_BUFFER_SIZE, _buffer); _flash_address += HTTP_TCP_BUFFER_SIZE; _pos = 0; } ``` നിലവിലെ വിലാസത്തിൽ നിന്ന് ഫ്ലാഷ് മെമ്മറിയിൽ നിന്ന് ഡേറ്റ വായിച്ച് ബഫറിലേയ്ക്ക് സേവ് ചെയ്യുന്നു. പിന്നീട് വിലാസം കൂട്ടി അടുത്ത കോളിൽ നിന്നും ഡേറ്റ വായിക്കാൻ കഴിഞ്ഞു ചെയ്യും. ബഫറിന്റെ വലിപ്പം HTTPClient REST API-യ്ക്ക് അയക്കാവുന്ന ഏറ്റവും വലിയ ചങ്കിന്റെ വലിപ്പത്തെ ആശ്രയിച്ചിരിക്കുന്നു. > 💁 ഫ്ലാഷ് മെമ്മറി ഇല്ലാതാക്കൽ (erase) ഗ്രെയിൻ വലുപ്പത്തിൽ നിർവഹിക്കേണ്ടതാണ്, വായിക്കൽ അതിനല്ല. 1. ഈ ക്ലാസിന്റെ `public` സെക്ഷനിൽ താഴെ കൊടുത്തിരിക്കുന്ന കോൺസ്ട്രക്ടർ ചേർക്കുക: ```cpp FlashStream() { _pos = 0; _flash_address = 0; _flash = sfud_get_device_table() + 0; populateBuffer(); } ``` ഫ്ലാഷ് മെമ്മറി ബ്ലോക്കിന്റെ ആരംഭത്തിൽ നിന്നും വായന തുടങ്ങാൻ എല്ലാ ഫീൽഡുകളും സജ്ജീകരിക്കുന്നു, ആദ്യബ്ലോക്കിൽ നിന്നും ഡേറ്റ ബഫറിലേയ്ക്ക് ലോഡ് ചെയ്യുന്നു. 1. `write` മെഥഡ് നടപ്പിലാക്കുക. ഈ സ്റ്റ്രീം ഡേറ്റ വായിക്കാൻ മാത്രം ഉപയോഗിക്കുന്നതിനാൽ ഈ മെഥഡ് ഒന്നും ചെയ്യാതെ 0 തിരികെ നൽകാം: ```cpp virtual size_t write(uint8_t val) { return 0; } ``` 1. `peek` മെഥഡ് നടപ്പിലാക്കുക. നിലവിലെ პოზിഷനിൽ ഉള്ള ഡേറ്റ തിരികെ നൽകുന്നു, സ്റ്റ്രീം മുന്നോട്ട് നീങ്ങാതെ. പല പ്രാവശ്യം `peek` വിളിക്കുമ്പോഴും ഒരേ ഡേറ്റ പാരാമറ്റർ തിരികെ ലഭിക്കും, സ്റ്റ്രീമിൽ നിന്നും ഡേറ്റ വായിച്ചിട്ടില്ലെങ്കിൽ. ```cpp virtual int peek() { return _buffer[_pos]; } ``` 1. `available` ഫംഗ്ഷൻ നിർവചിക്കുക. സ്റ്റ്രീത്തിൽ നിന്ന് എത്ര ബൈറ്റുകൾക്ക് വായിക്കാമെന്ന് നൽകും, അല്ലെങ്കിൽ -1 സ്റ്റ്രീം പൂര്‍ത്തിയായെന്ന് സൂചിപ്പിക്കും. HTTPClient-ന്റെ ചുങ്ക് വലുപ്പത്തിന് മുകളില്‍ ഇത് രക്ഷിക്കാനാകില്ല. സ്റ്റ്രീം REST API കാൾ ചെയ്യുമ്പോൾ, ലഭ്യമായ ഡേറ്റയുടെ അളവ് പരിശോധിക്കുക, പിന്നീട് അതിനനുസരിച്ച് ഡേറ്റ അയയ്ക്കും. REST API-യിലേക്ക് അയക്കപ്പെടുന്ന Chunk HTTPClient-ന്റെ ചുങ്ക് വലുപ്പത്തിൽ കൂടുതലാകരുത്. അതിനാൽ, കൂടുതലുള്ളപ്പോൾ HTTP Client Chunk സൈസ് തിരികെ നൽകിക്കൊടുക്കും; കുറവാണെങ്കിൽ ലഭ്യമായ അളവ് തിരികെ നൽകും. എല്ലാ ഡേറ്റയും ഒടുക്കം വായിച്ചശേഷം -1 തിരികെ നൽകും. ```cpp 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; } ``` 1. `read` മെത്തഡ് നടപ്പിലാക്കുക. ബഫറിൽ നിന്നുള്ള അടുത്ത ബൈറ്റ് തിരികെ നൽകുന്നു, സ്ഥാനം കൂട്ടുന്നു. സ്ഥാനം ബഫർ വലുപ്പം കവിയുമ്പോൾ, ഫ്ലാഷ് മെമ്മറിയിൽ നിന്നുള്ള അടുത്ത ബ്ലോക്കിൽനിന്നും ബഫർ പൂരിപ്പിച്ച് സ്ഥാനം പുനഃക്രമീകരിക്കുന്നു. ```cpp virtual int read() { int retVal = _buffer[_pos++]; if (_pos == HTTP_TCP_BUFFER_SIZE) { populateBuffer(); } return retVal; } ``` 1. `speech_to_text.h` ഹെഡർ ഫയലിൽ, ഈ പുതിയ ഹെഡർ ഫയലിന് ഇൻക്ലൂഡ് നിർദേശം ചേർക്കുക: ```cpp #include "flash_stream.h" ``` ### പ്രവൃത്തി - വാചകത്തെ എഴുത്തിലേക്ക് മാറ്റുക 1. വാചകം ടെക്സ്റ്റിലേക്ക് REST API വഴി Speech Service-നു അയച്ച് പരിവർത്തനം ചെയ്യാം. ഈ REST API-യുടെ സർട്ടിഫിക്കറ്റ് ടോക്കൺ നൽകുന്ന സർവീസിൽ നിന്നു വ്യത്യസ്തമാണ്, അതിനാൽ `config.h` ഹെഡറിലേക്ക് താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp 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"; ``` 1. ഈ ഫയലിലേക്ക്, സ്ഥലത്തിൻറെ പേര് ഇല്ലാതെ ഭാഷ സർവീസിന്റെ URL സജ്ജമാക്കുക. പിന്നീട് സ്ഥലം, ഭാഷ എന്നിവ ചേർത്ത് പൂർണ്ണ URL തയ്യാറാക്കും. ```cpp const char *SPEECH_URL = "https://%s.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=%s"; ``` 1. `SpeechToText` ക്ലാസിന്റെ `private` സെക്ഷനിൽ, സ്പീച്ച് സർട്ടിഫിക്കറ്റ് ഉപയോഗിച്ച് WiFi ക്ലയന്റ് ഫീൽഡ് നിർവചിക്കുക: ```cpp WiFiClientSecure _speech_client; ``` 1. `init` മെത്തഡിൽ ഈ WiFi ക്ലയന്റിൽ സർട്ടിഫിക്കറ്റ് സെറ്റ് ചെയ്യുക: ```cpp _speech_client.setCACert(SPEECH_CERTIFICATE); ``` 1. `SpeechToText` ക്ലാസിന്റെ `public` സെക്ഷനിൽ വാചകം മുതൽ എഴുത്തിലേക്ക് മാറ്റാനുള്ള മെത്തഡ് നിർവചിക്കുക: ```cpp String convertSpeechToText() { } ``` 1. ഈ മെത്തഡിൽ, സ്പീച്ച് സർട്ടിഫിക്കറ്റ് ഉപയോഗിച്ച് WiFi ക്ലയന്റ് കോൺഫിഗർ ചെയ്ത് സ്പീച്ച് URL-ഉം ഉപയോഗിച്ച് HTTPClient സൃഷ്ടിക്കുന്നതിന് താഴെ കാണുന്ന കോഡ് ചേർക്കുക: ```cpp char url[128]; sprintf(url, SPEECH_URL, SPEECH_LOCATION, LANGUAGE); HTTPClient httpClient; httpClient.begin(_speech_client, url); ``` 1. കണക്ഷനിൽ ചില ഹെഡറുകൾ സെറ്റ് ചെയ്യണം: ```cpp 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"); ``` ആക്സസ് ടോക്കൺ ഉപയോഗിച്ച് അധികാരത്തിന്, സാമ്പിൾ നിരക്ക് ഉപയോഗിച്ച് ഓഡിയോ ഫോർമാറ്റിനും, ഫലത്തെ JSON ആകൃത്തിൽ പ്രതീക്ഷിക്കുന്നതായി സെറ്റ് ചെയ്യുന്നു. 1. തുടർന്ന് REST API കാൾ നടത്താൻ താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp Serial.println("Sending speech..."); FlashStream stream; int httpResponseCode = httpClient.sendRequest("POST", &stream, BUFFER_SIZE); Serial.println("Speech sent!"); ``` `FlashStream` സൃഷ്ടിച്ച് അത് REST API-യിലേക്ക് ഡേറ്റ സ്റ്റ്രീം ചെയ്യാൻ ഉപയോഗിക്കുന്നു. 1. അതിനു താഴെ, താഴെ കാണുന്ന കോഡ് ചേർക്കുക: ```cpp String text = ""; if (httpResponseCode == 200) { String result = httpClient.getString(); Serial.println(result); DynamicJsonDocument doc(1024); deserializeJson(doc, result.c_str()); JsonObject obj = doc.as(); text = obj["DisplayText"].as(); } 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); } ``` ഇത് പ്രതികരണ കോഡ് പരിശോധിക്കുന്നു. 200 ആയാൽ വിജയത്തിന്റെ കോഡ് ആണെങ്കിൽ ഫലം JSON ആയി ഡികോഡ് ചെയ്തു, `DisplayText` പ്രോപ്പർട്ടി `text` വേരിയബിളിലേക്ക് സജ്ജമാക്കുന്നു. ഇത് വാചകത്തിൻറെ ടെക്സ്റ്റ് നേടുന്ന പ്രോപ്പർട്ടിയാണ്. 401 ആയാൽ ആക്സസ് ടോക്കൺ കാലഹരണപ്പെട്ടതാണ് (ഈ ടോക്കണുകൾ 10 മിനിറ്റ് മാത്രമേ നിലവിലുണ്ടാകൂ). പുതിയ ആക്സസ് ടോക്കൺ അഭ്യർത്ഥിച്ച് വീണ്ടും കോൾ ചെയ്യുന്നു. അല്ലാതെ സീരിയൽ മോനിറ്ററിലേക്ക് പിഴവ് അയയ്ക്കുകയും `text` ശൂന്യമായി മുന്നോട്ട് വെക്കുകയും ചെയ്യും. 1. HTTP Client അടയ്ക്കുകയും ടെക്സ്റ്റ് തിരികെ നൽകുകയും ചെയ്യാൻ ഈ മെത്തഡിന്റെ അവസാനം താഴെ കൊടുത്തിരിക്കുന്ന കോഡ് ചേർക്കുക: ```cpp httpClient.end(); return text; ``` 1. `main.cpp`-ൽ `processAudio` ഫംഗ്ഷനിൽ ഈ പുതിയ `convertSpeechToText` മെത്തഡ് വിളിച്ച്, സ്റ്റ്രീം മോനിറ്ററിലേക്ക് വാചകം പ്രിന്റ് ചെയ്യുക: ```cpp String text = speechToText.convertSpeechToText(); Serial.println(text); ``` 1. കോഡ് കമ്പൈൽ ചെയ്ത് Wio Terminal-ലേക്ക് അപ്‌ലോഡ് ചെയ്ത് ടെസ്റ്റ് ചെയ്യുക. സീരിയൽ മോനിറ്ററിൽ `Ready` കാണുമ്പോൾ, C ബട്ടൺ (വലത് കൈയിലുള്ള, പവർ സ്വിച്ച് അടുത്തുള്ള) അമർത്തി സംസാരിക്കുക. 4 സെക്കൻഡ് ഓഡിയോ പകർത്തി, തുടർന്ന് ടെക്സ്റ്റായി മാറ്റും. ```output --- 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. ``` > 💁 ഈ കോഡ് [code-speech-to-text/wio-terminal](../../../../../6-consumer/lessons/1-speech-recognition/code-speech-to-text/wio-terminal) ഫോൾഡറിൽ ലഭ്യമാണ്. 😀 നിങ്ങളുടെ വാചകത്തെ ടെക്സ്റ്റിലേക്ക് പരിവർത്തനം വിജയകരമായി പൂർത്തിയായി! --- **അസാധുവാക്കൽ**: ഈ രേഖ AI വിവർത്തന സേവനം [Co-op Translator](https://github.com/Azure/co-op-translator) ഉപയോഗിച്ച് വിവർത്തനം ചെയ്തതാണ്. നമുക്ക് കൃത്യത ഉറപ്പാക്കാൻ ശ്രമിച്ചിട്ടും, യന്ത്രം നിർവഹിച്ചു തർജ്ജമയിൽ പിശകുകളോ തെറ്റുകളോ ഉണ്ടാകാനുള്ള സാധ്യതയുണ്ട്. പ്രാഥമിക ഭാഷയിൽ ഉള്ള 원രേഖയാണ് കൃത്യമായ ഉറവിടം ആയി കരുതേണ്ടത്. സുപ്രധാന വിവരങ്ങൾക്ക്, പ്രൊഫഷണൽ മനുഷ്യ വിവർത്തനം ശുപാർശ ചെയ്യപ്പെടുന്നു. ഈ തർജ്ജമയുടെ ഉപയോഗത്തിൽ നിന്നുയർന്നിടുന്ന ഏതൊരു തെറ്റിദ്ധാരണയ്ക്കും ഞങ്ങൾ ഉത്തരവാദിത്തം വഹിക്കുകയില്ല.