Синтез речи под Linux на Python + RHVoice
Недавно я перешел с Windows на Linux. И обнаружил что под Linux нет нормального решения для синтеза русской речи с графическим интерфейсом. Самый лучший голосовой движок, который я нашел под Linux был RHVoice с голосом Anna. Но у движка напрочь отсутствовал графический интерфейс. Поэтому, я решил создать его, используя PyQT5 и Python.
Для начала нам нужно установить RHVoice.
Для сборки нужны некоторые библиотеки:
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pyqt5
sudo apt-get install scons gcc flite flite1-dev expat libunistring-dev libsox-dev
sudo apt-get install libasound-dev
sudo apt-get install libpulse-dev libao-dev
sudo git clone https://github.com/Olga-Yakovleva/RHVoice
cd RHVoice
sudo scons
sudo scons install
sudo ldconfig
После этого можно проверить, работает ли синтез речи с помощью команды в консоли:
echo «Привет я синтезатор речи» | RHVoice-test -p anna
Движок установили, теперь сделаем простенький GUI к нему.
Чтобы создать графический интерфейс под PyQt5, кроме самого PyQt5 понадобится также Qt designer. Как установить его, написано здесь:
https://askubuntu.com/questions/612314/how-to-install-pyqt-for-python-3-in-ubuntu-14-10
После установки, запускаем Designer командой:
qtchooser -run-tool=designer -qt=5
и создаем очень простой интерфейс из одного большого текстового поля и двух кнопок.
Сохраняем .ui файл как reader.ui, и преобразовываем его в файл .py командой:
pyuic5 reader.ui -o mygui.py
Теперь у нас есть файл mygui.py. В каталоге рядом с ним создаём файл reader.py и пишем в него такой код:
Если ввести в текстовое поле какой либо текст, и нажать кнопку "Читать текст", RHVoice последовательно будет читать предложения синтезируя речь на русском языке. При нажатии кнопки "Стоп" синтез речи прекратится.
Исходники данной программы можно скачать здесь:
http://solkogan.ru/rhvoicereader.zip
Программа тестировалась под Linux Mint с установленным Python 3.5, PyQt5.

import sys, time
import subprocess, re
import threading
from mygui import *
from PyQt5 import QtCore, QtGui, QtWidgets
# Переменная-флажок которая определяет произносить ли следующее предложение
# или выйти из цикла чтения предложений с помощью break
mstop=0
# Отдельный поток
def thread(my_func):
def wrapper(*args, **kwargs):
my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs)
my_thread.start()
return wrapper
# Функция отдельным потоком в которой производится чтение предложений
@thread
def processing(t):
# ставим переменную-флажок = 1
global mstop
mstop=1
# Заменяем в тексте переносы строк и табы на точки и пробелы
t=t.replace('\n','. ')
t=t.replace('\t','')
t=t.replace('\r','. ')
t=t.replace('..','.')
# Делим текст на массив предложений
mas=re.split("\\b[.!?\\n]+(?=\\s)", t)
for z in mas:
# Если переменная флажок обнулилась выходим из цикла чтения предложений
if (mstop==0): break
# Формируем командную строку для RHVoice
s='echo «'+z+'» | RHVoice-test -p anna'
# Запускаем командную строку
subprocess.call(s, shell=True)
class MyWin(QtWidgets.QMainWindow):
my_signal = QtCore.pyqtSignal(list, name='my_signal')
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Определяем функцию Mystop при нажатии на вторую кнопку
self.ui.pushButton_2.clicked.connect(self.Mystop)
# При нажатии на первую кнопку вызываем во втором потоке функцию чтения текста,
# передав в нее текст из текстового поля textEdit
self.ui.pushButton.clicked.connect(lambda: processing(self.ui.textEdit.toPlainText()))
# Функция срабатывающая при нажатии кнопки Стоп
# Обнуляет переменную-флажок и убивает процесс речи
def Mystop(self):
PIPE = subprocess.PIPE
subprocess.Popen('pkill -9 RHVoice-test', shell=True, stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT)
global mstop
mstop=0
if __name__=="__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
После запуска данной программы появляется наше окно:
