summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/base
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 /rbutil/rbutilqt/base
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
Diffstat (limited to 'rbutil/rbutilqt/base')
-rw-r--r--rbutil/rbutilqt/base/ttsbase.h2
-rw-r--r--rbutil/rbutilqt/base/ttscarbon.cpp49
2 files changed, 28 insertions, 23 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
36{ 36{
37 Q_OBJECT 37 Q_OBJECT
38 public: 38 public:
39 enum Capability { None = 0, RunInParallel = 1 }; 39 enum Capability { None = 0, RunInParallel = 1, CanSpeak = 2 };
40 Q_DECLARE_FLAGS(Capabilities, Capability) 40 Q_DECLARE_FLAGS(Capabilities, Capability)
41 41
42 TTSBase(QObject *parent); 42 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)
36 36
37TTSBase::Capabilities TTSCarbon::capabilities() 37TTSBase::Capabilities TTSCarbon::capabilities()
38{ 38{
39 return None; 39 return TTSBase::CanSpeak;
40} 40}
41 41
42bool TTSCarbon::configOk() 42bool TTSCarbon::configOk()
@@ -75,7 +75,7 @@ bool TTSCarbon::start(QString *errStr)
75 if(voiceIndex == numVoices) { 75 if(voiceIndex == numVoices) {
76 // voice not found. Add user notification here and proceed with 76 // voice not found. Add user notification here and proceed with
77 // system default voice. 77 // system default voice.
78 qDebug() << "selected voice not found, using system default!"; 78 qDebug() << "[TTSCarbon] Selected voice not found, using system default!";
79 GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc)); 79 GetVoiceDescription(&vspec, &vdesc, sizeof(vdesc));
80 if(vdesc.script != -1) 80 if(vdesc.script != -1)
81 m_voiceScript = (CFStringBuiltInEncodings)vdesc.script; 81 m_voiceScript = (CFStringBuiltInEncodings)vdesc.script;
@@ -160,18 +160,21 @@ TTSStatus TTSCarbon::voice(QString text, QString wavfile, QString* errStr)
160 TTSStatus status = NoError; 160 TTSStatus status = NoError;
161 OSErr error; 161 OSErr error;
162 162
163 QString aifffile = wavfile + ".aiff"; 163 char* tmpfile;
164 // FIXME: find out why we need to do this. 164 if(!wavfile.isEmpty()) {
165 // Create a local copy of the temporary file filename. 165 QString aifffile = wavfile + ".aiff";
166 // Not doing so causes weird issues (path contains trailing spaces) 166 // FIXME: find out why we need to do this.
167 unsigned int len = aifffile.size() + 1; 167 // Create a local copy of the temporary file filename.
168 char* tmpfile = (char*)malloc(len * sizeof(char)); 168 // Not doing so causes weird issues (path contains trailing spaces)
169 strncpy(tmpfile, aifffile.toLocal8Bit().constData(), len); 169 unsigned int len = aifffile.size() + 1;
170 CFStringRef tmpfileref = CFStringCreateWithCString(kCFAllocatorDefault, 170 tmpfile = (char*)malloc(len * sizeof(char));
171 tmpfile, kCFStringEncodingUTF8); 171 strncpy(tmpfile, aifffile.toLocal8Bit().constData(), len);
172 CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, 172 CFStringRef tmpfileref = CFStringCreateWithCString(kCFAllocatorDefault,
173 tmpfileref, kCFURLPOSIXPathStyle, false); 173 tmpfile, kCFStringEncodingUTF8);
174 SetSpeechInfo(m_channel, soOutputToFileWithCFURL, urlref); 174 CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
175 tmpfileref, kCFURLPOSIXPathStyle, false);
176 SetSpeechInfo(m_channel, soOutputToFileWithCFURL, urlref);
177 }
175 178
176 // speak it. 179 // speak it.
177 // Convert the string to the encoding requested by the voice. Do this 180 // 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)
206 free(textbuf); 209 free(textbuf);
207 CFRelease(cfstring); 210 CFRelease(cfstring);
208 211
209 // convert the temporary aiff file to wav 212 if(!wavfile.isEmpty()) {
210 if(status == NoError 213 // convert the temporary aiff file to wav
211 && convertAiffToWav(tmpfile, wavfile.toLocal8Bit().constData()) != 0) { 214 if(status == NoError
212 *errStr = tr("Could not convert intermediate file"); 215 && convertAiffToWav(tmpfile, wavfile.toLocal8Bit().constData()) != 0) {
213 status = FatalError; 216 *errStr = tr("Could not convert intermediate file");
217 status = FatalError;
218 }
219 // remove temporary aiff file
220 unlink(tmpfile);
221 free(tmpfile);
214 } 222 }
215 // remove temporary aiff file
216 unlink(tmpfile);
217 free(tmpfile);
218 223
219 return status; 224 return status;
220} 225}