LED flash by FFT

Dependencies:   PixelArray mbed

circuit diagram

回路図。

/media/uploads/ohneta/lpc1114fn28-ws2812b-fft.pdf

Revision:
0:65fd42a2043a
Child:
1:46df0dd09ed2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jan 29 15:05:47 2016 +0000
@@ -0,0 +1,419 @@
+//--------------------------------------------------------------
+/**
+ * SoundWS2812B-FFT for LPC1114FN28
+ *
+ *                           programed by Takehisa Oneta(ohneta)
+ *                           Aug. 2015
+ */
+//--------------------------------------------------------------
+
+#include "mbed.h"
+#include <math.h>
+#include "neopixel.h"
+#include "fftReal.hpp"
+
+#include "SoundWS2812B-FFT.h"
+
+//--------------------------------------------------------------
+#ifdef  _DEBUG_UART_
+Serial      pc(USBTX, USBRX);
+#endif
+AnalogIn    ainR(dp9);
+AnalogIn    ainL(dp10);
+Ticker      soundInterrupt;
+DigitalOut  led(LED2);
+
+//----------------------------------------------------
+neopixel::PixelArray pixelArray(dp2, neopixel::BYTE_ORDER_GRB, neopixel::PROTOCOL_800KHZ);
+neopixel::Pixel gPixelRGB[] = {
+    {0x00, 0x00, 0x00},
+    {0x00, 0x00, 0x00},
+    {0x00, 0x00, 0x00},
+    {0x00, 0x00, 0x00},
+};
+
+#ifdef  _DEBUG_UART_
+const char *gBarGraf[] = {
+    "                                ",
+    "*                               ",
+    "**                              ",
+    "***                             ",
+    "****                            ",
+    "*****                           ",
+    "******                          ",
+    "*******                         ",
+    "********                        ",
+    "*********                       ",
+    "**********                      ",
+    "***********                     ",
+    "************                    ",
+    "*************                   ",
+    "**************                  ",
+    "***************                 ",
+    "****************                ",
+    "*****************               ",
+    "******************              ",
+    "*******************             ",
+    "********************            ",
+    "*********************           ",
+    "**********************          ",
+    "***********************         ",
+    "************************        ",
+    "*************************       ",
+    "**************************      ",
+    "***************************     ",
+    "****************************    ",
+    "*****************************   ",
+    "******************************  ",
+    "******************************* ",
+    "********************************",
+};
+#endif
+
+//--------------------------------------------------------------
+
+uint32_t  gSoundIntrFlag = 0;
+uint32_t  gSoundIntrCount = 0;
+uint32_t  gLedCounter = 0;
+
+float   gBufferR[SAMPLING_NUM];
+float   gBufferL[SAMPLING_NUM];
+FftReal gFFT(SAMPLING_NUM);
+
+//----------------------------------------------------
+/**
+ * Ticker handler
+ */
+void soundInterruptHandle()
+{
+    if (gSoundIntrFlag == 0) {
+        gSoundIntrFlag = 1;
+    }
+    gLedCounter++;
+}
+
+//----------------------------------------------------
+#ifdef _DEBUG_UART_
+void uartFftView(Complex *yRight, Complex *yLeft)
+{
+
+    //pc.printf("%c[2J%c[;H", 27, 27);
+    pc.printf("%c[%c;%cH", 27, 0, 0);
+    //pc.printf("%c[;H", 27);
+
+    pc.printf("Right\r\n");
+    for (int n = 0; n < (SAMPLING_NUM / 2); n++) {
+        uint32_t dt = (uint32_t)abs(yRight[n]);
+        if (dt >= (SAMPLING_NUM / 2)) {
+            dt = SAMPLING_NUM / 2;
+        }
+        pc.printf("%2d[%02d]: %s\r\n", n, dt, gBarGraf[dt]);
+    }
+
+    pc.printf("\r\nLeft\r\n");
+    for (int n = 0; n < (SAMPLING_NUM / 2); n++) {
+        uint32_t dt = (uint32_t)abs(yLeft[n]);
+        if (dt >= (SAMPLING_NUM / 2)) {
+            dt = SAMPLING_NUM / 2;
+        }
+        pc.printf("%2d[%02d]: %s\r\n", n, dt, gBarGraf[dt]);
+    }
+}
+#endif
+
+//----------------------------------------------------
+void outputLeds(Complex *yRight, Complex *yLeft)
+{
+    int r, g, b;
+#if 1
+    r = (   (uint32_t)abs(yRight[1]) +
+            (uint32_t)abs(yRight[2])   );
+    g = (   (uint32_t)abs(yLeft[1]) +
+            (uint32_t)abs(yLeft[2])   );
+#else
+    r = (   (uint32_t)abs(yRight[0]) +
+            (uint32_t)abs(yRight[1]) +
+            (uint32_t)abs(yRight[2])   );
+    g = (   (uint32_t)abs(yLeft[0]) +
+            (uint32_t)abs(yLeft[1]) +
+            (uint32_t)abs(yLeft[2])   );
+#endif
+    b = (r + g) / 2;
+    gPixelRGB[0].red   = (r > 255) ? 255 : r;
+    gPixelRGB[0].green = (g > 255) ? 255 : g;
+    gPixelRGB[0].blue  = (b > 255) ? 255 : b;
+
+    r = (   (uint32_t)abs(yRight[3]) + 
+            (uint32_t)abs(yRight[4]) + 
+            (uint32_t)abs(yRight[5]) + 
+            (uint32_t)abs(yRight[6])   );
+    g = (   (uint32_t)abs(yLeft[3]) + 
+            (uint32_t)abs(yLeft[4]) + 
+            (uint32_t)abs(yLeft[5]) + 
+            (uint32_t)abs(yLeft[6])   );
+    b = (r + g) / 2;
+    gPixelRGB[1].red   = (r > 255) ? 255 : r;
+    gPixelRGB[1].green = (g > 255) ? 255 : g;
+    gPixelRGB[1].blue  = (b > 255) ? 255 : b;
+
+    r = (   (uint32_t)abs(yRight[7]) +
+            (uint32_t)abs(yRight[8]) + 
+            (uint32_t)abs(yRight[9]) + 
+            (uint32_t)abs(yRight[10]) + 
+            (uint32_t)abs(yRight[11]) + 
+            (uint32_t)abs(yRight[12]) + 
+            (uint32_t)abs(yRight[14]) + 
+            (uint32_t)abs(yRight[15])   );
+    g = (   (uint32_t)abs(yLeft[7]) +
+            (uint32_t)abs(yLeft[8]) + 
+            (uint32_t)abs(yLeft[9]) + 
+            (uint32_t)abs(yLeft[10]) + 
+            (uint32_t)abs(yLeft[11]) + 
+            (uint32_t)abs(yLeft[12]) + 
+            (uint32_t)abs(yLeft[14]) + 
+            (uint32_t)abs(yLeft[15])   );
+    b = (r + g) / 2;
+    gPixelRGB[2].red   = (r > 255) ? 255 : r;
+    gPixelRGB[2].green = (g > 255) ? 255 : g;
+    gPixelRGB[2].blue  = (b > 255) ? 255 : b;
+
+    r = (   (uint32_t)abs(yRight[16]) + 
+            (uint32_t)abs(yRight[17]) + 
+            (uint32_t)abs(yRight[18]) + 
+            (uint32_t)abs(yRight[19]) + 
+            (uint32_t)abs(yRight[20]) + 
+            (uint32_t)abs(yRight[21]) + 
+            (uint32_t)abs(yRight[22]) + 
+            (uint32_t)abs(yRight[23]) +
+            (uint32_t)abs(yRight[24]) + 
+            (uint32_t)abs(yRight[25]) + 
+            (uint32_t)abs(yRight[26]) + 
+            (uint32_t)abs(yRight[27]) + 
+            (uint32_t)abs(yRight[28]) + 
+            (uint32_t)abs(yRight[29]) + 
+            (uint32_t)abs(yRight[30]) +
+            (uint32_t)abs(yRight[31]) + 
+            (uint32_t)abs(yRight[32])   );
+    g = (   (uint32_t)abs(yLeft[16]) + 
+            (uint32_t)abs(yLeft[17]) + 
+            (uint32_t)abs(yLeft[18]) + 
+            (uint32_t)abs(yLeft[19]) + 
+            (uint32_t)abs(yLeft[20]) + 
+            (uint32_t)abs(yLeft[21]) + 
+            (uint32_t)abs(yLeft[22]) + 
+            (uint32_t)abs(yLeft[23]) +
+            (uint32_t)abs(yLeft[24]) + 
+            (uint32_t)abs(yLeft[25]) + 
+            (uint32_t)abs(yLeft[26]) + 
+            (uint32_t)abs(yLeft[27]) + 
+            (uint32_t)abs(yLeft[28]) + 
+            (uint32_t)abs(yLeft[29]) + 
+            (uint32_t)abs(yLeft[30]) +
+            (uint32_t)abs(yLeft[31]) + 
+            (uint32_t)abs(yLeft[32])   );
+    b = (r + g) / 2;
+    gPixelRGB[3].red   = (r > 255) ? 255 : r;
+    gPixelRGB[3].green = (g > 255) ? 255 : g;
+    gPixelRGB[3].blue  = (b > 255) ? 255 : b;
+
+
+    pixelArray.update(gPixelRGB, 4);
+}
+
+//----------------------------------------------------
+//----------------------------------------------------
+void outputLeds2(Complex *yRight, Complex *yLeft, float rVolume, float lVolume)
+{
+    int rr, rg, rb;
+    int lr, lg, lb;
+    
+    if (rVolume > 1.0) rVolume = 1.0;
+    if (lVolume > 1.0) lVolume = 1.0;
+    
+    rr = (
+        (uint32_t)abs(yRight[1]) +
+        (uint32_t)abs(yRight[2]) +
+        (uint32_t)abs(yRight[3])
+    );
+    rg = (int)(rVolume * 255.0);
+    rb = (
+        (uint32_t)abs(yRight[4]) +
+        (uint32_t)abs(yRight[5]) +
+        (uint32_t)abs(yRight[6]) +
+        (uint32_t)abs(yRight[7]) +
+        (uint32_t)abs(yRight[8]) + 
+        (uint32_t)abs(yRight[9]) + 
+        (uint32_t)abs(yRight[10]) + 
+        (uint32_t)abs(yRight[11]) + 
+        (uint32_t)abs(yRight[12]) + 
+        (uint32_t)abs(yRight[14]) +
+        (uint32_t)abs(yRight[15]) + 
+        (uint32_t)abs(yRight[16]) + 
+        (uint32_t)abs(yRight[17]) + 
+        (uint32_t)abs(yRight[18]) + 
+        (uint32_t)abs(yRight[19]) + 
+        (uint32_t)abs(yRight[20]) + 
+        (uint32_t)abs(yRight[21]) + 
+        (uint32_t)abs(yRight[22]) + 
+        (uint32_t)abs(yRight[23]) +
+        (uint32_t)abs(yRight[24]) + 
+        (uint32_t)abs(yRight[25]) + 
+        (uint32_t)abs(yRight[26]) + 
+        (uint32_t)abs(yRight[27]) + 
+        (uint32_t)abs(yRight[28]) + 
+        (uint32_t)abs(yRight[29]) + 
+        (uint32_t)abs(yRight[30]) +
+        (uint32_t)abs(yRight[31]) + 
+        (uint32_t)abs(yRight[32])
+    );
+    rr = (rr > 255) ? 255 : rr;
+    rg = (rg > 255) ? 255 : rg;
+    rb = (rb > 255) ? 255 : rb;
+
+
+    lr = (
+        (uint32_t)abs(yLeft[1]) +
+        (uint32_t)abs(yLeft[2]) +
+        (uint32_t)abs(yLeft[3])
+    );
+    lg = (int)(lVolume * 255.0);
+    lb = (
+        (uint32_t)abs(yLeft[4]) +
+        (uint32_t)abs(yLeft[5]) +
+        (uint32_t)abs(yLeft[6]) +
+        (uint32_t)abs(yLeft[7]) +
+        (uint32_t)abs(yLeft[8]) + 
+        (uint32_t)abs(yLeft[9]) + 
+        (uint32_t)abs(yLeft[10]) + 
+        (uint32_t)abs(yLeft[11]) + 
+        (uint32_t)abs(yLeft[12]) + 
+        (uint32_t)abs(yLeft[14]) +
+        (uint32_t)abs(yLeft[15]) + 
+        (uint32_t)abs(yLeft[16]) + 
+        (uint32_t)abs(yLeft[17]) + 
+        (uint32_t)abs(yLeft[18]) + 
+        (uint32_t)abs(yLeft[19]) + 
+        (uint32_t)abs(yLeft[20]) + 
+        (uint32_t)abs(yLeft[21]) + 
+        (uint32_t)abs(yLeft[22]) + 
+        (uint32_t)abs(yLeft[23]) +
+        (uint32_t)abs(yLeft[24]) + 
+        (uint32_t)abs(yLeft[25]) + 
+        (uint32_t)abs(yLeft[26]) + 
+        (uint32_t)abs(yLeft[27]) + 
+        (uint32_t)abs(yLeft[28]) + 
+        (uint32_t)abs(yLeft[29]) + 
+        (uint32_t)abs(yLeft[30]) +
+        (uint32_t)abs(yLeft[31]) + 
+        (uint32_t)abs(yLeft[32])
+    );
+    lr = (lr > 255) ? 255 : lr;
+    lg = (lg > 255) ? 255 : lg;
+    lb = (lb > 255) ? 255 : lb;
+
+#if 0
+    gPixelRGB[1].red   = lr;
+    gPixelRGB[1].green = lg;
+    gPixelRGB[1].blue  = lb;
+    {
+        int x;
+        x = (int)((float)lr * 0.8 + (float)rr * 0.2);
+        gPixelRGB[0].red   = (x > 255) ? 255 : x;
+        x = (int)((float)lg * 0.8 + (float)rg * 0.2);
+        gPixelRGB[0].green = (x > 255) ? 255 : x;
+        x = (int)((float)lb * 0.8 + (float)rb * 0.2);
+        gPixelRGB[0].blue  = (x > 255) ? 255 : x;
+    
+        x = (int)((float)lr * 0.2 + (float)rr * 0.8);
+        gPixelRGB[3].red   = (x > 255) ? 255 : x;
+        x = (int)((float)lg * 0.2 + (float)rg * 0.8);
+        gPixelRGB[3].green = (x > 255) ? 255 : x;
+        x = (int)((float)lb * 0.2 + (float)rb * 0.8);
+        gPixelRGB[3].blue  = (x > 255) ? 255 : x;
+    }
+    gPixelRGB[2].red   = rr;
+    gPixelRGB[2].green = rg;
+    gPixelRGB[2].blue  = rb;
+#else
+    gPixelRGB[0].red   = (lr >> 2);
+    gPixelRGB[0].green = (lg >> 2);
+    gPixelRGB[0].blue  = (lb >> 1);
+    
+    gPixelRGB[1].red   = lr;
+    gPixelRGB[1].green = lg;
+    gPixelRGB[1].blue  = lb;
+ 
+    gPixelRGB[2].red   = rr;
+    gPixelRGB[2].green = rg;
+    gPixelRGB[2].blue  = rb;
+    
+    gPixelRGB[3].red   = (rr >> 2);
+    gPixelRGB[3].green = (rg >> 2);
+    gPixelRGB[3].blue  = (rb >> 1);
+
+#endif
+
+    pixelArray.update(gPixelRGB, 4);
+}
+
+//----------------------------------------------------
+//----------------------------------------------------
+
+int main()
+{
+    led = 0;
+#ifdef _DEBUG_UART_
+    pc.baud(115200);
+    pc.printf("### START \n");
+#endif
+
+    Complex yRight[SAMPLING_NUM / 2 + 1], yLeft[SAMPLING_NUM / 2 + 1];
+
+    gSoundIntrFlag = 0;
+    gSoundIntrCount = 0;
+    soundInterrupt.attach_us(&soundInterruptHandle, 25);
+
+float dd = 20.0f;
+    while (1) {
+        
+        if (gSoundIntrFlag == 1) {
+            float r = ainR;
+            float l = ainL;
+ 
+            gBufferR[gSoundIntrCount] = r * dd - 1.0f;
+            if (gBufferR[gSoundIntrCount] < -1.0f) {
+                gBufferR[gSoundIntrCount] = -1.0f;
+            } else if (gBufferR[gSoundIntrCount] > 1.0f) {
+                gBufferR[gSoundIntrCount] = 1.0f;
+            }
+            gBufferL[gSoundIntrCount] = l * dd - 1.0f;
+            if (gBufferL[gSoundIntrCount] < -1.0f) {
+                gBufferL[gSoundIntrCount] = -1.0f;
+            } else if (gBufferL[gSoundIntrCount] > 1.0f) {
+                gBufferL[gSoundIntrCount] = 1.0f;
+            }
+
+            gSoundIntrCount++;
+            if (gSoundIntrCount >= SAMPLING_NUM) {
+                gSoundIntrCount = 0;
+
+                gFFT.Execute(gBufferR, yRight);
+                gFFT.Execute(gBufferL, yLeft);
+#ifdef _DEBUG_UART_
+                uartFftView(yRight, yLeft);
+#endif
+                //outputLeds(yRight, yLeft);
+                outputLeds2(yRight, yLeft, r, l);
+
+                gSoundIntrFlag = 0;
+            }
+        }
+        
+        if (gLedCounter > 1000) {
+            led = !led;
+            gLedCounter = 0;
+        }
+ 
+   }
+
+}