|
|
@@ -129,6 +129,26 @@ public class TencentTTSWebApi {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static Integer configNullableInt(JSONObject account, String... keys) {
|
|
|
+ if (account == null || keys == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ for (String key : keys) {
|
|
|
+ if (StringUtils.isBlank(key)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String value = account.getString(key);
|
|
|
+ if (StringUtils.isBlank(value)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return Integer.parseInt(value.trim());
|
|
|
+ } catch (Throwable ignore) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
private static boolean configBool(JSONObject account, String key, boolean defaultValue) {
|
|
|
if (account == null) {
|
|
|
return defaultValue;
|
|
|
@@ -168,6 +188,24 @@ public class TencentTTSWebApi {
|
|
|
return Math.min(timeoutSec, 120);
|
|
|
}
|
|
|
|
|
|
+ private static boolean isEffectInRange(Integer value) {
|
|
|
+ return value != null && value >= -100 && value <= 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String normalizeSoundEffect(String value) {
|
|
|
+ if (StringUtils.isBlank(value)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ String trimmed = value.trim();
|
|
|
+ if ("spacious_echo".equals(trimmed)
|
|
|
+ || "auditorium_echo".equals(trimmed)
|
|
|
+ || "lofi_telephone".equals(trimmed)
|
|
|
+ || "robotic".equals(trimmed)) {
|
|
|
+ return trimmed;
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
private static String formatDouble(double value) {
|
|
|
String raw = String.format(java.util.Locale.US, "%.3f", value);
|
|
|
while (raw.contains(".") && raw.endsWith("0")) {
|
|
|
@@ -234,7 +272,11 @@ public class TencentTTSWebApi {
|
|
|
int timeoutSec,
|
|
|
double speed,
|
|
|
double volume,
|
|
|
- String resId) throws Exception {
|
|
|
+ String resId,
|
|
|
+ Integer pitch,
|
|
|
+ Integer intensity,
|
|
|
+ Integer timbre,
|
|
|
+ String soundEffect) throws Exception {
|
|
|
String host = config(account, "websocket-host", "mps.cloud.tencent.com");
|
|
|
String appId = config(account, "appid", "");
|
|
|
String secretId = config(account, "secret-id", "");
|
|
|
@@ -256,6 +298,18 @@ public class TencentTTSWebApi {
|
|
|
if (Math.abs(volume) > 0.000001d) {
|
|
|
params.put("vol", formatDouble(volume));
|
|
|
}
|
|
|
+ if (isEffectInRange(pitch)) {
|
|
|
+ params.put("pitch", String.valueOf(pitch));
|
|
|
+ }
|
|
|
+ if (isEffectInRange(intensity)) {
|
|
|
+ params.put("intensity", String.valueOf(intensity));
|
|
|
+ }
|
|
|
+ if (isEffectInRange(timbre)) {
|
|
|
+ params.put("timbre", String.valueOf(timbre));
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(soundEffect)) {
|
|
|
+ params.put("soundEffect", soundEffect);
|
|
|
+ }
|
|
|
if (StringUtils.isNotBlank(resId)) {
|
|
|
params.put("resId", resId);
|
|
|
}
|
|
|
@@ -440,6 +494,11 @@ public class TencentTTSWebApi {
|
|
|
int timeoutSec = configInt(account, "timeout-sec", 60);
|
|
|
double speed = configDouble(account, "speed", 0d);
|
|
|
double volume = configDouble(account, "vol", 0d);
|
|
|
+ Integer pitch = configNullableInt(account, "pitch");
|
|
|
+ Integer intensity = configNullableInt(account, "intensity");
|
|
|
+ Integer timbre = configNullableInt(account, "timbre");
|
|
|
+ String soundEffect = normalizeSoundEffect(config(account, "sound-effect",
|
|
|
+ config(account, "soundEffect", "")));
|
|
|
String resId = config(account, "res-id", "");
|
|
|
boolean verifyPeer = configBool(account, "verify-peer", false);
|
|
|
int connectTimeoutMs = configInt(account, "connect-timeout-ms", 10000);
|
|
|
@@ -449,7 +508,8 @@ public class TencentTTSWebApi {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- String wsUrl = buildWsUrl(account, voiceId, requestedFormat, language, requestedSampleRate, timeoutSec, speed, volume, resId);
|
|
|
+ String wsUrl = buildWsUrl(account, voiceId, requestedFormat, language, requestedSampleRate,
|
|
|
+ timeoutSec, speed, volume, resId, pitch, intensity, timbre, soundEffect);
|
|
|
OkHttpClient client = buildClient(verifyPeer).newBuilder()
|
|
|
.connectTimeout(connectTimeoutMs, TimeUnit.MILLISECONDS)
|
|
|
.readTimeout(0, TimeUnit.MILLISECONDS)
|