Spaces:
Running
Running
File size: 3,407 Bytes
a5338b8 41d7d0b a5338b8 88eba2f e0a8546 a5338b8 e0a8546 4a341f8 e0a8546 88eba2f e0a8546 4a341f8 e0a8546 88eba2f e0a8546 4a341f8 88eba2f 4a341f8 88eba2f 4a341f8 88eba2f 4a341f8 88eba2f 4a341f8 88eba2f 4a341f8 e0a8546 88eba2f e0a8546 88eba2f e0a8546 41d7d0b fcd6164 a626371 fcd6164 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<!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> |