<!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Voice Changer</title>
</head>
<body>
<h1>Voice Changer</h1>
<button id="start">Start Voice Changer</button>
<button id="stop" disabled>Stop Voice Changer</button>
<label for="pitch">Pitch: </label>
<input id="pitch" type="range" min="0.5" max="2" step="0.1" value="1">
<label for="pitch">1x</label>
<script>
const startButton = [Link]("start");
const stopButton = [Link]("stop");
const pitchSlider = [Link]("pitch");
const pitchLabel = [Link];
let audioContext;
let mediaStream;
let source;
let pitchShiftNode;
[Link]("input", () => {
const pitchValue = [Link];
[Link] = `${pitchValue}x`;
if (pitchShiftNode) {
[Link] = pitchValue;
}
});
[Link]("click", async () => {
try {
// Get user microphone input
mediaStream = await [Link]({ audio:
true });
audioContext = new ([Link] ||
[Link])();
// Create audio source from the microphone
source = [Link](mediaStream);
// Create a playback rate node for pitch shifting
pitchShiftNode = [Link]();
const audioBuffer = [Link](1,
[Link] * 2, [Link]);
[Link] = audioBuffer;
[Link] = true;
[Link] = [Link];
// Connect nodes
[Link]([Link]);
[Link]([Link]);
[Link]();
// Enable the stop button
[Link] = true;
[Link] = false;
} catch (error) {
[Link]("Error accessing the microphone:", error);
}
});
[Link]("click", () => {
// Stop audio processing
if (audioContext) {
[Link]();
audioContext = null;
}
if (mediaStream) {
[Link]().forEach((track) => [Link]());
mediaStream = null;
}
[Link] = false;
[Link] = true;
});
</script>
</body>
</html>