summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2011-04-03 08:06:59 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2011-04-03 08:06:59 +0000
commit746f01dd775feb9b53577a2338fd9182d879c0d3 (patch)
treebc6daa8c97b4ef9665e7113f14b68e1dbdf17d7d
parent76c112ce6e3b79cdbc8545637d2bffbedff3f178 (diff)
downloadrockbox-746f01dd775feb9b53577a2338fd9182d879c0d3.tar.gz
rockbox-746f01dd775feb9b53577a2338fd9182d879c0d3.zip
Add capability to speak directly from the TTS engine.
The OS X TTS engine (and likely others) allows outputting its speech directly to the sound system. This avoids the extra step of creating a temporary file to play for TTS preview. Currently implemented as TTS capability reported. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29672 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--rbutil/rbutilqt/base/ttsbase.h2
-rw-r--r--rbutil/rbutilqt/base/ttscarbon.cpp49
-rw-r--r--rbutil/rbutilqt/configure.cpp33
3 files changed, 48 insertions, 36 deletions
diff --git a/rbutil/rbutilqt/base/ttsbase.h b/rbutil/rbutilqt/base/ttsbase.h
index f04016c85f..c6bbdcfb0b 100644
--- a/rbutil/rbutilqt/base/ttsbase.h
+++ b/rbutil/rbutilqt/base/ttsbase.h
@@ -36,7 +36,7 @@ class TTSBase : public EncTtsSettingInterface
{
Q_OBJECT
public:
- enum Capability { None = 0, RunInParallel = 1 };
+ enum Capability { None = 0, RunInParallel = 1, CanSpeak = 2 };
Q_DECLARE_FLAGS(Capabilities, Capability)
TTSBase(QObject *parent);
diff --git a/rbutil/rbutilqt/base/ttscarbon.cpp b/rbutil/rbutilqt/base/ttscarbon.cpp
index 63fb5315e3..ba744b5fcf 100644
--- a/rbutil/rbutilqt/base/ttscarbon.cpp
+++ b/rbutil/rbutilqt/base/ttscarbon.cpp
@@ -36,7 +36,7 @@ TTSCarbon::TTSCarbon(QObject* parent) : TTSBase(parent)
TTSBase::Capabilities TTSCarbon::capabilities()
{
- return None;
+ return TTSBase::CanSpeak;
}
bool TTSCarbon::configOk()
@@ -75,7 +75,7 @@ bool TTSCarbon::start(QString *errStr)
if(voiceIndex == numVoices) {
// voice not found. Add user notification here and proceed with
// system default voice.
- qDebug() << "selected voice not found, using system default!";
+ qDebug() << "[TTSCarbon] Selected voice not found, using system default!";
GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc));
if(vdesc.script != -1)
m_voiceScript = (CFStringBuiltInEncodings)vdesc.script;
@@ -160,18 +160,21 @@ TTSStatus TTSCarbon::voice(QString text, QString wavfile, QString* errStr)
TTSStatus status = NoError;
OSErr error;
- QString aifffile = wavfile + ".aiff";
- // FIXME: find out why we need to do this.
- // Create a local copy of the temporary file filename.
- // Not doing so causes weird issues (path contains trailing spaces)
- unsigned int len = aifffile.size() + 1;
- char* tmpfile = (char*)malloc(len * sizeof(char));
- strncpy(tmpfile, aifffile.toLocal8Bit().constData(), len);
- CFStringRef tmpfileref = CFStringCreateWithCString(kCFAllocatorDefault,
- tmpfile, kCFStringEncodingUTF8);
- CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
- tmpfileref, kCFURLPOSIXPathStyle, false);
- SetSpeechInfo(m_channel, soOutputToFileWithCFURL, urlref);
+ char* tmpfile;
+ if(!wavfile.isEmpty()) {
+ QString aifffile = wavfile + ".aiff";
+ // FIXME: find out why we need to do this.
+ // Create a local copy of the temporary file filename.
+ // Not doing so causes weird issues (path contains trailing spaces)
+ unsigned int len = aifffile.size() + 1;
+ tmpfile = (char*)malloc(len * sizeof(char));
+ strncpy(tmpfile, aifffile.toLocal8Bit().constData(), len);
+ CFStringRef tmpfileref = CFStringCreateWithCString(kCFAllocatorDefault,
+ tmpfile, kCFStringEncodingUTF8);
+ CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ tmpfileref, kCFURLPOSIXPathStyle, false);
+ SetSpeechInfo(m_channel, soOutputToFileWithCFURL, urlref);
+ }
// speak it.
// Convert the string to the encoding requested by the voice. Do this
@@ -206,15 +209,17 @@ TTSStatus TTSCarbon::voice(QString text, QString wavfile, QString* errStr)
free(textbuf);
CFRelease(cfstring);
- // convert the temporary aiff file to wav
- if(status == NoError
- && convertAiffToWav(tmpfile, wavfile.toLocal8Bit().constData()) != 0) {
- *errStr = tr("Could not convert intermediate file");
- status = FatalError;
+ if(!wavfile.isEmpty()) {
+ // convert the temporary aiff file to wav
+ if(status == NoError
+ && convertAiffToWav(tmpfile, wavfile.toLocal8Bit().constData()) != 0) {
+ *errStr = tr("Could not convert intermediate file");
+ status = FatalError;
+ }
+ // remove temporary aiff file
+ unlink(tmpfile);
+ free(tmpfile);
}
- // remove temporary aiff file
- unlink(tmpfile);
- free(tmpfile);
return status;
}
diff --git a/rbutil/rbutilqt/configure.cpp b/rbutil/rbutilqt/configure.cpp
index 8bfa20e6a0..9b6376e469 100644
--- a/rbutil/rbutilqt/configure.cpp
+++ b/rbutil/rbutilqt/configure.cpp
@@ -731,14 +731,16 @@ void Config::testTts()
{
QString errstr;
int index = ui.comboTts->currentIndex();
- TTSBase* tts = TTSBase::getTTS(this,ui.comboTts->itemData(index).toString());
+ TTSBase* tts;
+
+ ui.testTTS->setEnabled(false);
+ tts = TTSBase::getTTS(this,ui.comboTts->itemData(index).toString());
if(!tts->configOk())
{
QMessageBox::warning(this,tr("TTS configuration invalid"),
tr("TTS configuration invalid. \n Please configure TTS engine."));
return;
}
- ui.testTTS->setEnabled(false);
if(!tts->start(&errstr))
{
QMessageBox::warning(this,tr("Could not start TTS engine."),
@@ -748,10 +750,13 @@ void Config::testTts()
return;
}
- QTemporaryFile file(this);
- file.open();
- QString filename = file.fileName();
- file.close();
+ QString filename;
+ if(!(tts->capabilities() & TTSBase::CanSpeak)) {
+ QTemporaryFile file(this);
+ file.open();
+ filename = file.fileName();
+ file.close();
+ }
if(tts->voice(tr("Rockbox Utility Voice Test"),filename,&errstr) == FatalError)
{
@@ -763,16 +768,18 @@ void Config::testTts()
return;
}
tts->stop();
+ if(!(tts->capabilities() & TTSBase::CanSpeak)) {
#if defined(Q_OS_LINUX)
- QString exe = Utils::findExecutable("aplay");
- if(exe == "") exe = Utils::findExecutable("play");
- if(exe != "")
- {
- QProcess::execute(exe+" "+filename);
- }
+ QString exe = Utils::findExecutable("aplay");
+ if(exe == "") exe = Utils::findExecutable("play");
+ if(exe != "")
+ {
+ QProcess::execute(exe+" "+filename);
+ }
#else
- QSound::play(filename);
+ QSound::play(filename);
#endif
+ }
ui.testTTS->setEnabled(true);
delete tts; /* Config objects are never deleted (in fact, they are
leaked..), so we can't rely on QObject, since that would