1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #include "rbsettings.h"
23 #include "systeminfo.h"
25 TTSSapi::TTSSapi(QObject
* parent
) : TTSBase(parent
)
27 m_TTSTemplate
= "cscript //nologo \"%exe\" /language:%lang /voice:\"%voice\""
28 " /speed:%speed \"%options\"";
29 defaultLanguage
="english";
33 TTSBase::Capabilities
TTSSapi::capabilities()
38 void TTSSapi::generateSettings()
41 QStringList languages
= SystemInfo::languages();
43 EncTtsSetting
* setting
=new EncTtsSetting(this,EncTtsSetting::eSTRINGLIST
,
44 tr("Language:"),RbSettings::subValue("sapi",RbSettings::TtsLanguage
),
46 connect(setting
,SIGNAL(dataChanged()),this,SLOT(updateVoiceList()));
47 insertSetting(eLANGUAGE
,setting
);
49 setting
= new EncTtsSetting(this,EncTtsSetting::eSTRINGLIST
,
50 tr("Voice:"),RbSettings::subValue("sapi",RbSettings::TtsVoice
),
51 getVoiceList(RbSettings::subValue("sapi",RbSettings::TtsLanguage
).toString()),
52 EncTtsSetting::eREFRESHBTN
);
53 connect(setting
,SIGNAL(refresh()),this,SLOT(updateVoiceList()));
54 insertSetting(eVOICE
,setting
);
56 insertSetting(eSPEED
,new EncTtsSetting(this,EncTtsSetting::eINT
,
57 tr("Speed:"),RbSettings::subValue("sapi",RbSettings::TtsSpeed
),-10,10));
59 insertSetting(eOPTIONS
,new EncTtsSetting(this,EncTtsSetting::eSTRING
,
60 tr("Options:"),RbSettings::subValue("sapi",RbSettings::TtsOptions
)));
64 void TTSSapi::saveSettings()
66 //save settings in user config
67 RbSettings::setSubValue("sapi",RbSettings::TtsLanguage
,
68 getSetting(eLANGUAGE
)->current().toString());
69 RbSettings::setSubValue("sapi",RbSettings::TtsVoice
,
70 getSetting(eVOICE
)->current().toString());
71 RbSettings::setSubValue("sapi",RbSettings::TtsSpeed
,
72 getSetting(eSPEED
)->current().toInt());
73 RbSettings::setSubValue("sapi",RbSettings::TtsOptions
,
74 getSetting(eOPTIONS
)->current().toString());
79 void TTSSapi::updateVoiceList()
81 qDebug() << "update voiceList";
82 QStringList voiceList
= getVoiceList(getSetting(eLANGUAGE
)->current().toString());
83 getSetting(eVOICE
)->setList(voiceList
);
84 if(voiceList
.size() > 0) getSetting(eVOICE
)->setCurrent(voiceList
.at(0));
85 else getSetting(eVOICE
)->setCurrent("");
88 bool TTSSapi::start(QString
*errStr
)
91 m_TTSOpts
= RbSettings::subValue("sapi",RbSettings::TtsOptions
).toString();
92 m_TTSLanguage
=RbSettings::subValue("sapi",RbSettings::TtsLanguage
).toString();
93 m_TTSVoice
=RbSettings::subValue("sapi",RbSettings::TtsVoice
).toString();
94 m_TTSSpeed
=RbSettings::subValue("sapi",RbSettings::TtsSpeed
).toString();
95 m_sapi4
= RbSettings::subValue("sapi",RbSettings::TtsUseSapi4
).toBool();
97 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
98 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
99 m_TTSexec
= QDir::tempPath() +"/sapi_voice.vbs";
101 QFileInfo
tts(m_TTSexec
);
104 *errStr
= tr("Could not copy the Sapi-script");
107 // create the voice process
108 QString execstring
= m_TTSTemplate
;
109 execstring
.replace("%exe",m_TTSexec
);
110 execstring
.replace("%options",m_TTSOpts
);
111 execstring
.replace("%lang",m_TTSLanguage
);
112 execstring
.replace("%voice",m_TTSVoice
);
113 execstring
.replace("%speed",m_TTSSpeed
);
116 execstring
.append(" /sapi4 ");
118 qDebug() << "init" << execstring
;
119 voicescript
= new QProcess(NULL
);
120 //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
122 voicescript
->start(execstring
);
123 if(!voicescript
->waitForStarted())
125 *errStr
= tr("Could not start the Sapi-script");
129 if(!voicescript
->waitForReadyRead(300))
131 *errStr
= voicescript
->readAllStandardError();
136 voicestream
= new QTextStream(voicescript
);
137 voicestream
->setCodec("UTF16-LE");
143 QStringList
TTSSapi::getVoiceList(QString language
)
147 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
148 m_TTSexec
= QDir::tempPath() +"/sapi_voice.vbs";
150 QFileInfo
tts(m_TTSexec
);
154 // create the voice process
155 QString execstring
= "cscript //nologo \"%exe\" /language:%lang /listvoices";
156 execstring
.replace("%exe",m_TTSexec
);
157 execstring
.replace("%lang",language
);
159 if(RbSettings::value(RbSettings::TtsUseSapi4
).toBool())
160 execstring
.append(" /sapi4 ");
162 qDebug() << "init" << execstring
;
163 voicescript
= new QProcess(NULL
);
164 voicescript
->start(execstring
);
165 qDebug() << "wait for started";
166 if(!voicescript
->waitForStarted())
168 voicescript
->closeWriteChannel();
169 voicescript
->waitForReadyRead();
171 QString dataRaw
= voicescript
->readAllStandardError().data();
172 result
= dataRaw
.split(",",QString::SkipEmptyParts
);
173 if(result
.size() > 0)
176 result
.removeFirst();
177 for(int i
= 0; i
< result
.size();i
++)
179 result
[i
] = result
.at(i
).simplified();
184 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
185 QFile::ReadOwner
| QFile::WriteOwner
| QFile::ExeOwner
186 | QFile::ReadUser
| QFile::WriteUser
| QFile::ExeUser
187 | QFile::ReadGroup
| QFile::WriteGroup
| QFile::ExeGroup
188 | QFile::ReadOther
| QFile::WriteOther
| QFile::ExeOther
);
189 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
195 TTSStatus
TTSSapi::voice(QString text
,QString wavfile
, QString
*errStr
)
198 QString query
= "SPEAK\t"+wavfile
+"\t"+text
+"\r\n";
199 qDebug() << "voicing" << query
;
200 *voicestream
<< query
;
201 *voicestream
<< "SYNC\tbla\r\n";
202 voicestream
->flush();
205 //we use this, because waitForReadyRead doesnt work from a different thread
206 while( voicescript
->readLine(temp
,20) == 0)
207 QCoreApplication::processEvents();
214 *voicestream
<< "QUIT\r\n";
215 voicestream
->flush();
216 voicescript
->waitForFinished();
219 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
220 QFile::ReadOwner
| QFile::WriteOwner
| QFile::ExeOwner
221 | QFile::ReadUser
| QFile::WriteUser
| QFile::ExeUser
222 | QFile::ReadGroup
| QFile::WriteGroup
| QFile::ExeGroup
223 | QFile::ReadOther
| QFile::WriteOther
| QFile::ExeOther
);
224 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
228 bool TTSSapi::configOk()
230 if(RbSettings::subValue("sapi",RbSettings::TtsVoice
).toString().isEmpty())