Odczyt głosowy danych liczbowych z użyciem Google TTS jest dla języka polskiego sporym wyzwaniem, ponieważ TTS nie wie, w jakim przypadku deklinacji podać wynik. Nie jest to AI, więc z kontekstu zdania nic nie może wykminić.
Dotychczasowe komunikaty godzinowe brzmiały dla mnie lekko satyrycznie, więc napisałem funkcję, która podaje godzinę w dowolnie wybranym przypadku występującym w języku polskim. Dzielę się nią z Wami, bo może macie podobny problem z poziomem akceptacji poprawności językowej Google TTS.
Na wejściu funkcji wymagane są dwa parametry:
msg.datownik - //dowolny łańcuch w formacie daty, np. timestamp
msg.przypadek - //łańcuch tekstowy wskazujący wybrany przypadek deklinacji. Możliwe wartości tego łańcucha: mianownik, dopelniacz, celownik, biernik, narzednik, miejscownik.
Na wyjściu otrzymujemy tekst z datą i godziną odczytaną przez dowolny media_player
we wskazanym przypadku polskiej deklinacji.
Funkcja wygląda tak:
//# Dane WEJŚCIOWE #//
const teraz = new Date(msg.datownik);
const przypadek = msg.przypadek;
//# Tablice językowe #//
const dni_tygodnia_mianownik = ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"];
const dni_tygodnia_dopelniacz = ["niedzieli", "poniedziałku", "wtorku", "środy", "czwartku", "piątku", "soboty"];
const dni_tygodnia_celownik = ["niedzieli", "poniedziałkowi", "wtorkowi", "środzie", "czwartkowi", "piątkowi", "sobocie"];
const dni_tygodnia_biernik = ["niedzielę", "poniedziałek", "wtorek", "środę", "czwartek", "piątek", "sobotę"];
const dni_tygodnia_narzednik = ["niedzielą", "poniedziałkiem", "wtorkiem", "środą", "czwartkiem", "piątkiem", "sobotą"];
const dni_tygodnia_miejscownik = ["niedzieli", "poniedziałku", "wtorku", "środzie", "czwartku", "piątku", "sobocie"];
const miesiace = ["stycznia", "lutego", "marca", "kwietnia", "maja", "czerwca", "lipca",
"sierpnia", "września", "października", "listopada", "grudnia"];
const godziny_mianownik = ["zero", "pierwsza", "druga", "trzecia", "czwarta", "piąta",
"szósta", "siódma", "ósma", "dziewiąta", "dziesiąta", "jedenasta",
"dwunasta", "trzynasta", "czternasta", "piętnasta", "szesnasta",
"siedemnasta", "osiemnasta", "dziewiętnasta", "dwudziesta",
"dwudziesta pierwsza", "dwudziesta druga", "dwudziesta trzecia"];
const godziny_dopelniacz = ["zero", "pierwszej", "drugiej", "trzeciej", "czwartej", "piątej",
"szóstej", "siódmej", "ósmej", "dziewiątej", "dziesiątej", "jedenastej",
"dwunastej", "trzynastej", "czternastej", "piętnastej", "szesnastej",
"siedemnastej", "osiemnastej", "dziewiętnastej", "dwudziestej",
"dwudziestejpierwszej", "dwudziestejdrugiej", "dwudziestejtrzeciej"];
const godziny_celownik = ["zero", "pierwszej", "drugiej", "trzeciej", "czwartej", "piątej",
"szóstej", "siódmej", "ósmej", "dziewiątej", "dziesiątej", "jedenastej",
"dwunastej", "trzynastej", "czternastej", "piętnastej", "szesnastej",
"siedemnastej", "osiemnastej", "dziewiętnastej", "dwudziestej",
"dwudziestejpierwszej", "dwudziestejdrugiej", "dwudziestejtrzeciej"];
const godziny_biernik = ["zero", "pierwszą", "drugą", "trzecią", "czwartą", "piątą",
"szóstą", "siódmą", "ósmą", "dziewiątą", "dziesiątą", "jedenastą",
"dwunastą", "trzynastą", "czternastą", "piętnastą", "szesnastą",
"siedemnastą", "osiemnastą", "dziewiętnastą", "dwudziestą",
"dwudziestąpierwszą", "dwudziestądrugią", "dwudziestątrzecią"];
const godziny_narzednik = ["zero", "pierwszą", "drugą", "trzecią", "czwartą", "piątą",
"szóstą", "siódmą", "ósmą", "dziewiątą", "dziesiątą", "jedenastą",
"dwunastą", "trzynastą", "czternastą", "piętnastą", "szesnastą",
"siedemnastą", "osiemnastą", "dziewiętnastą", "dwudziestą",
"dwudziestąpierwszą", "dwudziestądrugią", "dwudziestątrzecią"];
const godziny_miejscownik = ["zero", "pierwszej", "drugiej", "trzeciej", "czwartej", "piątej",
"szóstej", "siódmej", "ósmej", "dziewiątej", "dziesiątej", "jedenastej",
"dwunastej", "trzynastej", "czternastej", "piętnastej", "szesnastej",
"siedemnastej", "osiemnastej", "dziewiętnastej", "dwudziestej",
"dwudziestejpierwszej", "dwudziestejdrugiej", "dwudziestejtrzeciej"];
const dzien_slowo = ["zerowy", "pierwszy", "drugi", "trzeci", "czwarty", "piąty", "szósty",
"siódmy", "ósmy", "dziewiąty", "dziesiąty", "jedynasty",
"dwunasty", "trzynasty", "czternasty", "piętnasty", "szesnasty",
"siedemnasty", "osiemnasty", "dziewiętnasty", "dwudziesty",
"dwudziestypierwszy", "dwudziestydrugi", "dwudziestytrzeci",
"dwudziestyczwarty", "dwudziestypiąty", "dwudziestyszósty",
"dwudziestysiódmy", "dwudziestyósmy", "dwudziestydziewiąty",
"trzydziesty", "trzydziestypierwszy"];
switch (przypadek)
{
case 'mianownik':
akt_godzina = `${godziny_mianownik[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_mianownik[teraz.getDay()]}`;
break;
case 'dopelniacz':
akt_godzina = `${godziny_dopelniacz[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_dopelniacz[teraz.getDay()]}`;
break;
case 'celownik':
akt_godzina = `${godziny_celownik[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_celownik[teraz.getDay()]}`;
break;
case 'biernik':
akt_godzina = `${godziny_biernik[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_biernik[teraz.getDay()]}`;
break;
case 'narzednik':
akt_godzina = `${godziny_narzednik[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_narzednik[teraz.getDay()]}`;
break;
case 'miejscownik':
akt_godzina = `${godziny_miejscownik[teraz.getHours()]}`;
dzien_tygodnia = `${dni_tygodnia_miejscownik[teraz.getDay()]}`;
break;
default:
break;
}
//# Dane WYJŚCIOWE #//
msg.dzien_tygodnia = dzien_tygodnia;
msg.dzien_miesiaca = `${dzien_slowo[teraz.getDate()]}`;
msg.miesiac = `${miesiace[teraz.getMonth()]}`;
msg.rok = teraz.getFullYear();
msg.godzina = akt_godzina;
msg.minuta = teraz.getMinutes();
return msg;
Użyta tu instrukcja warunkowa switch
wybiera ze zmiennych tablicowych właściwie odmienione słowo dla wskazanej w msg.datownik
godziny, w przypadku deklinacji wskazanym w msg.przypadek
.
Odmianie nie podlega dzień
i nazwa miesiąca
oraz rok
i minuty
, ponieważ wartości te odczytywane są przez Google TTS poprawnie.
Mozna teraz budować dowolne sekwencje zdaniowe z użyciem czasu i daty w wybranym przypadku deklinacji, jaki chcemy użyć.
Przykład zastosowania:
Nod Zegar słownie
, zawierający powyższą funkcję zamienia wartość zmiennej typu timestamp
czasu zakończenia pracy zmywarki na tekst, który następnie doklejany jest do zdania powstającego w następnym nodzie (koniec zadania
) i co godzinę taki komunikat idzie na stojący w kuchni media_player
.
Czyż nie fajne i praktyczne rozwiązanie?
W niektórych momentach odczytywanych przez TTS łańcuchów tekstowych przydałyby się dodatkowe 1- lub 2-sekundowe pauzy, żeby mówiony tekst brzmiał bardziej “po ludzku”. Ale nie wiem, czy istnieją jakieś specjalne znaki “nieme”, które - umieszczone w łańcuchu dałyby pożądany efekt. Może ktoś z Was wie coś na ten temat?