Дмитрий
ДмитрийШілде 10, 2017, 3:19 Т.Ж.

Сөйлеу синтезі үшін QtTextToSpeech модулін пайдалану

Библиотека Qt 5.8.0 предоставила программистам возможность использовать системный синтезатор речи. Синтезатор речи - это программа, преобразующая текст в речь. Синтезаторы речи является неотъемлемой частью любой современной операционной системы: Windows (версии 7 и выше), Mac OS, Linux, iOS и Android. Кроссплатформенный интерфейс для управления синтезом речи предоставляет модуль QtTextToSpeech библиотеки Qt.

Для работы с модулем QtTextToSpeech на ОС Windows необходимо:

  • установить библиотеку Qt c модулем QtTextToSpeech для компилятора Visual Studio 2015 или старше ( mingw работать не будет );
  • установить компилятор Visual Studio 2015 ;
  • установить библиотеку SAPI 5.1 , если по какой-то причине она отсутствует на вашем компьютере;
  • установить голоса для синтезатора речи (если у вас они отсутствуют).
  • При сборке проекта необходимо использовать теневую сборку.

Описание

Если при компиляции программы Вы видите сообщение

Error loading text-to-speech plug-in "sapi"

то вы сделали что-то неправильно.

Если вы используете Android , то по умолчанию у вас работает online синтезатор. За это вы расплатитесь задержкой при синтезе и потраченным трафиком. Если это вас не устраивает, то устанавливайте offline версию. На Android 5.1 для этого необходимо перейти в «настройки» - «специальные возможности» - «синтез речи» - «синтезатор речи Google » - «установка голосовых данных» - «русский (Россия)» и жмём установить и ожидаем завершения. Кроме того, подготавливаем Qt Creator для создания Android приложений.

Теперь можно приступать к написанию программы. По ссылке вы можете скачать проект с исходным кодом программы, описанной ниже. Создаём процесс новый проект qtwidget. В файл проекта подключает необходимый модуль

QT += texttospeech

Подключаем библиотеку синтезатора речи

#include <QtTextToSpeech>

Создаём указатель на объект класса QTextToSpeech

QTextToSpeech* speech;

а затем и сам объект

speech = new QtextToSpeech;

Теперь можно генерировать речевые сигналы с помощью функции say(), в качестве аргумента которой нужно передать произносимый текст. В примерах созданных разработчиками Qt Creator приведён простой пример helloSpeech. Рассмотрите его для того, чтобы лучше понять возможности рассматриваемого модуля.

Я перейду к некоторым более сложным вещам. Программа, которую вы можете скачать по ссылке, содержит виджет класса QTextEdit для воспроизводимого текста , управляющие кнопки: старт, стоп, вперёд назад, …, окно для выбора файлов, и окна для настройки синтезатора.

void MainWindow::start(bool checked)

Запускать на воспроизведение можно и большие текстовые фрагменты. Однако это приводит к необязательным задержкам, а в случае online синтезатора на Android и к зависанию программы. Поэтому дробим текст на фрагменты, чем меньше, тем лучше. Для начала я выделяю из текста абзац ( int activeBlock ), а затем разбиваю строку на лист строк ( QStringList readList ) использую точки в качестве разделителя.

void MainWindow::start(bool checked)
{
    if(checked)
    {
        if(readList.isEmpty())
        {
            readList = ui->textEdit->document()->findBlockByNumber( activeBlock ).text().split(".");
        }
        if(!readList.isEmpty())
        {
            readString = readList.first();
            readList.removeFirst();
            if(!readString.contains(QRegularExpression("[A-Z]|[a-z]|[0-9]|[А-Я]|[а-я]")))
            {
                readString = ".";//windows не читает точки
                if(QSysInfo::productType() == "android")
                    readString = " ";
            }
            speech->say( readString );
            scrollTo();
            ui->textEdit->setReadOnly(true);
        }
    }
    else
    {
        readList.prepend(readString);//
        speech->stop();
        ui->textEdit->setReadOnly(false);
    }
}

void MainWindow::speechStateChange(QTextToSpeech::State state)

На синтезатор передаётся одна строчка. После завершения её воспроизведения speech генерирует сигнал stateChanged. Подключенный к ней слот speechStateChange отвечает за воспроизведение очередной строки.

void MainWindow::speechStateChange( QTextToSpeech::State state)
{
    QString mes;
    switch(state)
    {
    case QTextToSpeech::Ready:
        if(ui->pushButtonStart->isChecked())
        {
            textBlockSelection(colorClean);
            if(readList.isEmpty())
            {
                if( setActiveBlock( activeBlock+1 ) )
                    start();
                else
                    stop();
            }
            else
            {
                start();
            }
        }
        mes = "ready";
        break;
    case QTextToSpeech::Speaking:
        textBlockSelection(Qt::green);
        mes = "speaking";
        break;
    case QTextToSpeech::Paused:
        mes = "paused";
        break;
    case QTextToSpeech::BackendError:
        mes = "error";
        break;
    }
}

Вспомогательные функции

Для удобства использования программы в качестве читалки были написаны две вспомогательные функции scrollTo() для прокручивания текста до выбранного абзаца и textBlockSelection( QColor ) для выделения читаемого абзаца цветом фона. Ниже приведён их исходный код.

void MainWindow::scrollTo()

void MainWindow::scrollTo()
{
    if(ui->textEdit->verticalScrollBar()->maximum() == 0)
        return;
    QTextDocument *textDoc = ui->textEdit->document();
    int value = 0;
    for(int i = 0; i < activeBlock; i++)
    {
        value +=textDoc->findBlockByNumber(i).layout()->lineCount()
                * textDoc->findBlockByNumber(i).layout()->lineAt(0).height()
                + textDoc->findBlockByNumber(i).blockFormat().bottomMargin();
    }
    if(value <= ui->textEdit->verticalScrollBar()->maximum())
        ui->textEdit->verticalScrollBar()->setValue(value);
}

bool MainWindow::setActiveBlock(int blockNumber, bool scroll)

bool MainWindow::setActiveBlock(int blockNumber, bool scroll)
{
    readList.clear();
    textBlockSelection(colorClean);
    if(blockNumber < 0)
    {
        activeBlock = 0;
        if(scroll)
            scrollTo();
        return false;
    }
    if(blockNumber >= ui->textEdit->document()->blockCount())
    {
        activeBlock = ui->textEdit->document()->blockCount()-1;
        if(scroll)
            scrollTo();
        return false;
    }
    else
    {
        activeBlock = blockNumber;
        if(scroll)
            scrollTo();
        return true;
    }
}

Ударение и Омографы

Существенной проблемой для синтезатора речи является ударение. Особенно в тех случаях, когда два слова пишутся одинаково, но имеют разные ударения (омографы). В таком случае, без применения сложных семантических алгоритмов, ударение может быть выставлено только в ручную. И Windows ( в отличии от Android) позволяет это сделать. Для этого нужно поставить знак «`» ( на одной клавиши с буквой ё ). Однако точного механизма работы этого инструмента установить не удалось.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Дмитрий
  • Шілде 23, 2017, 2:52 Т.Ж.

Если вы знаете простой способ для извлечения текста из pdf или djv файлов напишите в ответе.

Evgenii Legotckoi
  • Шілде 23, 2017, 6:10 Т.Ж.

Лично я простого не знаю способа. В обоих случаях понадобится использовать сторонние библиотеки.

В случае с pdf - это будет либа, которая работает с pdf, какой-нибудь poppler-qt.
В случае же с djvu - это уже либа по распознаванию текста в изображениях.
Но за пример такой работы ничего не скажу, не занимался таким.

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз