Como sintetizar voz no Python

Eu gosto muito de programas e scripts com sintetização de voz.
Sei que nem sempre são adequados — principalmente se houver outro computador/usuário interagindo no mesmo recinto.

Às vezes, contudo, é uma ótima forma de obter retorno das nossas ações, entre outros tipos de informações.
O recurso pode ser usado para dar um feedback discreto sobre o andamento de alguma tarefa em execução no segundo plano.

Se é para brincar e aprender, também vale “soltar a língua” desta máquina e ter alguns momentos de diversão.

Neste post, pretendo falar de 2 métodos (entre tantos outros) bastante simples para obter voz do seu computador, usando o Python.
Abra a shell do Python e vamos lá.

Use o sintetizador de voz do próprio sistema operacional

Muitos sistemas operacionais têm seus próprios recursos de sintetização de voz.
Tudo o que você precisa fazer é repassar esta parte do trabalho para o SO, de dentro do seu script Python.
No meu exemplo, uso o sistema operacional Debian Linux, com o sintetizador espeak.
Se você também usa o Linux, pode instalar o espeak e fazer a experiência, a seguir.
Veja como acionar o espeak, de dentro de um script Python.

>>> import os
>>> os.system("espeak -vpt 'Python é uma ótima linguagem de programação!'")
0

Outra forma de fazer, dentro da plataforma Linux, com o espeak, é a seguinte:

>>> from subprocess import call
>>> minhafala = "sintetização de voz com Python."
>>> call(["espeak",minhafala])
0

Instale e uso o módulo Python do espeak

É possível instalar um módulo do espeak para Python.
No Debian e no Ubuntu, isto pode ser feito com o apt, da seguinte forma:

sudo apt install python3-espeak

Quem usa outros sistemas operacionais, pode usar o pip, para instalá-lo:

pip3 install espeak3

Se você usar a opção “search” do pip, vai encontrar outras alternativas de sintetização de voz para Python.

Uma vez instalado o módulo, volte para a Python shell e teste:

>>> from espeak import espeak
>>> espeak.synth("Não posso deixá-lo fazer isto, Dave!")
True

Use a documentação do módulo, dentro da shell, para descobrir novas possibilidades:

help(espeak)

Como alterar o idioma da sintetização de voz do espeak, no Python

Há várias vozes — de nacionalidades e sotaques diferentes — embutidas no módulo.
Veja como obter uma lista delas:


>>> espeak.list_voices()

[{'name': 'afrikaans', 'variant': None, 'identifier': 'other/af', 'gender': 1, 'age': None}, {'name': 'aragonese', 'variant': None, 'identifier': 'europe/an', 'gender': 1, 'age': None}, {'name': 'bulgarian', 'variant': None, 'identifier': 'europe/bg', 'gender': None, 'age': None}, {'name': 'bosnian', 'variant': None, 'identifier': 'europe/bs', 'gender': 1, 'age': None}, {'name': 'catalan', 'variant': None, 'identifier': 'europe/ca', 'gender': 1, 'age': None}, {'name': 'czech', 'variant': None, 'identifier': 'europe/cs', 'gender': 1, 'age': None}, {'name': 'welsh', 'variant': None, 'identifier': 'europe/cy', 'gender': 1, 'age': None}, {'name': 'danish', 'variant': None, 'identifier': 'europe/da', 'gender': 1, 'age': None}, {'name': 'german', 'variant': None, 'identifier': 'de', 'gender': 1, 'age': None}, {'name': 'greek', 'variant': None, 'identifier': 'europe/el', 'gender': 1, 'age': None}, {'name': 'default', 'variant': None, 'identifier': 'default', 'gender': 1, 'age': None}, {'name': 'english', 'variant': None, 'identifier': 'en', 'gender': 1, 'age': None}, {'name': 'en-scottish', 'variant': None, 'identifier': 'other/en-sc', 'gender': 1, 'age': None}, {'name': 'english-north', 'variant': None, 'identifier': 'other/en-n', 'gender': 1, 'age': None}, {'name': 'english_rp', 'variant': None, 'identifier': 'other/en-rp', 'gender': 1, 'age': None}, {'name': 'english_wmids', 'variant': None, 'identifier': 'other/en-wm', 'gender': 1, 'age': None}, {'name': 'english-us', 'variant': None, 'identifier': 'en-us', 'gender': 1, 'age': None}, {'name': 'en-westindies', 'variant': None, 'identifier': 'other/en-wi', 'gender': 1, 'age': None}, {'name': 'esperanto', 'variant': None, 'identifier': 'other/eo', 'gender': 1, 'age': None}, {'name': 'spanish', 'variant': None, 'identifier': 'europe/es', 'gender': 1, 'age': None}, {'name': 'spanish-latin-am', 'variant': None, 'identifier': 'es-la', 'gender': 1, 'age': None}, {'name': 'estonian', 'variant': None, 'identifier': 'europe/et', 'gender': None, 'age': None}, {'name': 'persian', 'variant': None, 'identifier': 'asia/fa', 'gender': None, 'age': None}, {'name': 'persian-pinglish', 'variant': None, 'identifier': 'asia/fa-pin', 'gender': None, 'age': None}, {'name': 'finnish', 'variant': None, 'identifier': 'europe/fi', 'gender': 1, 'age': None}, {'name': 'french-Belgium', 'variant': None, 'identifier': 'europe/fr-be', 'gender': 1, 'age': None}, {'name': 'french', 'variant': None, 'identifier': 'fr', 'gender': 1, 'age': None}, {'name': 'irish-gaeilge', 'variant': None, 'identifier': 'europe/ga', 'gender': None, 'age': None}, {'name': 'greek-ancient', 'variant': None, 'identifier': 'other/grc', 'gender': 1, 'age': None}, {'name': 'hindi', 'variant': None, 'identifier': 'asia/hi', 'gender': 1, 'age': None}, {'name': 'croatian', 'variant': None, 'identifier': 'europe/hr', 'gender': 1, 'age': None}, {'name': 'hungarian', 'variant': None, 'identifier': 'europe/hu', 'gender': 1, 'age': None}, {'name': 'armenian', 'variant': None, 'identifier': 'asia/hy', 'gender': 1, 'age': None}, {'name': 'armenian-west', 'variant': None, 'identifier': 'asia/hy-west', 'gender': 1, 'age': None}, {'name': 'indonesian', 'variant': None, 'identifier': 'asia/id', 'gender': 1, 'age': None}, {'name': 'icelandic', 'variant': None, 'identifier': 'europe/is', 'gender': 1, 'age': None}, {'name': 'italian', 'variant': None, 'identifier': 'europe/it', 'gender': 1, 'age': None}, {'name': 'lojban', 'variant': None, 'identifier': 'other/jbo', 'gender': None, 'age': None}, {'name': 'georgian', 'variant': None, 'identifier': 'asia/ka', 'gender': None, 'age': None}, {'name': 'kannada', 'variant': None, 'identifier': 'asia/kn', 'gender': None, 'age': None}, {'name': 'kurdish', 'variant': None, 'identifier': 'asia/ku', 'gender': 1, 'age': None}, {'name': 'latin', 'variant': None, 'identifier': 'other/la', 'gender': 1, 'age': None}, {'name': 'lingua_franca_nova', 'variant': None, 'identifier': 'other/lfn', 'gender': 1, 'age': None}, {'name': 'lithuanian', 'variant': None, 'identifier': 'europe/lt', 'gender': 1, 'age': None}, {'name': 'latvian', 'variant': None, 'identifier': 'europe/lv', 'gender': 1, 'age': None}, {'name': 'macedonian', 'variant': None, 'identifier': 'europe/mk', 'gender': 1, 'age': None}, {'name': 'malayalam', 'variant': None, 'identifier': 'asia/ml', 'gender': 1, 'age': None}, {'name': 'malay', 'variant': None, 'identifier': 'asia/ms', 'gender': 1, 'age': None}, {'name': 'nepali', 'variant': None, 'identifier': 'asia/ne', 'gender': 1, 'age': None}, {'name': 'dutch', 'variant': None, 'identifier': 'europe/nl', 'gender': 1, 'age': None}, {'name': 'norwegian', 'variant': None, 'identifier': 'europe/no', 'gender': 1, 'age': None}, {'name': 'punjabi', 'variant': None, 'identifier': 'asia/pa', 'gender': None, 'age': None}, {'name': 'polish', 'variant': None, 'identifier': 'europe/pl', 'gender': 1, 'age': None}, {'name': 'brazil', 'variant': None, 'identifier': 'pt', 'gender': 1, 'age': None}, {'name': 'portugal', 'variant': None, 'identifier': 'europe/pt-pt', 'gender': 1, 'age': None}, {'name': 'romanian', 'variant': None, 'identifier': 'europe/ro', 'gender': 1, 'age': None}, {'name': 'russian', 'variant': None, 'identifier': 'europe/ru', 'gender': 1, 'age': None}, {'name': 'slovak', 'variant': None, 'identifier': 'europe/sk', 'gender': 1, 'age': None}, {'name': 'albanian', 'variant': None, 'identifier': 'europe/sq', 'gender': 1, 'age': None}, {'name': 'serbian', 'variant': None, 'identifier': 'europe/sr', 'gender': 1, 'age': None}, {'name': 'swedish', 'variant': None, 'identifier': 'europe/sv', 'gender': 1, 'age': None}, {'name': 'swahili-test', 'variant': None, 'identifier': 'other/sw', 'gender': 1, 'age': None}, {'name': 'tamil', 'variant': None, 'identifier': 'asia/ta', 'gender': 1, 'age': None}, {'name': 'turkish', 'variant': None, 'identifier': 'asia/tr', 'gender': 1, 'age': None}, {'name': 'vietnam', 'variant': None, 'identifier': 'asia/vi', 'gender': 1, 'age': None}, {'name': 'vietnam_hue', 'variant': None, 'identifier': 'asia/vi-hue', 'gender': 1, 'age': None}, {'name': 'vietnam_sgn', 'variant': None, 'identifier': 'asia/vi-sgn', 'gender': 1, 'age': None}, {'name': 'Mandarin', 'variant': None, 'identifier': 'asia/zh', 'gender': 1, 'age': None}, {'name': 'cantonese', 'variant': None, 'identifier': 'asia/zh-yue', 'gender': 1, 'age': None}]

Se você quiser o idioma e o sotaque do português falado em Portugal, use o seguinte ajuste:

>>> espeak.set_voice('portugal')
True
>>> espeak.synth("Sintetizador de voz em Python, com o sotaque português europeu")
True

A quem preferir o sotaque (genérico) brasileiro, faça o ajuste assim:

>>> espeak.set_voice('brazil')
True
>>> espeak.synth("Sintetizador de voz em Python, com o sotaque brasileiro")
True

Este é o básico da sintetização de voz, no Python.
Acho útil para usar em scripts que rodam em background e que possam informar sobre algum evento que precise da intervenção do usuário, para avisar que alguma tarefa foi concluída etc.

Referências

https://elias.praciano.com/2014/10/como-sintetizar-voz-com-o-espeak/.

https://stackoverflow.com/questions/1614059/how-to-make-python-speak.

http://espeak.sourceforge.net/samples.html.

https://launchpad.net/python-espeak.

Assinar blog por e-mail

Digite seu endereço de e-mail para assinar este blog e receber notificações de novas publicações por e-mail.

Junte-se a 45 outros assinantes

Como criar scripts Python

Usuários Linux podem criar scripts em, praticamente, qualquer linguagem de programação, para executar diretamente na shell, sem a necessidade de compilar previamente qualquer coisa.
Claro que há algumas regras ou requisitos a serem preenchidos — e vamos falar disso aqui.

Não é complicado.
Vou usar, como exemplo, um código bem simples (abaixo).
Use o seu editor de textos favorito para escrever:


nome = input("Qual é o seu nome? ")
print("Você se chama "+nome+"? Hah! Que nome engraçado!")

Grave o arquivo com qualquer nome.
No meu exemplo, gravei como “nome.py”.
A função da extensão, no Linux, é ajudar você a identificar visualmente os tipos de arquivos.
O Linux não precisa de extensões para isto. Portanto, ela é opcional.
Na linha de comando (CLI), rode o interpretador Python (versão 3 ou superior, neste caso) acompanhado do arquivo de código.


python3 nome.py

Qual é o seu nome? elias
Você se chama elias? Hah! Que nome engraçado!

Infelizmente, você não pode simplesmente executar o arquivo de script diretamente, do jeito que ele está.
Se o fizer, o sistema irá informar que você não tem permissão para executar este código:


./nome.py

bash: ./nome.py: Permissão negada

Para resolver o problema da permissão, use o comando chmod:


chmod +x nome.py 

Mas isto ainda não é o suficiente!
Agora, já é possível rodar o código… mas a shell do seu sistema não irá entender nada:


./nome.py 
./nome.py: linha 1: erro de sintaxe próximo ao token inesperado `('
./nome.py: linha 1: `nome = input("Qual é o seu nome? ")'

Ainda é necessário indicar, dentro do script, qual interpretador deve ser usado para executá-lo.
Na primeira linha insira o seguinte código:

#!/bin/python3

Esta linha se chama “shebang“.
Agora, já será possível rodar o programa, direto na CLI, sem precisar indicar mais nada:

./nome.py 
Qual é o seu nome? elias
Você se chama elias? Hah! Que nome engraçado!

Simples, não é?
Você gostaria de saber por que é necessário usar ‘ ./ ‘ antes do nome do programa?! Então leia este artigo.

Assinar blog por e-mail

Digite seu endereço de e-mail para assinar este blog e receber notificações de novas publicações por e-mail.

Junte-se a 45 outros assinantes

Como importar facilmente tabelas de outros sites

Através de APIs é possível buscar informações contidas em tabelas e listas em vários sites na Internet.
Mas… e quando não há uma API disponível?!

O Python tem algumas bibliotecas que, combinadas, permitem importar este tipo de informação para dentro de uma lista.
Depois de instalar as ferramentas necessárias, a “mágica” pode ser feita com uma única linha de código.

Os pacotes necessários são estes:

  1. pandas — estruturas de recuperação de dados para análise e estatística.
  2. lxml — biblioteca de processamento de conteúdo em XML.
  3. beautifulsoup4 — biblioteca de utilitários e funções para “raspar” informações da tela.

Você pode usar o PIP para instalar tudo de uma vez:


sudo pip3 install pandas lxml beautifulsoup4

O que vai ser feito, no exemplo abaixo, é buscar as tabelas de dentro de uma página na internet e criar uma lista com elas.
Feito isto, é fácil acessar e trabalhar com cada uma.
Para testar abra a Python Shell ou o seu editor favorito e rode o seguinte código:


import pandas as pd
tabelas = pd.read_html("https://en.wikipedia.org/wiki/Comparison_of_text_editors")
print(tabelas[0])

Acima, a função print() foi usada para imprimir a primeira tabela capturada.
Se você tiver a curiosidade de visita o site, vai ver que ha outras.
Experimente exibi-las:


print(tabelas[11])

                       0                    1                         2
0                    NaN  Right-to-left (RTL)     Bi-directional (Bidi)
1                   Acme                   No                        No
2                AkelPad                   No                        No
3                Alphatk                    ?                         ?
4               Aquamacs                    ?                         ?
5                   Atom                  Yes                       Yes
6                 BBEdit                   No                        No
7               Bluefish                  Yes                       Yes
8               Brackets                    ?                         ?
9                   Coda                    ?                         ?
10               ConTEXT                    ?                         ?
11        Crimson Editor                    ?                         ?
12         E Text Editor                    ?                         ?
13                    ed                    ?                         ?
14              EditPlus                   No                        No
15                Editra                    ?                         ?
16              EmEditor                   No                        No
17                 Geany                    ?                         ?
18                 gedit                  Yes                       Yes
19             GNU Emacs                  Yes                  Yes[146]
20                 Gobby                    ?                         ?
21                   JED                    ?                         ?
22                 jEdit                   No                        No
23                   JOE                    ?                         ?
24                  JOVE                   No                        No
25                    LE                    ?                         ?
26                  Kate                  Yes                       Yes
27                 KEDIT                   No                        No
28           Komodo Edit                   No                        No
29            Komodo IDE                   No                        No
..                   ...                  ...                       ...
40               NoteTab                    ?                         ?
41                   nvi                    ?                         ?
42            Peppermint                   No                        No
43                  Pico                    ?                         ?
44              PolyEdit                    ?                         ?
45  Programmer's Notepad                   No                        No
46                 PSPad                    ?                         ?
47                   Q10                    ?                         ?
48             RJ TextEd                  Yes                       Yes
49                 RText                    ?                         ?
50                 SciTE                   No                        No
51             SlickEdit                    ?                         ?
52              Smultron                    ?                         ?
53        Source Insight                   No                        No
54           SubEthaEdit                  Yes                       Yes
55          Sublime Text                   No                        No
56           TED Notepad                    ?                         ?
57              TextEdit                  Yes                       Yes
58              TextMate                   No                        No
59               TextPad                    ?                         ?
60          TextWrangler                   No                        No
61    The SemWare Editor                   No                        No
62             UltraEdit                   No                        No
63                 VEDIT                    ?                         ?
64                    vi                    ?                         ?
65                   Vim                  Yes  through terminal support
66    Visual Studio Code                   No                        No
67                XEmacs                    ?                         ?
68                    Yi                    ?                         ?
69                   NaN                  RTL                      Bidi

[70 rows x 3 columns]

Fácil, não é?

Referências

Leia este texto, para saber mais sobre a função:
https://medium.com/@ageitgey/quick-tip-the-easiest-way-to-grab-data-out-of-a-web-page-in-python-7153cecfca58.

Assinar blog por e-mail

Digite seu endereço de e-mail para assinar este blog e receber notificações de novas publicações por e-mail.

Junte-se a 45 outros assinantes