QtLingo 1
QtLingo is an Application to make Qt Computer Translations easier
qonlinetts.cpp
Go to the documentation of this file.
1/*
2 * Copyright © 2018-2021 Hennadii Chernyshchyk <genaloner@gmail.com>
3 *
4 * This file is part of QOnlineTranslator.
5 *
6 * QOnlineTranslator is free library; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a get of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include "qonlinetts.h"
22
23
27const QMap<QOnlineTts::Emotion, QString> QOnlineTts::s_emotionCodes =
28{
29 {Neutral, QStringLiteral("neutral")},
30 {Good, QStringLiteral("good")},
31 {Evil, QStringLiteral("evil")}
32};
33
37const QMap<QOnlineTts::Voice, QString> QOnlineTts::s_voiceCodes =
38{
39 {Zahar, QStringLiteral("zahar")},
40 {Ermil, QStringLiteral("ermil")},
41 {Jane, QStringLiteral("jane")},
42 {Oksana, QStringLiteral("oksana")},
43 {Alyss, QStringLiteral("alyss")},
44 {Omazh, QStringLiteral("omazh")}
45};
46
50QOnlineTts::QOnlineTts(QObject *parent) : QObject(parent)
51{
52}
53
58{
59 // Get speech
60 QString unparsedText = text;
61 switch (engine)
62 {
64 {
65 if (voice != NoVoice)
66 {
67 setError(UnsupportedVoice, QString("%1 %2 %3").arg(tr("Selected engine"), QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(engine), tr("does not support voice settings")));
68 return;
69 }
70
71 if (emotion != NoEmotion)
72 {
73 setError(UnsupportedEmotion, QString("%1 %2 %3").arg(tr("Selected engine"), QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(engine), tr("does not support emotion settings")));
74 return;
75 }
76
77 const QString langString = languageApiCode(engine, lang);
78 if (langString.isNull())
79 return;
80
81 // Google has a limit of characters per tts request. If the query is larger, then it should be splited into several
82 while (!unparsedText.isEmpty())
83 {
84 const int splitIndex = QOnlineTranslator::getSplitIndex(unparsedText, s_googleTtsLimit); // Split the part by special symbol
85
86 // Generate URL API for add it to the playlist
87 QUrl apiUrl(QStringLiteral("http://translate.googleapis.com/translate_tts"));
88 const QString query = QStringLiteral("ie=UTF-8&client=gtx&tl=%1&q=%2").arg(langString, QString(QUrl::toPercentEncoding(unparsedText.left(splitIndex))));
89 #if defined(Q_OS_LINUX)
90 apiUrl.setQuery(query);
91 #elif defined(Q_OS_WIN)
92 apiUrl.setQuery(query, QUrl::DecodedMode);
93 #endif
94 m_media.append(apiUrl);
95
96 // Remove the said part from the next saying
97 unparsedText = unparsedText.mid(splitIndex);
98 }
99 break;
100 }
102 {
103 const QString langString = languageApiCode(engine, lang);
104 if (langString.isNull())
105 return;
106
107 const QString voiceString = voiceApiCode(engine, voice);
108 if (voiceString.isNull())
109 return;
110
111 const QString emotionString = emotionApiCode(engine, emotion);
112 if (emotionString.isNull())
113 return;
114
115 // Yandex has a limit of characters per tts request. If the query is larger, then it should be splited into several
116 while (!unparsedText.isEmpty())
117 {
118 const int splitIndex = QOnlineTranslator::getSplitIndex(unparsedText, s_yandexTtsLimit); // Split the part by special symbol
119
120 // Generate URL API for add it to the playlist
121 QUrl apiUrl(QStringLiteral("https://tts.voicetech.yandex.net/tts"));
122 const QString query = QStringLiteral("text=%1&lang=%2&speaker=%3&emotion=%4&format=mp3")
123 .arg(QUrl::toPercentEncoding(unparsedText.left(splitIndex)), langString, voiceString, emotionString);
124 #if defined(Q_OS_LINUX)
125 apiUrl.setQuery(query);
126 #elif defined(Q_OS_WIN)
127 apiUrl.setQuery(query, QUrl::DecodedMode);
128 #endif
129 m_media.append(apiUrl);
130
131 // Remove the said part from the next saying
132 unparsedText = unparsedText.mid(splitIndex);
133 }
134 break;
135 }
137 setError(UnsupportedEngine, QString("%1 %2").arg(QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(QOnlineTranslator::Bing), tr("engine does not support TTS")));
138 }
139}
140
144QList<QMediaContent> QOnlineTts::media() const
145{
146 return m_media;
147}
148
153{
154 return m_errorString;
155}
156
161{
162 return m_error;
163}
164
169{
170 return s_voiceCodes.value(voice);
171}
172
177{
178 return s_emotionCodes.value(emotion);
179}
180
184QOnlineTts::Emotion QOnlineTts::emotion(const QString &emotionCode)
185{
186 return s_emotionCodes.key(emotionCode, NoEmotion);
187}
188
192QOnlineTts::Voice QOnlineTts::voice(const QString &voiceCode)
193{
194 return s_voiceCodes.key(voiceCode, NoVoice);
195}
196
200void QOnlineTts::setError(TtsError error, const QString &errorString)
201{
202 m_error = error;
203 m_errorString = errorString;
204}
205
209QString QOnlineTts::languageApiCode(QOnlineTranslator::Engine engine, QOnlineTranslator::Language lang)
210{
211 switch (engine)
212 {
214 if (lang != QOnlineTranslator::Auto)
215 { return QOnlineTranslator::languageApiCode(engine, lang); } // Google use the same codes for tts (except 'auto')
216 break;
218 switch (lang)
219 {
221 return QStringLiteral("ru_RU");
223 return QStringLiteral("tr_TR");
225 return QStringLiteral("en_GB");
226 default:
227 break;
228 }
229 break;
230 default:
231 break;
232 }
233
234 setError(UnsupportedLanguage, QString("%1 %2 %3").arg(tr("Selected language"), QMetaEnum::fromType<QOnlineTranslator::Language>().valueToKey(lang), QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(engine), tr("is not supported for")));
235 return QString();
236}
237
241QString QOnlineTts::voiceApiCode(QOnlineTranslator::Engine engine, Voice voice)
242{
243 if (engine == QOnlineTranslator::Yandex)
244 {
245 if (voice == NoVoice)
246 return voiceCode(Zahar);
247 return voiceCode(voice);
248 }
249
250 setError(UnsupportedVoice, QString(" %1 %2 %2").arg(tr("Selected voice"), QMetaEnum::fromType<Voice>().valueToKey(voice), QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(engine), tr("is not supported for")));
251 return QString();
252}
253
257QString QOnlineTts::emotionApiCode(QOnlineTranslator::Engine engine, Emotion emotion)
258{
259 if (engine == QOnlineTranslator::Yandex)
260 {
261 if (emotion == NoEmotion)
262 return emotionCode(Neutral);
263 return emotionCode(emotion);
264 }
265
266 setError(UnsupportedEmotion, QString("%1 %2 %3").arg(tr("Selected emotion"), QMetaEnum::fromType<Emotion>().valueToKey(emotion), QMetaEnum::fromType<QOnlineTranslator::Engine>().valueToKey(engine), tr("is not supported for")));
267 return QString();
268}
269
QString errorString() const
errorString
Definition: qonlinetts.cpp:152
static Voice voice(const QString &voiceCode)
voice
Definition: qonlinetts.cpp:192
QOnlineTts(QObject *parent=nullptr)
QOnlineTts.
Definition: qonlinetts.cpp:50
@ NoEmotion
NoEmotion
Definition: qonlinetts.h:55
@ Neutral
Neutral
Definition: qonlinetts.h:57
TtsError error() const
error
Definition: qonlinetts.cpp:160
static Emotion emotion(const QString &emotionCode)
emotion
Definition: qonlinetts.cpp:184
static QString emotionCode(Emotion emotion)
emotionCode
Definition: qonlinetts.cpp:176
QList< QMediaContent > media() const
media
Definition: qonlinetts.cpp:144
@ NoVoice
NoVoice
Definition: qonlinetts.h:41
@ Zahar
Zahar
Definition: qonlinetts.h:43
void generateUrls(const QString &text, QOnlineTranslator::Engine engine, QOnlineTranslator::Language lang, Voice voice=NoVoice, Emotion emotion=NoEmotion)
generateUrls
Definition: qonlinetts.cpp:57
@ UnsupportedEmotion
UnsupportedEmotion
Definition: qonlinetts.h:69
@ UnsupportedVoice
UnsupportedVoice
Definition: qonlinetts.h:68
@ UnsupportedEngine
UnsupportedEngine
Definition: qonlinetts.h:66
@ UnsupportedLanguage
UnsupportedLanguage
Definition: qonlinetts.h:67
static QString voiceCode(Voice voice)
voiceCode
Definition: qonlinetts.cpp:168