Skip to content

Instantly share code, notes, and snippets.

@PCJohn
Last active September 17, 2015 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PCJohn/700ae4572fdd0d7d354d to your computer and use it in GitHub Desktop.
Save PCJohn/700ae4572fdd0d7d354d to your computer and use it in GitHub Desktop.
Processing sketch for a music player
/*
A Processing sketch for an audio player with frequency visualization.
Authors: Prithvijit Chakrabarty (prithvichakra@gmail.com)
Kartik Lovekar (kslovekar@gmail.com)
*/
import ddf.minim.*;
import java.io.*;
import java.util.*;
Minim minim;
ddf.minim.AudioPlayer song;
AudioMetaData meta;
Play playButton;
Rewind rewind;
Forward ffwd;
long startTime = 0;
long endTime = 0;
ArrayList<String> filePaths = new ArrayList<String>();
boolean play = false;
int num = 0;
int numFiles = 0;
float position;
void setup()
{
size(500,500);
final File folder = new File("M:\\Music\\Sample Music\\MUSIC\\Queens of the Stone Age");
getFilePaths(folder);
playButton = new Play((width-width/25)/2, height-height/5, width/25, height/50);
rewind = new Rewind(width/2 - 71, height-height/5, width/25, height/50);
ffwd = new Forward(width/2 + 50, height-height/5, width/25, height/50);
minim = new Minim(this);
startTime = System.currentTimeMillis();
loadSong();
}
void draw()
{
background(0);
playButton.update();
playButton.draw();
rewind.update();
rewind.draw();
ffwd.update();
ffwd.draw();
if(play == true)
text("Now Playing: "+meta.author()+" - "+meta.title(),8,15);
else
text("Paused: "+meta.author()+" - "+meta.title(),8,15);
fill(255);
stroke(255);
line(0, 8*height/9, width, 8*height/9);
// sDrawing the waveform
for(int i = 0; i < song.bufferSize()-1; i++)
{
float x1 = map(i, 0, song.bufferSize(), 0, width);
float x2 = map(i+1, 0, song.bufferSize(), 0, width);
line(x1, height/5 + song.left.get(i)*height/10, x2, height/5 + song.left.get(i+1)*height/10);
line(x1, 2*height/5 + song.right.get(i)*height/10, x2, 2*height/5 + song.right.get(i+1)*height/10);
}
// Mapping position of the seek circle to song length
position = map(song.position(), 0, song.length(), 0, width);
ellipse(position, 8*height/9, 15, 15);
fill(255);
if(play == true)
endTime = System.currentTimeMillis();
// check if current track is over to load next track
if(endTime - startTime >= song.length() && !song.isPlaying() && play == true)
{
num++;
loadSong();
song.play();
play = true;
}
}
void keyPressed()
{
if(key == 'p')
{
if(!play)
{
song.play();
play = true;
//println(play);
}
else
{
song.pause();
play = false;
//println(play);
}
}
if(key == 'n') // to load next track
{
song.pause(); // pause current track
num++;
play = true;
loadSong();
song.play();
}
if(key == 'b') // to load previous track
{
song.pause(); // pause current track
num--;
play = true;
loadSong();
song.play();
}
}
// Fast forwards or rewinds when mouse is pressed
void mousePressed()
{
playButton.mousePressed();
rewind.mousePressed();
ffwd.mousePressed();
}
void mouseReleased()
{
playButton.mouseReleased();
rewind.mouseReleased();
ffwd.mouseReleased();
}
// loading file paths from specified directory
void getFilePaths(final File folder)
{
for(final File fileEntry : folder.listFiles())
{
if(fileEntry.isDirectory())
getFilePaths(fileEntry);
else
{
String path = fileEntry.getPath();
if(path.substring(path.length()-3,path.length()).equals("mp3"))
{
filePaths.add(path);
numFiles++;
}
}
}
}
void loadSong()
{
if(num == numFiles) // going back to the first track
num = 0;
if(num == -1)
num = 0;
startTime = System.currentTimeMillis();
song = minim.loadFile(filePaths.get(num));
meta = song.getMetaData();
position = map(song.position(), 0, song.length(), 0, width);
}
/*
Custom button classes
Authors: Prithvijit Chakrabarty (prithvichakra@gmail.com)
Kartik Lovekar (kslovekar@gmail.com)
*/
abstract class Button
{
int x, y, hw, hh;
Button(int x, int y, int hw, int hh)
{
this.x = x;
this.y = y;
this.hw = hw;
this.hh = hh;
}
boolean pressed()
{
return mouseX > x - hw && mouseX < x + hw && mouseY > y - hh && mouseY < y + hh;
}
abstract void mousePressed();
abstract void mouseReleased();
abstract void update();
abstract void draw();
}
class Play extends Button
{
boolean play;
boolean invert;
Play(int x, int y, int hw, int hh)
{
super(x, y, hw, hh);
play = true;
}
// code to handle playing and pausing the file
void mousePressed()
{
if ( pressed() )
{
invert = true;
if ( song.isPlaying() )
{
song.pause();
play = true;
}
else
{
song.play();
play = false;
}
}
}
void mouseReleased()
{
invert = false;
}
// play is a boolean value used to determine what to draw on the button
void update()
{
if ( song.isPlaying() ) play = false;
else play = true;
}
void draw()
{
if ( invert )
{
fill(255);
stroke(0);
}
else
{
noFill();
stroke(255);
}
rect(x - hw, y - hh, hw*2, hh*2);
if ( invert )
{
fill(0);
stroke(255);
}
else
{
fill(255);
noStroke();
}
if ( play )
{
triangle(x - hw/3, y - hh/2, x - hw/3, y + hh/2, x + hw/2, y);
}
else
{
rect(x - hw/3, y - hh/2, hw/4, hh);
rect(x + hw/8, y - hh/2, hw/4, hh);
}
}
}
class Rewind extends Button
{
boolean invert;
boolean pressed;
Rewind(int x, int y, int hw, int hh)
{
super(x, y, hw, hh);
invert = false;
}
// code used to scrub backward in the file
void update()
{
// if the rewind button is currently being pressed
if (pressed)
{
// get the current song position
int pos = song.position();
// if it greater than 255 milliseconds
if ( pos > 255 )
{
// rewind the song by 255 milliseconds
song.skip(-255);
}
else
{
// if the song hasn't played more than 100 milliseconds
// just rewind to the beginning
song.rewind();
}
}
}
void mousePressed()
{
pressed = pressed();
if ( pressed )
{
invert = true;
// if the song isn't currently playing, rewind it to the beginning
if ( !song.isPlaying() ) song.rewind();
}
}
void mouseReleased()
{
pressed = false;
invert = false;
}
void draw()
{
if ( invert )
{
fill(255);
stroke(0);
}
else
{
noFill();
stroke(255);
}
rect(x - hw, y - hh, hw*2, hh*2);
if ( invert )
{
fill(0);
stroke(255);
}
else
{
fill(255);
noStroke();
}
triangle(x - hw/2, y, x, y - hh/2, x, y + hh/2);
triangle(x, y, x + hw/2, y - hh/2, x + hw/2, y + hh/2);
}
}
class Forward extends Button
{
boolean invert;
boolean pressed;
Forward(int x, int y, int hw, int hh)
{
super(x, y, hw, hh);
invert = false;
}
void update()
{
// if the forward button is currently being pressed
if (pressed)
{
// get the current position of the song
int pos = song.position();
// if the song's position is more than 40 milliseconds from the end of the song
if ( pos < song.length() - 40 )
{
// forward the song by 40 milliseconds
song.skip(40);
}
else
{
// otherwise, cue the song at the end of the song
song.cue( song.length() );
}
// start the song playing
song.play();
}
}
void mousePressed()
{
pressed = pressed();
if ( pressed )
{
invert = true;
}
}
void mouseReleased()
{
pressed = false;
invert = false;
}
void draw()
{
if ( invert )
{
fill(255);
stroke(0);
}
else
{
noFill();
stroke(255);
}
rect(x - hw, y - hh, hw*2, hh*2);
if ( invert )
{
fill(0);
stroke(255);
}
else
{
fill(255);
noStroke();
}
triangle(x, y, x - hw/2, y - hh/2, x - hw/2, y + hh/2);
triangle(x, y - hh/2, x, y + hh/2, x + hw/2, y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment