7) Prototype 1We order a amplified microphone from adafruit. Using the FFT library to analyze voltage input from microphone into frequency arrays. And piccolo is a project by Adafruit visualize music on a 8X8 neopixel block. My goal was figuring out how is the code working, where is the input and how does it process it and output. Also, because the processing speed of this arduino board is very slow for doing ask like listening to music and analysing them all the time. It also use a command to tell arduino to run freely without stops.
So I built a prototype analyzing sound into one single RGB lights. Higher pitch -> green. Low pitch -> red.
Code:
#include <avr/pgmspace.h>
#include <ffft.h>
#include <math.h>
#include <Wire.h>
#ifdef __AVR_ATmega32U4__
#define ADC_CHANNEL 7
#else
#define ADC_CHANNEL 0
#endif
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int16_t capture[FFT_N];
complex_t bfly_buff[FFT_N];
uint16_t spectrum[FFT_N/2];
volatile byte samplePos = 0;
static const uint8_t PROGMEM
noise[64]={ 8,6,6,5,3,4,4,4,3,4,4,3,2,3,3,4,
2,1,2,1,3,2,3,2,1,2,3,1,2,3,4,4,
3,2,2,2,2,2,2,1,3,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4 },
eq[64]={
255, 175,218,225,220,198,147, 99, 68, 47, 33, 22, 14, 8, 4, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void setup() {
Serial.begin(9600);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
ADMUX = ADC_CHANNEL;
ADCSRA = _BV(ADEN) |
_BV(ADSC) |
_BV(ADATE) |
_BV(ADIE) |
_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
ADCSRB = 0;
DIDR0 = 1 << ADC_CHANNEL;
TIMSK0 = 0;
sei();
}
void loop() {
uint8_t i, x, L, *data, nBins, binNum, weighting, currentMax, currentMaxPo;
uint16_t minLvl, maxLvl;
int level, y, sum;
while(ADCSRA & _BV(ADIE));
fft_input(capture, bfly_buff);
samplePos = 0;
ADCSRA |= _BV(ADIE);
fft_execute(bfly_buff);
fft_output(bfly_buff, spectrum);
// Remove noise and apply EQ levels
for(x=0; x<FFT_N/2; x++) {
L = pgm_read_byte(&noise[x]);
spectrum[x] = (spectrum[x] <= L) ? 0 : // if (...) then S[] = 0; else,
(((spectrum[x] - L) * (256L - pgm_read_byte(&eq[x]))) >> 8); //256L means 256, >>8 = 256的倍数
}
for(int c; c < 64; c++) {
if(spectrum[c] > currentMax) {
currentMax = spectrum[c];
currentMaxPo = c;
}
if(currentMaxPo < 10) {
setColor(255, 255, 0);
}
else {
setColor(0, 0, 255);
}
Serial.println(currentMaxPo);
}
}
void setColor(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
ISR(ADC_vect) {
static const int16_t noiseThreshold = 4;
int16_t sample = ADC;
capture[samplePos] =
((sample > (512-noiseThreshold)) &&
(sample < (512+noiseThreshold))) ? 0 :
sample - 512;
if(++samplePos >= FFT_N) ADCSRA &= ~_BV(ADIE);
}
No comments:
Post a Comment