Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
window.allStyleEmbs = {} | |
window.styleEmbsMenuState = { | |
embeddingsDir: `${window.path}/embeddings`, | |
hasChangedEmb: false, // For clearing the use of the editor state when re-generating a line with a different embedding | |
selectedEmb: undefined, | |
activatedEmbeddings: {} | |
} | |
window.loadStyleEmbsFromDisk = () => { | |
window.allStyleEmbs = {} | |
// Read the activated embeddings file | |
window.styleEmbsMenuState.activatedEmbeddings = {} | |
if (fs.existsSync(`./embeddings.txt`)) { | |
const embeddingsEnabled = fs.readFileSync(`./embeddings.txt`, "utf8").split("\n") | |
embeddingsEnabled.forEach(emb => { | |
window.styleEmbsMenuState.activatedEmbeddings[emb.replace("*","")] = emb.includes("*") | |
}) | |
} | |
// Read all the embedding files | |
fs.mkdirSync(window.styleEmbsMenuState.embeddingsDir, {recursive: true}) | |
const embFiles = fs.readdirSync(window.styleEmbsMenuState.embeddingsDir) | |
embFiles.forEach(jsonFName => { | |
const jsonData = JSON.parse(fs.readFileSync(`${window.styleEmbsMenuState.embeddingsDir}/${jsonFName}`)) | |
jsonData.fileName = `${window.styleEmbsMenuState.embeddingsDir}/${jsonFName}` | |
if (!Object.keys(window.styleEmbsMenuState.activatedEmbeddings).includes(jsonData.emb_id)) { | |
window.styleEmbsMenuState.activatedEmbeddings[jsonData.emb_id] = true | |
} | |
jsonData.enabled = window.styleEmbsMenuState.activatedEmbeddings[jsonData.emb_id] | |
window.allStyleEmbs[jsonData.voiceId] = window.allStyleEmbs[jsonData.voiceId] || [] | |
window.allStyleEmbs[jsonData.voiceId].push(jsonData) | |
}) | |
window.saveEnabledStyleEmbs() | |
} | |
window.saveEnabledStyleEmbs = () => { | |
fs.writeFileSync(`./embeddings.txt`, Object.keys(window.styleEmbsMenuState.activatedEmbeddings).map(key => { | |
return `${window.styleEmbsMenuState.activatedEmbeddings[key]?"*":""}${key}` | |
}).join("\n"), "utf8") | |
} | |
window.loadStyleEmbsFromDisk() | |
window.resetStyleEmbFields = () => { | |
styleEmbAuthorInput.value = "" | |
styleEmbGameIdInput.value = "" | |
styleEmbVoiceIdInput.value = "" | |
styleEmbNameInput.value = "" | |
styleEmbDescriptionInput.value = "" | |
styleEmbIdInput.value = "" | |
wavFilepathForEmbComputeInput.value = "" | |
styleEmbValuesInput.value = "" | |
styleEmbGameIdInput.value = window.currentGame.gameId | |
if (window.currentModel) { | |
styleEmbVoiceIdInput.value = window.currentModel.voiceId | |
} | |
} | |
window.refreshStyleEmbsTable = () => { | |
styleembsRecordsContainer.innerHTML = "" | |
window.styleEmbsMenuState.selectedEmb = undefined | |
styleEmbDelete.disabled = true | |
window.resetStyleEmbFields() | |
Object.keys(window.allStyleEmbs).sort().forEach(key => { | |
window.allStyleEmbs[key].forEach((emb,ei) => { | |
const record = createElem("div") | |
const enabledCkbx = createElem("input", {type: "checkbox"}) | |
enabledCkbx.checked = emb.enabled | |
record.appendChild(createElem("div", enabledCkbx)) | |
const embName = createElem("div", emb["embeddingName"]) | |
embName.title = emb["embeddingName"] | |
record.appendChild(embName) | |
const embGameID = createElem("div", emb["gameId"]) | |
embGameID.title = emb["gameId"] | |
record.appendChild(embGameID) | |
const embVoiceID = createElem("div", emb["voiceId"]) | |
embVoiceID.title = emb["voiceId"] | |
record.appendChild(embVoiceID) | |
const embDescription = createElem("div", emb["description"]||"") | |
embDescription.title = emb["description"]||"" | |
record.appendChild(embDescription) | |
const embID = createElem("div", emb["emb_id"]) | |
embID.title = emb["emb_id"] | |
record.appendChild(embID) | |
const embVersion = createElem("div", emb["version"]||"1.0") | |
embVersion.title = emb["version"]||"1.0" | |
record.appendChild(embVersion) | |
enabledCkbx.addEventListener("click", () => { | |
window.allStyleEmbs[key][ei].enabled = !window.allStyleEmbs[key][ei].enabled | |
window.styleEmbsMenuState.activatedEmbeddings[emb["emb_id"]] = window.allStyleEmbs[key][ei].enabled | |
window.saveEnabledStyleEmbs() | |
if (window.currentModel) { | |
window.loadStyleEmbsForVoice(window.currentModel) | |
} | |
}) | |
record.addEventListener("click", (e) => { | |
if (e.target==enabledCkbx || e.target.nodeName=="BUTTON") { | |
return | |
} | |
// Clear visual selection of the old selected item, if there was already an item selected before | |
if (window.styleEmbsMenuState.selectedEmb) { | |
window.styleEmbsMenuState.selectedEmb[0].style.background = "none" | |
Array.from(window.styleEmbsMenuState.selectedEmb[0].children).forEach(child => child.style.color = "white") | |
} | |
window.styleEmbsMenuState.selectedEmb = [record, emb] | |
// Visually show that this row is selected | |
window.styleEmbsMenuState.selectedEmb[0].style.background = "white" | |
Array.from(window.styleEmbsMenuState.selectedEmb[0].children).forEach(child => child.style.color = "black") | |
styleEmbDelete.disabled = false | |
// Populate the edit fields | |
styleEmbAuthorInput.value = emb.author||"" | |
styleEmbGameIdInput.value = emb.gameId||"" | |
styleEmbVoiceIdInput.value = emb.voiceId||"" | |
styleEmbNameInput.value = emb.embeddingName||"" | |
styleEmbDescriptionInput.value = emb.description||"" | |
styleEmbIdInput.value = emb.emb_id||"" | |
wavFilepathForEmbComputeInput.value = "" | |
styleEmbValuesInput.value = emb.emb||"" | |
}) | |
styleembsRecordsContainer.appendChild(record) | |
}) | |
}) | |
} | |
styleembs_main.addEventListener("click", (e) => { | |
if (e.target == styleembs_main) { | |
window.refreshStyleEmbsTable() | |
} | |
}) | |
styleEmbSave.addEventListener("click", () => { | |
const missingFieldsValues = [] | |
if (!styleEmbAuthorInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.AUTHOR) | |
} | |
if (!styleEmbGameIdInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.GAME_ID) | |
} | |
if (!styleEmbVoiceIdInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.VOICE_ID) | |
} | |
if (!styleEmbNameInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.EMB_NAME) | |
} | |
if (!styleEmbIdInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.EMB_ID) | |
} | |
if (!styleEmbValuesInput.value.trim().length) { | |
missingFieldsValues.push(window.i18n.STYLE_EMB_VALUES) | |
} | |
if (missingFieldsValues.length) { | |
window.errorModal(window.i18n.ERROR_MISSING_FIELDS.replace("_1", missingFieldsValues.join(", "))) | |
} else { | |
let outputFilename | |
if (window.styleEmbsMenuState.selectedEmb) { | |
outputFilename = window.styleEmbsMenuState.selectedEmb[1].fileName | |
} else { | |
outputFilename = `${window.styleEmbsMenuState.embeddingsDir}/${styleEmbVoiceIdInput.value.trim().toLowerCase()}.${styleEmbGameIdInput.value.trim().toLowerCase()}.${styleEmbIdInput.value.trim().toLowerCase()}.${styleEmbAuthorInput.value.trim().toLowerCase()}.json` | |
} | |
const jsonData = { | |
"author": styleEmbAuthorInput.value.trim(), | |
"version": "1.0", // Should I make this editable in the UI? | |
"gameId": styleEmbGameIdInput.value.trim().toLowerCase(), | |
"voiceId": styleEmbVoiceIdInput.value.trim().toLowerCase(), | |
"description": styleEmbDescriptionInput.value.trim()||"", | |
"embeddingName": styleEmbNameInput.value.trim(), | |
"emb": styleEmbValuesInput.value.trim().split(",").map(v=>parseFloat(v)), | |
"emb_id": styleEmbIdInput.value.trim() | |
} | |
fs.writeFileSync(outputFilename, JSON.stringify(jsonData, null, 4), "utf8") | |
window.loadStyleEmbsFromDisk() | |
window.refreshStyleEmbsTable() | |
} | |
if (window.currentModel) { | |
window.loadStyleEmbsForVoice(window.currentModel) | |
} | |
}) | |
styleEmbDelete.addEventListener("click", () => { | |
window.confirmModal(window.i18n.CONFIRM_DELETE_STYLE_EMB).then(response => { | |
if (response) { | |
fs.unlinkSync(window.styleEmbsMenuState.selectedEmb[1].fileName) | |
window.loadStyleEmbsFromDisk() | |
window.refreshStyleEmbsTable() | |
if (window.currentModel) { | |
window.loadStyleEmbsForVoice(window.currentModel) | |
} | |
} | |
}) | |
}) | |
// Return the default embedding, plus any other ones | |
window.loadStyleEmbsForVoice = (currentModel) => { | |
const embeddings = {} | |
// Add the default option from the model json | |
embeddings["default"] = [window.i18n.DEFAULT, currentModel.games[0].base_speaker_emb] // TODO, specialize to specific game? | |
// Load any other style embeddings available | |
if (Object.keys(window.allStyleEmbs).includes(currentModel.voiceId)) { | |
window.allStyleEmbs[currentModel.voiceId].forEach(loadedStyleEmb => { | |
if (loadedStyleEmb.enabled) { | |
embeddings[loadedStyleEmb.emb_id] = [loadedStyleEmb.embeddingName, loadedStyleEmb.emb] | |
} | |
}) | |
} | |
// Add every option to the embeddings selection dropdown | |
style_emb_select.innerHTML = "" | |
Array.from(seq_edit_edit_select.children).forEach(option => { | |
if (option.value.startsWith("style_")) { | |
seq_edit_edit_select.removeChild(option) | |
} | |
}) | |
// Add Default first | |
const opt = createElem("option", embeddings["default"][0]) | |
opt.value = embeddings["default"][1].join(",") | |
style_emb_select.appendChild(opt) | |
Object.keys(embeddings).forEach(key => { | |
if (key=="default") { | |
return | |
} | |
const opt = createElem("option", embeddings[key][0]) | |
opt.value = embeddings[key][1].join(",") | |
style_emb_select.appendChild(opt) | |
}) | |
// First remove all existing styles from the dropdown | |
Array.from(seq_edit_view_select.children).forEach(elem => { | |
if (elem.value.startsWith("style")) { | |
seq_edit_view_select.removeChild(elem) | |
} | |
}) | |
// Add every option (except Default) to the sliders viewing/editing dropdowns | |
Object.keys(embeddings).forEach(key => { | |
if (key=="default") { | |
return | |
} | |
const opt = createElem("option", `${window.i18n.STYLE_EMB_IS} ${embeddings[key][0]}`) | |
opt.value = `style_${key}` | |
seq_edit_view_select.appendChild(opt) | |
const opt2 = createElem("option", `${window.i18n.STYLE_EMB_IS} ${embeddings[key][0]}`) | |
opt2.value = `style_${key}` | |
seq_edit_edit_select.appendChild(opt2) | |
}) | |
window.appState.currentModelEmbeddings = embeddings | |
} | |
style_emb_select.addEventListener("change", () => window.styleEmbsMenuState.hasChangedEmb) | |
window.styleEmbsModalOpenCallback = () => { | |
styleEmbGameIdInput.value = window.currentGame.gameId | |
if (window.currentModel) { | |
styleEmbVoiceIdInput.value = window.currentModel.voiceId | |
} | |
window.refreshStyleEmbsTable() | |
} | |
window.dragDropWavForEmbComputeFilepathInput = (eType, event) => { | |
if (["dragenter", "dragover"].includes(eType)) { | |
wavFileDragDropArea.style.background = "#5b5b5b" | |
wavFileDragDropArea.style.color = "white" | |
} | |
if (["dragleave", "drop"].includes(eType)) { | |
wavFileDragDropArea.style.background = "rgba(0,0,0,0)" | |
wavFileDragDropArea.style.color = "white" | |
} | |
event.preventDefault() | |
event.stopPropagation() | |
const dataLines = [] | |
if (eType=="drop") { | |
const dataTransfer = event.dataTransfer | |
const files = Array.from(dataTransfer.files) | |
if (files[0].path.endsWith(".wav")) { | |
wavFilepathForEmbComputeInput.value = String(files[0].path).replaceAll(/\\/g, "/") | |
} else { | |
window.errorModal(window.i18n.ERROR_FILE_MUST_BE_WAV) | |
} | |
} | |
} | |
wavFileDragDropArea.addEventListener("dragenter", event => window.dragDropWavForEmbComputeFilepathInput("dragenter", event), false) | |
wavFileDragDropArea.addEventListener("dragleave", event => window.dragDropWavForEmbComputeFilepathInput("dragleave", event), false) | |
wavFileDragDropArea.addEventListener("dragover", event => window.dragDropWavForEmbComputeFilepathInput("dragover", event), false) | |
wavFileDragDropArea.addEventListener("drop", event => window.dragDropWavForEmbComputeFilepathInput("drop", event), false) | |
getStyleEmbeddingBtn.addEventListener("click", async () => { | |
if (!wavFilepathForEmbComputeInput.value.trim().length) { | |
window.errorModal(window.i18n.ERROR_NEED_WAV_FILE) | |
} else { | |
const embedding = await window.getSpeakerEmbeddingFromFilePath(wavFilepathForEmbComputeInput.value) | |
styleEmbValuesInput.value = embedding | |
} | |
}) | |