1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2015 The Qt Company Ltd. |
4 | ** Contact: http://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Speech module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL3$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at http://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPLv3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or later as published by the Free |
28 | ** Software Foundation and appearing in the file LICENSE.GPL included in |
29 | ** the packaging of this file. Please review the following information to |
30 | ** ensure the GNU General Public License version 2.0 requirements will be |
31 | ** met: http://www.gnu.org/licenses/gpl-2.0.html. |
32 | ** |
33 | ** $QT_END_LICENSE$ |
34 | ** |
35 | ****************************************************************************/ |
36 | |
37 | |
38 | #include <QTest> |
39 | #include <QTextToSpeech> |
40 | #include <QSignalSpy> |
41 | #include <qttexttospeech-config.h> |
42 | |
43 | #if QT_CONFIG(speechd) |
44 | #include <libspeechd.h> |
45 | #if LIBSPEECHD_MAJOR_VERSION == 0 && LIBSPEECHD_MINOR_VERSION < 9 |
46 | #define HAVE_SPEECHD_BEFORE_090 |
47 | #endif |
48 | #endif |
49 | |
50 | enum : int { SpeechDuration = 20000 }; |
51 | |
52 | class tst_QTextToSpeech : public QObject |
53 | { |
54 | Q_OBJECT |
55 | |
56 | private slots: |
57 | void initTestCase(); |
58 | void say_hello(); |
59 | void speech_rate(); |
60 | void pitch(); |
61 | void set_voice(); |
62 | void volume(); |
63 | }; |
64 | |
65 | void tst_QTextToSpeech::initTestCase() |
66 | { |
67 | #if QT_CONFIG(speechd) && defined(LIBSPEECHD_MAJOR_VERSION) && defined(LIBSPEECHD_MINOR_VERSION) |
68 | qInfo("Using libspeechd v%d.%d" , LIBSPEECHD_MAJOR_VERSION, LIBSPEECHD_MINOR_VERSION); |
69 | #endif |
70 | } |
71 | |
72 | void tst_QTextToSpeech::say_hello() |
73 | { |
74 | QString text = QStringLiteral("this is an example text" ); |
75 | QTextToSpeech tts; |
76 | QCOMPARE(tts.state(), QTextToSpeech::Ready); |
77 | |
78 | QElapsedTimer timer; |
79 | timer.start(); |
80 | tts.say(text); |
81 | QTRY_COMPARE(tts.state(), QTextToSpeech::Speaking); |
82 | QSignalSpy spy(&tts, &QTextToSpeech::stateChanged); |
83 | QVERIFY(spy.wait(SpeechDuration)); |
84 | QCOMPARE(int(tts.state()), int(QTextToSpeech::Ready)); |
85 | QVERIFY(timer.elapsed() > 100); |
86 | } |
87 | |
88 | void tst_QTextToSpeech::speech_rate() |
89 | { |
90 | QString text = QStringLiteral("this is an example text" ); |
91 | QTextToSpeech tts; |
92 | tts.setRate(0.5); |
93 | QCOMPARE(tts.state(), QTextToSpeech::Ready); |
94 | #ifndef HAVE_SPEECHD_BEFORE_090 |
95 | QCOMPARE(tts.rate(), 0.5); |
96 | #endif |
97 | |
98 | qint64 lastTime = 0; |
99 | // check that speaking at slower rate takes more time (for 0.5, 0.0, -0.5) |
100 | for (int i = 1; i >= -1; --i) { |
101 | tts.setRate(i * 0.5); |
102 | QElapsedTimer timer; |
103 | timer.start(); |
104 | tts.say(text); |
105 | QTRY_COMPARE(tts.state(), QTextToSpeech::Speaking); |
106 | QSignalSpy spy(&tts, &QTextToSpeech::stateChanged); |
107 | QVERIFY(spy.wait(SpeechDuration)); |
108 | QCOMPARE(int(tts.state()), int(QTextToSpeech::Ready)); |
109 | qint64 time = timer.elapsed(); |
110 | QVERIFY(time > lastTime); |
111 | lastTime = time; |
112 | } |
113 | } |
114 | |
115 | void tst_QTextToSpeech::pitch() |
116 | { |
117 | QTextToSpeech tts; |
118 | for (int i = -10; i <= 10; ++i) { |
119 | tts.setPitch(i / 10.0); |
120 | #ifndef HAVE_SPEECHD_BEFORE_090 |
121 | QCOMPARE(tts.pitch(), i / 10.0); |
122 | #endif |
123 | } |
124 | } |
125 | |
126 | void tst_QTextToSpeech::set_voice() |
127 | { |
128 | QString text = QStringLiteral("this is an example text" ); |
129 | QTextToSpeech tts; |
130 | QCOMPARE(tts.state(), QTextToSpeech::Ready); |
131 | |
132 | // Choose a voice |
133 | QVector<QVoice> voices = tts.availableVoices(); |
134 | int vId = 0; |
135 | QVERIFY(voices.length()); // have at least one voice |
136 | if (voices.length() > 1) { |
137 | vId = 1; |
138 | } |
139 | tts.setVoice(voices[vId]); |
140 | QCOMPARE(tts.state(), QTextToSpeech::Ready); |
141 | |
142 | QElapsedTimer timer; |
143 | timer.start(); |
144 | tts.say(text); |
145 | QTRY_COMPARE(tts.state(), QTextToSpeech::Speaking); |
146 | QSignalSpy spy(&tts, &QTextToSpeech::stateChanged); |
147 | QVERIFY(spy.wait(SpeechDuration)); |
148 | QCOMPARE(int(tts.state()), int(QTextToSpeech::Ready)); |
149 | QVERIFY(timer.elapsed() > 100); |
150 | } |
151 | |
152 | void tst_QTextToSpeech::volume() |
153 | { |
154 | QTextToSpeech tts; |
155 | double volumeSignalEmitted = -99.0; |
156 | connect(sender: &tts, signal: static_cast<void (QTextToSpeech::*)(double)>(&QTextToSpeech::volumeChanged), |
157 | slot: [&volumeSignalEmitted](double volume){ volumeSignalEmitted = volume; } ); |
158 | tts.setVolume(0.7); |
159 | QTRY_VERIFY(volumeSignalEmitted > 0.6); |
160 | |
161 | #ifndef HAVE_SPEECHD_BEFORE_090 // older speechd doesn't signal any volume changes |
162 | // engines use different systems (integers etc), even fuzzy compare is off |
163 | QVERIFY2(tts.volume() > 0.65, QByteArray::number(tts.volume())); |
164 | QVERIFY2(tts.volume() < 0.75, QByteArray::number(tts.volume())); |
165 | #endif |
166 | } |
167 | |
168 | QTEST_MAIN(tst_QTextToSpeech) |
169 | #include "tst_qtexttospeech.moc" |
170 | |