VocaloidTTS / index.html
Dmtlant's picture
Update index.html
e0a8546 verified
raw
history blame
3.41 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Singing Vocoder with Rhythm</title>
</head>
<body>
<h1>Singing Vocoder with Rhythm</h1>
<input type="text" id="textInput" placeholder="Enter text to synthesize">
<button id="synthesizeButton">Synthesize</button>
<script>
const audioContext = new AudioContext();
let source, vocoder, rhythmInterval;
const textInput = document.getElementById('textInput');
const synthesizeButton = document.getElementById('synthesizeButton');
synthesizeButton.addEventListener('click', () => {
const text = textInput.value;
if (text) {
synthesizeText(text);
}
});
function synthesizeText(text) {
const utterance = new SpeechSynthesisUtterance(text);
const voices = window.speechSynthesis.getVoices();
utterance.voice = voices.find(voice => voice.name === 'Google US English') || voices[0];
window.speechSynthesis.speak(utterance);
utterance.addEventListener('start', () => {
console.log('Speech synthesis started');
});
utterance.addEventListener('end', () => {
console.log('Speech synthesis ended');
const audioBlob = new Blob([utterance.audioBuffer], { type: 'audio/wav' });
const audioUrl = URL.createObjectURL(audioBlob);
setupVocoder(audioUrl);
startRhythmGenerator();
});
}
function setupVocoder(audioUrl) {
const carrier = audioContext.createOscillator();
carrier.type = 'sawtooth';
carrier.frequency.value = 200;
const modulator = audioContext.createBufferSource();
modulator.connect(audioContext.destination);
vocoder = audioContext.createGain();
const modulatorGain = audioContext.createGain();
modulatorGain.gain.value = 500;
modulator.connect(modulatorGain);
modulatorGain.connect(vocoder.gain);
carrier.connect(vocoder);
vocoder.connect(audioContext.destination);
audioContext.decodeAudioData(fetch(audioUrl).then(response => response.arrayBuffer()))
.then(buffer => {
modulator.buffer = buffer;
modulator.loop = true;
source = modulator;
source.start(0);
});
}
function startRhythmGenerator() {
const tempoRange = [60, 120]; // Диапазон темпа в ударах в минуту
const tempo = Math.floor(Math.random() * (tempoRange[1] - tempoRange[0] + 1)) + tempoRange[0];
const beatDuration = 60 / tempo; // Длительность удара в секундах
rhythmInterval = setInterval(() => {
vocoder.gain.value = vocoder.gain.value === 0 ? 1 : 0; // Переключение усиления вокодера между 0 и 1
}, beatDuration * 1000 / 2); // Интервал в миллисекундах, соответствующий половине длительности удара
}
</script>
</body>
</html>