11/*
2+ AUDIO SPECTRUM LIGHT SHOW for Adafruit EyeLights (LED Glasses + Driver).
3+ Uses onboard microphone and a lot of math to react to music.
24*/
35
46#include < Adafruit_IS31FL3741.h> // For LED driver
57#include < PDM.h> // For microphone
68#include < Adafruit_ZeroFFT.h> // For math
79
810Adafruit_EyeLights_buffered glasses; // Buffered for smooth animation
9- extern PDMClass PDM;
11+ extern PDMClass PDM; // Mic
12+
13+ #define NUM_SAMPLES 512 // Audio & FFT buffer, MUST be a power of two
14+ #define SPECTRUM_SIZE (NUM_SAMPLES / 2 ) // Output spectrum is 1/2 of FFT output
15+
1016
11- #define NUM_SAMPLES 512 // FFT size, MUST be a power of two
1217short sampleBuffer[NUM_SAMPLES]; // buffer to read samples into, each sample is 16-bits
18+
19+ // short sbuf[2][NUM_SAMPLES];
20+ // uint8_t sbuf_idx = 0;
21+
1322volatile int samplesRead; // number of samples read (set in interrupt)
1423
15- #define SPECTRUM_SIZE (NUM_SAMPLES / 2 ) // Output spectrum is 1/2 of FFT result
1624
1725// Bottom of spectrum tends to be noisy, while top often exceeds musical
1826// range and is just harmonics, so clip both ends off:
19- // #define LOW_BIN 10 // Lowest bin of spectrum that contributes to graph
20- // #define HIGH_BIN 75 // Highest bin "
21-
2227#define LOW_BIN 3 // Lowest bin of spectrum that contributes to graph
2328#define HIGH_BIN 180 // Highest bin "
2429
@@ -47,7 +52,7 @@ void setup() { // Runs once at program start...
4752
4853 // Initialize hardware
4954 Serial.begin (115200 );
50- // while(!Serial);
55+ while (!Serial);
5156 if (! glasses.begin ()) err (" IS3741 not found" , 2 );
5257
5358 uint8_t spectrum_bits = (int )log2f ((float )SPECTRUM_SIZE);
@@ -121,6 +126,7 @@ void loop() { // Repeat forever...
121126 while (samplesRemaining) {
122127 if (samplesRead) { // Set in onPDMdata()
123128 samplesRemaining -= samplesRead;
129+ samplesRead = 0 ;
124130 }
125131 yield ();
126132 }
@@ -131,21 +137,11 @@ void loop() { // Repeat forever...
131137 ZeroFFT (sampleBuffer, NUM_SAMPLES);
132138
133139
134-
135140 // Convert FFT output to spectrum
136141 for (int i=0 ; i<SPECTRUM_SIZE; i++) {
137142// data[i] = (data[i] * 0.25) + ((float)sampleBuffer[i] * 0.75);
138143 data[i] = (data[i] * 0.2 ) + ((sampleBuffer[i] ? log ((float )sampleBuffer[i]) : 0.0 ) * 0.8 );
139144// data[i] = (float)sampleBuffer[i];
140- #if 0
141- uint32_t mag2 = fr[i] * fr[i] + fi[i] * fi[i];
142- if (mag2) {
143- data[i] = log(sqrt((float)mag2));
144- // data[i] = sqrt((float)mag2);
145- } else {
146- data[i] = 0.0;
147- }
148- #endif
149145 }
150146
151147 float lower = data[0 ], upper = data[0 ];
@@ -204,16 +200,30 @@ void loop() { // Repeat forever...
204200// Serial.println(frames * 1000 / elapsed);
205201}
206202
207-
203+ int16_t bitbucket[ 512 ];
208204void onPDMdata () {
205+ pinMode (LED_BUILTIN, OUTPUT);
206+ digitalWrite (LED_BUILTIN, (millis () * 2 / 500 ) & 1 );
207+
208+ int bytesAvailable = PDM.available ();
209209 if (mic_on) {
210- // query the number of bytes available
211- int bytesAvailable = PDM.available ();
212-
213- // read into the sample buffer
214- PDM.read (sampleBuffer, bytesAvailable);
215-
216- // 16-bit, 2 bytes per sample
217- samplesRead = bytesAvailable / 2 ;
210+ // wait, what? shouldn't this increment until full?
211+ // yes it should. No wonder.
212+ if (bytesAvailable) {
213+ int maxbytes = (NUM_SAMPLES - samplesRead) * 2 ;
214+ if (bytesAvailable > maxbytes) bytesAvailable = maxbytes;
215+ PDM.read (&sampleBuffer[samplesRead], bytesAvailable);
216+ // PDM.read(sampleBuffer, bytesAvailable);
217+ samplesRead = bytesAvailable / 2 ;
218+ }
219+ } else {
220+ if (bytesAvailable) {
221+ PDM.read (bitbucket, bytesAvailable);
222+ }
218223 }
224+ // When buffer is full...
225+ // indicate to calling code that it's ready
226+ // stop recording
227+ // calling code will indicate that next buffer is ready
228+
219229}
0 commit comments