using microphone input for speech recognition and web audio together?

1.2k Views Asked by At

I would like to do speech analysis in the browser. I have a microphone input as my main stream that is created when I start the speech recognition object. I would like to get frequencies from the same stream. How do I connect the audio context source to the same microphone stream as the voice recognition one? Do I have to request for microphone permissions twice? I tried the code below but the getMicData() will only log '0' values.

JS

 var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
                            window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
let audioCtx, analyser;
let amplitude;
let bufferLength;
let dataArray;
let bassArray;
let trebleArray;

let recognition = new SpeechRecognition();
recognition.continuous = false;
recognition.lang = 'en-US';
recognition.interimResults = false;
recognition.maxAlternatives = 1
let animationRequest;
const recordbtn = document.getElementById('record');

recordbtn.addEventListener('click', () => {
   // start speech rec
   recognition.start();
   audioCtx = new(window.AudioContext || window.webkitAudioContext)();
   analyser = audioCtx.createAnalyser();
   analyser.fftSize = 512;
   analyser.smoothingTimeConstant = 0.85;
   
})

recognition.onstart = function () {
   document.getElementById('font-name').innerHTML = "START SPEAKING";
   getMicData()
}

recognition.onspeechend = function () {
   cancelAnimationFrame(animationRequest);
}
function getMicData() {
animationRequest =  window.requestAnimationFrame(getMicData)
   bufferLength = analyser.fftSize;
   dataArray = new Uint8Array(bufferLength);
   analyser.getByteFrequencyData(dataArray);

   let maxAmp = 0;
   let sumOfAmplitudes = 0;

   for (let i = 0; i < bufferLength; i++) {
      let thisAmp = dataArray[i]; // amplitude of current bin
      if (thisAmp > maxAmp) {
         sumOfAmplitudes = sumOfAmplitudes + thisAmp;
      }
   }
   let averageAmplitude = sumOfAmplitudes / bufferLength;
   console.log(averageAmplitude)
   return averageAmplitude;
}
0

There are 0 best solutions below