0

I am trying to create a flappybird like game where the amplitude of microphone is used to fly a plane. The problem is I keep getting an "Uncaught TypeError: Cannot read property 'getByteTimeDomainData' of undefined" when trying to access the audio signal data using analyserNode.

I think the problem is created because initialization of the AudioContext happens AFTER calling AnalyserNode since console log shows that getAudioAmp() gets declared before draw() before $(document).ready() using console.log().

Here is relevant parts of the code below:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var audioContext;
var mediaStreamSource;
var analyser;
var bufferLength;
var dataArray;
var myAudio = document.querySelector('audio');

$(document).ready(function() {
  navigator.getUserMedia = (navigator.webkitGetUserMedia ||navigator.mozGetUserMedia ||navigator.msGetUserMedia);
  if (navigator.getUserMedia) {
    navigator.getUserMedia({video: false,audio: true},
                            function(stream) {
                              if (window.AudioContext) {
                                audioContext = new AudioContext();
                              } else {
                                audioContext = new webkitAudioContext();
                              }
                              mediaStreamSource = audioContext.createMediaStreamSource(stream);
                              console.log(1)
                              analyser = audioContext.createAnalyser();   <----initialization of AnalyserNode------------
                              bufferLength = analyser.frequencyBinCount;
                              dataArray = new Uint8Array(bufferLength);
                              mediaStreamSource.connect(analyser);},

                             function(){alert("The following error occured: " + err.name);});
  } else {
      alert('OOPS No browser Support');
  }
});

var getAudioAmp  = function() {
  console.log(2)
  analyser.getByteTimeDomainData(dataArray); <---Line that causes Error----------------
  var total = 0;
  for (var i = 0; i < bufferLength; i++) {
    total += dataArray[i];
    var amp = total / dataArray.length;
  }
  return amp;

}

function draw() {
      console.log(3)
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      amp = getAudioAmp() <----------------where I call getAudioAmp()-------------
      console.log(amp)
      drawScore()
      drawStat()
      drawplane()
      drawBricks()
      collisionDetection()
      score++;
      requestAnimationFrame(draw);
    }

draw(); 

here is the code in jsfiddle https://fiddle.jshell.net/kkawabat/bh4dbo1y/44/

kkawabat
  • 1,530
  • 1
  • 14
  • 37
  • 1
    where you do create the variable `analyser`, its omitted.. – urbz May 29 '17 at 13:37
  • 1
    What is `ctx` in `draw` function? – apires May 29 '17 at 13:42
  • 1
    Does `navigator.getUserMedia` need to run before everything else? – whatAboutJohn May 29 '17 at 13:43
  • @urbz & doutriforce sorry I added the declarations for those variable at the top of the code. – kkawabat May 29 '17 at 13:49
  • @whatAboutJohn I'm not really sure I used some sample code I seen for that portion. – kkawabat May 29 '17 at 13:53
  • 1
    @kkawabat, can you post the html? – apires May 29 '17 at 13:58
  • @doutriforce I'm using jsfiddle the only line in the body is '' https://fiddle.jshell.net/kkawabat/bh4dbo1y/44/ – kkawabat May 29 '17 at 14:12
  • 1
    Great, that's enough. – apires May 29 '17 at 14:12
  • 1
    And where did you get this example from? You're setting `analyser = audioContext.createAnalyser();` in a function that is never reached. That's why `analyser` is undefined when you try to access it. – apires May 29 '17 at 14:39
  • That should have been reached because I set a print statement that outputs a 1 and that does appear in the console log. I got the code from this thread https://stackoverflow.com/questions/12407321/navigator-getusermedia#12409728 basically the successful callback for navigator.getUserMedia(). But now that you mention it the method is depreciated, I will see if there are any new implementation I can use that might solve this problem. Thank you for your help. – kkawabat May 29 '17 at 15:10
  • 1
    Sorry, for some reason, it wasn't hitting the `debbuger;` i placed when i pasted your code onto SO code editor. Have you tried calling `draw()` from inside this `if` statement? – apires May 29 '17 at 16:32

0 Answers0