Wybieranie losowej linii z pliku i synteza mowy

Ktos

Jeżeli posiadamy plik w którym są jakieś interesujące dane umieszczone w kolejnych liniach to w łatwy sposób można to wczytać do kolekcji - a skoro można wczytać do kolekcji, to i można także wybrać i pokazać tylko jeden z elementów tej kolekcji.

Przyjmijmy, że mamy plik zawierający znane fortunki i by umilić sobie pracę chcielibyśmy, bo nasz komputer mógł je nam losowo pokazywać:

Plik ma przykładowo taką treść:

Początkujący informatyk uważa, że 1 kB to 1000 B, a doświadczony jest pewien, ze 1 km to 1024 m.
Życie byłoby prostsze, gdyby Bóg dostarczył kod źródłowy.
Linux is like a wigwam: no windows, no gates, apache inside.
Idealne wymiary kobiety informatyka - 1024x768.
How many surrealists does it take to screw in a lightbulb? Banana.

By wczytać do kolekcji zawartość tego pliku wystarczy posłużyć się komendą Get-Content:

$text = Get-Content 'New Text Document.txt'

Wystarczy teraz na przykład spróbować wyświetlić $text[0], by zobaczyć, że plik został przekształcony w kolekcję, a nie w łańcuch znaków.

Potem wystarczy stworzyć obiekt klasy System.Random, który umożliwi nam wybór (pseudolosowy) linii z pliku (czyli de facto elementu z kolekcji $text):

$rnd = New-Object System.Random

po czym skorzystać z jego metody Next() zwracającej liczbę pseudolosową z zakresu od 0 do podanego parametru. Ale jaki to ma być parametr? Oczywiście powinna to być ilość elementów dostępnych w kolekcji $text, którą można uzyskać dzięki właściwości Count.

A zatem ostatecznie skrypt wyglądać będzie tak:

$text = Get-Content 'New Text Document.txt'
$rnd = New-Object System.Random
Write-Host $text[$rnd.Next($text.Count)]

Synteza mowy

Gdy jednak znudzimy się przykładowo tymi wyświetlanymi tylko fortunkami możemy przecież spróbować zmusić komputer, by je nam powiedział! Standardowo system Windows XP dysponuje okropnym syntezatorem mowy, ale nic nie stoi na przeszkodzie by zainstalować inny - ważne by wspierał standardowe mechanizmy SAPI. Windows Vista dysponuje syntezatorem "Microsoft Anna", który jest bardzo dobry, ale działa tylko w języku angielskim (w przypadku polskiego słowa brzmią cokolwiek niezrozumiale). W jaki sposób zaprząc mechanizmy Speech API do współpracy z PowerShellem?

Nic prostszego, wystarczy stworzyć nowy obiekt COM, SAPI.SpVoice i użyć jego metody "Voice" - a posługiwanie się obiektami COM czy WMI w PowerShellu nie jest trudne.

Przykładowo:

$voice = New-Object -com SAPI.SpVoice
$voice.Speak("Hello World!")

Zatem wystarczy podmienić Write-Host z poprzedniego przykładu na wywołanie metody Speak(), na przykład:

$voice.Speak($text[$rnd.Next($text.Count)])

I voila, dysponujemy mówiącymi fortunkami!

Sama metoda Speak() dysponuje także drugim parametrem, w którym możemy podać pewne właściwości dodatkowe - na przykład, by mówienie było wykonywane w sposób asynchroniczny - przykładowo

$voice.Speak("Hello world!",1)

nie spowoduje "zamrożenia" wykonywania skryptu. Kilka ciekawych informacji na temat wykorzystania SAPI (oraz niezły skrypt Out-Speech) można znaleźć na blogu Joela Benneta: http://huddledmasses.org/jaykul/powershell-speaks/

1 komentarz

Szkoda, że tylko po angielsku, ale ciekawe ciekawe.. i jakie proste ;)