forked from len0rd/rockbox
rbutil: Merge rbutil with utils folder.
rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21
This commit is contained in:
parent
6c6f0757d7
commit
c876d3bbef
494 changed files with 13 additions and 13 deletions
274
utils/rbutilqt/base/ttssapi.cpp
Normal file
274
utils/rbutilqt/base/ttssapi.cpp
Normal file
|
@ -0,0 +1,274 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Wenger
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "ttssapi.h"
|
||||
#include "utils.h"
|
||||
#include "rbsettings.h"
|
||||
#include "playerbuildinfo.h"
|
||||
#include "Logger.h"
|
||||
|
||||
TTSSapi::TTSSapi(QObject* parent) : TTSBase(parent)
|
||||
{
|
||||
m_TTSTemplate = "cscript //nologo \"%exe\" /language:%lang "
|
||||
"/voice:\"%voice\" /speed:%speed \"%options\"";
|
||||
m_TTSVoiceTemplate = "cscript //nologo \"%exe\" /language:%lang /listvoices";
|
||||
m_TTSType = "sapi";
|
||||
defaultLanguage = "english";
|
||||
m_started = false;
|
||||
}
|
||||
|
||||
TTSBase::Capabilities TTSSapi::capabilities()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
void TTSSapi::generateSettings()
|
||||
{
|
||||
// language
|
||||
QMap<QString, QVariant> langmap = PlayerBuildInfo::instance()->value(
|
||||
PlayerBuildInfo::LanguageList).toMap();
|
||||
EncTtsSetting* setting = new EncTtsSetting(this,
|
||||
EncTtsSetting::eSTRINGLIST, tr("Language:"),
|
||||
RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage),
|
||||
langmap.keys());
|
||||
connect(setting, &EncTtsSetting::dataChanged, this, &TTSSapi::updateVoiceList);
|
||||
insertSetting(eLANGUAGE,setting);
|
||||
// voice
|
||||
setting = new EncTtsSetting(this,
|
||||
EncTtsSetting::eSTRINGLIST, tr("Voice:"),
|
||||
RbSettings::subValue(m_TTSType, RbSettings::TtsVoice),
|
||||
getVoiceList(RbSettings::subValue(m_TTSType,
|
||||
RbSettings::TtsLanguage).toString()),
|
||||
EncTtsSetting::eREFRESHBTN);
|
||||
connect(setting, &EncTtsSetting::refresh, this, &TTSSapi::updateVoiceList);
|
||||
insertSetting(eVOICE,setting);
|
||||
//speed
|
||||
int speed = RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toInt();
|
||||
if(speed > 10 || speed < -10)
|
||||
speed = 0;
|
||||
insertSetting(eSPEED, new EncTtsSetting(this,
|
||||
EncTtsSetting::eINT, tr("Speed:"), speed, -10, 10));
|
||||
// options
|
||||
insertSetting(eOPTIONS, new EncTtsSetting(this,
|
||||
EncTtsSetting::eSTRING, tr("Options:"),
|
||||
RbSettings::subValue(m_TTSType, RbSettings::TtsOptions)));
|
||||
|
||||
}
|
||||
|
||||
void TTSSapi::saveSettings()
|
||||
{
|
||||
//save settings in user config
|
||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsLanguage,
|
||||
getSetting(eLANGUAGE)->current().toString());
|
||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsVoice,
|
||||
getSetting(eVOICE)->current().toString());
|
||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsSpeed,
|
||||
getSetting(eSPEED)->current().toInt());
|
||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsOptions,
|
||||
getSetting(eOPTIONS)->current().toString());
|
||||
|
||||
RbSettings::sync();
|
||||
}
|
||||
|
||||
void TTSSapi::updateVoiceList()
|
||||
{
|
||||
LOG_INFO() << "updating voicelist";
|
||||
QStringList voiceList = getVoiceList(getSetting(eLANGUAGE)->current().toString());
|
||||
getSetting(eVOICE)->setList(voiceList);
|
||||
if(voiceList.size() > 0) getSetting(eVOICE)->setCurrent(voiceList.at(0));
|
||||
else getSetting(eVOICE)->setCurrent("");
|
||||
}
|
||||
|
||||
bool TTSSapi::start(QString *errStr)
|
||||
{
|
||||
|
||||
m_TTSOpts = RbSettings::subValue(m_TTSType, RbSettings::TtsOptions).toString();
|
||||
m_TTSLanguage =RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage).toString();
|
||||
m_TTSVoice=RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString();
|
||||
m_TTSSpeed=RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toString();
|
||||
|
||||
QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
|
||||
QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
|
||||
m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
|
||||
|
||||
QFileInfo tts(m_TTSexec);
|
||||
if(!tts.exists())
|
||||
{
|
||||
*errStr = tr("Could not copy the SAPI script");
|
||||
return false;
|
||||
}
|
||||
// create the voice process
|
||||
QString execstring = m_TTSTemplate;
|
||||
execstring.replace("%exe",m_TTSexec);
|
||||
execstring.replace("%options",m_TTSOpts);
|
||||
execstring.replace("%lang",m_TTSLanguage);
|
||||
execstring.replace("%voice",m_TTSVoice);
|
||||
execstring.replace("%speed",m_TTSSpeed);
|
||||
|
||||
LOG_INFO() << "Start:" << execstring;
|
||||
voicescript = new QProcess(nullptr);
|
||||
//connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
|
||||
voicescript->start(execstring);
|
||||
LOG_INFO() << "wait for process";
|
||||
if(!voicescript->waitForStarted())
|
||||
{
|
||||
*errStr = tr("Could not start SAPI process");
|
||||
LOG_ERROR() << "starting process timed out!";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!voicescript->waitForReadyRead(300))
|
||||
{
|
||||
*errStr = voicescript->readAllStandardError();
|
||||
if(*errStr != "")
|
||||
return false;
|
||||
}
|
||||
|
||||
voicestream = new QTextStream(voicescript);
|
||||
#if QT_VERSION < 0x060000
|
||||
voicestream->setCodec("UTF16-LE");
|
||||
#else
|
||||
voicestream->setEncoding(QStringConverter::Utf16LE);
|
||||
#endif
|
||||
|
||||
m_started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString TTSSapi::voiceVendor(void)
|
||||
{
|
||||
bool keeprunning = m_started;
|
||||
QString vendor;
|
||||
if(!m_started) {
|
||||
QString error;
|
||||
start(&error);
|
||||
}
|
||||
*voicestream << "QUERY\tVENDOR\r\n";
|
||||
voicestream->flush();
|
||||
while((vendor = voicestream->readLine()).isEmpty())
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
LOG_INFO() << "TTS vendor:" << vendor;
|
||||
if(!keeprunning) {
|
||||
stop();
|
||||
}
|
||||
return vendor;
|
||||
}
|
||||
|
||||
QStringList TTSSapi::getVoiceList(QString language)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
|
||||
m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
|
||||
|
||||
QFileInfo tts(m_TTSexec);
|
||||
if(!tts.exists())
|
||||
return result;
|
||||
|
||||
// create the voice process
|
||||
QString execstring = m_TTSVoiceTemplate;
|
||||
execstring.replace("%exe",m_TTSexec);
|
||||
execstring.replace("%lang",language);
|
||||
|
||||
LOG_INFO() << "Start:" << execstring;
|
||||
voicescript = new QProcess(nullptr);
|
||||
voicescript->start(execstring);
|
||||
LOG_INFO() << "wait for process";
|
||||
if(!voicescript->waitForStarted()) {
|
||||
LOG_INFO() << "process startup timed out!";
|
||||
return result;
|
||||
}
|
||||
voicescript->closeWriteChannel();
|
||||
voicescript->waitForReadyRead();
|
||||
|
||||
QString dataRaw = voicescript->readAllStandardError().data();
|
||||
if(dataRaw.startsWith("Error")) {
|
||||
LOG_INFO() << "Error:" << dataRaw;
|
||||
}
|
||||
#if QT_VERSION >= 0x050e00
|
||||
result = dataRaw.split(";", Qt::SkipEmptyParts);
|
||||
#else
|
||||
result = dataRaw.split(";", QString::SkipEmptyParts);
|
||||
#endif
|
||||
if(result.size() > 0)
|
||||
{
|
||||
result.sort();
|
||||
result.removeFirst();
|
||||
for(int i = 0; i< result.size();i++)
|
||||
{
|
||||
result[i] = result.at(i).simplified();
|
||||
}
|
||||
}
|
||||
|
||||
delete voicescript;
|
||||
QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
|
||||
QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
|
||||
| QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
|
||||
| QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup
|
||||
| QFile::ReadOther | QFile::WriteOther | QFile::ExeOther );
|
||||
QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TTSStatus TTSSapi::voice(QString text,QString wavfile, QString *errStr)
|
||||
{
|
||||
(void) errStr;
|
||||
QString query = "SPEAK\t"+wavfile+"\t"+text;
|
||||
LOG_INFO() << "voicing" << query;
|
||||
// append newline to query. Done now to keep debug output more readable.
|
||||
query.append("\r\n");
|
||||
*voicestream << query;
|
||||
*voicestream << "SYNC\tbla\r\n";
|
||||
voicestream->flush();
|
||||
// do NOT poll the output with readLine(), this causes sync issues!
|
||||
voicescript->waitForReadyRead();
|
||||
|
||||
if(!QFileInfo(wavfile).isFile()) {
|
||||
LOG_ERROR() << "output file does not exist:" << wavfile;
|
||||
return FatalError;
|
||||
}
|
||||
return NoError;
|
||||
}
|
||||
|
||||
bool TTSSapi::stop()
|
||||
{
|
||||
*voicestream << "QUIT\r\n";
|
||||
voicestream->flush();
|
||||
voicescript->waitForFinished();
|
||||
delete voicestream;
|
||||
delete voicescript;
|
||||
QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",
|
||||
QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
|
||||
| QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
|
||||
| QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup
|
||||
| QFile::ReadOther | QFile::WriteOther | QFile::ExeOther );
|
||||
QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
|
||||
m_started = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TTSSapi::configOk()
|
||||
{
|
||||
if(RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString().isEmpty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue