I'm trying to test playing audio using a HTMLAudioElement and a AudioSourceNode. For the later application I need two features:
- The pitch must be preserved after the playbackRate changed.
- The volume needs to be changed to a value greater than 1.
Because feature 2 I added a workaround with the AudioSourceNode and the GainNode.
I need the audio file as ArrayBuffer in the later app that's why I added the file reading part before.
Problem:
The code works fine with Chrome and Opera, but not with Firefox. The playBackRate is set to 2, but the playbackRate of audio signal did not change. Why is that's the case and how can I fix it?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Timestretching 2</title>
<script type="text/javascript">
var audioContext = window.AudioContext // Default
|| window.webkitAudioContext // Safari and old versions of Chrome
|| window.mozAudioContext
|| false;
function play() {
var fileInput = document.getElementById("file");
var file = fileInput.files[0];
var reader = new FileReader();
reader.onload = function (event) {
console.log("finished!");
console.log(event.srcElement.result);
var audioCtxt = new audioContext();
var url = URL.createObjectURL(new File([event.srcElement.result], "test.wav"));
var player = new Audio();
const source = audioCtxt.createMediaElementSource(player);
player.src = url;
console.log("wait to play");
player.addEventListener("canplay", function () {
// create a gain node to set volume greater than 1
const gainNode = audioCtxt.createGain();
gainNode.gain.value = 2.0; // double the volume
source.connect(gainNode);
gainNode.connect(audioCtxt.destination);
player.playbackRate = 2.0;
player.play();
player.playbackRate = 2.0;
console.log("playbackRate is " + player.playbackRate);
});
};
reader.onprogress = function (progress) {
console.log(progress.loaded / progress.total);
};
reader.onerror = function (error) {
console.error(error);
};
reader.readAsArrayBuffer(file);
}
</script>
</head>
<body>
<input id="file" type="file" value="Audio Datei auswählen"/>
<button onclick="play()">PLAY</button>
</body>
</html>