Przeszukaj forum
Pokazywanie wyników dla tagów 'TTS'.
Znaleziono 5 wyników
-
Miałem opisać zupełnie inne urządzenie - cóż, w ostatniej chwili postanowiłem coś poprawić i wyskoczyło parę niedogodności. Ponieważ w międzyczasie udało mi się dokończyć mój odtwarzacz do książek - więc pozwolę sobie go przedstawić: oto Lekton. Dla tych którzy pamiętają poprzedną wersję: zrezygnowałem z określenia "czytak" z uwagi na istnienie komercyjnego produktu o tej nazwie, z którym nie mam zamiaru konkurować. Niech więc będzie (jak przystało na maniaka SF) Lekton... Zacząłem od przeanalizowania zalet i wad poprzedniego urządzenia (które zresztą uległo awarii, co prawda dość szybko usuniętej ale jednak). Na pierwszy rzut poszła konstrukcja. Niewątpliwie układ klawiatury był trafieniem w dziesiątkę: tylko dziewięć klawiszy, łatwych do odróżnienia bezwzrokowo, obsługujących najpotrzebniejsze funkcje... No i z zalet to tak praktycznie wszystko. Matrycowe podłączenie klawiatury praktycznie eliminowało możliwość odczytania więcej niż jednego klawisza jednocześnie. W dodatku stanowiąca całość z resztą obudowy klawiatura do jakiegokolwiek serwisowania wymagała rozebrania praktycznie całego urządzenia (a to mi się zdarzyło, bo wskutek upadku urwał mi się jeden z przewodów). Dalej: co prawda udało mi się zmieścić urządzenie w zakładanym rozmiarze paczki papierosów, ale okazało się to nieco bez sensu. Wewnątrz panował straszliwy ścisk, złożenie całości wymagało jakiejś potwornej ekwilibrystyki, rozmiar implikował niewygodne rozmieszczenie poszczególnych modułów których zresztą było za dużo. W dodatku użyty moduł WROVER co prawda miał wystarczającą ilość pamięci (16 MB flash, 8 MB PSRAM z czego praktycznie 4 MB do bezpośredniego użytku) ale konwerter UART/USB już się nie zmieścił i trzeba było użyć dedykowanego zewnętrznego konwertera. Poza tym stwierdziłem, że głośnik jest tu absolutnie niepotrzebny. Mogłem zamienić moduł MAX98357 na PCM5702A, w efekcie otrzymując możliwość zarówno odtwarzania w stereo (o tym potem), jak i podłączenia przycisku w słuchawkach (czego mi w poprzedniej wersji brakowało). Zahaczając nieco o program: Przede wszystkim założenie o trzymaniu wszystkiego w wewnętrznej pamięci flash modułu ESP32 wydawało się dobrym pomysłem - okazało się jednak, że miejsca nawet po kompresji jest trochę za mało. Co prawda teoretycznie obsługa przez interfejs WWW nie wymagała jakichś specjalnych dedykowanych aplikacji - jednak samo przygotowanie książki jej wymaga, co czyni ów pomysł niespecjalnie trafnym. Dlatego postanowiłem wrócić do pierwotnej koncepcji karty microSD. Dzięki temu mogłem ograniczyć wymagania co do pojemności pamięci flash do 8 MB (przy czym należało pamiętać, że ponad 4MB zajmuje partycja z głosem Mbroli), a tym samym użycie miniaturowej płytki XIAO S3. Tak więc postanowiłem nie opierać się na poprzednim projekcie. Ponieważ największym elementem był akumulator 5000 mAh - wewnętrzna szerokość wyszła mi 75mm. Pozostałe wymiary dopasowywałem na bieżąco w trakcie projektowania. Zacząłem od klawiatury. Postanowiłem zrobić z niej oddzielny moduł (zawierający również gniazdko słuchawkowe) po prostu wsuwany w odpowiednie szczeliny w obudowie. Jako że długość gniazda wyznaczała rozmiar modułu, nie musiałem bawić się w miniaturyzację. Na kawałku taniej płytki uniwersalnej umieściłem klawisze i wyłącznik, na drugiej (takiej porządniejszej) ekspander MCP23017 Wyszło to tak: Dzięki ekspanderowi mogłem podłączyć wszystkie klawisze oddzielnie oraz przycisk na słuchawkach. Oprócz scalaka są tak tylko dwa rezystory - jeden 10k jako pullup do resetu, drugi 3.3k do przysisku słuchawek. Całość łączy się pięcioma przewodami z główną płytką. Jako że z założenia konstrukcja miała być raczej prowizorycznym prototypem - nie bawiłem się w jakieś wymyślne płytki i miniaturyzacje. Znów kawałek uniwersalnej, na nim XIAO wetknięty w dwa żeńskie goldpiny (żeby można było później wyjąć) i dekoder I2S (co prawda wlutowany, ale pięć pinów wystarczy dmuchnąć hotairem). Dodatkowo rezystory dzielnika i kondensatorek do pomiaru stanu akumulatora - i prowizorka wyszła tak: Oddzielnie umieściłem moduł DS3231 (ten z EEPROM-em) i gniazdo karty microSD (miałem takie do Wemosa D1 Mini, wystarczyło dociągnąć jeden drucik żeby mieć wszystkie piny po jednej stronie): Docelowo miało to być umieszczone nad akumulatorem, czyli miejsca miałem dużo... I tu uwaga: mimo że starałem się zrobić to z gotowych modułów, jednego nie mogłem przeskoczyć: pamięci FRAM. Postanowiłem po prostu przylutować ją "na plecach" EEPROM-u moduły zegarka, zwierając linie adresowe do masy. W ten sposób miałem tam dwie pamięci: EEPROM na adresie 0x57 i FRAM na 0x50. Obudowa po umieszczeniu w niej akumulatora (widać, skąd takie a nie inne wymiary wygląda tak): A zmontowana całość razem z płytką główną i kłębowiskiem kabli: Teraz wystarczyło wydrukować górną część obudowy i urządzenie było gotowe do testów (przy okazji w zdjęciu zawarta jest informacja że nie jestem wielbłądem): W międzyczasie oczywiście powstawał program. Nie będę wnikał w szczegóły (kod w załączniku, każdy może obejrzeć), powiem tylko jakie są możliwości: Odtwarzanie audiobooków z możliwością przyspieszenia (pliki sonicFiler.cpp i sonicFilter.h w katalogu src są przystosowane do współpracy z popularną biblioteką ESP8266Audio) Odtwarzanie ebooków za pomocą syntezatora Mbrola Głosowe komunikaty (również generowane Mbrolą) Możliwość zrobienia zakładki (jednej na książkę) Autozakładka czyli możliwość zrobienia "redo" jeśli coś się pogubiłem w przewijaniu Możliwość przechowywania 511 książek (audio i ebook razem) z zapamiętywaniem ostatnio słuchanej książki oraz pozycji w każdej książce Zapis pozycji w pamięci FRAM co kilka sekund (audiobook) lub co zdanie (ebook) umożliwia powrót do ostatnio słuchanej pozycji nawet w przypadku nieoczekiwanego wyłączenia zasilania Ebooki podzielone na zestawy po max. 16 pozycji, ilość zestawów nieograniczona Przewijanie w trakcie odtwarzania jest możliwe (czasowe przy audio, zdanie/akapit przy ebookach) ale bez przeskoczenia granic pliku mp3 (audio) czy rozdziału (ebook), jast to możliwe tylko w trybie pauzy Podanie ogólnych lub szczegółowych informacji o bieżącej pozycji czytania Zegarek (godzina i minuta) oraz stan akumulatora (w procentach) Do wgrania audiobooka trzeba wyjąć kartę i przełożyć do czytnika. Za pomocą programu mkaudiobook mogę wgrać audio na kartę, z możliwą korektą (mono 65 kbps dla czytanych książek lub kopia dla słuchowisk stereo). Program przy okazji tworzy pliki informacyjne dla każdego pliku mp3 - nie jest to konieczne, Lekton potrafi sobie sam te pliki utworzyć, ale wtedy pierwsza próba odtworzenia rozpoczyna się od stworzenia owych plików, i ma się czas na zrobienie kawy. Co prawda nie przewiduję takiej sytuacji - ale pozostawiam sobie możliwość przegrania audiobooka z komputera na którym nie mogę uruchomić programu. Ebook (w odpowiednim formacie tekstowym, można go zrobić dowolnym edytorem tekstu w ciągu paru chwil z pliku txt ebooka) też może być przegrany bezpośrednio, ale wygodniejsze jest przegranie za pomocą dedykowaniej aplikacji. Aplikacja (Python3 i Gtk+ 3) umożliwia wygodne wgrywanie/usuwanie książek i robienie porządków na karcie poprzez połączenie do USB. Ogólnie jest tam tego trochę więcej, ale nie będę Was zanudzać szczegółami. Oczywiście jak najszybciej wziąłem się do testowania. Już następnego dnia wyskoczył problem: czy ja to coś wyłączyłem czy może leży sobie i podgryza akumulator? Mógłbym oczywiście dodać jakieś ledy ale w porę się opamiętałem: przecież na dekoderze I2S świeci sobie na czerwono śliczna dioda, wystarzy dodać okienko przez które będzie ją widać. Drugi problem był raczej natury usability: identyczne przyciski utrudniały szybkie znalesienie właściwego. Tak więc przycisk START zrobiłem nieco większy i wyczuwalny pod palcem, przy okazji poprawiłem suwak wyłącznika (na zdjęciu wydrukowane żółtym filamentem), dorobiłem okienka nad diodą I2S i przy okazji nad kontrolką ładowania XIAO - i wyszło to tak: Teraz mogłem wziąć się do dłuższych testów. Jak zwykle wyskoczyły jakeś drobne poprawki w programie, ale to było do przewidzenia i poprawiałem na bieżąco. I pewnie bym to w takiej postaci pozostawił, gdyby nie dwie sprawy: po pierwsze urządzenie było jednak nieco za duże, po drugie nie wziąłem pod uwagę drobiazgu - mianowicie naładowanie do pełna akumulatora za pomocą rachitycznej ładowareczki XIAO trwałoby jakiś tydzień... Ponieważ nie miałem jakiegoś porządnego modułu z gniazdem microSD, a nie bardzo miałem ochotę na lutowanie jakiegoś milimetrowego rastra (cóż, oczy już nie te co kiedyś) poszukałem trochę po sieci i znalazłem coś co wydawało mi się idealne do moich celów: produkcji Adafruit płytka z gniazdem, którą montuje się pod płytką XIAO. Trochę musiałem poczekać, bo botlandowe "kilka dni" zmieniło się w dwa tygodnie, ale wreszcie zamówiłem, przyszła... I po rozpakowaniu myślałem że mnie coś strzeli. Nauczka na przyszłość: zanim coś zamówisz obejrzyj sobie duże zdjęcie i nie chrzań, że się nie chce okularów szukać. Okazało się, że jakiś geniusz z Adafruit nie bardzo chyba wiedział jak się obchodzić z chińskimi wynalazkami. Gniazdo jest na płytce umieszczone tak, że kartę trzeba włożyć centralnie na płytce (trochę by to było niewygodne ale ujdzie), to jeszcze od tyłu (nie od strony gniazda USB na XIAO). Po prostu nie zauważyłem, że gniazdo na płytce nie jest umieszczone tak jak myślałem (czyli z przodu przy krawędzi) ale dokładnie odwrotnie! Czyli mój piękny projekt PCB mogłem wyrzucić do kosza i zacząłem się zastanawiać, co z tym fantem zrobić. W desperacji chwyciłem nożyce do laminatu, przyciąłem płytkę tak że mogłaby się zmieścić na PCB... i udało się! Teraz już mi sie nie chciało siadać do projektowania. Przed nosem leżała sobie porządna płytka uniwersalna 70x50 mm, akurat mieściły się obok siebie S3 i to nieszczęsne gniazdko. Rezystorki i kondensator w wersji SMD poszły na spód płytki (na szczęście 0805 bardzo ładnie pasują do rozstawu pól lutowniczych na płytce), parę połączeń kynarem - i gotowe! Mogłem zmniejszyć obudowę do jakichś rozsądnych rozmiarów! Wewnątrz wygląda to tak: Jak widać, cała elektronika zmieściła się nad akumulatorem, co pozwoliło mi na zmniejszenie długości obudowy. Dodałem jeszcze otwór przez który mogę się dostać do wtyczki akumulatora (zrobiłem sobie kiedyś taką uniwersalną ładowarkę do LiPo, przy 1A powinno się przez noc naładować), wydrukowane z polipropylenu zaślepki (wolałbym żeby jakieś paprochy z kieszeni nie dostały się do wnętrza), drugie okienko na drugą diodę XIAO (sygnalizuje stan urządzenia STOP/PAUZA/PLAY) - i w efekcie wygląda to tak: Tym razem kilkudniowe intensywne testy wykazały, że urządzenie w tej wersji jest wygodne i spełnia wszystkie moje oczekiwania. Na zakończenie kilka słów o załączonym pliku Lekton.zip. W kodzie pozostawiłem wyłączone fragmenty. MSC nie udało mi się uruchomić (zresztą w pewnym momencie zrezygnowałem z uwagi na dziwaczne problemy z komunikacją serial w trybier TinyUSB/CDC). Plik wifi pozostawiłem bo jest dość uniwersalny, krótki i być może ktoś będzie potrzebować czegoś podobnego. Plik OpenSCAD-a jest raczej do pooglądania sobie, nie jest stuprocentowo kompletny ale raczej chciałem pokazać w jaki sposób można w tym programie stworzyć projekt w miarę skomplikowanej obudowy. Gdyby ktoś koniecznie chciał uruchomić to u siebie, należy z GitHuba zgrać plik espola_pl1_full.blob i wgrać go do ESP od adresu 0x36E000 (zgodnie z adresem w mbro8nof.csv). W razie jakichkolwiek pytań jestem do dyspozycji.
- 6 odpowiedzi
-
- 13
-
-
Cóż - jak zwykle miało być o czymś innym, tylko że ten "czymś" cały czas ma problemy egzystencjonalne typu "a ja nie będę działać po twojemu ale po swojemu". Dlatego dzisiaj o czymś, co powstało w międzyczasie. Dzisiaj przedstawiam bibliotekę poldit, służącą do słownego rozwijania różnych liczb (w tym liczb mianowanych, godzin, dat czy zakresów). Zaczęło się to jakoś 20 lat temu, kiedy potrzebowałem systemu TTS dla Linuxa. Moja Milena działała (i do dziś działa) praktycznie bezproblemowo, tyle że jest przystosowana przede wszystkim do Mbroli, poza tym jest duża, ciężka zbyt specjalizowana (powstała do czytania beletrystyki, więc wiele jej reguł dotyczy właśnie powieści - choćby francuskie rewolucyjne daty, stopnie Reaumura czy wymowa wyrazów obcojęzycznych). Co prawda najnowsze wersje potrafią od biedy wygenerowć tekst dla innych syntezatorów, ale nie jest to jej głównym celem. Dlatego postanowiłem stworzyć coś prostszego, a jednocześnie mającego nieco większe możliwości interpretacji tekstu. Kompletny kod i techniczny opis zamieszczony jest na githubie, nie będę więc się specjalnie powtarzać, postaram się opisać o coś od strony bardziej praktycznej. Jako że główną platformą dla biblioteki jest Linux (w tym RaspiOS) podaję najprostszy sposób instalacji. Zacznę od biblioteki libpoldit i programu poldit wykorzystującego bibliotekę: sudo apt install build-essential git git clone https://github.com/ethanak/poldit.git cd poldit/src make sudo make install Można teraz wypróbować działanie programu, przykładowo: $ poldit napięcie powinno wynosić od 1.5 do 5 V napięcie powinno wynosić od jednego i pięć do pięciu woltów Oczywiście warto wypróbować różne przełączniki, przykładowo: $ poldit -p -n napięcie powinno wynosić od 1.5 do 15 V napięcie powinno wynosić od półtora do pietnastu wolt Jak widać, w tym przypadku poldit zastosował skróconą/potoczną konwersję i skorygował przesadną wymowę. Bieżącą datę i czas można odczytać przykładowo w ten sposób: $ date -Iminutes | cut -f1 -d+ | poldit dwudziesty drugi stycznia dwa tysiące dwadzieścia sześć czternasta pięćdziesiąt siedem Pokazany wyżej sposób będzie działać zarówno na RPi (nawet na maleńkim Zero W), jak i na wszelkich debianobodobnych dystrybucjach Linuksa. Dla innych wystarczy w sposób odpowiedni dla systemu zainstalować pakiety build-essential i git. Oczywiście to co wypisuje poldit nie służy do czytania na konsoli ale do sterowania syntezą mowy. Pomijając rozwiązania wymagające dostępu do internetu, płatne syntezatory (i moją Milenę) dla języka polskiego mamy niewiele praktycznych możliwości: espeak - tu dwie możliwości: albo syntezator Klatta (mechaniczny głos, ale czytelny przy wysokich prędkościach) albo Mbrola (niestety, raczej tylko jako ciekawostka); piper - z założenia głos wysokiej jakości generowany przy użyciu AI. Niestety są to jedynie założenia, bo polskie modele generują coś w stylu mieszanki polsko-rosyjskiej gubiąc po drodze niewygodne spółgłoski; RHVoice - od początku projektowany z myślą o praktycznych zastosowaniach. Po polsku mówi całkiem dobrze, do dyspozycji mamy pięć głosów. Istnieje jeszcze oczywiście korpusowy syntezator mowy (PJWSTK) oraz leciwy Festival, ale to są projekty bardziej akademickie; o ile Festival był w paru aplikacjach używany, o tyle ten polsko-japoński nigdy nie doczekał się praktycznego zastosowania. Aby więc posłuchać efektów trzeba mieć przede wszystkim komputer z wyjściem audio (może być RPi, ale model co najmniej Zero 2 W). Można zacząć od espeaka (jest w repozytoriach) żeby po prostu stwierdzić że to działa. Jednak jeśli ktoś chciałby stworzyć jakąś rzeczywistą aplikację, polecam RHVoice. Dla nowych dystrybucji sprawa jest prosta: $ sudo apt install rhvoice rhvoice-polish Niestety - starsze dystrybucje mogą w repozytoriach mieć wersje bez dostępnego języka polskiego lub w ogóle nie mieć pakietu. W takim przypadku trzeba pobrać go z githuba skompilować samodzielnie. Na szczęście sposób instalacji jest dobrze opisany, wymaga tylko kilku dodatkowych bibliotek z repozytorium (np. libao) i programu scons. Można więc spróbować już czegoś bardziej przydatnego, przykładowo: $ date +'Jest %H:%M, %A, %d.%m.%Y' | poldit -n | RHVoice-test -p natan Taki skrypt można podłączyć np. pod jakiś klawisz i mieć do dyspozycji zegarek, który nie wymaga gapienia się w ekran. Szczególnie w rozwiązaniach bez interfejsu graficznego może to być przydatne. Tak mniej więcej działa czytanie godziny i daty przez różne syntezatory: W załączniku pliki mp3 dla głosów espeak-ng, piper i RHVoice (róœnież z głosem Cezary, który ma tak dziwaczną licencję że nie wiem czy w ogóle można go słuchać i dlatego nie ma go w filmie). Oczywiście czytanie bieżącego roku nie jest w większości przypadków konieczne. Można się bez tego obejść, tyle że trzeba polditowi powiedzieć dokładniej co ma czytać (czyli użyć formatów): $ date +'jest %H:%M, F[DWdM/,:%u %d %m]' | poldit -n | RHVoice-test -p natan W wielu przypadkach programik poldit może być wystarczający, ale na RPi (który jest główną platformą dla której powstała biblioteka) programy pisze się raczej w Pythonie a nie Bashu. Dlatego powstały dwa modułt do Pythona: polditLL - niskopoziomowy moduł, stanowiący wyłącznie interfejs do biblioteki poldit poldit - moduł udostępniający dodatkowe funkcje rozszerzające możliwości polditLL Sposób instalacji jest w miarę prosty: sudo apt install python3-setuptools python3-pip pip3 install build --break-system-packages cd ~/poldit/python/modules python3 -m build --no-isolation pip3 install . --break-system-packages W niektórych dystrybucjach przełącznik --break-system-packages może być niepotrzebny! Oczywiście można moduł zainstalować globalnie, używając sudo w obu przypadkach uruchamiania pip3 Można przetestować moduł np. poleceniem: $ python3 ../demo/kolej.py Wynik powinien wyglądać w ten sposób: Na torze czwartym przy peronie trzecim stoi pociąg do stacji Warszawa Główna. Wagony o numerach jeden do trzy zatrzymują się w sektorze trzecim. Opóźniony o pietnaście minut pociąg intersjity I C dwadzieścia trzy sto czterdzieści cztery "Maruda", ze stacji Warszawa Centralna do stacji Katowice Wschodnie, wjedzie na tor siódmy przy peronie czwartym. No i teraz najważniejsze - co można z tym zrobić? Wyobrażam sobie kilka zastosowań - szczególnie jeśli chodzi o RPi. Jednym z ciekawszych może być modelarstwo kolejowe. RPi Zero 2W obsłuży zarówno jakiś porządny interfejs, ustawi zwrotnice i semafory, będzie sterować lokomotywami i całą infrastrukturą dworca, jak i zasymuluje komumikaty na dworcu. Zamieszczony przykład pokazuje, jak w bardzo prosy sposób można generować komunikaty na dworcu kolejowym czy autobusowym, nie wnikając w prawidłową odmianę (np. "natorze 7 przy peronie 3" czy "autobus odjeżdzą ze stanowiska 7"). Innym typem zastosowań może być automatyka domowa, gdzie czasem infrmacje głosowe są dużo wygodniejsze niż wyświelane na jakimś ekranie, Przykładowo - w mojej domowej instalacji wciśnięcie przycisku na ścianie spowoduje w efekcie przeczytanie na głos aktualnego czasu i temperatury na zewnątrz, albo prognozy pogody na najbliższe dni ściągniętej z openmeteo. Sprawdza się od dłuszego czasu (syntezator RHVoice, głos Alicja), przy czym przycisk jest obok mojego ulubionego fotela Taki programik do prognozy wcale nie jest taki skomplikowany, przykładowe rozwiązanie to: #!/usr/bin/env python3 import requests, os, time, json class weather(object): cachefile = '/dev/shm/prognoza.json' weacodes={ 0: "Czyste niebo", 1: "Przeważnie bezchmurnie", 2: "Zachmurzenie częściowe", 3: "Pochmurno", 45: "Mgła", 48: "Marznąca mgła", 51: "Lekka mżawka", 53: "Umiarkowana mżawka", 55: "Intensywmna mżawka", 56: "Lekka marznąca mżawka", 57: "Intensywna marznąca mżawka", 61: "Niewielki deszcz", 63: "Umiarkowany deszcz", 65: "Intensywny deszcz", 66: "Lekki marznący deszcz", 67: "Silny marznący deszcz", 71: "Słabe opady śniegu", 73: "Uniarkowane opady śniegu", 75: "Silne opady śniegu", 77: "Śnieg ziarnisty", 80: "Przelotne lekkie opady deszczu", 81: "Przelotne umiarkowane opady deszczu", 82: "Przelotne gwałtowne opady deszczu", 85: "Przelotne słabe opady sniegu", 86: "Przelotne intensywne opady sniegu", 95: "Burza z piorunami", 96: "Burza z lekkim gradem", 99: "Burza z silnym gradem" } def __init__(self, latitude, longitude): self.url="https://api.open-meteo.com/v1/forecast?latitude=%.5f&longitude=%.5f&timeformat=iso8601&forecast_days=2&timezone=Europe/Warsaw" + \ "&daily=wind_speed_10m_min,wind_speed_10m_max,weather_code,wind_gusts_10m_max" + \ ",temperature_2m_min,apparent_temperature_min,temperature_2m_max,apparent_temperature_max" + \ ",rain_sum,showers_sum,snowfall_sum" self.url = self.url % (latitude, longitude) self.json = None def getWeatherJSON(self): try: st=os.stat(self.__class__.cachefile) delta = time.time() - st.st_mtime if delta >= 900: raise Exception() return json.loads(open(self.__class__.cachefile,'rb').read()) except: return self.getNetWeather() def getNetWeather(self): try: rc=requests.get(self.url) js=rc.content rc=json.loads(js) open(self.__class__.cachefile,'wb').write(js) return rc except: return None def _getIVals(self, name): return int(self.dly.get(name+'_min')[self.idx]), \ int(self.dly.get(name+'_max')[self.idx]) def _getIVal(self, name): return int(self.dly.get(name)[self.idx]) def getWeatherString(self, tomorrow=False): if self.json is None: self.json = self.getWeatherJSON() if self.json is None: return 'Brak prognozy' self.idx = 1 if tomorrow else 0 self.dly = self.json['daily'] sout = [] wcode = self._getIVal('weather_code') if (wdesc := self.__class__.weacodes.get(wcode)) is not None: sout.append(wdesc) tm1, tm2 = self._getIVals('temperature_2m') to1, to2 = self._getIVals('apparent_temperature') if tm1 == tm2: stm = "temperatura %d °" % tm1 else: stm = "temperatura od %d do %d °" % (tm1, tm2) if to1 == to2: stm += ", odczuwalna %d °" % to1 else: stm += ", odczuwalna %d do %d °" % (to1, to2) sout.append(stm) w1, w2 = self._getIVals('wind_speed_10m') w3 = self._getIVal('wind_gusts_10m_max') if w1 == w2: stm = "wiatr %d km/h" % w1 else: stm = "wiatr %d do %d km/h" % (w1, w2) if w3 > w2: stm += ", w porywach do %d km/h" % w3 sout.append(stm) rain = int(self._getIVal('rain_sum')+self._getIVal('showers_sum')) snow = int(self._getIVal('snowfall_sum')) if rain > 0 or snow > 0: stm = 'przewidywane opady' if rain > 0: stm += ' deszczu %d mm' % rain if snow > 0: stm += ',' if snow > 0: stm += ' śniegu %d cm' % snow sout.append(stm) return '. '.join(sout) latitude = 52.23 longitude = 23.01 w=weather(latitude,longitude) so="Pogoda na dziś: %s. Pogoda na jutro: %s." % ( w.getWeatherString(), w.getWeatherString(True)) import poldit p=poldit.Fonetyzer() print(p.Stringify(so, nat=True)) Należy tylko wpisać do programu właściwe wartości zmiennych latitude i longitude, a wygenerowany tekst wrzucić do syntezatora. No i kolejne zastosowanie, tym razem wymagające posiadania odpowiedniego sprzętu: gadające przystawki do urządzeń pomiarowych. Tu już specjalnie nie mam praktyki (np. mierniki z wyjściem cyfrowym są trochę poza moimi możliwościami finansowymi, ale używam takiego prostego gadającego miernika własnego sumptu). Chyba każdy przyzna, że wtyknięcie końcówek przyrządu w jakąś gęstą płytkę z rastrem rzędu milimetra albo mniej i odwrócenie wzroku żeby popatrzeć na wyświetlacz może skończyć się smętnie. Mogę jednak wyobrazić sobie jakiś interfejs oparty na czymś co ma wejście serial i komunikację WiFi/BT (esp32, RPi Pico czy co kto lubi), czyta dane z miernika wyrzuca np. na smartfona z prostą aplikacją (przykład aplikacji w wątku o suwmiarce) A jeśli chodzi o komunikaty... fajnie by było, aby w pociągach oprócz wyświetlania informacji na wyświetlaczach (do których człowiek albo siedzi tyłem, albo coś/ktoś mu zasłania) były informacje głosowe o bieżących opóźnieniach i przewidywanych czasach przyjazdu na następną stację. Jeśli obsługa może wprowadzić takie dane do wyświetlania - raczej nie byłoby problemu z wygenerowaniem (automatycznym) odpowiedniehgo komunikatu, np. na podstawie rozkładu jazdy i opóźnienia można wygenerować coś w stylu: Następna stacja Trypucie, przyjazd 15:32, opóźnienie 137 min Czytać tego wcale nie musi koniecznie Ivona... Ale chyba za dużo bym od kolei wymagał Oprócz plików mp3 w załączniku źródełko programu do prognozy pogody oraz prosta klasa umożliwiająca użycie RHVoice bezpośrednuio w skrypcie Pythona bez zabawy w (nie zawsze działający) moduł rhvoice-wrapper: poldemo.zip A na koniec konkurs bez nagród: kto wymyśli jakieś sensowne zastosowanie dla poldita? Jak zwykle w razie pytań pozostaję do dyspozycji ethanak
-
Kolejny gadający sprzęt... ale może od początku. Zaczęło się od tego, że moje (dość prowizoryczne) konstrukcje odmówiły wreszcie współpracy i trzeba to zrobić porządnie. A konkretniej - suwmiarka (chyba trzeci kolejny eksperymentalny model) i metrówka (to była straszna prowizora). Niestety - te "porządne" egzemplarze poszły w ludzi i trzeba usiąść i zrobić to od początku. Postanowiłem zacząć od suwmiarki. Przede wszystkim - zgubiłem gdzieś klapkę od baterii, dodrukowana potrzebuje podkładania jakichś papierków żeby bateria chciała stykać - stwierdziłem więc, że będę suwmiarkę zasilać z akumulatora przystawki. W razie czego zawsze szybciej podładować akumulator niż zamawiać baterie w necie Druga sprawa to synteza mowy. O ile stary dobry syntezator Klatta działa, jednak warto to trochę uwspółcześnić. Początkowo chciałem zastosować microlenę, ale zastosowanie pełnego systemu TTS to czytania paru cyferek uznałem za overkill. Zrobiłem parę prób z nagraniem słów za pomocą RHVoice. Wyniki opiszę następnym razem razem z jakimś plikiemk dźwiękowym, ale próbna wersja gada całkiem nieźle. Jednocześnie chcę umożliwić użycie smartfona do syntezy mowy. Co prawda Android 14 rządzi się jakimiś swoimi dziwnymi prawami jeśli chodzi o wybór silnika TTS przez aplikację, ale użycie nawet syntezy Samsunga może dla osoby widzącej być wygodniejsze niż wsłuchiwanie się w rachityczny głośniczek przystawki. Postanowiłem zastosować XIAO S3 z uwagi na wielkość płytki (i wbudowaną ładowarkę). Kilka problemów jeszcze muszę rozwiązać, ale na początek zasilanie. Chcę to zrobić w ten sposób jak na schemacie poniżej. Diody D1 i D2 (akurat wyciągnięte z szuflady małe diody Zenera, ale mogą być normalne prostownicze) służą do obniżenia napięcia zasilania suwmiarki do ok. 1.5V. Diody D3 i D4 to powinny być Schottky z uwagi na niski spadek napięcia - akurat mam takie jednoamperowe, powinny wystarczyć. Układ służy do zasilania wzmacniacza MAX98357 albo z akumulatora, albo (jeśli podłączony jest kabel USB) z napięcia wejściowego. MAX ma dość szeroki zakres napięcia zasilania, działa zarówno z 3V (np. z dwóch ogniw AA) jak i za 5V z USB. Tyle wstępu - na razie prośba: jeśli ktoś mógłby sprawdzić czy ten pomysł z zasilaniem nie ma jakichś błędów będę wdzięczny. A dalej spróbuję opisać moje boje z syntezą mowy - może komuś się przyda? Na razie!
-
Cóż... jak się jakiś projekt skończyło to warto opisać Dziś na tapecie coś, co jest rozwinięciem jednego z poprzednich projektów - suwmiarki. Od razu na wstępie: ponieważ dokładniejszy opis jest na githubie TalkingCaliper - nie chcę duplikować treści, ale raczej ogólnie powiedzieć coś o tym projekcie. Urządzenie stanowi przystawkę do popularnej suwmiarki Vorel 15240. Jako jedyna chyba w tej klasie cenowej posiada wyjście danych, a jej dokładność jest wystarczająca do typowych zastosowań (pomijając oczywiście zegarmistrzostwo). Ponieważ niespecjalnie mi się chciało bawić się w projektowanie nowej obudowy - użyłem lekko zmodyfikowanego starego projektu.Dlatego też wygląd urządzenia praktycznie się nie zmienił - poza oczywiście zmienionym mocowaniem głośnika i dostosowaniem do płytki XIAO S3. Poprzednio użyłem syntezatora Klatta do generowania mowy. Co prawda to działało, nawet coś można było zmierzyć - ale nie byłem zadowolony z wyników. O ile osobie przyzwyczajonej do tego typu syntezatorów (np. eSpeaka) nie sprawia trudności zrozumienie tego co urządzenie tam marmoli pod nosem - o tyle ktoś kto nie używa tego typu syntezatorów może mieć pewne problemy. Dodatkowo - mały głośniczek i uproszczony wzmacniacz nie były super rozwiązaniem. Najpierw postanowiłem użyć Gadacza - projekt w sumie sprawdzony, a przede wszystkim przeznaczony do tego typu urządzeń. Tym razem mowa była dużo bardziej czytelna - ale miało to jedną wadę: program działałby wyłącznie dla języka polskiego, który raczej nie jest najpopularniejszym językiem na świecie. Trzeba było zupełnie innego podejścia. I tu pojawia się coś, co określane jest "syntezą korpusową" w najprostszej postaci. Po prostu program odtwarza nagrane uprzednio fragmenty wypowiedzi odpowiednio je łącząc. Co prawda nie zawsze takie połączenie brzmi naturalnie - no ale to jest suwmiarka a nie czytnik książek! Ponieważ założenia jako takie już miałem, trzeba było wybrać potrzebne podzespoły. Jako że ceny w porównaniu z okresem, kiedy robiłem pierwszą wersję mocno spadły, a poza tym pojawiły się nowe możliwości - postanowiłem zamiast ESP32 Lite użyć XIAO ESP32-S3. Oba moduły mają możliwość współpracy z akumulatorem, przy czym dzisiejsza cena XIAO jest w praktyce taka sama, jak wtedy Lite. Dodatkowo układ MAX98357A - wtedy niespecjalnie dostępny i kosztujący jakieś dziwne pieniądze - pojawił się w wersji chińskiej za mniej więcej 30% tej ceny. Tak więc główne podzespoły to: XIAO ESP32-S3 jako "mózg" urządzenia Płytka MAX98357A (czyli dekoder I2S z wyjściem bezpośrednio na głośnik) Głośnik miniaturowy 15x24x4 1W Akumulator (na razie wyjęty ze starego urządzenia). Niestety - wycofany z oferty a szkoda, bo wymiarami bardzo ładnie pasował do tego typu urządzeń. Początkowo chciałem zrobić piękną płytkę drukowaną, ale okazało się, że nie mam wszystkich potrzebnych elementów w wersji SMD. Tak więc na kawałku płytki uniwersalnej wylądowały dwie diody Schottky w wersji THT, a zamiast diod prostowniczych użytych do stabilizacji napięcia 1.5V zastosowałem małe diody Zenera, zalegające mi w szufladzie. Do tego użyłem jakiegoś nietypowego gniazda do podłączenia wzmacniacza - tak, że projektowanie czegokolwiek nadającego się do publikacji mijałoby się z celem. Układ jest dość prosty: a wygląda to tak: I tu drobna uwaga: zdjęcia pochodzą z roboczej wersji, docelowa różni się jedynie położeniem wyłącznika. Jeśli chodzi o program - użyłem jak poprzednio kodu do odczytu suwmiarki z projektu EspDRO. Do regulacji prędkości mowy zastosowałem bibliotekę Sonic, a konkretniej wersję lite dostosowaną do mikrokontrolerów. Możliwości programu: przełączanie między odczytem ciągłym (co sekundę), odczytem zmian i odczytem na żądanie (czyli po wciśnięciu przycisku); sygnalizacja braku sygnału z suwmiarki; w trybach "zmiany" i "na żądanie" jeśli przez dłuższy czas nie używamy suwmiarki prośba o wyłączenie urządzenia; automatyczne włączenie trybu ładowania po podłączeniu USB (program nic nie mówi i nic nie przypomina); odczyt stanu akumulatora; połączenie z dedykowaną aplikacją na Androidzie Preferencje programu (ustawiane przyciskiem) obejmują: zmianę prędkości (siedem możliwości) zmianę głośności (trzy możliwości) zmianę głosu (o ile jest więcej niż jeden) tryb rozdzielenia cyfr (brzmi mniej naturalnie ale może być czytelniejszy) tryb czytania małych wartości calowych (możliwość odczytu w mils dla wartości poniżej cala) Dodatkowo używając terminala serial można ustawić: kalibrację odczytu napięcia akumulatora; stałe czasowe dla przytrzymania i podwójnego kliknięcia; włączenie filtra dolnoprzepustowego (raczej rzadko potrzebne ale może się przydać w przypadku głośnika za mocno uwypuklającego wysokie tony); nazwę pod którą widziane będzie urządzenie przez BlueTooth (o ile jest to włączone w czasie kompilacji); tryb załączania BlueTooth (zawsze albo jeśli w czasie włączania zasilania przytrzymywany jest przycisk). W przypadku Androida kod języka TTS przesyłany jest przez program suwmiarki i nie musi on być taki sam, jak język interfejsu telefonu. W trakcie działania aplikacji wewnętrzny syntezator suwmiarki jest wyłączony poza trybem ustawień. A oto krótki filmik z działania suwmiarki. I to już chyba wszystko. Jeśli ktoś pokusiłby się o wykonanie takiego urządzenia proszę o kontakt - co prawda starałem się aby opis był w miarę kompletny, ale mogłem zapomnieć o jakimś ważnym szczególe. A... nie, to nie wszystko. Ponieważ ostatnio pojawiły się dodatkowe wymagania gdyby ktoś chciał skorzystać z promocji w Botlandzie niniejsze zdjęcie dowodzi że nie jestem wielbłądem!
-
- poniżej program w którym nie potrafię zmienić wyjścia espeak z i2s na głośność! - jak ściągamy mp3 z Url to schemat jest taki UrlStream -> copy-> EncodedAudioStream -> Volume -> I2S. - proszę o pomoc bo po powodzi klepki uciekły. /** * @file espeak-arduino-pl.ino * @author Phil Schatzmann * @brief Arduino C++ API - minimum example. The espeak-ng-data is stored on in * progmem with the arduino-posix-fs library and we output audio to I2S with the * help of the AudioTools library. * We use Polish instead of English! * @version 0.1 * @date 2022-10-27 * * @copyright Copyright (c) 2022 */ // UrlStream -copy-> EncodedAudioStream -> Volume -> I2S #include "AudioTools.h" // v 2.0.0 https://github.com/pschatzmann/arduino-audio-tools //#include "AudioLibs/AudioKit.h" // https://github.com/pschatzmann/arduino-audiokit #include "FileSystems.h" // https://github.com/pschatzmann/arduino-posix-fs #include "espeak.h" I2SStream i2s; // or replace with AudioKitStream for AudioKit VolumeStream volume(i2s); //VolumeMeter out; // 2 const bool load_english = false; ESpeak espeak(i2s, load_english); StreamCopy copier(volume, i2s); // StreamCopy copier(out, i2s); // 2 // -------------------------------------------------- setup --------------------------------- void setup() { Serial.begin(115200); file_systems::FSLogger.begin(file_systems::FSInfo, Serial); // ----------------------- tylko dla LilyGo T-embed ----------------------- pinMode(46, OUTPUT); digitalWrite(46, HIGH); // add foreign language configuration files espeak.add("/mem/data/pl_dict", espeak_ng_data_pl_dict,espeak_ng_data_pl_dict_len); espeak.add("/mem/data/lang/pl", espeak_ng_data_lang_zlw_pl, espeak_ng_data_lang_zlw_pl_len); // setup espeak espeak.begin(); espeak.setVoice("pl"); // setup output auto espeak_info = espeak.audioInfo(); // audio_info espeak_info = espeak_get_audio_info(); auto cfg = i2s.defaultConfig(); cfg.channels = espeak_info.channels; // 1 cfg.sample_rate = espeak_info.sample_rate; // 22050 cfg.bits_per_sample = espeak_info.bits_per_sample; // 16 i2s.begin(cfg); //espeak_set_audio_output(&i2s); // 3 // set initial volume volume.begin(cfg); // we need to provide the bits_per_sample and channels volume.setVolume(0.0); // } // --------------------------------------------------- loop ------------------------------- void loop() { espeak.say("Dzień dobry !"); delay(1000); espeak.say("Pogoda wspaniała "); delay(5000); copier.copy(); }
