Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Added speed control option for Text-to-Speech module #1317

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,8 @@
"select-read-voice": "Select reading voice",
"select-read-language": "Select reading language",
"save-or-open": "Save or Open file",
"save-or-open-text": "What should Kiwix do with this file?"
"save-or-open-text": "What should Kiwix do with this file?",
"speed": "Speed",
"increase-tts-speed": "Represents the action of increasing the speed of the text-to-speech.",
"decrease-tts-speed": "Represents the action of decreasing the speed of the text-to-speech."
}
5 changes: 4 additions & 1 deletion resources/i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,8 @@
"select-read-voice": "Represents the action of opening the voice selection for text-to-speech.",
"select-read-language": "Represents the action of opening the language selection for text-to-speech.",
"save-or-open": "Title of the message box allowing to choose whether a remote resource should be saved to disk or opened with a respective application",
"save-or-open-text": "Text of the message box allowing to choose whether a remote resource should be saved to disk or opened with a respective application"
"save-or-open-text": "Text of the message box allowing to choose whether a remote resource should be saved to disk or opened with a respective application",
"speed": "Label for text-to-speech speed adjustment control.",
"increase-tts-speed": "Represents the action of increasing the speed of the text-to-speech.",
"decrease-tts-speed": "Represents the action of decreasing the speed of the text-to-speech."
}
12 changes: 12 additions & 0 deletions src/kiwixapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ void KiwixApp::createActions()
CREATE_ACTION_SHORTCUT(ReadStopAction, gt("read-stop"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_X));
CREATE_ACTION_SHORTCUT(ToggleTTSLanguageAction, gt("select-read-language"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_L));
CREATE_ACTION_SHORTCUT(ToggleTTSVoiceAction, gt("select-read-voice"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_V));
CREATE_ACTION_SHORTCUT(IncreaseTTSSpeedAction, gt("increase-tts-speed"), QKeySequence(Qt::Key_Greater));
CREATE_ACTION_SHORTCUT(DecreaseTTSSpeedAction, gt("decrease-tts-speed"), QKeySequence(Qt::Key_Less));
mpa_actions[ToggleTTSLanguageAction]->setCheckable(true);
mpa_actions[ToggleTTSVoiceAction]->setCheckable(true);

Expand Down Expand Up @@ -558,6 +560,11 @@ void KiwixApp::saveVoiceName(const QString& langName, const QString& voiceName)
mp_session->setValue("voice/" + langName, voiceName);
}

void KiwixApp::saveTtsSpeed(const QString& langName, double speed)
{
mp_session->setValue("speed/" + langName, speed);
}

void KiwixApp::restoreWindowState()
{
getMainWindow()->restoreGeometry(mp_session->value("geometry").toByteArray());
Expand All @@ -579,6 +586,11 @@ QString KiwixApp::getSavedVoiceName(const QString& langName) const
return mp_session->value("voice/" + langName, "").toString();
}

double KiwixApp::getSavedTtsSpeed(const QString& langName) const
{
return mp_session->value("speed/" + langName, 1.0).toDouble(); // Default: 1.0 (normal speed)
}

QString KiwixApp::getPrevSaveDir() const
{
QString prevSaveDir = mp_session->value("prevSaveDir", DEFAULT_SAVE_DIR).toString();
Expand Down
4 changes: 4 additions & 0 deletions src/kiwixapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class KiwixApp : public QtSingleApplication
ToggleAddBookmarkAction,
ToggleTTSLanguageAction,
ToggleTTSVoiceAction,
IncreaseTTSSpeedAction,
DecreaseTTSSpeedAction,
ZoomInAction,
ZoomOutAction,
ZoomResetAction,
Expand Down Expand Up @@ -101,10 +103,12 @@ class KiwixApp : public QtSingleApplication
void saveListOfOpenTabs();
void saveWindowState();
void saveVoiceName(const QString& langName, const QString& voiceName);
void saveTtsSpeed(const QString& langName, double speed);
void restoreWindowState();
void saveCurrentTabIndex();
void savePrevSaveDir(const QString& prevSaveDir);
QString getSavedVoiceName(const QString& langName) const;
double getSavedTtsSpeed(const QString& langName) const;
QString getPrevSaveDir() const;
void restoreTabs();
void setupDirectoryMonitoring();
Expand Down
2 changes: 2 additions & 0 deletions src/mainmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ MainMenu::MainMenu(QWidget *parent) :
m_viewMenu.ADD_ACTION(ToggleReadingListAction);
m_viewMenu.ADD_ACTION(ToggleTTSLanguageAction);
m_viewMenu.ADD_ACTION(ToggleTTSVoiceAction);
m_viewMenu.ADD_ACTION(IncreaseTTSSpeedAction);
m_viewMenu.ADD_ACTION(DecreaseTTSSpeedAction);
m_viewMenu.ADD_ACTION(ZoomInAction);
m_viewMenu.ADD_ACTION(ZoomOutAction);
m_viewMenu.ADD_ACTION(ZoomResetAction);
Expand Down
59 changes: 59 additions & 0 deletions src/texttospeechbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,36 @@ TextToSpeechBar::TextToSpeechBar(QWidget *parent)
connect(ui->closeButton, &QPushButton::pressed,
this, &TextToSpeechBar::speechClose);

setupSpeedOptionsComboBox();
setupVoiceComboBox();
setupLanguageComboBox();
languageSelected(ui->langComboBox->currentIndex());
connect(app->getAction(KiwixApp::ToggleTTSLanguageAction), &QAction::triggered,
this, &TextToSpeechBar::toggleLanguage);
connect(app->getAction(KiwixApp::ToggleTTSVoiceAction), &QAction::triggered,
this, &TextToSpeechBar::toggleVoice);
connect(app->getAction(KiwixApp::IncreaseTTSSpeedAction), &QAction::triggered,
this, &TextToSpeechBar::increaseSpeed);
connect(app->getAction(KiwixApp::DecreaseTTSSpeedAction), &QAction::triggered,
this, &TextToSpeechBar::decreaseSpeed);
connect(ui->speedComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &TextToSpeechBar::onSpeedChanged);
}

void TextToSpeechBar::increaseSpeed()
{
int currentIndex = ui->speedComboBox->currentIndex();
if (currentIndex < ui->speedComboBox->count() - 1) {
ui->speedComboBox->setCurrentIndex(currentIndex + 1);
}
}

void TextToSpeechBar::decreaseSpeed()
{
int currentIndex = ui->speedComboBox->currentIndex();
if (currentIndex > 0) {
ui->speedComboBox->setCurrentIndex(currentIndex - 1);
}
}

void TextToSpeechBar::speak(const QString &text)
Expand All @@ -54,6 +77,16 @@ void TextToSpeechBar::setLocale(const QLocale& locale)
}
}

void TextToSpeechBar::setupSpeedOptionsComboBox()
{
ui->speedLabel->setText(gt("speed"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot to include the change to resources/i18n/en.json. Please also don't forget to update resources/i18n/qqq.json too.

ui->speedComboBox->setMaxVisibleItems(10);
ui->speedComboBox->setLineEdit(new ComboBoxLineEdit(ui->speedComboBox));

QStringList speedOptions = {"0.25","0.50","0.75","1.00","1.25","1.50","1.75","2.00"};
ui->speedComboBox->addItems(speedOptions);
}

void TextToSpeechBar::setupLanguageComboBox()
{
ui->langLabel->setText(gt("language"));
Expand Down Expand Up @@ -107,6 +140,13 @@ void TextToSpeechBar::resetVoiceComboBox()
connect(ui->voiceComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &TextToSpeechBar::voiceSelected);
}

void TextToSpeechBar::resetSpeedComboBox()
{
double savedSpeed = KiwixApp::instance()->getSavedTtsSpeed(m_speech.locale().name());
int index = (savedSpeed - 0.25) * 4;
ui->speedComboBox->setCurrentIndex(index);
}

int TextToSpeechBar::getVoiceIndex()
{
int voiceIndex = 0;
Expand Down Expand Up @@ -174,6 +214,7 @@ void TextToSpeechBar::languageSelected(int index)
const QLocale locale = ui->langComboBox->itemData(index).toLocale();
m_speech.setLocale(locale);
resetVoiceComboBox();
resetSpeedComboBox();
}

void TextToSpeechBar::voiceSelected(int index)
Expand Down Expand Up @@ -203,6 +244,24 @@ void TextToSpeechBar::onStateChanged(QTextToSpeech::State state)
ui->stopButton->setEnabled(state != QTextToSpeech::Ready);
}

void TextToSpeechBar::onSpeedChanged(int index)
{
QString speedText = ui->speedComboBox->itemText(index);
double speed = speedText.toDouble();
m_speech.setRate(speed - 1); // range:-1,1

// Save tts speed for current lang
const auto currentLang = ui->langComboBox->currentData().toLocale().name();
KiwixApp::instance()->saveTtsSpeed(currentLang, speed);

// Restarting the speech with new speed set above
if (m_speech.state() == QTextToSpeech::Speaking)
{
m_speech.stop();
m_speech.say(m_text);
}
}

ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) : QLineEdit(parent)
{
setFrame(false);
Expand Down
5 changes: 5 additions & 0 deletions src/texttospeechbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class TextToSpeechBar : public QFrame
void setupLanguageComboBox();
void setupVoiceComboBox();
void resetVoiceComboBox();
void setupSpeedOptionsComboBox();
void resetSpeedComboBox();

int getVoiceIndex();

Expand All @@ -46,6 +48,9 @@ public slots:
void toggleLanguage();
void languageSelected(int index);
void voiceSelected(int index);
void onSpeedChanged(int index);
void increaseSpeed();
void decreaseSpeed();

protected:
void keyPressEvent(QKeyEvent *event);
Expand Down
14 changes: 14 additions & 0 deletions src/texttospeechbar.ui
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="speedLabel">
<property name="text">
<string>Speed</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="speedComboBox">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
Expand Down