Commit
·
4993215
1
Parent(s):
2e800bc
update model
Browse files- app-tts.js +33 -19
app-tts.js
CHANGED
|
@@ -26,9 +26,21 @@ Module.locateFile = function(path, scriptDirectory = '') {
|
|
| 26 |
Module.setStatus = function(status) {
|
| 27 |
console.log(`status ${status}`);
|
| 28 |
const statusElement = document.getElementById('status');
|
| 29 |
-
if (status ==
|
| 30 |
status = 'Model downloaded. Initializing text to speech model...'
|
| 31 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
statusElement.textContent = status;
|
| 33 |
if (status === '') {
|
| 34 |
statusElement.style.display = 'none';
|
|
@@ -57,7 +69,9 @@ Module.onRuntimeInitialized = function() {
|
|
| 57 |
generateBtn.disabled = false;
|
| 58 |
};
|
| 59 |
|
| 60 |
-
speedInput.oninput = function() {
|
|
|
|
|
|
|
| 61 |
|
| 62 |
generateBtn.onclick = function() {
|
| 63 |
let speakerId = speakerIdInput.value;
|
|
@@ -89,12 +103,12 @@ generateBtn.onclick = function() {
|
|
| 89 |
console.log('text', text);
|
| 90 |
|
| 91 |
let audio =
|
| 92 |
-
tts.generate({text
|
| 93 |
|
| 94 |
console.log(audio.samples.length, audio.sampleRate);
|
| 95 |
|
| 96 |
if (!audioCtx) {
|
| 97 |
-
audioCtx = new AudioContext({sampleRate
|
| 98 |
}
|
| 99 |
|
| 100 |
const buffer = audioCtx.createBuffer(1, audio.samples.length, tts.sampleRate);
|
|
@@ -175,22 +189,22 @@ function toWav(floatSamples, sampleRate) {
|
|
| 175 |
|
| 176 |
// http://soundfile.sapp.org/doc/WaveFormat/
|
| 177 |
// F F I R
|
| 178 |
-
view.setUint32(0, 0x46464952, true);
|
| 179 |
-
view.setUint32(4, 36 + samples.length * 2, true);
|
| 180 |
// E V A W
|
| 181 |
-
view.setUint32(8, 0x45564157, true);
|
| 182 |
-
|
| 183 |
// t m f
|
| 184 |
-
view.setUint32(12, 0x20746d66, true);
|
| 185 |
-
view.setUint32(16, 16, true);
|
| 186 |
-
view.setUint32(20, 1, true);
|
| 187 |
-
view.setUint16(22, 1, true);
|
| 188 |
-
view.setUint32(24, sampleRate, true);
|
| 189 |
-
view.setUint32(28, sampleRate * 2, true);
|
| 190 |
-
view.setUint16(32, 2, true);
|
| 191 |
-
view.setUint16(34, 16, true);
|
| 192 |
-
view.setUint32(36, 0x61746164, true);
|
| 193 |
-
view.setUint32(40, samples.length * 2, true);
|
| 194 |
|
| 195 |
let offset = 44;
|
| 196 |
for (let i = 0; i < samples.length; ++i) {
|
|
@@ -198,5 +212,5 @@ function toWav(floatSamples, sampleRate) {
|
|
| 198 |
offset += 2;
|
| 199 |
}
|
| 200 |
|
| 201 |
-
return new Blob([
|
| 202 |
}
|
|
|
|
| 26 |
Module.setStatus = function(status) {
|
| 27 |
console.log(`status ${status}`);
|
| 28 |
const statusElement = document.getElementById('status');
|
| 29 |
+
if (status == 'Running...') {
|
| 30 |
status = 'Model downloaded. Initializing text to speech model...'
|
| 31 |
}
|
| 32 |
+
|
| 33 |
+
const downloadMatch = status.match(/Downloading data... \((\d+)\/(\d+)\)/);
|
| 34 |
+
if (downloadMatch) {
|
| 35 |
+
const downloaded = BigInt(downloadMatch[1]);
|
| 36 |
+
const total = BigInt(downloadMatch[2]);
|
| 37 |
+
const percent =
|
| 38 |
+
total === 0 ? 0.00 : Number((downloaded * 10000n) / total) / 100;
|
| 39 |
+
status = `Downloading data... ${percent.toFixed(2)}% (${downloadMatch[1]}/${
|
| 40 |
+
downloadMatch[2]})`;
|
| 41 |
+
console.log(`here ${status}`)
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
statusElement.textContent = status;
|
| 45 |
if (status === '') {
|
| 46 |
statusElement.style.display = 'none';
|
|
|
|
| 69 |
generateBtn.disabled = false;
|
| 70 |
};
|
| 71 |
|
| 72 |
+
speedInput.oninput = function() {
|
| 73 |
+
speedValue.innerHTML = this.value;
|
| 74 |
+
};
|
| 75 |
|
| 76 |
generateBtn.onclick = function() {
|
| 77 |
let speakerId = speakerIdInput.value;
|
|
|
|
| 103 |
console.log('text', text);
|
| 104 |
|
| 105 |
let audio =
|
| 106 |
+
tts.generate({text: text, sid: speakerId, speed: speedInput.value});
|
| 107 |
|
| 108 |
console.log(audio.samples.length, audio.sampleRate);
|
| 109 |
|
| 110 |
if (!audioCtx) {
|
| 111 |
+
audioCtx = new AudioContext({sampleRate: tts.sampleRate});
|
| 112 |
}
|
| 113 |
|
| 114 |
const buffer = audioCtx.createBuffer(1, audio.samples.length, tts.sampleRate);
|
|
|
|
| 189 |
|
| 190 |
// http://soundfile.sapp.org/doc/WaveFormat/
|
| 191 |
// F F I R
|
| 192 |
+
view.setUint32(0, 0x46464952, true); // chunkID
|
| 193 |
+
view.setUint32(4, 36 + samples.length * 2, true); // chunkSize
|
| 194 |
// E V A W
|
| 195 |
+
view.setUint32(8, 0x45564157, true); // format
|
| 196 |
+
//
|
| 197 |
// t m f
|
| 198 |
+
view.setUint32(12, 0x20746d66, true); // subchunk1ID
|
| 199 |
+
view.setUint32(16, 16, true); // subchunk1Size, 16 for PCM
|
| 200 |
+
view.setUint32(20, 1, true); // audioFormat, 1 for PCM
|
| 201 |
+
view.setUint16(22, 1, true); // numChannels: 1 channel
|
| 202 |
+
view.setUint32(24, sampleRate, true); // sampleRate
|
| 203 |
+
view.setUint32(28, sampleRate * 2, true); // byteRate
|
| 204 |
+
view.setUint16(32, 2, true); // blockAlign
|
| 205 |
+
view.setUint16(34, 16, true); // bitsPerSample
|
| 206 |
+
view.setUint32(36, 0x61746164, true); // Subchunk2ID
|
| 207 |
+
view.setUint32(40, samples.length * 2, true); // subchunk2Size
|
| 208 |
|
| 209 |
let offset = 44;
|
| 210 |
for (let i = 0; i < samples.length; ++i) {
|
|
|
|
| 212 |
offset += 2;
|
| 213 |
}
|
| 214 |
|
| 215 |
+
return new Blob([view], {type: 'audio/wav'});
|
| 216 |
}
|