Recording and analyzing sound

Posted on
  • Hi Guys,

    I have a sound which is between 150Hz-250Hz. I need two things:

    1) The average frequency of the sound for the last 5 seconds. After a discussion with @Gordon it appeared that 1Khz sampling rate will be enough and this could be done on the Puck with FTT.
    2) Get the digitalized sound from the microphone for the last 5 seconds.

    The microphone is connected on D2(for analog), D1 (for power) and GND.

    Thank you.

  • Something like this seems to work:

    var w = new Waveform(512,{doubleBuffer:true,bits:16}­);
    var a2 = new Uint16Array(512);
    var a = new Int16Array(a2.buffer);
    w.on("buffer", function(buf) {
      a2.set(buf);
      E.FFT(a2);
      var m=0,n=-1,b;
      for (var i=150;i<250;i++){b=Math.abs(a[i]);if(b>n­){n=b;m=i;}}
      console.log(m.toFixed(0)+"Hz @ "+n);
    });
    w.startInput(D2,512,{repeat:true});
    

    It's sampling at 512Hz, which seems to be good enough for what you want.

    Ideally the input voltage range would be higher and you could go back to 8 bits though - I had to use 16 because my microphone isn't very good.

    Also, there appears to be some bug in the FFT where it's returning signed values when it shouldn't be - I'll look into that, but for now the attached code seems to work ok.

  • Ok, FFT is now fixed, and will be in the 1v92 release.

    When 1v92 is released you'll be able to use this (slightly cleaner & faster) code:

    var w = new Waveform(512,{doubleBuffer:true,bits:16}­);
    var a = new Uint16Array(512);
    w.on("buffer", function(buf) {
      a.set(buf);
      E.FFT(a);
      var m=0,n=-1;
      for (var i=150;i<250;i++)if(a[i]>n)n=a[m=i];
      console.log(m.toFixed(0)+"Hz @ "+n);
    });
    w.startInput(D2,512,{repeat:true});
    

    The 'for' loop is intentionally quite tight - Espruino's execution speed isn't that fast so I'm trying to make it as quick as possible.

    The @ xxx part that's printed is the volume of the most prominent frequency. If no frequency is playing then you'll get a random frequency shown, but with a lower volume.

    Also, just a note: don't expect great battery life when using this. Realistically you'll need to use a bigger power source if you want to get more than a day's life out of it.

  • Hi Gordon,

    Really appreciate your feedback and quick reaction! I will require an average frequency for 5 seconds every hour, as we discussed it could double decrease the battery life, but the Puck open architecture give possibility for additional power supply, everything is a matter of evaluation.

    Thank you again.

  • Ahh, forgot about that - yes, 5 seconds an hour will provide much better battery life.

    It should be easy enough for you to tweak the code above to do a 5 second average (probably just keep a sum of the FFTs, and do the loop over them at the end).

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Recording and analyzing sound

Posted by Avatar for user73560 @user73560

Actions