Spaces:
Sleeping
Sleeping
| /* Copyright 2013 Chris Wilson | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| window.AudioContext = window.AudioContext || window.webkitAudioContext; | |
| var audioContext = new AudioContext(); | |
| var audioInput = null, | |
| realAudioInput = null, | |
| inputPoint = null, | |
| audioRecorder = null; | |
| var rafID = null; | |
| var analyserContext = null; | |
| var canvasWidth, canvasHeight; | |
| var recIndex = 0; | |
| function gotBuffers(buffers) { | |
| audioRecorder.exportMonoWAV(doneEncoding); | |
| } | |
| function doneEncoding(soundBlob) { | |
| fetch('/audio', { | |
| method: "POST", // Specify POST method | |
| body: soundBlob | |
| }) | |
| .then(response => { | |
| if (response.ok) { | |
| return response.json(); // Parse JSON response | |
| } else { | |
| throw new Error("Error in Flask /audio route: " + response.status); | |
| } | |
| }) | |
| .then(data => { | |
| window.location.href = data.url; // Redirect using URL from the response | |
| }) | |
| .catch(error => { | |
| console.error(error); | |
| }); | |
| } | |
| function stopRecording() { | |
| // stop recording | |
| audioRecorder.stop(); | |
| document.getElementById('stop').disabled = true; | |
| document.getElementById('start').removeAttribute('disabled'); | |
| audioRecorder.getBuffers(gotBuffers); | |
| } | |
| function startRecording() { | |
| // start recording | |
| if (!audioRecorder) | |
| return; | |
| document.getElementById('start').disabled = true; | |
| document.getElementById('stop').removeAttribute('disabled'); | |
| audioRecorder.clear(); | |
| audioRecorder.record(); | |
| } | |
| function convertToMono(input) { | |
| var splitter = audioContext.createChannelSplitter(2); | |
| var merger = audioContext.createChannelMerger(2); | |
| input.connect(splitter); | |
| splitter.connect(merger, 0, 0); | |
| splitter.connect(merger, 0, 1); | |
| return merger; | |
| } | |
| function cancelAnalyserUpdates() { | |
| window.cancelAnimationFrame(rafID); | |
| rafID = null; | |
| } | |
| function updateAnalysers(time) { | |
| if (!analyserContext) { | |
| var canvas = document.getElementById("analyser"); | |
| console.log("Canvas:", canvas); // Log 1 | |
| if (canvas) { // Check canvas exists | |
| canvasWidth = canvas.width; | |
| canvasHeight = canvas.height; | |
| analyserContext = canvas.getContext('2d'); | |
| } else { | |
| console.error("Canvas with ID 'analyser' not found!"); | |
| } | |
| } | |
| // analyzer draw code here | |
| { | |
| var SPACING = 3; | |
| var BAR_WIDTH = 1; | |
| var numBars = Math.round(canvasWidth / SPACING); | |
| var freqByteData = new Uint8Array(analyserNode.frequencyBinCount); | |
| analyserNode.getByteFrequencyData(freqByteData); | |
| analyserContext.clearRect(0, 0, canvasWidth, canvasHeight); | |
| analyserContext.fillStyle = '#F6D565'; | |
| analyserContext.lineCap = 'round'; | |
| var multiplier = analyserNode.frequencyBinCount / numBars; | |
| // Draw rectangle for each frequency bin. | |
| for (var i = 0; i < numBars; ++i) { | |
| var magnitude = 0; | |
| var offset = Math.floor(i * multiplier); | |
| // gotta sum/average the block, or we miss narrow-bandwidth spikes | |
| for (var j = 0; j < multiplier; j++) | |
| magnitude += freqByteData[offset + j]; | |
| magnitude = magnitude / multiplier; | |
| var magnitude2 = freqByteData[i * multiplier]; | |
| analyserContext.fillStyle = "hsl( " + Math.round((i * 360) / numBars) + ", 100%, 50%)"; | |
| analyserContext.fillRect(i * SPACING, canvasHeight, BAR_WIDTH, -magnitude); | |
| } | |
| } | |
| rafID = window.requestAnimationFrame(updateAnalysers); | |
| } | |
| function toggleMono() { | |
| if (audioInput != realAudioInput) { | |
| audioInput.disconnect(); | |
| realAudioInput.disconnect(); | |
| audioInput = realAudioInput; | |
| } else { | |
| realAudioInput.disconnect(); | |
| audioInput = convertToMono(realAudioInput); | |
| } | |
| audioInput.connect(inputPoint); | |
| } | |
| function gotStream(stream) { | |
| document.getElementById('start').removeAttribute('disabled'); | |
| inputPoint = audioContext.createGain(); | |
| // Create an AudioNode from the stream. | |
| realAudioInput = audioContext.createMediaStreamSource(stream); | |
| audioInput = realAudioInput; | |
| audioInput.connect(inputPoint); | |
| // audioInput = convertToMono( input ); | |
| analyserNode = audioContext.createAnalyser(); | |
| analyserNode.fftSize = 2048; | |
| inputPoint.connect(analyserNode); | |
| audioRecorder = new Recorder(inputPoint); | |
| zeroGain = audioContext.createGain(); | |
| zeroGain.gain.value = 0.0; | |
| inputPoint.connect(zeroGain); | |
| zeroGain.connect(audioContext.destination); | |
| updateAnalysers(); | |
| } | |
| function initAudio() { | |
| if (!navigator.getUserMedia) | |
| navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; | |
| if (!navigator.cancelAnimationFrame) | |
| navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame; | |
| if (!navigator.requestAnimationFrame) | |
| navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame; | |
| navigator.getUserMedia( | |
| { | |
| "audio": { | |
| "mandatory": { | |
| "googEchoCancellation": "false", | |
| "googAutoGainControl": "false", | |
| "googNoiseSuppression": "false", | |
| "googHighpassFilter": "false" | |
| }, | |
| "optional": [] | |
| }, | |
| }, gotStream, function (e) { | |
| alert('Error getting audio'); | |
| console.log(e); | |
| }); | |
| } | |
| window.addEventListener('load', initAudio); | |
| function unpause() { | |
| document.getElementById('init').style.display = 'none'; | |
| audioContext.resume().then(() => { | |
| console.log('Playback resumed successfully'); | |
| }); | |
| } | |