mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Text to speech engine - finishing
This commit is contained in:
@ -108,7 +108,9 @@ PDFSidebarWidget::PDFSidebarWidget(pdf::PDFDrawWidgetProxy* proxy, PDFTextToSpee
|
|||||||
|
|
||||||
m_textToSpeech->initializeUI(ui->speechLocaleComboBox, ui->speechVoiceComboBox,
|
m_textToSpeech->initializeUI(ui->speechLocaleComboBox, ui->speechVoiceComboBox,
|
||||||
ui->speechRateEdit, ui->speechPitchEdit, ui->speechVolumeEdit,
|
ui->speechRateEdit, ui->speechPitchEdit, ui->speechVolumeEdit,
|
||||||
ui->speechPlayButton, ui->speechPauseButton, ui->speechStopButton, ui->speechSynchronizeButton);
|
ui->speechPlayButton, ui->speechPauseButton, ui->speechStopButton, ui->speechSynchronizeButton,
|
||||||
|
ui->speechRateValueLabel, ui->speechPitchValueLabel, ui->speechVolumeValueLabel,
|
||||||
|
ui->speechActualTextEdit);
|
||||||
|
|
||||||
selectPage(Invalid);
|
selectPage(Invalid);
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
@ -274,16 +274,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="0">
|
||||||
<widget class="QSlider" name="speechVolumeEdit">
|
<widget class="QLabel" name="speechVolumeLabel">
|
||||||
<property name="maximum">
|
<property name="text">
|
||||||
<number>100</number>
|
<string>Volume</string>
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -300,13 +294,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="speechRateLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Rate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="speechPitchLabel">
|
<widget class="QLabel" name="speechPitchLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -314,13 +301,35 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="speechVolumeLabel">
|
<widget class="QSlider" name="speechVolumeEdit">
|
||||||
<property name="text">
|
<property name="maximum">
|
||||||
<string>Volume</string>
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="speechRateLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="speechRateValueLabel"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="speechPitchValueLabel"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="speechVolumeValueLabel"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -368,22 +377,18 @@
|
|||||||
<iconset resource="pdfforqtviewer.qrc">
|
<iconset resource="pdfforqtviewer.qrc">
|
||||||
<normaloff>:/resources/synchronize.svg</normaloff>:/resources/synchronize.svg</iconset>
|
<normaloff>:/resources/synchronize.svg</normaloff>:/resources/synchronize.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<widget class="QTextBrowser" name="speechActualTextEdit"/>
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>393</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
#include "pdfcompiler.h"
|
#include "pdfcompiler.h"
|
||||||
#include "pdfdrawwidget.h"
|
#include "pdfdrawwidget.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
#include <QTextBrowser>
|
||||||
#include <QTextToSpeech>
|
#include <QTextToSpeech>
|
||||||
|
|
||||||
namespace pdfviewer
|
namespace pdfviewer
|
||||||
@ -45,7 +47,11 @@ PDFTextToSpeech::PDFTextToSpeech(QObject* parent) :
|
|||||||
m_speechPlayButton(nullptr),
|
m_speechPlayButton(nullptr),
|
||||||
m_speechPauseButton(nullptr),
|
m_speechPauseButton(nullptr),
|
||||||
m_speechStopButton(nullptr),
|
m_speechStopButton(nullptr),
|
||||||
m_speechSynchronizeButton(nullptr)
|
m_speechSynchronizeButton(nullptr),
|
||||||
|
m_speechRateValueLabel(nullptr),
|
||||||
|
m_speechPitchValueLabel(nullptr),
|
||||||
|
m_speechVolumeValueLabel(nullptr),
|
||||||
|
m_speechActualTextBrowser(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -138,7 +144,7 @@ void PDFTextToSpeech::setSettings(const PDFViewerSettings* viewerSettings)
|
|||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFTextToSpeech::setProxy(const pdf::PDFDrawWidgetProxy* proxy)
|
void PDFTextToSpeech::setProxy(pdf::PDFDrawWidgetProxy* proxy)
|
||||||
{
|
{
|
||||||
m_proxy = proxy;
|
m_proxy = proxy;
|
||||||
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
|
pdf::PDFAsynchronousTextLayoutCompiler* compiler = m_proxy->getTextLayoutCompiler();
|
||||||
@ -153,7 +159,11 @@ void PDFTextToSpeech::initializeUI(QComboBox* speechLocaleComboBox,
|
|||||||
QToolButton* speechPlayButton,
|
QToolButton* speechPlayButton,
|
||||||
QToolButton* speechPauseButton,
|
QToolButton* speechPauseButton,
|
||||||
QToolButton* speechStopButton,
|
QToolButton* speechStopButton,
|
||||||
QToolButton* speechSynchronizeButton)
|
QToolButton* speechSynchronizeButton,
|
||||||
|
QLabel* speechRateValueLabel,
|
||||||
|
QLabel* speechPitchValueLabel,
|
||||||
|
QLabel* speechVolumeValueLabel,
|
||||||
|
QTextBrowser* speechActualTextBrowser)
|
||||||
{
|
{
|
||||||
Q_ASSERT(speechLocaleComboBox);
|
Q_ASSERT(speechLocaleComboBox);
|
||||||
Q_ASSERT(speechVoiceComboBox);
|
Q_ASSERT(speechVoiceComboBox);
|
||||||
@ -174,6 +184,10 @@ void PDFTextToSpeech::initializeUI(QComboBox* speechLocaleComboBox,
|
|||||||
m_speechPauseButton = speechPauseButton;
|
m_speechPauseButton = speechPauseButton;
|
||||||
m_speechStopButton = speechStopButton;
|
m_speechStopButton = speechStopButton;
|
||||||
m_speechSynchronizeButton = speechSynchronizeButton;
|
m_speechSynchronizeButton = speechSynchronizeButton;
|
||||||
|
m_speechRateValueLabel = speechRateValueLabel;
|
||||||
|
m_speechPitchValueLabel = speechPitchValueLabel;
|
||||||
|
m_speechVolumeValueLabel = speechVolumeValueLabel;
|
||||||
|
m_speechActualTextBrowser = speechActualTextBrowser;
|
||||||
|
|
||||||
connect(m_speechLocaleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onLocaleChanged);
|
connect(m_speechLocaleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onLocaleChanged);
|
||||||
connect(m_speechVoiceComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onVoiceChanged);
|
connect(m_speechVoiceComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PDFTextToSpeech::onVoiceChanged);
|
||||||
@ -303,18 +317,21 @@ void PDFTextToSpeech::setRate(const double rate)
|
|||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechRateEdit->minimum(), m_speechRateEdit->maximum());
|
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechRateEdit->minimum(), m_speechRateEdit->maximum());
|
||||||
m_speechRateEdit->setValue(qRound(interpolation(rate)));
|
m_speechRateEdit->setValue(qRound(interpolation(rate)));
|
||||||
|
onRateChanged(m_speechRateEdit->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFTextToSpeech::setPitch(const double pitch)
|
void PDFTextToSpeech::setPitch(const double pitch)
|
||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum());
|
pdf::PDFLinearInterpolation<double> interpolation(-1.0, 1.0, m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum());
|
||||||
m_speechPitchEdit->setValue(qRound(interpolation(pitch)));
|
m_speechPitchEdit->setValue(qRound(interpolation(pitch)));
|
||||||
|
onPitchChanged(m_speechPitchEdit->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFTextToSpeech::setVolume(const double volume)
|
void PDFTextToSpeech::setVolume(const double volume)
|
||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(0.0, 1.0, m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum());
|
pdf::PDFLinearInterpolation<double> interpolation(0.0, 1.0, m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum());
|
||||||
m_speechVolumeEdit->setValue(qRound(interpolation(volume)));
|
m_speechVolumeEdit->setValue(qRound(interpolation(volume)));
|
||||||
|
onVolumeChanged(m_speechVolumeEdit->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFTextToSpeech::onLocaleChanged()
|
void PDFTextToSpeech::onLocaleChanged()
|
||||||
@ -345,7 +362,9 @@ void PDFTextToSpeech::onRateChanged(int rate)
|
|||||||
if (m_textToSpeech)
|
if (m_textToSpeech)
|
||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(m_speechRateEdit->minimum(), m_speechRateEdit->maximum(), -1.0, 1.0);
|
pdf::PDFLinearInterpolation<double> interpolation(m_speechRateEdit->minimum(), m_speechRateEdit->maximum(), -1.0, 1.0);
|
||||||
m_textToSpeech->setRate(interpolation(rate));
|
double value = interpolation(rate);
|
||||||
|
m_textToSpeech->setRate(value);
|
||||||
|
m_speechRateValueLabel->setText(QString::number(value, 'f', 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +373,9 @@ void PDFTextToSpeech::onPitchChanged(int pitch)
|
|||||||
if (m_textToSpeech)
|
if (m_textToSpeech)
|
||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum(), -1.0, 1.0);
|
pdf::PDFLinearInterpolation<double> interpolation(m_speechPitchEdit->minimum(), m_speechPitchEdit->maximum(), -1.0, 1.0);
|
||||||
m_textToSpeech->setPitch(interpolation(pitch));
|
double value = interpolation(pitch);
|
||||||
|
m_textToSpeech->setPitch(pitch);
|
||||||
|
m_speechPitchValueLabel->setText(QString::number(value, 'f', 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +384,9 @@ void PDFTextToSpeech::onVolumeChanged(int volume)
|
|||||||
if (m_textToSpeech)
|
if (m_textToSpeech)
|
||||||
{
|
{
|
||||||
pdf::PDFLinearInterpolation<double> interpolation(m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum(), 0.0, 1.0);
|
pdf::PDFLinearInterpolation<double> interpolation(m_speechVolumeEdit->minimum(), m_speechVolumeEdit->maximum(), 0.0, 1.0);
|
||||||
m_textToSpeech->setVolume(interpolation(volume));
|
double value = interpolation(volume);
|
||||||
|
m_textToSpeech->setVolume(value);
|
||||||
|
m_speechVolumeValueLabel->setText(QString::number(value, 'f', 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +398,10 @@ void PDFTextToSpeech::onPlayClicked()
|
|||||||
{
|
{
|
||||||
m_textToSpeech->resume();
|
m_textToSpeech->resume();
|
||||||
m_state = Playing;
|
m_state = Playing;
|
||||||
updatePlay();
|
if (m_textToSpeech->state() == QTextToSpeech::Ready)
|
||||||
|
{
|
||||||
|
updatePlay();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,6 +478,7 @@ void PDFTextToSpeech::updatePlay()
|
|||||||
const pdf::PDFTextFlow& textFlow = m_textFlows[m_currentTextFlowIndex];
|
const pdf::PDFTextFlow& textFlow = m_textFlows[m_currentTextFlowIndex];
|
||||||
QString text = textFlow.getText();
|
QString text = textFlow.getText();
|
||||||
m_textToSpeech->say(text);
|
m_textToSpeech->say(text);
|
||||||
|
m_speechActualTextBrowser->setText(text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -480,6 +507,7 @@ void PDFTextToSpeech::updateToNextPage(pdf::PDFInteger pageIndex)
|
|||||||
|
|
||||||
m_currentTextLayout = pdf::PDFTextLayout();
|
m_currentTextLayout = pdf::PDFTextLayout();
|
||||||
m_textFlows.clear();
|
m_textFlows.clear();
|
||||||
|
m_speechActualTextBrowser->clear();
|
||||||
|
|
||||||
// Find first nonempty page
|
// Find first nonempty page
|
||||||
while (m_currentPage < pageCount)
|
while (m_currentPage < pageCount)
|
||||||
@ -495,6 +523,11 @@ void PDFTextToSpeech::updateToNextPage(pdf::PDFInteger pageIndex)
|
|||||||
++m_currentPage;
|
++m_currentPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_currentPage < pageCount && m_speechSynchronizeButton->isChecked())
|
||||||
|
{
|
||||||
|
m_proxy->goToPage(m_currentPage);
|
||||||
|
}
|
||||||
|
|
||||||
m_currentTextFlowIndex = 0;
|
m_currentTextFlowIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,11 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
class QSlider;
|
class QSlider;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
|
class QTextBrowser;
|
||||||
class QTextToSpeech;
|
class QTextToSpeech;
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
@ -70,7 +72,7 @@ public:
|
|||||||
void setSettings(const PDFViewerSettings* viewerSettings);
|
void setSettings(const PDFViewerSettings* viewerSettings);
|
||||||
|
|
||||||
/// Set draw proxy
|
/// Set draw proxy
|
||||||
void setProxy(const pdf::PDFDrawWidgetProxy* proxy);
|
void setProxy(pdf::PDFDrawWidgetProxy* proxy);
|
||||||
|
|
||||||
/// Initialize the ui, which is used
|
/// Initialize the ui, which is used
|
||||||
void initializeUI(QComboBox* speechLocaleComboBox,
|
void initializeUI(QComboBox* speechLocaleComboBox,
|
||||||
@ -81,7 +83,11 @@ public:
|
|||||||
QToolButton* speechPlayButton,
|
QToolButton* speechPlayButton,
|
||||||
QToolButton* speechPauseButton,
|
QToolButton* speechPauseButton,
|
||||||
QToolButton* speechStopButton,
|
QToolButton* speechStopButton,
|
||||||
QToolButton* speechSynchronizeButton);
|
QToolButton* speechSynchronizeButton,
|
||||||
|
QLabel* speechRateValueLabel,
|
||||||
|
QLabel* speechPitchValueLabel,
|
||||||
|
QLabel* speechVolumeValueLabel,
|
||||||
|
QTextBrowser* speechActualTextBrowser);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Updates UI controls depending on the state
|
/// Updates UI controls depending on the state
|
||||||
@ -111,7 +117,7 @@ private:
|
|||||||
|
|
||||||
QTextToSpeech* m_textToSpeech;
|
QTextToSpeech* m_textToSpeech;
|
||||||
const pdf::PDFDocument* m_document;
|
const pdf::PDFDocument* m_document;
|
||||||
const pdf::PDFDrawWidgetProxy* m_proxy;
|
pdf::PDFDrawWidgetProxy* m_proxy;
|
||||||
State m_state;
|
State m_state;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
|
||||||
@ -124,6 +130,10 @@ private:
|
|||||||
QToolButton* m_speechPauseButton;
|
QToolButton* m_speechPauseButton;
|
||||||
QToolButton* m_speechStopButton;
|
QToolButton* m_speechStopButton;
|
||||||
QToolButton* m_speechSynchronizeButton;
|
QToolButton* m_speechSynchronizeButton;
|
||||||
|
QLabel* m_speechRateValueLabel;
|
||||||
|
QLabel* m_speechPitchValueLabel;
|
||||||
|
QLabel* m_speechVolumeValueLabel;
|
||||||
|
QTextBrowser* m_speechActualTextBrowser;
|
||||||
|
|
||||||
pdf::PDFTextLayout m_currentTextLayout; ///< Text layout for actual page
|
pdf::PDFTextLayout m_currentTextLayout; ///< Text layout for actual page
|
||||||
pdf::PDFTextFlows m_textFlows; ///< Text flows for actual page
|
pdf::PDFTextFlows m_textFlows; ///< Text flows for actual page
|
||||||
|
Reference in New Issue
Block a user