mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-09 23:53:28 -04:00
FS#13984 - Rockbox Utility: Add SAPI5 voice volume control (Alessio Lenzi)
Rockbox Utility currently exposes SAPI5 voice speed but not the SAPI voice volume. The encoder volume setting is applied after synthesis, so it cannot prevent clipping or distortion already present in the generated wave file. This patch adds a Volume control to the SAPI5 TTS configuration. The value is passed to the standard SpVoice.Volume property before synthesis. Change-Id: Ifa43e55f716f98150e94c86e5e6a6c8bce0ca852
This commit is contained in:
parent
3f1ec2385f
commit
fd2b070bb1
5 changed files with 19 additions and 1 deletions
|
|
@ -39,7 +39,7 @@ Dim oShell, oArgs, oEnv
|
||||||
Dim oFSO, oStdIn, oStdOut
|
Dim oFSO, oStdIn, oStdOut
|
||||||
Dim bVerbose, bList
|
Dim bVerbose, bList
|
||||||
Dim bMSSP
|
Dim bMSSP
|
||||||
Dim sLanguage, sVoice, sSpeed, sName, sVendor
|
Dim sLanguage, sVoice, sSpeed, sVolume, sName, sVendor
|
||||||
|
|
||||||
Dim oSpVoice, oSpFS ' SAPI5 voice and filestream
|
Dim oSpVoice, oSpFS ' SAPI5 voice and filestream
|
||||||
Dim oVoice ' for traversing the list of voices
|
Dim oVoice ' for traversing the list of voices
|
||||||
|
|
@ -64,6 +64,7 @@ bList = oArgs.Exists("listvoices")
|
||||||
sLanguage = oArgs.Item("language")
|
sLanguage = oArgs.Item("language")
|
||||||
sVoice = oArgs.Item("voice")
|
sVoice = oArgs.Item("voice")
|
||||||
sSpeed = oArgs.Item("speed")
|
sSpeed = oArgs.Item("speed")
|
||||||
|
sVolume = oArgs.Item("volume")
|
||||||
|
|
||||||
' Create SAPI5 object
|
' Create SAPI5 object
|
||||||
If bMSSP Then
|
If bMSSP Then
|
||||||
|
|
@ -116,6 +117,8 @@ End If
|
||||||
|
|
||||||
' Speed selection
|
' Speed selection
|
||||||
If sSpeed <> "" Then oSpVoice.Rate = sSpeed
|
If sSpeed <> "" Then oSpVoice.Rate = sSpeed
|
||||||
|
' Volume selection
|
||||||
|
If sVolume <> "" Then oSpVoice.Volume = sVolume
|
||||||
' Get vendor information, protect from missing attribute
|
' Get vendor information, protect from missing attribute
|
||||||
sVendor = oSpVoice.Voice.GetAttribute("Vendor")
|
sVendor = oSpVoice.Voice.GetAttribute("Vendor")
|
||||||
If Err.Number <> 0 Then
|
If Err.Number <> 0 Then
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ const static struct {
|
||||||
{ RbSettings::EncoderNarrowBand, ":encoder:/narrowband", "false" },
|
{ RbSettings::EncoderNarrowBand, ":encoder:/narrowband", "false" },
|
||||||
{ RbSettings::WavtrimThreshold, "wavtrimthreshold", "500"},
|
{ RbSettings::WavtrimThreshold, "wavtrimthreshold", "500"},
|
||||||
{ RbSettings::TtsSpeed, ":tts:/speed", "175" },
|
{ RbSettings::TtsSpeed, ":tts:/speed", "175" },
|
||||||
|
{ RbSettings::TtsVolume, ":tts:/volume", "100" },
|
||||||
{ RbSettings::EncoderComplexity, ":encoder:/complexity", "10" },
|
{ RbSettings::EncoderComplexity, ":encoder:/complexity", "10" },
|
||||||
{ RbSettings::EncoderQuality, ":encoder:/quality", "-1.0" },
|
{ RbSettings::EncoderQuality, ":encoder:/quality", "-1.0" },
|
||||||
{ RbSettings::EncoderVolume, ":encoder:/volume", "1.0" },
|
{ RbSettings::EncoderVolume, ":encoder:/volume", "1.0" },
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ class RbSettings : public QObject
|
||||||
WavtrimThreshold,
|
WavtrimThreshold,
|
||||||
EncoderComplexity,
|
EncoderComplexity,
|
||||||
TtsSpeed,
|
TtsSpeed,
|
||||||
|
TtsVolume,
|
||||||
CacheDisabled,
|
CacheDisabled,
|
||||||
EncoderNarrowBand,
|
EncoderNarrowBand,
|
||||||
EncoderQuality,
|
EncoderQuality,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ TTSSapi::TTSSapi(QObject* parent) : TTSBase(parent)
|
||||||
m_TTSTemplate << "/language:%lang";
|
m_TTSTemplate << "/language:%lang";
|
||||||
m_TTSTemplate << "/voice:%voice";
|
m_TTSTemplate << "/voice:%voice";
|
||||||
m_TTSTemplate << "/speed:%speed";
|
m_TTSTemplate << "/speed:%speed";
|
||||||
|
m_TTSTemplate << "/volume:%volume";
|
||||||
m_TTSTemplate << "%options";
|
m_TTSTemplate << "%options";
|
||||||
|
|
||||||
m_TTSVoiceTemplate << "//nologo";
|
m_TTSVoiceTemplate << "//nologo";
|
||||||
|
|
@ -74,6 +75,12 @@ void TTSSapi::generateSettings()
|
||||||
speed = 0;
|
speed = 0;
|
||||||
insertSetting(eSPEED, new EncTtsSetting(this,
|
insertSetting(eSPEED, new EncTtsSetting(this,
|
||||||
EncTtsSetting::eINT, tr("Speed:"), speed, -10, 10));
|
EncTtsSetting::eINT, tr("Speed:"), speed, -10, 10));
|
||||||
|
// volume
|
||||||
|
int volume = RbSettings::subValue(m_TTSType, RbSettings::TtsVolume).toInt();
|
||||||
|
if(volume > 100 || volume < 0)
|
||||||
|
volume = 100;
|
||||||
|
insertSetting(eVOLUME, new EncTtsSetting(this,
|
||||||
|
EncTtsSetting::eINT, tr("Volume:"), volume, 0, 100));
|
||||||
// options
|
// options
|
||||||
insertSetting(eOPTIONS, new EncTtsSetting(this,
|
insertSetting(eOPTIONS, new EncTtsSetting(this,
|
||||||
EncTtsSetting::eSTRING, tr("Options:"),
|
EncTtsSetting::eSTRING, tr("Options:"),
|
||||||
|
|
@ -90,6 +97,8 @@ void TTSSapi::saveSettings()
|
||||||
getSetting(eVOICE)->current().toString());
|
getSetting(eVOICE)->current().toString());
|
||||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsSpeed,
|
RbSettings::setSubValue(m_TTSType, RbSettings::TtsSpeed,
|
||||||
getSetting(eSPEED)->current().toInt());
|
getSetting(eSPEED)->current().toInt());
|
||||||
|
RbSettings::setSubValue(m_TTSType, RbSettings::TtsVolume,
|
||||||
|
getSetting(eVOLUME)->current().toInt());
|
||||||
RbSettings::setSubValue(m_TTSType, RbSettings::TtsOptions,
|
RbSettings::setSubValue(m_TTSType, RbSettings::TtsOptions,
|
||||||
getSetting(eOPTIONS)->current().toString());
|
getSetting(eOPTIONS)->current().toString());
|
||||||
|
|
||||||
|
|
@ -112,6 +121,7 @@ bool TTSSapi::start(QString *errStr)
|
||||||
m_TTSLanguage =RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage).toString();
|
m_TTSLanguage =RbSettings::subValue(m_TTSType, RbSettings::TtsLanguage).toString();
|
||||||
m_TTSVoice=RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString();
|
m_TTSVoice=RbSettings::subValue(m_TTSType, RbSettings::TtsVoice).toString();
|
||||||
m_TTSSpeed=RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toString();
|
m_TTSSpeed=RbSettings::subValue(m_TTSType, RbSettings::TtsSpeed).toString();
|
||||||
|
m_TTSVolume=RbSettings::subValue(m_TTSType, RbSettings::TtsVolume).toString();
|
||||||
|
|
||||||
QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
|
QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
|
||||||
QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
|
QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
|
||||||
|
|
@ -130,6 +140,7 @@ bool TTSSapi::start(QString *errStr)
|
||||||
exec.replaceInStrings("%lang",m_TTSLanguage);
|
exec.replaceInStrings("%lang",m_TTSLanguage);
|
||||||
exec.replaceInStrings("%voice",m_TTSVoice);
|
exec.replaceInStrings("%voice",m_TTSVoice);
|
||||||
exec.replaceInStrings("%speed",m_TTSSpeed);
|
exec.replaceInStrings("%speed",m_TTSSpeed);
|
||||||
|
exec.replaceInStrings("%volume",m_TTSVolume);
|
||||||
|
|
||||||
LOG_INFO() << "Start: cscript " << exec;
|
LOG_INFO() << "Start: cscript " << exec;
|
||||||
voicescript = new QProcess(nullptr);
|
voicescript = new QProcess(nullptr);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class TTSSapi : public TTSBase
|
||||||
eLANGUAGE,
|
eLANGUAGE,
|
||||||
eVOICE,
|
eVOICE,
|
||||||
eSPEED,
|
eSPEED,
|
||||||
|
eVOLUME,
|
||||||
eOPTIONS
|
eOPTIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -64,6 +65,7 @@ class TTSSapi : public TTSBase
|
||||||
QString m_TTSLanguage;
|
QString m_TTSLanguage;
|
||||||
QString m_TTSVoice;
|
QString m_TTSVoice;
|
||||||
QString m_TTSSpeed;
|
QString m_TTSSpeed;
|
||||||
|
QString m_TTSVolume;
|
||||||
bool m_started;
|
bool m_started;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue