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 #ifndef QTEXTTOSPEECHPROCESSOR_P_H 38 #define QTEXTTOSPEECHPROCESSOR_P_H 39 40 #include "qvoice.h" 41 42 #include <QtCore/QString> 43 #include <QtCore/QThread> 44 #include <QtCore/QMutex> 45 #include <QtCore/QSemaphore> 46 #include <QtCore/QIODevice> 47 #include <QtMultimedia/QAudioOutput> 48 49 QT_BEGIN_NAMESPACE 50 51 // A common base class for text-to-speech engine integrations 52 // that require audio output implementation and thread handling. 53 // 54 // QAudioOutput is used for audio, and each call to say() cancels 55 // any previous processing. The public interface is thread-safe. 56 class QTextToSpeechProcessor : public QThread { 57 Q_OBJECT 58 59 public: 60 struct VoiceInfo 61 { 62 int id; 63 QString name; 64 QString locale; 65 QVoice::Gender gender; 66 QVoice::Age age; 67 }; 68 QTextToSpeechProcessor(); 69 ~QTextToSpeechProcessor() override; 70 void say(const QString &text, int voiceId); 71 void stop(); 72 void pause(); 73 void resume(); 74 bool isIdle() const; 75 bool setRate(double rate); 76 bool setPitch(double pitch); 77 bool setVolume(double volume); 78 double rate() const; 79 double pitch() const; 80 double volume() const; 81 virtual const QVector<VoiceInfo> &voices() const = 0; 82 83 protected: 84 // These are re-implemented QThread methods. 85 // exit() waits until the processor thread finishes or the wait times out. 86 void start(QThread::Priority = QThread::InheritPriority); 87 void exit(int retcode = 0); 88 89 // These methods can be used for audio output. 90 // audioOutput() blocks until all the audio has been written or processing 91 // is interrupted. 92 bool audioStart(int sampleRate, int channelCount, QString *errorString = nullptr); 93 bool audioOutput(const char* data, qint64 dataSize, QString *errorString = nullptr); 94 void audioStop(bool abort = false); 95 96 // These methods should be re-implemented if the parameters need 97 // to be changed while TTS is speaking. By default, updateVolume() just 98 // changes the QAudioOutput volume. The other methods do nothing by default. 99 virtual bool updateRate(double rate); 100 virtual bool updatePitch(double pitch); 101 virtual bool updateVolume(double volume); 102 103 // This method is called from the internal processor thread, and should block 104 // until the given text has been processed or processing is interrupted. 105 virtual int processText(const QString &text, int voiceId) = 0; 106 107 signals: 108 // This signal is emitted when the processor goes to idle state, i.e. when no 109 // new text is set to be spoken. The parameter is the latest return value of 110 // processText(). As the signal is emitted from the internal thread, the recipient 111 // should call isIdle() to get updated state. 112 void notSpeaking(int statusCode); 113 114 private: 115 void run() override; 116 mutable QMutex m_lock; 117 volatile bool m_stop; 118 volatile bool m_idle; 119 volatile bool m_paused; 120 double m_rate; 121 double m_pitch; 122 double m_volume; 123 QSemaphore m_speakSem; 124 QString m_nextText; 125 int m_nextVoice; 126 QAudioOutput *m_audio; 127 QIODevice *m_audioBuffer; 128 }; 129 130 QT_END_NAMESPACE 131 132 #endif 133