Spotify is boring. There's no interesting visuals to look at or bright flashing colors. Not to mention the outlandish prices that they are charging for premium! I fixed this problem by creating my own version of spotify which using the java processing library to display the beat and pulse of the music. The best part is it is free for me to use.
import ddf.minim.*;
import processing.core.PApplet;
import ddf.minim.analysis.FFT;
import processing.core.PImage;
public class MusicVisualizer extends PApplet {
private int xCenter;
private int yCenter;
private Minim minim;
private AudioPlayer audio;
private FFT fft;
private final int blue = color(0, 0, 255);
private final int red = color(255, 0, 0);
private final int green = color(0, 255, 0);
private boolean isPaused;
private PImage playButton;
private PImage pauseButton;
private int[] pauseCoordinates = {20, 20};
int count = 0;
AudioPlayer[] player = new AudioPlayer[3];
String[] songs = {"resources/windows.mp3", "resources/song.mp3","resources/song.mp3"};
public static void main(String[] args) {
PApplet.main("MusicVisualizer");
}
public void settings() {
size(1000, 500);
}
public void setup() {
playButton = loadImage("play.png");
pauseButton = loadImage("pause.png");
background(0);
isPaused = false;
yCenter = height / 2;
xCenter = width /2;
count = 0;
minim = new Minim(this);
audio = minim.loadFile(songs[count]);
fft = new FFT(audio.bufferSize(), audio.sampleRate());
audio.play();
}
public void draw() {
background(0);
drawButtons();
//convert each channel into array
float[] leftChannel = audio.left.toArray();
float[] rightChannel = audio.right.toArray();
//increment fft
fft.forward(audio.mix);
// loop through every sample
for (int i = 0; i < leftChannel.length - 1; i++) {
drawChannel(leftChannel, i, -1, blue);
drawChannel(rightChannel, i, 1, red);
}
for (int i =0; i <fft.specSize(); i++){
drawFrequency(i);
}
if (!isPaused && !audio.isPlaying()){
count ++;
System.out.println(count);
if (count >= songs.length){
count = 0;
}
audio = minim.loadFile(songs[count]);
fft = new FFT(audio.bufferSize(), audio.sampleRate());
audio.play();
}
}
public void drawChannel(float[] channel, int index, int direction, int color) {
strokeWeight(3);
for (int i = 1; i <= 3; i++){
stroke(color, (float) 100 / sq(i));
//draw a short line representing channel at specific index
line(index,
yCenter + (direction * abs(channel[index] * (200 * sq(i)))),
index + 1,
yCenter + (direction * abs(channel[index + 1] * (200 * sq(i)))));
}
}
private void drawFrequency(int index){
stroke(255, 0);
for (int i = 1; i <= 3; i++){
fill(green, (float) 100/sq(i));
circle(xCenter, yCenter, fft.getBand(index) * (3*sq(i)));
}
circle(xCenter, yCenter, fft.getBand(index)*3);
}
private void drawButtons(){
if (mouseOver(pauseCoordinates[0], pauseCoordinates[1], pauseButton.width, pauseButton.height)){
tint(255, 175);
}else{
tint(255, 255);
}
if (isPaused) {
image(playButton, pauseCoordinates[0], pauseCoordinates[1]);
} else {
image(pauseButton, pauseCoordinates[0], pauseCoordinates[1]);
}
}
private boolean mouseOver(int x, int y, int width, int height){
if (mouseX > x && mouseX <(x+width) && mouseY > y && mouseY < (y+height)){
return true;
}else{
return false;
}
}
public void mouseClicked(){
if (mouseOver (pauseCoordinates[0],
pauseCoordinates[1],
pauseButton.width,
pauseButton.height)) {
togglePause();
}
}
private void togglePause(){
isPaused = !isPaused;
if (isPaused){
audio.pause();
}else{
audio.play();
}
}
}