Takehisa Oneta
/
SoundWS2812B-FFT
LED flash by FFT
circuit diagram
回路図。
/media/uploads/ohneta/lpc1114fn28-ws2812b-fft.pdf
Diff: main.cpp
- 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; + } + + } + +}