+
+ This exact wording goes into every shot prompt, unchanged, so your pet sounds
+ like one character rather than a different one each time. Keep it to sound only — pitch, weight,
+ pace, age. Words like “actress” or “warrior” describe a role and end up in the picture.
+
+
+
+
+
+
This goes to the writer, not the recording — it shapes the words your pet uses, not the voice itself.
@@ -104,8 +115,34 @@ function describeVoice() {
+ '';
}
+// Filled from the server so the presets cannot drift from the ones the prompt
+// builder knows about.
+var formulaPresets = [];
+
+function fillFormulaPresets(list) {
+ formulaPresets = list || [];
+ document.getElementById("pformulapreset").innerHTML =
+ ''
+ + formulaPresets.map(function (d) {
+ return '';
+ }).join("");
+}
+
+document.getElementById("pformulapreset").addEventListener("change", function () {
+ if (this.value) document.getElementById("pformula").value = this.value;
+});
+
+// Empty means “whatever the chosen voice says”, which is what the server does
+// with a blank field, so clearing it is the honest way to reset.
+document.getElementById("resetformula").addEventListener("click", function () {
+ var v = voiceById(document.getElementById("pvoiceid").value);
+ document.getElementById("pformula").value = v ? v.formula : "";
+ document.getElementById("pformulapreset").value = "";
+});
+
async function loadVoices() {
var r = await api("camera_presets", {});
+ fillFormulaPresets(r.voice_descriptions);
var sel = document.getElementById("pvoiceid");
if (!r.ok || !(r.voices || []).length) {
sel.innerHTML = '';
@@ -217,6 +254,7 @@ document.getElementById("petform").addEventListener("submit", async function (e)
appearance: document.getElementById("pappear").value.trim(),
personality: document.getElementById("pperson").value.trim(),
voice: document.getElementById("pvoice").value.trim(),
+ voice_formula: document.getElementById("pformula").value.trim(),
eleven_voice_id: document.getElementById("pvoiceid").value
};
if (!pet.name) { showMsg("msg", "Your pet needs a name."); return; }
@@ -234,7 +272,8 @@ document.getElementById("petform").addEventListener("submit", async function (e)
function resetForm() {
document.getElementById("petid").value = "";
- ["pname", "pbreed", "pappear", "pperson", "pvoice"].forEach(function (i) { document.getElementById(i).value = ""; });
+ ["pname", "pbreed", "pappear", "pperson", "pvoice", "pformula"].forEach(function (i) { document.getElementById(i).value = ""; });
+ document.getElementById("pformulapreset").value = "";
document.getElementById("pvoiceid").value = "";
describeVoice();
document.getElementById("pspecies").value = "dog";
@@ -281,6 +320,8 @@ document.getElementById("list").addEventListener("click", async function (e) {
document.getElementById("pperson").value = p.personality || "";
document.getElementById("pvoice").value = p.voice || "";
document.getElementById("pvoiceid").value = p.eleven_voice_id || "";
+ document.getElementById("pformula").value = p.voice_formula || "";
+ document.getElementById("pformulapreset").value = "";
describeVoice();
document.getElementById("formtitle").textContent = "Edit " + (p.name || "pet");
document.getElementById("cancel").style.display = "";