Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>TTS Arabic</title> | |
<link rel="icon" type="image/png" href="favicon.png"> | |
<script src="static/mappings.js"></script> | |
<style> | |
* { | |
box-sizing: border-box; | |
} | |
body { | |
margin: 0; | |
} | |
h1 { | |
font-size: 1.6rem; | |
font-weight: 600; | |
color: #111; | |
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif | |
} | |
header { | |
height: 3rem; | |
border-bottom: 1px solid black; | |
margin-bottom: 4.5rem; | |
padding-left: 0.5rem; | |
} | |
main { | |
width: 38rem; | |
margin: auto; | |
} | |
label { | |
font-size: 1.5rem; | |
margin-bottom: 0.18rem; | |
} | |
textarea { | |
height: 7rem; | |
border: 2px solid #aaa; | |
border-radius: 3px; | |
} | |
#ta-arabic { | |
font-family:'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; | |
font-size: 1.9rem; | |
} | |
#ta-buckw { | |
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; | |
font-size: 1.5rem; | |
} | |
#audio-output { | |
width: 38rem; | |
height: 2.2rem; | |
} | |
#para-phonemes { | |
font-family: Verdana, Geneva, Tahoma, sans-serif; | |
margin: 0.5rem; | |
font-size: 1.3rem; | |
width: 38rem; | |
} | |
.ta-container { | |
display: flex; | |
flex-direction: column; | |
margin: auto; | |
} | |
button { | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-weight: 600; | |
font-size: 1rem; | |
background-color: white; | |
border-radius: 3px; | |
margin-top: 0.2rem; | |
width: 4.8rem; | |
height: 2rem; | |
border: 2px solid #888; | |
cursor: pointer; | |
} | |
button svg { | |
fill: #555; | |
} | |
button:hover, | |
button:active { | |
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.26); | |
} | |
.control-bar { | |
display: flex; | |
justify-content: right; | |
align-items: center; | |
} | |
.control-bar input { | |
height: 1.5rem; | |
width: 3.5rem; | |
margin-right: 0.5rem; | |
} | |
.control-bar label { | |
color: #555; | |
font-size: 1.2rem; | |
margin-right: 0.3rem; | |
} | |
ul { | |
list-style-type: none; | |
padding-left: 0; | |
} | |
</style> | |
</head> | |
<!-- BODY --> | |
<body> | |
<header><h1>TTS Tacotron2 Arabic</h1></header> | |
<main> | |
<div class="ta-container"> | |
<label for="ta-arabic">Arabic</label> | |
<textarea | |
id="ta-arabic" | |
dir="rtl" | |
oninput="taArabicChanged()" | |
></textarea> | |
</div> | |
<br /> | |
<div class="ta-container"> | |
<label for="ta-buckw">Buckwalter</label> | |
<textarea id="ta-buckw" spellcheck="false" oninput="taBuckwChanged()"></textarea> | |
</div> | |
<div class="control-bar"> | |
<label for="denoise-input">Denoise:</label> | |
<input id="denoise-input" type="number" min="0" value="0.01" step="0.005"/> | |
<label for="speed-input">Speed:</label> | |
<input id="speed-input" type="number" value="1.0" step="0.1"/> | |
<button onclick="tts(event)"> | |
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M4 22q-.825 0-1.412-.587Q2 20.825 2 20V4q0-.825.588-1.413Q3.175 2 4 2h9l-2 2H4v16h11v-3h2v3q0 .825-.587 1.413Q15.825 22 15 22Zm2-4v-2h7v2Zm0-3v-2h5v2Zm9 0-4-4H8V6h3l4-4Zm2-3.05v-6.9q.9.525 1.45 1.425.55.9.55 2.025t-.55 2.025q-.55.9-1.45 1.425Zm0 4.3v-2.1q1.75-.625 2.875-2.163Q21 10.45 21 8.5q0-1.95-1.125-3.488Q18.75 3.475 17 2.85V.75q2.6.675 4.3 2.812Q23 5.7 23 8.5t-1.7 4.938q-1.7 2.137-4.3 2.812Z"/></svg>TTS | |
</button> | |
</div> | |
<br /> | |
<ul id="res-list"> | |
</ul> | |
</main> | |
<!-- SCRIPT --> | |
<script> | |
const taArabic = document.getElementById("ta-arabic"); | |
const taBuckw = document.getElementById("ta-buckw"); | |
const inputSpeed = document.getElementById("speed-input"); | |
const inputDenoise = document.getElementById("denoise-input"); | |
// const audioOut = document.getElementById("audio-output"); | |
// const phonemesOut = document.getElementById("para-phonemes"); | |
const resList = document.getElementById("res-list"); | |
// audioOut.volume = 0.5; | |
let outputIdx = 0; | |
const taArabicChanged = () => { | |
const buckw = [...taArabic.value] | |
.map((ar) => { | |
if (ar in arabicToBuckw) { | |
return arabicToBuckw[ar]; | |
} | |
return ar; | |
}) | |
.join(""); | |
taBuckw.value = buckw; | |
}; | |
const taBuckwChanged = () => { | |
const arabic = [...taBuckw.value] | |
.map((lat) => { | |
if (lat in buckwToArabic) { | |
return buckwToArabic[lat]; | |
} | |
return lat; | |
}) | |
.join(""); | |
taArabic.value = arabic; | |
}; | |
const addResults = (data) => { | |
while(resList.firstChild) { | |
resList.removeChild(resList.firstChild); | |
} | |
data.forEach((d, i) => { | |
const li = document.createElement('li'); | |
li.innerHTML = ` | |
<label for="para-phonemes">${d.name}</label> | |
<p id="para-phonemes">${d.phon}</p> | |
<audio id="audio-output" src="static/wave${d.id}.wav?${outputIdx}" controls>Play</audio>`; | |
resList.append(li); | |
}); | |
resList.querySelectorAll("audio").forEach( | |
a => a.volume = 0.5 | |
) | |
}; | |
const tts = async () => { | |
const response = await fetch("/api/tts", { | |
method: "POST", | |
headers: { | |
"content-type": "application/json", | |
}, | |
body: JSON.stringify({ | |
buckw: taBuckw.value, | |
rate: inputSpeed.value, | |
denoise: inputDenoise.value, | |
}), | |
}); | |
const data = await response.json(); | |
// phonemesOut.textContent = data.phonemes; | |
console.log(data); | |
outputIdx++; | |
addResults(data); | |
}; | |
</script> | |
</body> | |
</html> | |