LED flash by FFT

Dependencies:   PixelArray mbed

circuit diagram

回路図。

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

main.cpp

Committer:
mbed_tw_hoehoe
Date:
2016-04-18
Revision:
2:97f927b73354
Parent:
1:46df0dd09ed2

File content as of revision 2:97f927b73354:

//--------------------------------------------------------------
/**
 * 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"

using namespace Mikami;

//--------------------------------------------------------------
#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;
        }
 
   }

}