Skip to content

Commit

Permalink
made tts language detection automatic
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke100000 committed Feb 13, 2024
1 parent f4d0c4f commit d0e0adf
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 26 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 7.5.14

* TTS language is now detected automatically

# 7.5.13

* Updated chatAI to v2
Expand Down
1 change: 0 additions & 1 deletion common/src/main/java/net/mca/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ public static Config getInstance() {
// TTS
public boolean enableOnlineTTS = false;
public String villagerTTSServer = "http://api.rk.conczin.net/";
public String onlineTTSLanguage = "en";

//village behavior
public float guardSpawnFraction = 0.175f;
Expand Down
124 changes: 124 additions & 0 deletions common/src/main/java/net/mca/client/LanguageMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package net.mca.client;

import java.util.HashMap;
import java.util.Map;

public class LanguageMap {
public static final Map<String, String> LANGUAGE_MAP = new HashMap<>();

static {
LANGUAGE_MAP.put("af_za", "");
LANGUAGE_MAP.put("ar_sa", "ar");
LANGUAGE_MAP.put("ast_es", "es");
LANGUAGE_MAP.put("az_az", "");
LANGUAGE_MAP.put("be_by", "ru");
LANGUAGE_MAP.put("bg_bg", "");
LANGUAGE_MAP.put("br_fr", "fr");
LANGUAGE_MAP.put("brb", "nl");
LANGUAGE_MAP.put("bs_BA", "");
LANGUAGE_MAP.put("ca_es", "");
LANGUAGE_MAP.put("cs_cz", "cs");
LANGUAGE_MAP.put("cy_gb", "");
LANGUAGE_MAP.put("da_dk", "");
LANGUAGE_MAP.put("de_at", "de");
LANGUAGE_MAP.put("de_ch", "de");
LANGUAGE_MAP.put("de_de", "de");
LANGUAGE_MAP.put("el_gr", "");
LANGUAGE_MAP.put("en_au", "en");
LANGUAGE_MAP.put("en_ca", "en");
LANGUAGE_MAP.put("en_za", "en");
LANGUAGE_MAP.put("en_gb", "en");
LANGUAGE_MAP.put("en_nz", "en");
LANGUAGE_MAP.put("en_7s", "en");
LANGUAGE_MAP.put("en_ud", "en");
LANGUAGE_MAP.put("en_us", "en");
LANGUAGE_MAP.put("eo_uy", "");
LANGUAGE_MAP.put("es_ar", "es");
LANGUAGE_MAP.put("es_es", "es");
LANGUAGE_MAP.put("es_cl", "es");
LANGUAGE_MAP.put("es_mx", "es");
LANGUAGE_MAP.put("es_uy", "es");
LANGUAGE_MAP.put("es_ve", "es");
LANGUAGE_MAP.put("et_ee", "");
LANGUAGE_MAP.put("eu_es", "");
LANGUAGE_MAP.put("fa_ir", "");
LANGUAGE_MAP.put("fi_fi", "");
LANGUAGE_MAP.put("fil_ph", "");
LANGUAGE_MAP.put("fo_fo", "");
LANGUAGE_MAP.put("fr_ca", "fr");
LANGUAGE_MAP.put("fr_fr", "fr");
LANGUAGE_MAP.put("fy_nl", "");
LANGUAGE_MAP.put("ga_ie", "");
LANGUAGE_MAP.put("gd_gb", "");
LANGUAGE_MAP.put("gl_es", "");
LANGUAGE_MAP.put("gv_im", "");
LANGUAGE_MAP.put("haw", "");
LANGUAGE_MAP.put("he_il", "");
LANGUAGE_MAP.put("hi_in", "hi");
LANGUAGE_MAP.put("hr_hr", "");
LANGUAGE_MAP.put("hu_hu", "hu");
LANGUAGE_MAP.put("hy_am", "");
LANGUAGE_MAP.put("id_id", "");
LANGUAGE_MAP.put("isv", "");
LANGUAGE_MAP.put("ig_ng", "");
LANGUAGE_MAP.put("io_en", "");
LANGUAGE_MAP.put("is_is", "");
LANGUAGE_MAP.put("it_it", "it");
LANGUAGE_MAP.put("ja_jp", "ja");
LANGUAGE_MAP.put("jbo", "");
LANGUAGE_MAP.put("ka_ge", "");
LANGUAGE_MAP.put("ko_kr", "ko");
LANGUAGE_MAP.put("ksh_de", "de"); // Kölsch/Ripuarian - mapping to German
LANGUAGE_MAP.put("kw_gb", "");
LANGUAGE_MAP.put("la_va", "");
LANGUAGE_MAP.put("lb_lu", "");
LANGUAGE_MAP.put("li_li", "");
LANGUAGE_MAP.put("lol_aa", "");
LANGUAGE_MAP.put("lt_lt", "");
LANGUAGE_MAP.put("lv_lv", "");
LANGUAGE_MAP.put("mi_nz", "");
LANGUAGE_MAP.put("mk_mk", "");
LANGUAGE_MAP.put("mn_mn", "");
LANGUAGE_MAP.put("moh_us", "");
LANGUAGE_MAP.put("ms_my", "");
LANGUAGE_MAP.put("mt_mt", "");
LANGUAGE_MAP.put("nds_de", "de"); // Low German - mapping to German
LANGUAGE_MAP.put("nl_be", "nl");
LANGUAGE_MAP.put("nl_nl", "nl");
LANGUAGE_MAP.put("nn_no", "");
LANGUAGE_MAP.put("no_no", "");
LANGUAGE_MAP.put("nb_no", "");
LANGUAGE_MAP.put("nuk", "");
LANGUAGE_MAP.put("oc_fr", "");
LANGUAGE_MAP.put("oj_ca", "");
LANGUAGE_MAP.put("ovd_se", "");
LANGUAGE_MAP.put("pl_pl", "pl");
LANGUAGE_MAP.put("pt_br", "pt");
LANGUAGE_MAP.put("pt_pt", "pt");
LANGUAGE_MAP.put("qya_aa", "");
LANGUAGE_MAP.put("ro_ro", "");
LANGUAGE_MAP.put("ru_ru", "ru");
LANGUAGE_MAP.put("sme", "");
LANGUAGE_MAP.put("sk_sk", "");
LANGUAGE_MAP.put("sl_si", "");
LANGUAGE_MAP.put("so_so", "");
LANGUAGE_MAP.put("sq_al", "");
LANGUAGE_MAP.put("sr_sp", "");
LANGUAGE_MAP.put("sv_se", "");
LANGUAGE_MAP.put("swg", "");
LANGUAGE_MAP.put("sxu", "de"); // Upper Saxon German - mapping to German
LANGUAGE_MAP.put("szl", "");
LANGUAGE_MAP.put("ta_IN", "");
LANGUAGE_MAP.put("th_th", "");
LANGUAGE_MAP.put("tlh_aa", "");
LANGUAGE_MAP.put("tr_tr", "tr");
LANGUAGE_MAP.put("tt_ru", "");
LANGUAGE_MAP.put("tzl_tzl", "");
LANGUAGE_MAP.put("uk_ua", "");
LANGUAGE_MAP.put("vi_vn", "");
LANGUAGE_MAP.put("vmf_de", "de"); // Franconian - mapping to German
LANGUAGE_MAP.put("yo_ng", "");
LANGUAGE_MAP.put("zh_cn", "zh-cn");
LANGUAGE_MAP.put("zh_tw", "");
}
}
3 changes: 1 addition & 2 deletions common/src/main/java/net/mca/client/OnlineSpeechManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ public String getHash(String text) {
return toHex(MESSAGEDIGEST.digest()).toLowerCase(Locale.ROOT);
}

public void play(String voice, float pitch, String text, Entity entity) {
public void play(String language, String voice, float pitch, String text, Entity entity) {
String hash = getHash(text);
String language = Config.getInstance().onlineTTSLanguage;
CompletableFuture.runAsync(() -> {
if (downloadAudio(language, voice, text, hash)) {
play(language, voice, pitch, entity, hash);
Expand Down
19 changes: 15 additions & 4 deletions common/src/main/java/net/mca/client/SpeechManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
import net.minecraft.entity.Entity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TextContent;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.Language;
import net.minecraft.util.math.random.Random;
Expand Down Expand Up @@ -71,10 +74,18 @@ private void speak(String phrase, UUID sender) {

String gender = villager.getGenetics().getGender().binary().getDataName();
if (Config.getInstance().enableOnlineTTS) {
String content = Language.getInstance().get(phrase);
int tone = Math.min(TOTAL_VOICES - 1, (int) Math.floor(gene * TOTAL_VOICES));
String voice = gender + "_" + tone;
OnlineSpeechManager.INSTANCE.play(voice, pitch, content, villager);
String gameLang = client.options.language;
if (LanguageMap.LANGUAGE_MAP.containsKey(gameLang) && !LanguageMap.LANGUAGE_MAP.get(gameLang).isEmpty()) {
String content = Language.getInstance().get(phrase);
int tone = Math.min(TOTAL_VOICES - 1, (int) Math.floor(gene * TOTAL_VOICES));
String voice = gender + "_" + tone;
OnlineSpeechManager.INSTANCE.play(LanguageMap.LANGUAGE_MAP.get(gameLang), voice, pitch, content, villager);
} else {
MutableText styled = (Text.translatable("command.tts_unsupported_language")).styled(s -> s
.withColor(Formatting.RED)
.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/Luke100000/minecraft-comes-alive/wiki/TTS")));
client.inGameHud.getChatHud().addMessage(styled);
}
} else {
int tone = Math.min(9, (int) Math.floor(gene * 10.0f));
Identifier sound = new Identifier("mca_voices", phrase.toLowerCase(Locale.ROOT) + "/" + gender + "_" + tone);
Expand Down
21 changes: 2 additions & 19 deletions common/src/main/java/net/mca/server/command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -60,10 +59,7 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
.then(register("tts")
.requires(p -> p.getServer().isSingleplayer())
.then(CommandManager.literal("enable").then(CommandManager.argument("enabled", BoolArgumentType.bool()).executes(Command::ttsEnable)))
.then(CommandManager.literal("language").then(CommandManager.argument("language", StringArgumentType.string()).executes(Command::ttsLanguage)))
.then(CommandManager.literal("scan").requires(p -> p.getPlayer() != null && p.getPlayer().getEntityName().contains("Player")).executes(Command::ttsScan))
)
);
.then(CommandManager.literal("scan").then(CommandManager.argument("language", StringArgumentType.string()).requires(p -> p.getPlayer() != null && p.getPlayer().getEntityName().contains("Player")).executes(Command::ttsScan)))));
}

private static int chatAIHelp(CommandContext<ServerCommandSource> context) {
Expand All @@ -89,19 +85,6 @@ private static int ttsEnable(CommandContext<ServerCommandSource> ctx) {
return 0;
}

private static int ttsLanguage(CommandContext<ServerCommandSource> ctx) {
Set<String> languages = Set.of("en", "es", "fr", "de", "it", "pt", "pl", "tr", "ru", "nl", "cs", "ar", "zh-cn", "hu", "ko", "ja", "hi");
String language = ctx.getArgument("language", String.class);
if (languages.contains(language)) {
Config.getInstance().onlineTTSLanguage = language;
Config.getInstance().save();
return 0;
} else {
sendMessage(ctx, "Choose one of: " + String.join(", ", languages));
return 1;
}
}

private static boolean couldBePersonalityRelated(String phrase) {
for (Personality value : Personality.values()) {
if (phrase.contains(value.name().toLowerCase(Locale.ROOT))) {
Expand All @@ -116,7 +99,7 @@ private static int ttsScan(CommandContext<ServerCommandSource> ctx) {
String key = text.getKey();
if ((key.contains("dialogue.") || key.contains("interaction.") || key.contains("villager.")) && !couldBePersonalityRelated(key)) {
String hash = OnlineSpeechManager.INSTANCE.getHash(text.getValue());
String language = Config.getInstance().onlineTTSLanguage;
String language = ctx.getArgument("language", String.class);
CompletableFuture.runAsync(() -> {
OnlineSpeechManager.INSTANCE.downloadAudio(language, "male_" + (SpeechManager.TOTAL_VOICES - 1), text.getValue(), hash);
});
Expand Down
1 change: 1 addition & 0 deletions common/src/main/resources/assets/mca/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@
"command.only_one_destiny": "You already decided your destiny.",
"command.no_mail": "You have no mails.",
"command.tts_busy": "(Whenever villagers remain silent, it means the text-to-speech has to generate that phrase first. It will be there next time.)",
"command.tts_unsupported_language": "Your game language is not supported by the text-to-speech. Please change it to English or disable TTS.",

"blueprint.noBuilding": "You need to stand within a building",
"blueprint.refreshed": "Buildings refreshed!",
Expand Down

0 comments on commit d0e0adf

Please sign in to comment.