diff --git a/code/controllers/subsystem/SShttp.dm b/code/controllers/subsystem/SShttp.dm index c0e4fb6ca098..fade67c56a76 100644 --- a/code/controllers/subsystem/SShttp.dm +++ b/code/controllers/subsystem/SShttp.dm @@ -53,9 +53,9 @@ SUBSYSTEM_DEF(http) * Generates an async request, and adds it to the subsystem's processing list * These should be used as they do not lock the entire DD process up as they execute inside their own thread pool inside RUSTG */ -/datum/controller/subsystem/http/proc/create_async_request(method, url, body = "", list/headers, datum/callback/proc_callback) +/datum/controller/subsystem/http/proc/create_async_request(method, url, body = "", list/headers, datum/callback/proc_callback, output_file = "") var/datum/http_request/req = new() - req.prepare(method, url, body, headers) + req.prepare(method, url, body, headers, output_file) if(proc_callback) req.cb = proc_callback diff --git a/modular_ss220/text_to_speech/_tts.dme b/modular_ss220/text_to_speech/_tts.dme index 4facec666490..20d9de31f57b 100644 --- a/modular_ss220/text_to_speech/_tts.dme +++ b/modular_ss220/text_to_speech/_tts.dme @@ -5,9 +5,11 @@ #include "code/hear.dm" #include "code/numbers.dm" #include "code/providers/silero.dm" +#include "code/providers/white_dream.dm" #include "code/rust_g_ss220.dm" #include "code/seeds/base.dm" #include "code/seeds/silero.dm" +#include "code/seeds/white_dream.dm" #include "code/sound.dm" #include "code/tts_preferences.dm" #include "code/tts_provider.dm" diff --git a/modular_ss220/text_to_speech/code/configuration.dm b/modular_ss220/text_to_speech/code/configuration.dm index 30d862197bfb..da7a53e41237 100644 --- a/modular_ss220/text_to_speech/code/configuration.dm +++ b/modular_ss220/text_to_speech/code/configuration.dm @@ -13,6 +13,8 @@ var/tts_enabled = FALSE /// TTS API token for silero provider var/tts_token_silero = "" + /// TTS API token for white dream provider + var/tts_token_white_dream = "" /// Should oggs be cached var/tts_cache_enabled = FALSE /// What cpu threads should ffmpeg use @@ -21,10 +23,11 @@ /datum/configuration_section/tts_configuration/load_data(list/data) CONFIG_LOAD_BOOL(tts_enabled, data["tts_enabled"]) CONFIG_LOAD_STR(tts_token_silero, data["tts_token_silero"]) + CONFIG_LOAD_STR(tts_token_white_dream, data["tts_token_white_dream"]) CONFIG_LOAD_BOOL(tts_cache_enabled, data["tts_cache_enabled"]) CONFIG_LOAD_STR(ffmpeg_cpuaffinity, data["ffmpeg_cpuaffinity"]) - tts_enabled = tts_token_silero && tts_enabled + tts_enabled = (tts_token_silero || tts_token_white_dream) && tts_enabled var/sanitized = regex(@"[^0-9,-]", "g").Replace(ffmpeg_cpuaffinity, "") if(ffmpeg_cpuaffinity != sanitized) log_config("Wrong value for ffmpeg_cpuaffinity. Check out taskset man page.") diff --git a/modular_ss220/text_to_speech/code/providers/silero.dm b/modular_ss220/text_to_speech/code/providers/silero.dm index 9f3f2bba1772..bbf5e6a40b67 100644 --- a/modular_ss220/text_to_speech/code/providers/silero.dm +++ b/modular_ss220/text_to_speech/code/providers/silero.dm @@ -8,7 +8,7 @@ return FALSE return ..() -/datum/tts_provider/silero/request(text, datum/tts_seed/silero/seed, datum/callback/proc_callback) +/datum/tts_provider/silero/request(text, datum/tts_seed/silero/seed, datum/callback/proc_callback, file_name) if(throttle_check()) return FALSE diff --git a/modular_ss220/text_to_speech/code/providers/white_dream.dm b/modular_ss220/text_to_speech/code/providers/white_dream.dm new file mode 100644 index 000000000000..492d54f73b7a --- /dev/null +++ b/modular_ss220/text_to_speech/code/providers/white_dream.dm @@ -0,0 +1,36 @@ +/datum/tts_provider/white_dream + name = "White Dream" + is_enabled = FALSE + api_url = "https://pubtts.ss14.su/api/v1/tts" + skip_explicit_file_save = TRUE + +/datum/tts_provider/white_dream/vv_edit_var(var_name, var_value) + if(var_name == "api_url") + return FALSE + return ..() + +/datum/tts_provider/white_dream/request(text, datum/tts_seed/white_dream/seed, datum/callback/proc_callback, file_name) + if(throttle_check()) + return FALSE + + var/ssml_text = {"[text]"} + + var/requestQuery = {"speaker=[seed.value]&ext=ogg&text=[url_encode(ssml_text)]"} + + rustg_file_write("", file_name) + + SShttp.create_async_request(RUSTG_HTTP_METHOD_GET, {"[api_url]?[requestQuery]"}, "", list("content-type" = "application/json", "Authorization" = {"Bearer [GLOB.configuration.tts.tts_token_white_dream]"}), proc_callback, file_name) + + return TRUE + +/datum/tts_provider/white_dream/process_response(datum/http_response/response) + return "voice" + +/datum/tts_provider/white_dream/pitch_whisper(text) + return {"[text]"} + +/datum/tts_provider/white_dream/rate_faster(text) + return {"[text]"} + +/datum/tts_provider/white_dream/rate_medium(text) + return {"[text]"} diff --git a/modular_ss220/text_to_speech/code/seeds/white_dream.dm b/modular_ss220/text_to_speech/code/seeds/white_dream.dm new file mode 100644 index 000000000000..3a72e1273274 --- /dev/null +++ b/modular_ss220/text_to_speech/code/seeds/white_dream.dm @@ -0,0 +1,386 @@ +/datum/tts_seed/white_dream + provider = /datum/tts_provider/white_dream + +/datum/tts_seed/white_dream/papich + name = "Papich" + value = "papich" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/bebey + name = "Bebey" + value = "bebey" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/charlotte + name = "Charlotte" + value = "charlotte" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/planya + name = "Planya" + value = "planya" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/mana + name = "Mana" + value = "mana" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/amina + name = "Amina" + value = "amina" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/biden + name = "Biden" + value = "biden" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/obama + name = "Obama" + value = "obama" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/trump + name = "Trump" + value = "trump" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/dbkn + name = "Dbkn" + value = "dbkn" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/xrenoid + name = "Xrenoid" + value = "xrenoid" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/valtos + name = "Valtos" + value = "valtos" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/briman + name = "Briman" + value = "briman" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/father_grigori + name = "Father_grigori" + value = "father_grigori" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/kleiner + name = "Kleiner" + value = "kleiner" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/mossman + name = "Mossman" + value = "mossman" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/vance + name = "Vance" + value = "vance" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/alyx + name = "Alyx" + value = "alyx" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/gman + name = "Gman" + value = "gman" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/barni + name = "Barni" + value = "barni" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/neco + name = "Neco" + value = "neco" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/soldier + name = "Soldier" + value = "soldier" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/sentrybot + name = "Sentrybot" + value = "sentrybot" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/polina + name = "Polina" + value = "polina" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/cicero + name = "Cicero" + value = "cicero" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/sheogorath + name = "Sheogorath" + value = "sheogorath" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/kodlakwhitemane + name = "Kodlakwhitemane" + value = "kodlakwhitemane" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/glados + name = "Glados" + value = "glados" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/adventure_core + name = "Adventure_core" + value = "adventure_core" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/fact_core + name = "Fact_core" + value = "fact_core" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/space_core + name = "Space_core" + value = "space_core" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/turret_floor + name = "Turret_floor" + value = "turret_floor" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/geralt + name = "Geralt" + value = "geralt" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/cirilla + name = "Cirilla" + value = "cirilla" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/lambert + name = "Lambert" + value = "lambert" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/triss + name = "Triss" + value = "triss" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/azir + name = "Azir" + value = "azir" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/ekko + name = "Ekko" + value = "ekko" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/twitch + name = "Twitch" + value = "twitch" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/ziggs + name = "Ziggs" + value = "ziggs" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/caitlyn + name = "Caitlyn" + value = "caitlyn" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/arthas + name = "Arthas" + value = "arthas" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/illidan + name = "Illidan" + value = "illidan" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/rexxar + name = "Rexxar" + value = "rexxar" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/voljin + name = "Voljin" + value = "voljin" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/bandit + name = "Bandit" + value = "bandit" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/forester + name = "Forester" + value = "forester" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/sidorovich + name = "Sidorovich" + value = "sidorovich" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/strelok + name = "Strelok" + value = "strelok" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/tracer + name = "Tracer" + value = "tracer" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/engineer + name = "Engineer" + value = "engineer" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/heavy + name = "Heavy" + value = "heavy" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/medic + name = "Medic" + value = "medic" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/demoman + name = "Demoman" + value = "demoman" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/sniper + name = "Sniper" + value = "sniper" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/spy + name = "Spy" + value = "spy" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/khajiit + name = "Khajiit" + value = "khajiit" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/punisher + name = "Punisher" + value = "punisher" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/johnny + name = "Johnny" + value = "johnny" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/panam + name = "Panam" + value = "panam" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/v_female + name = "V" + value = "v_female" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_FEMALE + +/datum/tts_seed/white_dream/dornan + name = "Dornan" + value = "dornan" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/officer_enclave + name = "Officer Enclave" + value = "officer_enclave" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE + +/datum/tts_seed/white_dream/richardson + name = "Richardson" + value = "richardson" + category = TTS_CATEGORY_OTHER + gender = TTS_GENDER_MALE diff --git a/modular_ss220/text_to_speech/code/tts_preferences.dm b/modular_ss220/text_to_speech/code/tts_preferences.dm index 7e86aed414fb..da32e5a0a12c 100644 --- a/modular_ss220/text_to_speech/code/tts_preferences.dm +++ b/modular_ss220/text_to_speech/code/tts_preferences.dm @@ -42,10 +42,11 @@ var/list/providers = list() for(var/_provider in SStts220.tts_providers) var/datum/tts_provider/provider = SStts220.tts_providers[_provider] - providers += list(list( - "name" = provider.name, - "is_enabled" = provider.is_enabled, - )) + if (provider.is_enabled) + providers += list(list( + "name" = provider.name, + "is_enabled" = provider.is_enabled, + )) data["providers"] = providers var/list/seeds = list() diff --git a/modular_ss220/text_to_speech/code/tts_provider.dm b/modular_ss220/text_to_speech/code/tts_provider.dm index bd47e3d58567..7ac9611f3ccd 100644 --- a/modular_ss220/text_to_speech/code/tts_provider.dm +++ b/modular_ss220/text_to_speech/code/tts_provider.dm @@ -2,6 +2,7 @@ var/name = "STUB" var/is_enabled = TRUE var/api_url + var/skip_explicit_file_save = FALSE var/is_throttled = FALSE var/throttled_until = 0 @@ -10,7 +11,7 @@ var/failed_requests = 0 var/failed_requests_limit = 10 -/datum/tts_provider/proc/request(text, datum/tts_seed/seed, datum/callback/proc_callback) +/datum/tts_provider/proc/request(text, datum/tts_seed/seed, datum/callback/proc_callback, file_name) return TRUE /datum/tts_provider/proc/process_response(datum/http_response/response) diff --git a/modular_ss220/text_to_speech/code/tts_subsystem.dm b/modular_ss220/text_to_speech/code/tts_subsystem.dm index 78f5f5233cf1..f32d209aa93b 100644 --- a/modular_ss220/text_to_speech/code/tts_subsystem.dm +++ b/modular_ss220/text_to_speech/code/tts_subsystem.dm @@ -211,7 +211,8 @@ SUBSYSTEM_DEF(tts220) var/datum/tts_seed/seed = request[2] var/datum/callback/proc_callback = request[3] var/datum/tts_provider/provider = seed.provider - provider.request(text, seed, proc_callback) + var/file_name = request[4] + provider.request(text, seed, proc_callback, file_name) tts_rps_counter++ tts_requests_queue.Cut(1, clamp(LAZYLEN(tts_requests_queue), 0, free_rps) + 1) @@ -229,7 +230,7 @@ SUBSYSTEM_DEF(tts220) tts_request_succeeded = SStts220.tts_request_succeeded tts_reused = SStts220.tts_reused -/datum/controller/subsystem/tts220/proc/queue_request(text, datum/tts_seed/seed, datum/callback/proc_callback) +/datum/controller/subsystem/tts220/proc/queue_request(text, datum/tts_seed/seed, datum/callback/proc_callback, fileName) if(LAZYLEN(tts_requests_queue) > tts_requests_queue_limit) is_enabled = FALSE to_chat(world, span_announcement("SERVER: очередь запросов превысила лимит, подсистема SStts220 принудительно отключена!")) @@ -237,11 +238,11 @@ SUBSYSTEM_DEF(tts220) if(tts_rps_counter < tts_rps_limit) var/datum/tts_provider/provider = seed.provider - provider.request(text, seed, proc_callback) + provider.request(text, seed, proc_callback, fileName) tts_rps_counter++ return TRUE - tts_requests_queue += list(list(text, seed, proc_callback)) + tts_requests_queue += list(list(text, seed, proc_callback, fileName)) return TRUE /datum/controller/subsystem/tts220/proc/get_tts(atom/speaker, mob/listener, message, seed_name, is_local = TRUE, effect = SOUND_EFFECT_NONE, traits = TTS_TRAIT_RATE_FASTER, preSFX = null, postSFX = null) @@ -298,7 +299,7 @@ SUBSYSTEM_DEF(tts220) return var/datum/callback/cb = CALLBACK(src, PROC_REF(get_tts_callback), speaker, listener, filename, seed, is_local, effect, preSFX, postSFX) - queue_request(text, seed, cb) + queue_request(text, seed, cb, "[filename].ogg") LAZYADD(tts_queue[filename], play_tts_cb) /datum/controller/subsystem/tts220/proc/get_tts_callback(atom/speaker, mob/listener, filename, datum/tts_seed/seed, is_local, effect, preSFX, postSFX, datum/http_response/response) @@ -331,7 +332,8 @@ SUBSYSTEM_DEF(tts220) if(!voice) return - rustg_ss220_file_write_b64decode(voice, "[filename].ogg") + if (!provider.skip_explicit_file_save) + rustg_ss220_file_write_b64decode(voice, "[filename].ogg") if (!GLOB.configuration.tts.tts_cache_enabled) addtimer(CALLBACK(src, PROC_REF(cleanup_tts_file), "[filename].ogg"), 30 SECONDS)