diff options
Diffstat (limited to 'rbutil/rbutilqt/base/ttssapi.cpp')
-rw-r--r-- | rbutil/rbutilqt/base/ttssapi.cpp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/base/ttssapi.cpp b/rbutil/rbutilqt/base/ttssapi.cpp new file mode 100644 index 0000000000..e356d613de --- /dev/null +++ b/rbutil/rbutilqt/base/ttssapi.cpp | |||
@@ -0,0 +1,213 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 by Dominik Wenger | ||
10 | * $Id$ | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "ttssapi.h" | ||
21 | #include "utils.h" | ||
22 | #include "rbsettings.h" | ||
23 | |||
24 | TTSSapi::TTSSapi(QObject* parent) : TTSBase(parent) | ||
25 | { | ||
26 | m_TTSTemplate = "cscript //nologo \"%exe\" /language:%lang /voice:\"%voice\" /speed:%speed \"%options\""; | ||
27 | defaultLanguage ="english"; | ||
28 | m_sapi4 =false; | ||
29 | } | ||
30 | |||
31 | void TTSSapi::generateSettings() | ||
32 | { | ||
33 | // language | ||
34 | QStringList languages = RbSettings::languages(); | ||
35 | languages.sort(); | ||
36 | EncTtsSetting* setting =new EncTtsSetting(this,EncTtsSetting::eSTRINGLIST, | ||
37 | tr("Language:"),RbSettings::subValue("sapi",RbSettings::TtsLanguage),languages); | ||
38 | connect(setting,SIGNAL(dataChanged()),this,SLOT(updateVoiceList())); | ||
39 | insertSetting(eLANGUAGE,setting); | ||
40 | // voice | ||
41 | setting = new EncTtsSetting(this,EncTtsSetting::eSTRINGLIST, | ||
42 | tr("Voice:"),RbSettings::subValue("sapi",RbSettings::TtsVoice),getVoiceList(RbSettings::subValue("sapi",RbSettings::TtsLanguage).toString()),EncTtsSetting::eREFRESHBTN); | ||
43 | connect(setting,SIGNAL(refresh()),this,SLOT(updateVoiceList())); | ||
44 | insertSetting(eVOICE,setting); | ||
45 | //speed | ||
46 | insertSetting(eSPEED,new EncTtsSetting(this,EncTtsSetting::eINT, | ||
47 | tr("Speed:"),RbSettings::subValue("sapi",RbSettings::TtsSpeed),-10,10)); | ||
48 | // options | ||
49 | insertSetting(eOPTIONS,new EncTtsSetting(this,EncTtsSetting::eSTRING, | ||
50 | tr("Options:"),RbSettings::subValue("sapi",RbSettings::TtsOptions))); | ||
51 | |||
52 | } | ||
53 | |||
54 | void TTSSapi::saveSettings() | ||
55 | { | ||
56 | //save settings in user config | ||
57 | RbSettings::setSubValue("sapi",RbSettings::TtsLanguage,getSetting(eLANGUAGE)->current().toString()); | ||
58 | RbSettings::setSubValue("sapi",RbSettings::TtsVoice,getSetting(eVOICE)->current().toString()); | ||
59 | RbSettings::setSubValue("sapi",RbSettings::TtsSpeed,getSetting(eSPEED)->current().toInt()); | ||
60 | RbSettings::setSubValue("sapi",RbSettings::TtsOptions,getSetting(eOPTIONS)->current().toString()); | ||
61 | |||
62 | RbSettings::sync(); | ||
63 | } | ||
64 | |||
65 | void TTSSapi::updateVoiceList() | ||
66 | { | ||
67 | qDebug() << "update voiceList"; | ||
68 | QStringList voiceList = getVoiceList(getSetting(eLANGUAGE)->current().toString()); | ||
69 | getSetting(eVOICE)->setList(voiceList); | ||
70 | if(voiceList.size() > 0) getSetting(eVOICE)->setCurrent(voiceList.at(0)); | ||
71 | else getSetting(eVOICE)->setCurrent(""); | ||
72 | } | ||
73 | |||
74 | bool TTSSapi::start(QString *errStr) | ||
75 | { | ||
76 | |||
77 | m_TTSOpts = RbSettings::subValue("sapi",RbSettings::TtsOptions).toString(); | ||
78 | m_TTSLanguage =RbSettings::subValue("sapi",RbSettings::TtsLanguage).toString(); | ||
79 | m_TTSVoice=RbSettings::subValue("sapi",RbSettings::TtsVoice).toString(); | ||
80 | m_TTSSpeed=RbSettings::subValue("sapi",RbSettings::TtsSpeed).toString(); | ||
81 | m_sapi4 = RbSettings::subValue("sapi",RbSettings::TtsUseSapi4).toBool(); | ||
82 | |||
83 | QFile::remove(QDir::tempPath() +"/sapi_voice.vbs"); | ||
84 | QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs"); | ||
85 | m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs"; | ||
86 | |||
87 | QFileInfo tts(m_TTSexec); | ||
88 | if(!tts.exists()) | ||
89 | { | ||
90 | *errStr = tr("Could not copy the Sapi-script"); | ||
91 | return false; | ||
92 | } | ||
93 | // create the voice process | ||
94 | QString execstring = m_TTSTemplate; | ||
95 | execstring.replace("%exe",m_TTSexec); | ||
96 | execstring.replace("%options",m_TTSOpts); | ||
97 | execstring.replace("%lang",m_TTSLanguage); | ||
98 | execstring.replace("%voice",m_TTSVoice); | ||
99 | execstring.replace("%speed",m_TTSSpeed); | ||
100 | |||
101 | if(m_sapi4) | ||
102 | execstring.append(" /sapi4 "); | ||
103 | |||
104 | qDebug() << "init" << execstring; | ||
105 | voicescript = new QProcess(NULL); | ||
106 | //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error())); | ||
107 | |||
108 | voicescript->start(execstring); | ||
109 | if(!voicescript->waitForStarted()) | ||
110 | { | ||
111 | *errStr = tr("Could not start the Sapi-script"); | ||
112 | return false; | ||
113 | } | ||
114 | |||
115 | if(!voicescript->waitForReadyRead(300)) | ||
116 | { | ||
117 | *errStr = voicescript->readAllStandardError(); | ||
118 | if(*errStr != "") | ||
119 | return false; | ||
120 | } | ||
121 | |||
122 | voicestream = new QTextStream(voicescript); | ||
123 | voicestream->setCodec("UTF16-LE"); | ||
124 | |||
125 | return true; | ||
126 | } | ||
127 | |||
128 | |||
129 | QStringList TTSSapi::getVoiceList(QString language) | ||
130 | { | ||
131 | QStringList result; | ||
132 | |||
133 | QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs"); | ||
134 | m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs"; | ||
135 | |||
136 | QFileInfo tts(m_TTSexec); | ||
137 | if(!tts.exists()) | ||
138 | return result; | ||
139 | |||
140 | // create the voice process | ||
141 | QString execstring = "cscript //nologo \"%exe\" /language:%lang /listvoices"; | ||
142 | execstring.replace("%exe",m_TTSexec); | ||
143 | execstring.replace("%lang",language); | ||
144 | |||
145 | if(RbSettings::value(RbSettings::TtsUseSapi4).toBool()) | ||
146 | execstring.append(" /sapi4 "); | ||
147 | |||
148 | qDebug() << "init" << execstring; | ||
149 | voicescript = new QProcess(NULL); | ||
150 | voicescript->start(execstring); | ||
151 | qDebug() << "wait for started"; | ||
152 | if(!voicescript->waitForStarted()) | ||
153 | return result; | ||
154 | voicescript->closeWriteChannel(); | ||
155 | voicescript->waitForReadyRead(); | ||
156 | |||
157 | QString dataRaw = voicescript->readAllStandardError().data(); | ||
158 | result = dataRaw.split(",",QString::SkipEmptyParts); | ||
159 | if(result.size() > 0) | ||
160 | { | ||
161 | result.sort(); | ||
162 | result.removeFirst(); | ||
163 | for(int i = 0; i< result.size();i++) | ||
164 | { | ||
165 | result[i] = result.at(i).simplified(); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | delete voicescript; | ||
170 | QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner | ||
171 | |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser | ||
172 | |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup | ||
173 | |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther ); | ||
174 | QFile::remove(QDir::tempPath() +"/sapi_voice.vbs"); | ||
175 | return result; | ||
176 | } | ||
177 | |||
178 | |||
179 | |||
180 | TTSStatus TTSSapi::voice(QString text,QString wavfile, QString *errStr) | ||
181 | { | ||
182 | (void) errStr; | ||
183 | QString query = "SPEAK\t"+wavfile+"\t"+text+"\r\n"; | ||
184 | qDebug() << "voicing" << query; | ||
185 | *voicestream << query; | ||
186 | *voicestream << "SYNC\tbla\r\n"; | ||
187 | voicestream->flush(); | ||
188 | voicescript->waitForReadyRead(); | ||
189 | return NoError; | ||
190 | } | ||
191 | |||
192 | bool TTSSapi::stop() | ||
193 | { | ||
194 | |||
195 | *voicestream << "QUIT\r\n"; | ||
196 | voicestream->flush(); | ||
197 | voicescript->waitForFinished(); | ||
198 | delete voicestream; | ||
199 | delete voicescript; | ||
200 | QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner | ||
201 | |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser | ||
202 | |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup | ||
203 | |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther ); | ||
204 | QFile::remove(QDir::tempPath() +"/sapi_voice.vbs"); | ||
205 | return true; | ||
206 | } | ||
207 | |||
208 | bool TTSSapi::configOk() | ||
209 | { | ||
210 | if(RbSettings::subValue("sapi",RbSettings::TtsVoice).toString().isEmpty()) | ||
211 | return false; | ||
212 | return true; | ||
213 | } | ||