From d03af9b41dbde04fa7dbb5e96fff652957314688 Mon Sep 17 00:00:00 2001 From: ouoertheo Date: Fri, 25 Aug 2023 22:51:58 -0500 Subject: [PATCH] name updates, complete custom voices --- public/scripts/extensions/tts/coqui.js | 114 +++++++++++++------------ 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/public/scripts/extensions/tts/coqui.js b/public/scripts/extensions/tts/coqui.js index a05291d25..2c8cc5045 100644 --- a/public/scripts/extensions/tts/coqui.js +++ b/public/scripts/extensions/tts/coqui.js @@ -6,7 +6,7 @@ TODO: import { doExtrasFetch, extension_settings, getApiUrl, getContext, modules, ModuleWorkerWrapper } from "../../extensions.js" import { callPopup } from "../../../script.js" -import { onTtsProviderSettingsInput } from "./index.js" +import { initVoiceMap } from "./index.js" export { CoquiTtsProvider } @@ -63,7 +63,8 @@ class CoquiTtsProvider { settings defaultSettings = { - voiceMap: "", + voiceMap: {}, + customVoices: {}, voiceIds: [], voiceMapDict: {} } @@ -74,8 +75,8 @@ class CoquiTtsProvider {
To use CoquiTTS, select the origin, language, and model, then click Add Voice. The voice will then be available to add to a character. Voices are saved globally.
- -
@@ -137,7 +138,7 @@ class CoquiTtsProvider { } initLocalModels(); - this.updateVoiceMap(); // Overide any manual modification + this.updateCustomVoices(); // Overide any manual modification $("#coqui_api_model_div").hide(); $("#coqui_local_model_div").hide(); @@ -200,48 +201,44 @@ class CoquiTtsProvider { // Perform a simple readiness check by trying to fetch voiceIds async checkReady(){ throwIfModuleMissing() - await this.fetchTtsVoiceIds() + await this.fetchTtsVoiceObjects() } - updateVoiceMap() { + updateCustomVoices() { // Takes voiceMapDict and converts it to a string to save to voiceMap - this.settings.voiceMap = ""; - for (let i in this.settings.voiceMapDict) { - const voice_settings = this.settings.voiceMapDict[i]; - this.settings.voiceMap += i + ":" + voice_settings["model_id"]; + this.settings.customVoices = {}; + for (let voiceName in this.settings.voiceMapDict) { + const voiceId = this.settings.voiceMapDict[voiceName]; + this.settings.customVoices[voiceName] = voiceId["model_id"]; - if (voice_settings["model_language"] != null) - this.settings.voiceMap += "[" + voice_settings["model_language"] + "]"; + if (voiceId["model_language"] != null) + this.settings.customVoices[voiceName] += "[" + voiceId["model_language"] + "]"; - if (voice_settings["model_speaker"] != null) - this.settings.voiceMap += "[" + voice_settings["model_speaker"] + "]"; - - this.settings.voiceMap += ","; + if (voiceId["model_speaker"] != null) + this.settings.customVoices[voiceName] += "[" + voiceId["model_speaker"] + "]"; } // Update UI select list with voices - $("#coqui_voiceid_select").empty() - $('#coqui_voiceid_select') + $("#coqui_voicename_select").empty() + $('#coqui_voicename_select') .find('option') .remove() .end() - .append('') + .append('') .val('none') - for (const voiceId in this.settings.voiceMapDict) { - $("#coqui_voiceid_select").append(new Option(voiceId, voiceId)); + for (const voiceName in this.settings.voiceMapDict) { + $("#coqui_voicename_select").append(new Option(voiceName, voiceName)); } - extension_settings.tts.Coqui = this.settings; this.onSettingsChange() } onSettingsChange() { console.debug(DEBUG_PREFIX, "Settings changes", this.settings); extension_settings.tts.Coqui = this.settings; - onTtsProviderSettingsInput() } - async onApplyClick() { + async onRefreshClick() { this.checkReady() } @@ -251,7 +248,7 @@ class CoquiTtsProvider { } // Ask user for voiceId name to save voice - const voiceId = await callPopup('

Name of Coqui voice to add to voice select dropdown:

', 'input') + const voiceName = await callPopup('

Name of Coqui voice to add to voice select dropdown:

', 'input') const model_origin = $("#coqui_model_origin").val(); const model_language = $("#coqui_api_language").val(); @@ -260,15 +257,15 @@ class CoquiTtsProvider { let model_setting_speaker = $("#coqui_api_model_settings_speaker").val(); - if (!voiceId) { - toastr.error(`VoiceId empty, please enter one.`, DEBUG_PREFIX + " voice mapping voiceId", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); - this.updateVoiceMap(); // Overide any manual modification + if (!voiceName) { + toastr.error(`Voice name empty, please enter one.`, DEBUG_PREFIX + " voice mapping voice name", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); + this.updateCustomVoices(); // Overide any manual modification return; } if (model_origin == "none") { toastr.error(`Origin not selected, please select one.`, DEBUG_PREFIX + " voice mapping origin", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); - this.updateVoiceMap(); // Overide any manual modification + this.updateCustomVoices(); // Overide any manual modification return; } @@ -277,25 +274,25 @@ class CoquiTtsProvider { if (model_name == "none") { toastr.error(`Model not selected, please select one.`, DEBUG_PREFIX + " voice mapping model", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); - this.updateVoiceMap(); // Overide any manual modification + this.updateCustomVoices(); // Overide any manual modification return; } - this.settings.voiceMapDict[voiceId] = { model_type: "local", model_id: "local/" + model_id }; - console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceId, ":", this.settings.voiceMapDict[voiceId]); - this.updateVoiceMap(); // Overide any manual modification + this.settings.voiceMapDict[voiceName] = { model_type: "local", model_id: "local/" + model_id }; + console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceName, ":", this.settings.voiceMapDict[voiceName]); + this.updateCustomVoices(); // Overide any manual modification return; } if (model_language == "none") { toastr.error(`Language not selected, please select one.`, DEBUG_PREFIX + " voice mapping language", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); - this.updateVoiceMap(); // Overide any manual modification + this.updateCustomVoices(); // Overide any manual modification return; } if (model_name == "none") { toastr.error(`Model not selected, please select one.`, DEBUG_PREFIX + " voice mapping model", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); - this.updateVoiceMap(); // Overide any manual modification + this.updateCustomVoices(); // Overide any manual modification return; } @@ -324,42 +321,48 @@ class CoquiTtsProvider { return; } - console.debug(DEBUG_PREFIX, "Current voice map: ", this.settings.voiceMap); + console.debug(DEBUG_PREFIX, "Current custom voices: ", this.settings.customVoices); - this.settings.voiceMapDict[voiceId] = { model_type: "coqui-api", model_id: model_id, model_language: model_setting_language, model_speaker: model_setting_speaker }; + this.settings.voiceMapDict[voiceName] = { model_type: "coqui-api", model_id: model_id, model_language: model_setting_language, model_speaker: model_setting_speaker }; - console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceId, ":", this.settings.voiceMapDict[voiceId]); + console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceName, ":", this.settings.voiceMapDict[voiceName]); - this.updateVoiceMap(); + this.updateCustomVoices(); + initVoiceMap() // Update TTS extension voiceMap - let successMsg = voiceId + ":" + model_id; + let successMsg = voiceName + ":" + model_id; if (model_setting_language != null) successMsg += "[" + model_setting_language + "]"; if (model_setting_speaker != null) successMsg += "[" + model_setting_speaker + "]"; toastr.info(successMsg, DEBUG_PREFIX + " voice map updated", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); + return } - // DBG: assume voiceName is correct - // TODO: check voice is correct async getVoice(voiceName) { - console.log(DEBUG_PREFIX, "getVoice", voiceName); - const output = { voice_id: voiceName }; - return output; + let match = await this.fetchTtsVoiceObjects() + match = match.filter( + voice => voice.name == voiceName + )[0] + if (!match) { + throw `TTS Voice name ${voiceName} not found in CoquiTTS Provider voice list` + } + return match; } async onRemoveClick() { - const voiceId = $("#coqui_voiceid_select").val(); + const voiceName = $("#coqui_voicename_select").val(); - if (voiceId === "none") { - toastr.error(`VoiceId not selected, please select one.`, DEBUG_PREFIX + " voice mapping voiceId", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); + if (voiceName === "none") { + toastr.error(`Voice not selected, please select one.`, DEBUG_PREFIX + " voice mapping voiceId", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true }); return; } // Todo erase from voicemap - delete (this.settings.voiceMapDict[voiceId]); - this.updateVoiceMap(); // TODO + delete (this.settings.voiceMapDict[voiceName]); + this.updateCustomVoices(); + initVoiceMap() // Update TTS extension voiceMap } async onModelOriginChange() { @@ -677,6 +680,8 @@ class CoquiTtsProvider { // ts_models/ja/kokoro/tacotron2-DDC async generateTts(text, voiceId) { throwIfModuleMissing() + voiceId = this.settings.customVoices[voiceId] + const url = new URL(getApiUrl()); url.pathname = '/api/text-to-speech/coqui/generate-tts'; @@ -724,8 +729,11 @@ class CoquiTtsProvider { } // Dirty hack to say not implemented - async fetchTtsVoiceIds() { - return [{ name: "Voice samples not implemented for coqui TTS yet, search for the model samples online", voice_id: "", lang: "", }] + async fetchTtsVoiceObjects() { + const voiceIds = Object + .keys(this.settings.voiceMapDict) + .map(voice => ({ name: voice, voice_id: voice, preview_url: false })); + return voiceIds } // Do nothing