Recording and analyzing sound

Posted on
Page
of 2
Prev
/ 2
  • Yes, that's because I've had to update the Softdevice version in order to fix some Nordic SDK bugs that were stopping Windows from pairing. While the main firmware will build, the bootloader won't at the moment.

  • Hi @Gordon,

    FYI, I cannot do a DFU firmware update with http://www.espruino.com/binaries/travis/­master/espruino_1v95.140_puckjs.zip

    Honestly I am confused with the builds here http://www.espruino.com/binaries/travis/­?C=M;O=D

    Most recent build has lower number than the previous one ? For example http://www.espruino.com/binaries/travis/­07ae7710e3cd84e7773a7faba3124b3a6c9de85f­/ from 2018-01-29 15:55 has version 1v95.140 while http://www.espruino.com/binaries/travis/­773a83387fb2f9baefcbdd2cf37d0f79107f3389­/ from 2018-01-29 15:27 has version 1v95.141.

    Please explain.

    Thank you.

  • FYI, I cannot do a DFU firmware update with

    Why? What happens? error messages? fails to run afterwards? does it explode?

    Honestly I am confused with the builds

    As I said 2 posts ago it's the number of commits on that branch since the last release tag.

    You get it by running git log --oneline RELEASE_1V95..HEAD and counting the number of lines (commits) returned.

    However I have absolutely no idea why Travis seems to be getting differing numbers of commits returned from that command each time - there are more important things to work on than figuring out why a number in a filename is off by 1. If you find out why I'd appreciate a PR though.

  • Hi @Gordon,

    Concerning the DFU update, I am doing it with NRF Connect. It starts the firmware update, the blue led is on, when the upload is done the device is not restarted and the blue led continues to be on. If I try to upload the file again, it immediately says that the update is done successfully, when the device is restarted nobody is there. If I disconnect from the device the red led is on waiting DFU to connect. Previous DFU updates are fine.

    Thank you.

  • Did you try the long-press at boot mentioned here: http://www.espruino.com/Puck.js#firmware­-updates

    I just uploaded the latest firmware from http://www.espruino.com/binaries/travis/­07ae7710e3cd84e7773a7faba3124b3a6c9de85f­/ and it works perfectly on my Puck.js

  • Hi @Gordon,

    How should I interpret the returned Uint16Array buf in order to play it with javascript in the web browser for example ?

  • Just treat it as an array of numbers. Once that is on a webpage it should be pretty easy to load that into whatever sound API you want in order to play it.

  • Hi @Gordon,

    I am running with firmware 1v99.50 and trying run your example at https://www.espruino.com/Waveform

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

    but have :
    ***Uncaught Error: Insufficient stack for computing FFT
    at line 8 col 12

    E.FFT(a);***
    

    Is it possible to measure 500Hz frequency or we are restricted by the Puck's memory ?

  • Yeah, the issue is that it needs to allocate 2*8*1024 = 16kB on the stack in order to perform the FFT in double arithmetic, and that's too much for Puck.js.

    However you can still measure 500Hz - just record a shorter buffer of 512 samples and do the FFT on that (it works for higher frequencies too).

  • Hi @Gordon,
    1) You mean this code can still measure 500Hz with lower accuracy ?

    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=100;i<500;i++)if(a[i]>n)n=a[m=i];
      console.log(m.toFixed(0)+"Hz @ "+n);
    });
    w.startInput(D2,512,{repeat:true});
    

    2) Is it possible to use 1024 buffer size on behalf of other functionalities ?

  • 1) Yes - but you need w.startInput(D2,1024,{repeat:true}); - so you're still getting a 1kHz set of data, but for half a second. Less accurate but otherwise usually more than good enough.

    2) I'm not sure I understand the question? For now, you could use a JS implementation of FFT that stored the results in 32 bit Float32Arrays. There is actually an open issue about switching the FFT to 32 bits from 64, as it'd be faster and I don't think anyone would really be impacted.

  • Hi @Gordon,

    I did some tests on point one above, it appeared that when you have:

    1) Input at 512Hz with 512 buffer size restricting frequencies between 100Hz and 250Hz.

    * Produce 200Hz sine wave audio frequency, then every thing is correctly determined - 200Hz @ XXX
    

    2) Input at 1024Hz with 512 buffer size restricting frequencies between 100Hz and 500Hz.

     * Produce 200Hz sine wave audio frequency, then you have - 100Hz @ XXX as buffer is received twice per second
     * Produce 400Hz sine wave audio frequency, then you have - 200Hz @ XXX as buffer is received twice per second
    

    How can the correct frequency be determined from point 2 above ?

  • 1) Yes, absolutely. You need at least 2x the sample rate to be able to get a signal.

    2) I'm pretty sure it's as you'd expect based on your results. It's half the size array, so the array indexes will be halfway along it.

  • Hi @Gordon,

    In order to calculate 400Hz when such frequency is produced, should I gather(concat) the two buffers for once second and then run FTT over them ?

  • I'm not sure I understand - if you concat both buffers then you have a 1024 item array that you want to FFT and you're back to square one?

  • Does the following work for you:

    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=50;i<250;i++)if(a[i]>n)n=a[m=i];
      console.log((m*2).toFixed(0)+"Hz @ "+n);
    });
    w.startInput(D2,1024,{repeat:true});
    
  • Hi @Gordon,

    Adding the two results for one seconds works better for me with 200Hz test.

    var p=0, sBuff=new Uint8Array(2), sN=new Uint8Array(2);
    function soundTest() {
      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=50;i<250;i++)if(a[i]>n)n=a[m=i];
        sBuff[p]=m;
        sN[p]=n;
        if(p==1){
          var avgF=E.sum(sBuff);
          var nAvg=E.sum(sN);
          console.log(avgF+"Hz @ "+nAvg);
          p=0;
        } else {
          p=1;
        }
      });
      w.startInput(D2,1024,{repeat:true});
    }
    

    Do you know what is the accuracy loss on doubling the input sound compared to the buffer we have for processing ?

  • I don't know exactly, no. You'd have to do some research - it's all standard FFT stuff.

    I'm not convinced by your averaging at all, but hey, if it works for you...

    If you really want a better result, average the entire array after the FFT, and do your calculations on that. If you know you have one single frequency then you can even get a more accurate idea of the frequency by looking at the relative size of the FFT peaks, eg:

    // exactly that frequency
    0,0,0,0,0,255,0,0,0,0,0
    // halfway between two frequencies
    0,0,0,0,0,128,128,0,0,0,0,0
    // nearer the first frequency than the next one
    0,0,0,0,0,192,64,0,0,0,0
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Recording and analyzing sound

Posted by Avatar for user73560 @user73560

Actions