Visualise music with leds
This example shows how to make an audio level meter with a set of ten LEDs.
- Connect an LED in series with a 470ohm resistor between every Digital pin 0 - 9 and ground.
You will also need to connect an audio adapter to the audio input pins and connect something that can produce an audio signal to this (a laptop, mp3 player, phone or keyboard). The code preforms peak detection on the audio input and lights the LEDs once the amplitude of the input signal passes a certain threshold stored in gThresholds[i]
. Each LED has its own threshold, the values of which are set in setup()
and are steps of -3dB. All digital pins are set to output pinMode(context, 0, i, OUTPUT);
and they are toggled on and off in render()
when the amplitude passes the threshold for that LED. The LEDs below the current peak value always remain lit to create a classic amplitude peak meter. The audio input is passed through to the output so you can listen as you watch the light show.
#include <cmath>
#include <algorithm>
#define NUMBER_OF_SEGMENTS 10
unsigned int gAudioChannelNum;
float gAudioLocalLevel = 0, gAudioPeakLevel = 0;
float gLocalDecayRate = 0.99, gPeakDecayRate = 0.999;
float gThresholds[NUMBER_OF_SEGMENTS + 1];
int gSamplesToLight[NUMBER_OF_SEGMENTS];
float gLastX[2] = {0};
float gLastY[2] = {0};
double gB0 = 0.99949640;
double gB1 = -1.99899280;
double gB2 = gB0;
double gA1 = -1.99899254;
double gA2 = 0.99899305;
{
rt_printf("Error: this project needs the audio and digital sample rates to be the same.\n");
return false;
}
for(int i = 0; i < NUMBER_OF_SEGMENTS + 1; i++) {
gThresholds[i] = powf(10.0f, (-1.0 * (NUMBER_OF_SEGMENTS - i)) * .05);
}
for(int i = 0; i < NUMBER_OF_SEGMENTS; i++) {
gSamplesToLight[i] = 0;
}
return true;
}
{
for(
unsigned int n = 0; n < context->
audioFrames; n++) {
float sample = 0;
}
for(unsigned int ch = 0; ch < gAudioChannelNum; ch++)
float out = gB0 * sample + gB1 * gLastX[0] + gB2 * gLastX[1]
- gA1 * gLastY[0] - gA2 * gLastY[1];
gLastX[1] = gLastX[0];
gLastX[0] = sample;
gLastY[1] = gLastY[0];
gLastY[0] = out;
out = fabsf(out / (float)gAudioChannelNum);
if(out > gAudioLocalLevel)
gAudioLocalLevel = out;
else
gAudioLocalLevel *= gLocalDecayRate;
if(out > gAudioPeakLevel)
gAudioPeakLevel = out;
else {
gAudioPeakLevel *= gPeakDecayRate;
}
for(int led = 0; led < NUMBER_OF_SEGMENTS; led++) {
int state = LOW;
if(gAudioLocalLevel > gThresholds[led]) {
state = HIGH;
gSamplesToLight[led] = 1000;
}
else if(--gSamplesToLight[led] > 0)
state = HIGH;
}
}
}
{
}