Przeglądaj źródła

Update SpectrumAnalyzerBasic example

dds
PaulStoffregen 10 lat temu
rodzic
commit
9b923a1d35
1 zmienionych plików z 83 dodań i 81 usunięć
  1. +83
    -81
      examples/Analysis/SpectrumAnalyzerBasic/SpectrumAnalyzerBasic.ino

+ 83
- 81
examples/Analysis/SpectrumAnalyzerBasic/SpectrumAnalyzerBasic.ino Wyświetl plik

@@ -1,51 +1,64 @@
#include <LiquidCrystal.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>

//const int myInput = AUDIO_INPUT_LINEIN;
const int myInput = AUDIO_INPUT_MIC;
// 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

// Create the Audio components. These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
AudioInputI2S audioInput; // audio shield: mic or line-in
AudioAnalyzeFFT256 myFFT(11);
AudioOutputI2S audioOutput; // audio shield: headphones & line-out

// Create Audio connections between the components
//
AudioConnection c1(audioInput, 0, audioOutput, 0);
AudioConnection c2(audioInput, 0, myFFT, 0);
AudioConnection c3(audioInput, 1, audioOutput, 1);
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];


// Create an object to control the audio shield.
//
AudioControlSGTL5000 audioShield;

// 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};
byte bar3[8] = {0,0,0,0,0,255,255,255};
byte bar4[8] = {0,0,0,0,255,255,255,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 connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
// Audio requires memory to work.
AudioMemory(12);

// Enable the audio shield and set the output volume.
audioShield.enable();
audioShield.inputSelect(myInput);
audioShield.volume(0.6);
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);
@@ -57,83 +70,72 @@ void setup() {
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);
}

int count=0;

const int nsum[16] = {1, 1, 2, 2, 3, 4, 5, 6, 6, 8, 12, 14, 16, 20, 28, 24};

int maximum[16];

void loop() {
if (myFFT.available()) {
// convert the 128 FFT frequency bins
// to only 16 sums, for a 16 character LCD
int sum[16];
int i;
for (i=0; i<16; i++) {
sum[i] = 0;
}
int n=0;
int count=0;
for (i=0; i<128; i++) {
sum[n] = sum[n] + myFFT.output[i];
count = count + 1;
if (count >= nsum[n]) {
Serial.print(count);
Serial.print(" ");
n = n + 1;
if (n >= 16) break;
count = 0;
}
}

// The range is set by the audio shield's
// knob, which connects to analog pin A1.
int scale;
scale = 2 + (1023 - analogRead(A1)) / 7;
Serial.print(" - ");
Serial.print(scale);
Serial.print(" ");
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);

// 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++) {
// Reduce the range to 0-8
int val = sum[i] / scale;
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;

// Compute an animated maximum, where increases
// show instantly, but if the number is less that
// the last displayed value, decrease it by 1 for
// a slow decay (looks pretty)
if (val >= maximum[i]) {
maximum[i] = val;
if (val >= shown[i]) {
shown[i] = val;
} else {
if (maximum[i] > 0) maximum[i] = maximum[i] - 1;
if (shown[i] > 0) shown[i] = shown[i] - 1;
val = shown[i];
}

// a switch on pin 22 select whether we show the
// slower animation or the direct/fast data
if (digitalRead(21) == HIGH) {
val = maximum[i];
}
//Serial.print(shown[i]);
Serial.print(" ");

// print each custom digit
if (val == 0) {
if (shown[i] == 0) {
lcd.write(' ');
} else {
lcd.write(val - 1);
lcd.write(shown[i] - 1);
}
Serial.print(sum[i]);
Serial.print("=");
Serial.print(val);
Serial.print(",");
}
Serial.println();
count = 0;
Serial.print(" cpu:");
Serial.println(AudioProcessorUsageMax());
}
}


Ładowanie…
Anuluj
Zapisz