Skip to content

Instantly share code, notes, and snippets.

@hizkifw
Last active November 25, 2018 06:13
Show Gist options
  • Save hizkifw/e86e9036b05485646e8faed95008c07d to your computer and use it in GitHub Desktop.
Save hizkifw/e86e9036b05485646e8faed95008c07d to your computer and use it in GitHub Desktop.
Audio analyzer/visualizer written in Processing.
import processing.sound.*;
FFT fft;
Amplitude amp;
AudioIn ain;
// Circle settings
float min_size = 200;
float threshold = 0.1;
int bass_range = 5;
int scale = 1,
bands = 128,
b_mult = 8;
float r_width;
float[] spectr = new float[bands*b_mult];
float ave;
float smooth_factor = .2;
Background bg;
void setup() {
// replace with fullScreen() to go fullscreen
size(1280, 720, P2D);
//fullScreen();
smooth();
frameRate(60);
colorMode(RGB, 1.0f);
//fullScreen();
r_width = width/float(bands);
ain = new AudioIn(this, 0);
ain.start();
fft = new FFT(this, bands*b_mult);
fft.input(ain);
amp = new Amplitude(this);
amp.input(ain);
bg = new Background();
bg.overlays.add(new SnowOverlay());
}
float circle_size = 0;
int size_increasing = 0;
void draw() {
background(0);
//bg.drawBackground();
fill(1);
fft.analyze(spectr);
for(int i = 0; i < bands-1; i++) {
int j = i; // * b_mult;
// Smooth FFT data
spectr[j] += (fft.spectrum[j] - spectr[j]) * smooth_factor;
// Draw FFT
//rect(i*r_width, height, r_width, -spectr[j]*height*scale);
stroke(1);
strokeWeight(1);
line(i*r_width, (spectr[i])*height*scale, (i+1)*r_width, (spectr[i+1])*height*scale);
//text(i, i*r_width, 10+(10*(i%4)));
}
// Bass avg amplitude
int divisor = bass_range + 2; // +2 because one is to divide the average and the other one to keep it going down
for(int i = 0; i < bass_range; i++) {
if(spectr[i] > threshold)
ave += spectr[i];
else
divisor--;
//ave += (spectr[i] > threshold ? spectr[i] : 0);
}
ave /= divisor;
if(ave > circle_size) {
circle_size = (circle_size + ave*3) / 4;
size_increasing = 2;
} else {
if(size_increasing > 0)
size_increasing--;
else
circle_size *= .9;
}
//text(circle_size, 10, 10);
fill(color(0xffffff, 0.05f));
//ellipse(width/2, height/2, circle_size*height*scale+min_size, circle_size*height*scale+min_size);
bg.update();
bg.draw();
}
class Background {
public ArrayList<Overlay> overlays;
public PImage wallpaper;
public Background() {
overlays = new ArrayList<Overlay>();
//wallpaper = loadImage("D:/Processing/audiovis1/wallpapers/default.jpg");
}
public void update() {
for(int i = 0; i < overlays.size(); i++) {
overlays.get(i).update();
}
}
public void drawBackground() {
//image(wallpaper, 0, 0, width, height);
background(0);
}
public void draw() {
for(int i = 0; i < overlays.size(); i++) {
overlays.get(i).draw();
}
}
}
public interface Overlay {
public void update();
public void draw();
}
class SnowOverlay implements Overlay {
private ArrayList<Snowflake> snowflakes;
private int fallInterval = 4; // update()s per snowflake
private int lastFall = 0;
private float speedMultiplier = 0.03;
public SnowOverlay() {
// Generates falling snow
snowflakes = new ArrayList<Snowflake>();
}
public void update() {
if(lastFall == 0) {
snowflakes.add(new Snowflake(speedMultiplier));
lastFall = fallInterval;
} else lastFall--;
for(int i = 0; i < snowflakes.size(); i++) {
if(snowflakes.get(i).y > height)
snowflakes.remove(i);
else
snowflakes.get(i).update();
}
}
public void draw() {
for(int i = 0; i < snowflakes.size(); i++) {
snowflakes.get(i).draw();
}
}
private class Snowflake {
public float x;
public float y;
public float vx;
public float vy;
public float fallSpeed;
public Snowflake(float _fallSpeed) {
this.fallSpeed = _fallSpeed;
x = random(0, width);
y = 0;
vx = random(-5, 5);
vy = random(10, 50) * this.fallSpeed;
}
public void update() {
x += vx;
y += vy;
}
public void draw() {
noStroke();
for(float i = 10; i > 0; i--) {
fill(color(0xffffff, (10-i)/100f));
ellipse(x, y, ((i+1)/11.0f)*(vy/fallSpeed)/2, ((i+1)/11.0f)*(vy/fallSpeed)/2);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment