简体   繁体   中英

p5.js ball movement based on Microphone Frequency

I am building an project for which I need a ball which moves up and down based on the frequency of microphone input. I am using p5.js library for it.

Ball Movement: I want to take average of frequencies for each second and change the y-axis placement of the ball based on that.

Here is the code that I have written as of now.

var mic;
var fft;
const average = arr => arr.reduce((a,b) => a + b, 0) / arr.length;

function setup() {
  createCanvas(700, 700);

  mic = new p5.AudioIn();
  buttonStart = createButton('start')
  buttonStop = createButton('stop')

  buttonStart.mousePressed(() => {
    mic.start();
  })

  fft = new p5.FFT(0, 32);
  fft.setInput(mic);
  buttonStop.mousePressed(() => {
    mic.stop();
  })
}

function timeout(freqs) {
  var avgFreq = average(freqs);
  console.log(avgFreq);
  fill(0);
  ellipse(50, avgFreq, 30, 30)

}

function draw() {
  background(220);
  let temp = [];
  let freqs = fft.analyze();
  temp.push(average(freqs));
  setInterval(timeout(temp),1000);
  console.log(temp);
}

This doesn't seem to work very well, each time the draw function is called then its calling the timeout function as well without waiting for 1 second which is specified in setInterval()

You have a basic JavaScript mistake: when you pass a function to another function for it to call later (ie the first argument of setInterval ) you either need to pass it by name: setInterval(timeout, 1000) , or use an arrow expression (aka lambda function): setInterval(() => timeout(temp), 1000) . Otherwise you are just calling timeout immediately and passing the result, which is undefined, to setInterval() .

That said, there are definitely several other issues and it isn't clear what exactly you are trying to accomplish.

  1. You are going to have lots of delayed calls to this timeout function (~60 per second) but these will basically just amount to delayed rendering
  2. The temp array is always going to contain a single value because you declare it and add a single item to it in each call to draw()
  3. the FFT.analyze functions is going to return a list of buckets representing different frequency ranges and the value for each bucket is going to be the amplitude of that bucket. So the average of those values does not change with frequency but with volume.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM