add speed parameter

This commit is contained in:
ANLGBOY
2025-11-19 19:42:24 +09:00
parent c31b6745e4
commit 8518b839c1
30 changed files with 246 additions and 61 deletions

View File

@@ -4,6 +4,8 @@ This example demonstrates how to use Supertonic in a web browser using ONNX Runt
## 📰 Update News
**2025.11.19** - Added speed control slider to adjust speech synthesis speed (default: 1.05, recommended range: 0.9-1.5).
**2025.11.19** - Added automatic text chunking for long-form inference. Long texts are split into chunks and synthesized with natural pauses.
## Features

View File

@@ -72,7 +72,7 @@ export class TextToSpeech {
this.sampleRate = cfgs.ae.sample_rate;
}
async _infer(textList, style, totalStep, progressCallback = null) {
async _infer(textList, style, totalStep, speed = 1.05, progressCallback = null) {
const bsz = textList.length;
// Process text
@@ -94,6 +94,11 @@ export class TextToSpeech {
});
const duration = Array.from(dpOutputs.duration.data);
// Apply speed factor to duration
for (let i = 0; i < duration.length; i++) {
duration[i] /= speed;
}
// Encode text
const textEncOutputs = await this.textEncOrt.run({
text_ids: textIdsTensor,
@@ -176,7 +181,7 @@ export class TextToSpeech {
return { wav, duration };
}
async call(text, style, totalStep, silenceDuration = 0.3, progressCallback = null) {
async call(text, style, totalStep, speed = 1.05, silenceDuration = 0.3, progressCallback = null) {
if (style.ttl.dims[0] !== 1) {
throw new Error('Single speaker text to speech only supports single style');
}
@@ -185,7 +190,7 @@ export class TextToSpeech {
let durCat = 0;
for (const chunk of textList) {
const { wav, duration } = await this._infer([chunk], style, totalStep, progressCallback);
const { wav, duration } = await this._infer([chunk], style, totalStep, speed, progressCallback);
if (wavCat.length === 0) {
wavCat = wav;
@@ -201,8 +206,8 @@ export class TextToSpeech {
return { wav: wavCat, duration: [durCat] };
}
async batch(textList, style, totalStep, progressCallback = null) {
return await this._infer(textList, style, totalStep, progressCallback);
async batch(textList, style, totalStep, speed = 1.05, progressCallback = null) {
return await this._infer(textList, style, totalStep, speed, progressCallback);
}
sampleNoisyLatent(duration, sampleRate, baseChunkSize, chunkCompress, latentDim) {

View File

@@ -48,6 +48,12 @@
<input type="number" id="totalStep" value="5"
min="1" max="50">
</div>
<div class="section">
<label for="speed">Speed (0.9-1.5 recommended):</label>
<input type="number" id="speed" value="1.05"
min="0.5" max="2.0" step="0.05">
</div>
</div>

View File

@@ -25,6 +25,7 @@ const textInput = document.getElementById('text');
const voiceStyleSelect = document.getElementById('voiceStyleSelect');
const voiceStyleInfo = document.getElementById('voiceStyleInfo');
const totalStepInput = document.getElementById('totalStep');
const speedInput = document.getElementById('speed');
const generateBtn = document.getElementById('generateBtn');
const statusBox = document.getElementById('statusBox');
const statusText = document.getElementById('statusText');
@@ -186,6 +187,7 @@ async function generateSpeech() {
`;
const totalStep = parseInt(totalStepInput.value);
const speed = parseFloat(speedInput.value);
showStatus(' <strong>Generating speech from text...</strong>');
const tic = Date.now();
@@ -194,6 +196,7 @@ async function generateSpeech() {
text,
currentStyle,
totalStep,
speed,
0.3,
(step, total) => {
showStatus(` <strong>Denoising (${step}/${total})...</strong>`);