rbutil: Rework TTS classes to use a stringlist for arguments

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Thu, 9 Jul 2026 15:00:30 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 390d17893fc257aa1d501d0f5b5d098939b78d28
Author: Solomon Peachy <[email protected]>
Date:   Thu Jul 9 14:41:54 2026 -0400

    rbutil: Rework TTS classes to use a stringlist for arguments
    
    Instead of passing the entire cmdline as a single string that was
    treated as the exectuable name on some platforms
    
    Change-Id: Ic4f043a3a48e1b1bfab82bbfa8983c2d224606ec

diff --git a/utils/rbutilqt/base/ttsespeak.h b/utils/rbutilqt/base/ttsespeak.h
index afe19fbdac..c069d5bbfb 100644
--- a/utils/rbutilqt/base/ttsespeak.h
+++ b/utils/rbutilqt/base/ttsespeak.h
@@ -33,8 +33,15 @@ class TTSEspeak : public TTSExes
             m_name = "espeak";
 
             /* default to espeak */
-            m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
-            m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
+            m_TTSTemplate << "%options";
+            m_TTSTemplate << "-w";
+            m_TTSTemplate << "%wavfile";
+            m_TTSTemplate << "--";
+            m_TTSTemplate << "%text";
+            m_TTSSpeakTemplate << "%options";
+            m_TTSSpeakTemplate << "--";
+            m_TTSSpeakTemplate << "%text";
+
             m_capabilities = TTSBase::CanSpeak;
         }
 };
diff --git a/utils/rbutilqt/base/ttsespeakng.h b/utils/rbutilqt/base/ttsespeakng.h
index 55aba62e7d..d47eb7cd42 100644
--- a/utils/rbutilqt/base/ttsespeakng.h
+++ b/utils/rbutilqt/base/ttsespeakng.h
@@ -32,8 +32,15 @@ class TTSEspeakNG : public TTSExes
         {
             m_name = "espeak-ng";
 
-            m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
-            m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
+            m_TTSTemplate << "%options";
+            m_TTSTemplate << "-w";
+            m_TTSTemplate << "%wavfile";
+            m_TTSTemplate << "--";
+            m_TTSTemplate << "%text";
+            m_TTSSpeakTemplate << "%options";
+            m_TTSSpeakTemplate << "--";
+            m_TTSSpeakTemplate << "%text";
+
             m_capabilities = TTSBase::CanSpeak;
         }
 };
diff --git a/utils/rbutilqt/base/ttsexes.cpp b/utils/rbutilqt/base/ttsexes.cpp
index 3eae930eef..a4ecf985b7 100644
--- a/utils/rbutilqt/base/ttsexes.cpp
+++ b/utils/rbutilqt/base/ttsexes.cpp
@@ -24,14 +24,10 @@
 
 TTSExes::TTSExes(QObject* parent) : TTSBase(parent)
 {
-    /* default to espeak */
-    m_name = "espeak";
-    m_capabilities = TTSBase::CanSpeak;
-    m_TTSTemplate = "\"%exe\" %options -w \"%wavfile\" -- \"%text\"";
-    m_TTSSpeakTemplate = "\"%exe\" %options -- \"%text\"";
+    m_name = "false";
+    m_capabilities = TTSBase::None;
 }
 
-
 TTSBase::Capabilities TTSExes::capabilities()
 {
     return m_capabilities;
@@ -83,14 +79,14 @@ bool TTSExes::start(QString *errStr)
 TTSStatus TTSExes::voice(const QString& text, const QString& wavfile, QString *errStr)
 {
     (void) errStr;
-    QString execstring;
+    QStringList exec;
     if(wavfile.isEmpty() && m_capabilities & TTSBase::CanSpeak) {
         if(m_TTSSpeakTemplate.isEmpty()) {
             LOG_ERROR() << "internal error: TTS announces CanSpeak "
                            "but template empty!";
             return FatalError;
         }
-        execstring = m_TTSSpeakTemplate;
+        exec = m_TTSSpeakTemplate;
     }
     else if(wavfile.isEmpty()) {
         LOG_ERROR() << "no output file passed to voice() "
@@ -98,15 +94,19 @@ TTSStatus TTSExes::voice(const QString& text, const QString& wavfile, QString *e
         return FatalError;
     }
     else {
-        execstring = m_TTSTemplate;
+        exec = m_TTSTemplate;
     }
 
-    execstring.replace("%exe",m_TTSexec);
-    execstring.replace("%options",m_TTSOpts);
-    execstring.replace("%wavfile",wavfile);
-    execstring.replace("%text",text);
+    exec.replaceInStrings("%options",m_TTSOpts);
+    exec.replaceInStrings("%wavfile",wavfile);
+    exec.replaceInStrings("%text",text);
 
-    QProcess::execute(execstring);
+    int ret;
+    if ((ret = QProcess::execute(m_TTSexec, exec))) {
+        LOG_ERROR() << "TTS exec failed (" << ret << "): " << m_TTSexec << " " << exec;
+
+        return FatalError;
+    }
 
     if(!wavfile.isEmpty() && !QFileInfo(wavfile).isFile()) {
         LOG_ERROR() << "output file does not exist:" << wavfile;
@@ -124,4 +124,3 @@ bool TTSExes::configOk()
     else
         return false;
 }
-
diff --git a/utils/rbutilqt/base/ttsexes.h b/utils/rbutilqt/base/ttsexes.h
index 470b007e92..c9b1bb185d 100644
--- a/utils/rbutilqt/base/ttsexes.h
+++ b/utils/rbutilqt/base/ttsexes.h
@@ -50,8 +50,8 @@ class TTSExes : public TTSBase
         void loadSettings(void);
 
     protected:
-        QString m_TTSTemplate;
-        QString m_TTSSpeakTemplate;
+        QStringList m_TTSTemplate;
+        QStringList m_TTSSpeakTemplate;
         QString m_name;
         QString m_TTSexec;
         QString m_TTSOpts;
diff --git a/utils/rbutilqt/base/ttsflite.h b/utils/rbutilqt/base/ttsflite.h
index 717c311a34..6d6c36740d 100644
--- a/utils/rbutilqt/base/ttsflite.h
+++ b/utils/rbutilqt/base/ttsflite.h
@@ -32,11 +32,14 @@ class TTSFlite : public TTSExes
         {
             m_name = "flite";
 
-            /* default to espeak */
-            m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -t \"%text\"";
-            m_TTSSpeakTemplate = "";
-            m_capabilities = TTSBase::None;
+            m_TTSTemplate << "%options";
+            m_TTSTemplate << "-o";
+            m_TTSTemplate << "%wavfile";
+            m_TTSTemplate << "-t";
+            m_TTSTemplate << "%text";
+            //m_TTSSpeakTemplate << "";
 
+            m_capabilities = TTSBase::None;
         }
 };
 
diff --git a/utils/rbutilqt/base/ttsmimic.h b/utils/rbutilqt/base/ttsmimic.h
index f4d7a8beac..3b0295f44e 100644
--- a/utils/rbutilqt/base/ttsmimic.h
+++ b/utils/rbutilqt/base/ttsmimic.h
@@ -32,8 +32,15 @@ class TTSMimic : public TTSExes
         {
             m_name = "mimic";
 
-            m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -t \"%text\"";
-            m_TTSSpeakTemplate = "\"%exe\" %options -t \"%text\"";
+            m_TTSTemplate << "%options";
+            m_TTSTemplate << "-o";
+            m_TTSTemplate << "%wavfile";
+            m_TTSTemplate << "-t";
+            m_TTSTemplate << "%text";
+            m_TTSSpeakTemplate << "%options";
+            m_TTSSpeakTemplate << "-t";
+            m_TTSSpeakTemplate << "%text";
+
             m_capabilities = TTSBase::CanSpeak;
         }
 };
diff --git a/utils/rbutilqt/base/ttsmssp.h b/utils/rbutilqt/base/ttsmssp.h
index 817b9fde58..755841338d 100644
--- a/utils/rbutilqt/base/ttsmssp.h
+++ b/utils/rbutilqt/base/ttsmssp.h
@@ -30,14 +30,10 @@ class TTSMssp: public TTSSapi
     public:
         TTSMssp(QObject* parent=nullptr) : TTSSapi(parent)
         {
-            m_TTSTemplate = "cscript //nologo \"%exe\" "
-                "/language:%lang /voice:\"%voice\" "
-                "/speed:%speed \"%options\" /mssp";
-            m_TTSVoiceTemplate = "cscript //nologo \"%exe\" "
-                "/language:%lang /listvoices /mssp";
+            m_TTSTemplate << "/mssp";
+            m_TTSVoiceTemplate << "/mssp";
             m_TTSType = "mssp";
         }
-
 };
 
 #endif
diff --git a/utils/rbutilqt/base/ttssapi.cpp b/utils/rbutilqt/base/ttssapi.cpp
index 96ca3cb498..14c0cae70e 100644
--- a/utils/rbutilqt/base/ttssapi.cpp
+++ b/utils/rbutilqt/base/ttssapi.cpp
@@ -24,9 +24,18 @@
 
 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_TTSTemplate << "//nologo";
+    m_TTSTemplate << "%exe";
+    m_TTSTemplate << "/language:%lang";
+    m_TTSTemplate << "/voice:%voice";
+    m_TTSTemplate << "/speed:%speed";
+    m_TTSTemplate << "%options";
+
+    m_TTSVoiceTemplate << "//nologo";
+    m_TTSVoiceTemplate << "%exe";
+    m_TTSVoiceTemplate << "/language:%lang";
+    m_TTSVoiceTemplate << "/listvoices";
+
     m_TTSType = "sapi";
     defaultLanguage = "english";
     m_started = false;
@@ -113,17 +122,17 @@ bool TTSSapi::start(QString *errStr)
         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;
+    QStringList exec = m_TTSTemplate;
+    exec.replaceInStrings("%exe",m_TTSexec);
+    exec.replaceInStrings("%options",m_TTSOpts);
+    exec.replaceInStrings("%lang",m_TTSLanguage);
+    exec.replaceInStrings("%voice",m_TTSVoice);
+    exec.replaceInStrings("%speed",m_TTSSpeed);
+
+    LOG_INFO() << "Start: cscript " << exec;
     voicescript = new QProcess(nullptr);
     //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
-    voicescript->start(execstring);
+    voicescript->start("cscript", exec);
     LOG_INFO() << "wait for process";
     if(!voicescript->waitForStarted())
     {
@@ -178,13 +187,13 @@ QStringList TTSSapi::getVoiceList(QString language)
         return result;
 
     // create the voice process
-    QString execstring = m_TTSVoiceTemplate;
-    execstring.replace("%exe",m_TTSexec);
-    execstring.replace("%lang",language);
+    QStringList exec = m_TTSVoiceTemplate;
+    exec.replaceInStrings("%exe",m_TTSexec);
+    exec.replaceInStrings("%lang",language);
 
-    LOG_INFO() << "Start:" << execstring;
+    LOG_INFO() << "Start: cscript " << exec;
     voicescript = new QProcess(nullptr);
-    voicescript->start(execstring);
+    voicescript->start("cscript", exec);
     LOG_INFO() << "wait for process";
     if(!voicescript->waitForStarted()) {
         LOG_INFO() << "process startup timed out!";
diff --git a/utils/rbutilqt/base/ttssapi.h b/utils/rbutilqt/base/ttssapi.h
index b30b9d5fac..8ea1370133 100644
--- a/utils/rbutilqt/base/ttssapi.h
+++ b/utils/rbutilqt/base/ttssapi.h
@@ -67,8 +67,8 @@ class TTSSapi : public TTSBase
         bool m_started;
 
     protected:
-        QString m_TTSTemplate;
-        QString m_TTSVoiceTemplate;
+        QStringList m_TTSTemplate;
+        QStringList m_TTSVoiceTemplate;
         QString m_TTSType;
 };
 
diff --git a/utils/rbutilqt/base/ttsswift.h b/utils/rbutilqt/base/ttsswift.h
index adbc674d78..78237bea2e 100644
--- a/utils/rbutilqt/base/ttsswift.h
+++ b/utils/rbutilqt/base/ttsswift.h
@@ -31,8 +31,14 @@ class TTSSwift : public TTSExes
         TTSSwift(QObject* parent=nullptr) : TTSExes(parent)
         {
             m_name = "swift";
-            m_TTSTemplate = "\"%exe\" %options -o \"%wavfile\" -- \"%text\"";
-            m_TTSSpeakTemplate = "";
+
+            m_TTSTemplate << "%options";
+            m_TTSTemplate << "-o";
+            m_TTSTemplate << "%wavfile";
+            m_TTSTemplate << "--";
+            m_TTSTemplate << "%text";
+            //m_TTSSpeakTemplate << "";
+
             m_capabilities = TTSBase::None;
         }
 };
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs