Main Sketch
import themidibus.*;
import java.util.*;
MidiBus bus;
NoteManager nm;
void setup() {
size(700, 700);
background(0);
MidiBus.list();
bus = new MidiBus(this, 1, 2);
nm = new NoteManager();
}
void draw() {
background(0);
nm.track();
}
void noteOn(int channel, int pitch, int velocity) {
nm.addNote(new Note(channel, pitch, velocity));
println("Note On: "+channel, +pitch, +velocity);
}
void noteOff(int channel, int pitch, int velocity) {
nm.releaseNote(new Note(channel, pitch, velocity));
println("Note Off: " +channel, +pitch, +velocity);
}
Class Definition Note
// Note class handles attributes that all played notes share
class Note {
int channel, velocity, pitch; // store the channel, velocity and pitch
int lifespan; // lifespan of note, in frames
boolean isReleased; // whether or not the note has been released yet
float x, y;
float size;
// constructor for new Note object
Note(int channel_, int pitch_, int velocity_) {
this.channel = channel_;
this.pitch = pitch_;
this.velocity = velocity_;
this.lifespan = 30;
this.isReleased = false;
this.x = map(pitch, 48, 109, 0, width);
this.y = height/2;
this.size = map(velocity, 0, 127, 5, 100);
}
void display() {
if (this.pitch == 30) {
fill(50);
ellipse(this.x, this.y, this.size, this.size);
}
}
// update note properties
void update() {
}
// display note on canvas
// NoteManager class manages the tracking of MIDI notes, as played live
class NoteManager {
public HashSet notes = new HashSet(); // all note objects currently being tracked
private HashSet notesToAdd = new HashSet(); // notes to add to the list of tracked notes
private HashSet release = new HashSet(); // notes that will be released on this iteration of the draw() loop
private HashSet notesToRelease = new HashSet(); // notes waiting for the next iteration of draw() to be released
// construct a new NoteManager object
public NoteManager() {
}
// add a new note to tracked notes
void addNote(Note n) {
// add note to list of notes that will be tracked in the next iteration of draw()
notesToAdd.add(n);
}
// remove a note from tracked notes
void releaseNote(Note n) {
// add note to list of notes that will be released in the next iteration of draw()
notesToRelease.add(n);
}
// add new notes to tracked notens, remove old notes from tracked notes
void track() {
this.release.addAll(this.notesToRelease); // add every note waiting to be released to list of notes about to be released
this.notesToRelease.clear(); // remove everything from list of notes waiting to be released
// for each note that needs to be released
for (Note n : this.release) {
// find its counterpart in the tracked notes array
for (Note m : this.notes) {
if (n.channel == m.channel && n.pitch == m.pitch) {
m.isReleased = true; // record that this note is now released
}
}
}
this.release.clear(); // remove everything from the list of notes to remove
this.notes.addAll(this.notesToAdd); // add every note waiting to be kept track of
this.notesToAdd.clear(); // remove everything from list of notes waiting to be tracked
// iterate through all notes currently being tracked
Iterator<Note> iter = this.notes.iterator();
while (iter.hasNext()) {
Note n = iter.next();
// if note has been released, decrement lifespan
if (n.isReleased) {
n.lifespan--;
}
// update and display each note
n.update();
n.display();
// if a note is finished, remove from tracked notes
if (n.lifespan <= 0) {
iter.remove();
}
}
}
}
The basis of the program is by Thomas Castleman.
`