source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/libraries/Adafruit_CircuitPlayground/examples/Microphone/mic_meter/mic_meter.ino @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 2 years ago

Adding new version

File size: 6.6 KB
Line 
1// Audio level visualizer for Adafruit Circuit Playground: uses the
2// built-in mic on A4, 10x NeoPixels for display.  Like the FFT example,
3// the real work is done in the Circuit Playground library via the 'mic'
4// object; this code is almost entirely just dressing up the output with
5// a lot of averaging and scaling math and colors.
6
7#include <Adafruit_CircuitPlayground.h>
8#include <Wire.h>
9#include <SPI.h>
10
11// GLOBAL STUFF ------------------------------------------------------------
12
13// To keep the display 'lively,' an upper and lower range of volume
14// levels are dynamically adjusted based on recent audio history, and
15// the graph is fit into this range.
16#define  FRAMES 8
17uint16_t lvl[FRAMES],           // Audio level for the prior #FRAMES frames
18         avgLo  = 6,            // Audio volume lower end of range
19         avgHi  = 512,          // Audio volume upper end of range
20         sum    = 256 * FRAMES; // Sum of lvl[] array
21uint8_t  lvlIdx = 0;            // Counter into lvl[] array
22int16_t  peak   = 0;            // Falling dot shows recent max
23int8_t   peakV  = 0;            // Velocity of peak dot
24
25// SETUP FUNCTION - runs once ----------------------------------------------
26
27void setup() {
28  CircuitPlayground.begin();
29  CircuitPlayground.setBrightness(255);
30  CircuitPlayground.clearPixels();
31
32  for(uint8_t i=0; i<FRAMES; i++) lvl[i] = 256;
33}
34
35// COLOR TABLES for animation ----------------------------------------------
36
37const uint8_t PROGMEM
38  reds[]   = { 0x9A, 0x75, 0x00, 0x00, 0x00, 0x65, 0x84, 0x9A, 0xAD, 0xAD },
39  greens[] = { 0x00, 0x00, 0x00, 0x87, 0xB1, 0x9E, 0x87, 0x66, 0x00, 0x00 },
40  blues[]  = { 0x95, 0xD5, 0xFF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
41  gamma8[] = { // Gamma correction improves the appearance of midrange colors
42    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
45    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
46    0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06,
47    0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
48    0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0E,
49    0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
50    0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1B,
51    0x1B, 0x1C, 0x1D, 0x1D, 0x1E, 0x1F, 0x1F, 0x20, 0x21, 0x22, 0x22, 0x23,
52    0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2A, 0x2B, 0x2C, 0x2D,
53    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
54    0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x44, 0x45, 0x46,
55    0x47, 0x48, 0x49, 0x4B, 0x4C, 0x4D, 0x4E, 0x50, 0x51, 0x52, 0x54, 0x55,
56    0x56, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x66,
57    0x67, 0x69, 0x6A, 0x6C, 0x6D, 0x6F, 0x70, 0x72, 0x73, 0x75, 0x77, 0x78,
58    0x7A, 0x7C, 0x7D, 0x7F, 0x81, 0x82, 0x84, 0x86, 0x88, 0x89, 0x8B, 0x8D,
59    0x8F, 0x91, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4,
60    0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC,
61    0xBF, 0xC1, 0xC3, 0xC5, 0xC7, 0xCA, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD7,
62    0xDA, 0xDC, 0xDF, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xED, 0xF0, 0xF2, 0xF5,
63    0xF7, 0xFA, 0xFC, 0xFF };
64
65// LOOP FUNCTION - runs over and over - does animation ---------------------
66
67void loop() {
68  uint8_t  i, r, g, b;
69  uint16_t minLvl, maxLvl, a, scaled;
70
71  a           = CircuitPlayground.mic.peak(10); // 10 ms of audio
72  sum        -= lvl[lvlIdx];
73  lvl[lvlIdx] = a;
74  sum        += a;                              // Sum of lvl[] array
75  minLvl = maxLvl = lvl[0];                     // Calc min, max of lvl[]...
76  for(i=1; i<FRAMES; i++) {
77    if(lvl[i] < minLvl)      minLvl = lvl[i];
78    else if(lvl[i] > maxLvl) maxLvl = lvl[i];
79  }
80
81  // Keep some minimum distance between min & max levels,
82  // else the display gets "jumpy."
83  if((maxLvl - minLvl) < 40) {
84    maxLvl = (minLvl < (512-40)) ? minLvl + 40 : 512;
85  }
86  avgLo = (avgLo * 7 + minLvl + 2) / 8; // Dampen min/max levels
87  avgHi = (maxLvl >= avgHi) ?           // (fake rolling averages)
88    (avgHi *  3 + maxLvl + 1) /  4 :    // Fast rise
89    (avgHi * 31 + maxLvl + 8) / 32;     // Slow decay
90
91  a = sum / FRAMES; // Average of lvl[] array
92  if(a <= avgLo) {  // Below min?
93    scaled = 0;     // Bargraph = zero
94  } else {          // Else scale to fixed-point coordspace 0-2560
95    scaled = 2560L * (a - avgLo) / (avgHi - avgLo);
96    if(scaled > 2560) scaled = 2560;
97  }
98  if(scaled >= peak) {            // New peak
99    peakV = (scaled - peak) / 4;  // Give it an upward nudge
100    peak  = scaled;
101  }
102
103  uint8_t  whole  = scaled / 256,    // Full-brightness pixels (0-10)
104           frac   = scaled & 255;    // Brightness of fractional pixel
105  int      whole2 = peak / 256,      // Index of peak pixel
106           frac2  = peak & 255;      // Between-pixels position of peak
107  uint16_t a1, a2;                   // Scaling factors for color blending
108
109  for(i=0; i<10; i++) {              // For each NeoPixel...
110    if(i <= whole) {                 // In currently-lit area?
111      r = pgm_read_byte(&reds[i]),   // Look up pixel color
112      g = pgm_read_byte(&greens[i]),
113      b = pgm_read_byte(&blues[i]);
114      if(i == whole) {               // Fraction pixel at top of range?
115        a1 = (uint16_t)frac + 1;     // Fade toward black
116        r  = (r * a1) >> 8;
117        g  = (g * a1) >> 8;
118        b  = (b * a1) >> 8;
119      }
120    } else {
121      r = g = b = 0;                 // In unlit area
122    }
123    // Composite the peak pixel atop whatever else is happening...
124    if(i == whole2) {                // Peak pixel?
125      a1 = 256 - frac2;              // Existing pixel blend factor 1-256
126      a2 = frac2 + 1;                // Peak pixel blend factor 1-256
127      r  = ((r * a1) + (0x84 * a2)) >> 8; // Will
128      g  = ((g * a1) + (0x87 * a2)) >> 8; // it
129      b  = ((b * a1) + (0xC3 * a2)) >> 8; // blend?
130    } else if(i == (whole2-1)) {     // Just below peak pixel
131      a1 = frac2 + 1;                // Opposite blend ratios to above,
132      a2 = 256 - frac2;              // but same idea
133      r  = ((r * a1) + (0x84 * a2)) >> 8;
134      g  = ((g * a1) + (0x87 * a2)) >> 8;
135      b  = ((b * a1) + (0xC3 * a2)) >> 8;
136    }
137    CircuitPlayground.strip.setPixelColor(i,
138      pgm_read_byte(&gamma8[r]),
139      pgm_read_byte(&gamma8[g]),
140      pgm_read_byte(&gamma8[b]));
141  }
142  CircuitPlayground.strip.show();
143
144  peak += peakV;
145  if(peak <= 0) {
146    peak  = 0;
147    peakV = 0;
148  } else if(peakV >= -126) {
149    peakV -= 2;
150  }
151
152  if(++lvlIdx >= FRAMES) lvlIdx = 0;
153}
Note: See TracBrowser for help on using the repository browser.