|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #include <LiquidCrystal.h>
- #include <Audio.h>
- #include <Wire.h>
- #include <SPI.h>
- #include <SD.h>
- #include <SerialFlash.h>
-
- // GUItool: begin automatically generated code
- AudioInputI2S i2s1; //xy=139,91
- AudioMixer4 mixer1; //xy=312,134
- AudioOutputI2S i2s2; //xy=392,32
- AudioAnalyzeFFT1024 fft1024; //xy=467,147
- AudioConnection patchCord1(i2s1, 0, mixer1, 0);
- AudioConnection patchCord2(i2s1, 0, i2s2, 0);
- AudioConnection patchCord3(i2s1, 1, mixer1, 1);
- AudioConnection patchCord4(i2s1, 1, i2s2, 1);
- AudioConnection patchCord5(mixer1, fft1024);
- AudioControlSGTL5000 audioShield; //xy=366,225
- // GUItool: end automatically generated code
-
-
- const int myInput = AUDIO_INPUT_LINEIN;
- //const int myInput = AUDIO_INPUT_MIC;
-
-
- // The scale sets how much sound is needed in each frequency range to
- // show all 8 bars. Higher numbers are more sensitive.
- float scale = 60.0;
-
- // An array to hold the 16 frequency bands
- float level[16];
-
- // This array holds the on-screen levels. When the signal drops quickly,
- // these are used to lower the on-screen level 1 bar per update, which
- // looks more pleasing to corresponds to human sound perception.
- int shown[16];
-
-
-
- // Use the LiquidCrystal library to display the spectrum
- //
- LiquidCrystal lcd(0, 1, 2, 3, 4, 5);
- byte bar1[8] = {0,0,0,0,0,0,0,255};
- byte bar2[8] = {0,0,0,0,0,0,255,255}; // 8 bar graph
- byte bar3[8] = {0,0,0,0,0,255,255,255}; // custom
- byte bar4[8] = {0,0,0,0,255,255,255,255}; // characters
- byte bar5[8] = {0,0,0,255,255,255,255,255};
- byte bar6[8] = {0,0,255,255,255,255,255,255};
- byte bar7[8] = {0,255,255,255,255,255,255,255};
- byte bar8[8] = {255,255,255,255,255,255,255,255};
-
-
- void setup() {
- // Audio requires memory to work.
- AudioMemory(12);
-
- // Enable the audio shield and set the output volume.
- audioShield.enable();
- audioShield.inputSelect(myInput);
- audioShield.volume(0.5);
-
- // turn on the LCD and define the custom characters
- lcd.begin(16, 2);
- lcd.print("Audio Spectrum");
- lcd.createChar(0, bar1);
- lcd.createChar(1, bar2);
- lcd.createChar(2, bar3);
- lcd.createChar(3, bar4);
- lcd.createChar(4, bar5);
- lcd.createChar(5, bar6);
- lcd.createChar(6, bar7);
- lcd.createChar(7, bar8);
-
- // configure the mixer to equally add left & right
- mixer1.gain(0, 0.5);
- mixer1.gain(1, 0.5);
-
- // pin 21 will select rapid vs animated display
- pinMode(21, INPUT_PULLUP);
- }
-
-
- void loop() {
- if (fft1024.available()) {
- // read the 512 FFT frequencies into 16 levels
- // music is heard in octaves, but the FFT data
- // is linear, so for the higher octaves, read
- // many FFT bins together.
- level[0] = fft1024.read(0);
- level[1] = fft1024.read(1);
- level[2] = fft1024.read(2, 3);
- level[3] = fft1024.read(4, 6);
- level[4] = fft1024.read(7, 10);
- level[5] = fft1024.read(11, 15);
- level[6] = fft1024.read(16, 22);
- level[7] = fft1024.read(23, 32);
- level[8] = fft1024.read(33, 46);
- level[9] = fft1024.read(47, 66);
- level[10] = fft1024.read(67, 93);
- level[11] = fft1024.read(94, 131);
- level[12] = fft1024.read(132, 184);
- level[13] = fft1024.read(185, 257);
- level[14] = fft1024.read(258, 359);
- level[15] = fft1024.read(360, 511);
- // See this conversation to change this to more or less than 16 log-scaled bands?
- // https://forum.pjrc.com/threads/32677-Is-there-a-logarithmic-function-for-FFT-bin-selection-for-any-given-of-bands
-
- // if you have the volume pot soldered to your audio shield
- // uncomment this line to make it adjust the full scale signal
- //scale = 8.0 + analogRead(A1) / 5.0;
-
- // begin drawing at the first character on the 2nd row
- lcd.setCursor(0, 1);
-
- for (int i=0; i<16; i++) {
- Serial.print(level[i]);
-
- // TODO: conversion from FFT data to display bars should be
- // exponentially scaled. But how keep it a simple example?
- int val = level[i] * scale;
- if (val > 8) val = 8;
-
- if (val >= shown[i]) {
- shown[i] = val;
- } else {
- if (shown[i] > 0) shown[i] = shown[i] - 1;
- val = shown[i];
- }
-
- //Serial.print(shown[i]);
- Serial.print(" ");
-
- // print each custom digit
- if (shown[i] == 0) {
- lcd.write(' ');
- } else {
- lcd.write(shown[i] - 1);
- }
- }
- Serial.print(" cpu:");
- Serial.println(AudioProcessorUsageMax());
- }
- }
-
-
|