Newer
Older
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "QGCApplication.h"
#include "QGC.h"
AudioOutput::AudioOutput(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
connect(_tts, &QTextToSpeech::stateChanged, this, &AudioOutput::_stateChanged);
bool AudioOutput::say(const QString& inText)
bool muted = qgcApp()->toolbox()->settingsManager()->appSettings()->audioMuted()->rawValue().toBool();
QString text = fixTextMessageForAudio(inText);
if(_tts->state() == QTextToSpeech::Speaking) {
if(!_texts.contains(text)) {
//-- Some arbitrary limit
if(_texts.size() > 20) {
_texts.removeFirst();
}
_texts.append(text);
}
} else {
_tts->say(text);
void AudioOutput::_stateChanged(QTextToSpeech::State state)
{
if(state == QTextToSpeech::Ready) {
if(_texts.size()) {
QString text = _texts.first();
_texts.removeFirst();
_tts->say(text);
}
}
}
bool AudioOutput::getMillisecondString(const QString& string, QString& match, int& number) {
static QRegularExpression re("([0-9]+ms)");
QRegularExpressionMatchIterator i = re.globalMatch(string);
while (i.hasNext()) {
QRegularExpressionMatch qmatch = i.next();
if (qmatch.hasMatch()) {
match = qmatch.captured(0);
number = qmatch.captured(0).replace("ms", "").toInt();
return true;
}
}
return false;
}
QString AudioOutput::fixTextMessageForAudio(const QString& string) {
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
QString match;
QString newNumber;
QString result = string;
//-- Look for codified terms
if(result.contains("ERR ", Qt::CaseInsensitive)) {
result.replace("ERR ", "error ", Qt::CaseInsensitive);
}
if(result.contains("ERR:", Qt::CaseInsensitive)) {
result.replace("ERR:", "error.", Qt::CaseInsensitive);
}
if(result.contains("POSCTL", Qt::CaseInsensitive)) {
result.replace("POSCTL", "Position Control", Qt::CaseInsensitive);
}
if(result.contains("ALTCTL", Qt::CaseInsensitive)) {
result.replace("ALTCTL", "Altitude Control", Qt::CaseInsensitive);
}
if(result.contains("AUTO_RTL", Qt::CaseInsensitive)) {
result.replace("AUTO_RTL", "auto Return To Launch", Qt::CaseInsensitive);
} else if(result.contains("RTL", Qt::CaseInsensitive)) {
result.replace("RTL", "Return To Launch", Qt::CaseInsensitive);
}
if(result.contains("ACCEL ", Qt::CaseInsensitive)) {
result.replace("ACCEL ", "accelerometer ", Qt::CaseInsensitive);
}
if(result.contains("RC_MAP_MODE_SW", Qt::CaseInsensitive)) {
result.replace("RC_MAP_MODE_SW", "RC mode switch", Qt::CaseInsensitive);
}
if(result.contains("REJ.", Qt::CaseInsensitive)) {
result.replace("REJ.", "Rejected", Qt::CaseInsensitive);
}
if(result.contains("WP", Qt::CaseInsensitive)) {
result.replace("WP", "way point", Qt::CaseInsensitive);
}
if(result.contains("CMD", Qt::CaseInsensitive)) {
result.replace("CMD", "command", Qt::CaseInsensitive);
}
if(result.contains("COMPID", Qt::CaseInsensitive)) {
result.replace("COMPID", "component eye dee", Qt::CaseInsensitive);
}
if(result.contains(" params ", Qt::CaseInsensitive)) {
result.replace(" params ", " parameters ", Qt::CaseInsensitive);
}
if(result.contains(" id ", Qt::CaseInsensitive)) {
result.replace(" id ", " eye dee ", Qt::CaseInsensitive);
}
if(result.contains(" ADSB ", Qt::CaseInsensitive)) {
result.replace(" ADSB ", " Hey Dee Ess Bee ", Qt::CaseInsensitive);
}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Convert negative numbers
QRegularExpression re(QStringLiteral("(-)[0-9]*\\.?[0-9]"));
QRegularExpressionMatch reMatch = re.match(result);
while (reMatch.hasMatch()) {
if (!reMatch.captured(1).isNull()) {
// There is a negative prefix
qDebug() << "negative" << reMatch.captured(1) << reMatch.capturedStart(1) << reMatch.capturedEnd(1);
result.replace(reMatch.capturedStart(1), reMatch.capturedEnd(1) - reMatch.capturedStart(1), tr(" negative "));
qDebug() << result;
}
reMatch = re.match(result);
}
// Convert meter postfix after real number
re.setPattern(QStringLiteral("[0-9]*\\.?[0-9]\\s?(m)([^A-Za-z]|$)"));
reMatch = re.match(result);
while (reMatch.hasMatch()) {
if (!reMatch.captured(1).isNull()) {
// There is a meter postfix
qDebug() << "meters" << reMatch.captured(1) << reMatch.capturedStart(1) << reMatch.capturedEnd(1);
result.replace(reMatch.capturedStart(1), reMatch.capturedEnd(1) - reMatch.capturedStart(1), tr(" meters"));
qDebug() << result;
}
reMatch = re.match(result);
}
int number;
if(getMillisecondString(string, match, number) && number > 1000) {
if(number < 60000) {
int seconds = number / 1000;
newNumber = QString("%1 second%2").arg(seconds).arg(seconds > 1 ? "s" : "");
} else {
int minutes = number / 60000;
int seconds = (number - (minutes * 60000)) / 1000;
if (!seconds) {
newNumber = QString("%1 minute%2").arg(minutes).arg(minutes > 1 ? "s" : "");
} else {
newNumber = QString("%1 minute%2 and %3 second%4").arg(minutes).arg(minutes > 1 ? "s" : "").arg(seconds).arg(seconds > 1 ? "s" : "");
}
}
result.replace(match, newNumber);
}
return result;
}