You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Yes, the MSGEQ7 would be the easiest solution, and it looks like it would be pretty easy to use with Espruino...

    I'll see about adding that convolve function in Espruino 1v58 though, so you should be able to get a few bands of EQ quite easily.

    I just gave FFT (using an LCD screen) a quick go:

    // http://www-ee.uta.edu/eeweb/ip/Courses/DSP_new/Programs/fft.cpp
    function fft(data) { // data must be 2 more than required
      var mmax, m, istep, i;
      var wtemp, wr, wpr, wpi, wi, theta;
      var tempr, tempi;
      
      var n = data.length-1;
      var j = 1;
      for (i = 1; i < n; i += 2) {
        if (j > i) {
          tempr = data[j];     data[j] = data[i];     data[i] = tempr;
          tempr = data[j+1]; data[j+1] = data[i+1]; data[i+1] = tempr;
        }
        m = n >> 1;
        while (m >= 2 && j > m) {
          j -= m;
          m >>= 1;
        }
        j += m;
      }
      mmax = 2;
      while (n > mmax) {
        istep = 2*mmax;
        theta = 2*Math.PI/mmax;
        wtemp = Math.sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = Math.sin(theta);
        wr = 1.0;
        wi = 0.0;
        
        for (m = 1; m < mmax; m += 2) {
          for (i = m; i <= n; i += istep) {        
            j = i + mmax;
            tempr = wr*data[j]   - wi*data[j+1];
            tempi = wr*data[j+1] + wi*data[j];
            data[j]   = data[i]   - tempr;
            data[j+1] = data[i+1] - tempi;
            data[i] += tempr;
            data[i+1] += tempi;
          }
          wr = (wtemp = wr)*wpr - wi*wpi + wr;
          wi = wi*wpr + wtemp*wpi + wi;
        }
        mmax = istep;
      }
    }
    
    SPI1.setup({ baud: 1000000, sck:B3, mosi:B5 });
    var g = require("PCD8544").connect(SPI1,B6,B7,B8);
    
    var wave = new Waveform(32);
    var floatData = new Float32Array(32+1); // note the +1
    wave.on("finish", function(buf) {
      floatData.set(buf,1);
      floatData[0]=0;
      fft(floatData);
      g.clear();
      for (var i=0;i<buf.length;i+=2)
        g.setPixel(i,24+Math.sqrt(floatData[i+1]*floatData[i+1] + floatData[i+2]*floatData[i+2])>>4);
      g.flip();
      // go again
      wave.startInput(A0,1000);
    });
    
    function onTimer() {
      print("Start");
     
    }
    
    setTimeout(function() {
       wave.startInput(A0,1000);
    }, 1000);
    

    It's only managing around 2 FPS at the moment. I guess with LEDs it would be significantly faster though...

About

Avatar for Gordon @Gordon started