【发布时间】:2019-04-23 22:04:43
【问题描述】:
当用户将网络合成语音设置为默认值时,我的应用程序会缓存经常出现的请求,以防止未来出现网络延迟。
我的代码here 演示了我是如何做到这一点的。简而言之,它将引擎名称和话语与请求相匹配,如果它们匹配,我会流式传输缓存的音频,而不是使用 TTS 引擎。
如果用户随后在 Android 文本到语音设置中更改了他们的音调和语速,缓存的音频当然将不再反映这一点,需要忽略并“重新缓存”,或者相应地处理音频。
我的问题:如何获得系统默认设置,用于音高和语速。
要设置 Pitch & Rate,TextToSpeech API 中提供了公开的方法:
/**
* Sets the speech rate.
*
* This has no effect on any pre-recorded speech.
*
* @param speechRate Speech rate. {@code 1.0} is the normal speech rate,
* lower values slow down the speech ({@code 0.5} is half the normal speech rate),
* greater values accelerate it ({@code 2.0} is twice the normal speech rate).
*
* @return {@link #ERROR} or {@link #SUCCESS}.
*/
public int setSpeechRate(float speechRate) {
if (speechRate > 0.0f) {
int intRate = (int)(speechRate * 100);
if (intRate > 0) {
synchronized (mStartLock) {
mParams.putInt(Engine.KEY_PARAM_RATE, intRate);
}
return SUCCESS;
}
}
return ERROR;
}
/**
* Sets the speech pitch for the TextToSpeech engine.
*
* This has no effect on any pre-recorded speech.
*
* @param pitch Speech pitch. {@code 1.0} is the normal pitch,
* lower values lower the tone of the synthesized voice,
* greater values increase it.
*
* @return {@link #ERROR} or {@link #SUCCESS}.
*/
public int setPitch(float pitch) {
if (pitch > 0.0f) {
int intPitch = (int)(pitch * 100);
if (intPitch > 0) {
synchronized (mStartLock) {
mParams.putInt(Engine.KEY_PARAM_PITCH, intPitch);
}
return SUCCESS;
}
}
return ERROR;
}
鉴于上述方法都导致将值放入绑定 TTS 引擎 (link) 的 Private Bundle:
private final Bundle mParams = new Bundle();
我使用反射来查看这些值是否被绑定引擎默认/持久化或注入。下面是一个精简示例,其中the Class 扩展了TextToSpeech:
private int getSpeechRate() {
Bundle reflectBundle;
try {
final Field f = this.getClass().getSuperclass().getDeclaredField(TTSDefaults.BOUND_PARAMS);
f.setAccessible(true);
reflectBundle = (Bundle) f.get(this);
if (reflectBundle != null && !reflectBundle.isEmpty()) {
examineBundle(reflectBundle);
if (reflectBundle.containsKey(TTSDefaults.KEY_PARAM_RATE)) {
final int reflectRate = reflectBundle.getInt(TTSDefaults.KEY_PARAM_RATE);
// log
return reflectRate;
} else {
// missing
}
} else {
// empty or null
}
} catch (final NoSuchFieldException e) {
} catch (final IllegalAccessException e) {
} catch (final NullPointerException e) {
}
return -1;
}
/**
* For debugging the bundle extras
*
* @param bundle containing potential extras
*/
private void examineBundle(@Nullable final Bundle bundle) {
if (bundle != null) {
final Set<String> keys = bundle.keySet();
//noinspection Convert2streamapi
for (final String key : keys) {
Log.v(CLS_NAME, "examineBundle: " + key + " ~ " + bundle.get(key));
}
}
}
这些值丢失了,因此,也许可以理解,这不是它们“全局”持久化的方式。
当我第一次尝试解决这个问题时,我认为这将是微不足道的 - 我希望事实证明是这样的,但我就是只见树木不见森林......
感谢您阅读本文 - 帮助!
【问题讨论】:
标签: java android text-to-speech saiy