summaryrefslogtreecommitdiff
path: root/TSITOplayer/TSITOplayer.pde
diff options
context:
space:
mode:
Diffstat (limited to 'TSITOplayer/TSITOplayer.pde')
-rw-r--r--TSITOplayer/TSITOplayer.pde218
1 files changed, 218 insertions, 0 deletions
diff --git a/TSITOplayer/TSITOplayer.pde b/TSITOplayer/TSITOplayer.pde
new file mode 100644
index 0000000..1de0862
--- /dev/null
+++ b/TSITOplayer/TSITOplayer.pde
@@ -0,0 +1,218 @@
+//pixelstick image generator
+//
+//pixelstick playing at 20fps, 400 pixel frame makes a 20 second shot
+//200 pixels height
+//notes 36-45 velocities 3-122
+//notes vary by 9
+//multiply notes movement by 9 = 81
+//add 60
+
+
+import java.io.File;
+import ddf.minim.*;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+import java.util.Iterator;
+import java.util.Map;
+
+Table table;
+
+String audioFileName = "The Son is the One.mp3";
+int NOTE_LOW = 36, NOTE_HIGH = 45;
+
+int[] notes=new int[NOTE_HIGH+1];
+int[] oldnotes=new int[NOTE_HIGH+1];
+color[] cols={#FF0000,#FF00BF,#8000FF,#013ADF,#00FFFF,#00FF40,#80FF00,#FFFF00,#FF8000};
+
+int NOTE_SCALE=12,NOTE_OFFSET=60;
+
+Minim minim;
+AudioPlayer audioPlayer;
+
+int pw,ph;
+
+int ln=200, hn=0, lv= 200, hv=0;
+
+boolean loaded=false;
+
+PImage sc;
+
+class Event {
+ int pitch;
+ int velocity;
+ Event(int p,int v){
+ pitch=p;
+ velocity=v;
+ }
+}
+//NavigableMap<int, ArrayList<event>> events = new NavigableMap<int, ArrayList>();
+NavigableMap events= new TreeMap();
+Iterator iterator;
+ArrayList eventlist;
+int startTime;
+int noteTime=0;
+
+void setup(){
+ size(400, 200);
+ sc=createImage(width,height,RGB);
+
+
+ table= loadTable("TSITO.csv", "header");
+ println(table.getRowCount() + " total rows in table");
+ for (TableRow row : table.rows()) {
+
+
+ int pitch = row.getInt("pitch");
+ int velocity = row.getInt("velocity");
+ String event = row.getString("event");
+ int time = (int)(row.getInt("time")*0.55309734513274); //tick to ms
+ if (event.equals("Note_on_c")||event.equals("Note_off_c")){
+ ArrayList templist;
+ if (!events.containsKey(time)){
+ templist=new ArrayList();
+ }
+ else templist=(ArrayList)events.get(time);
+ templist.add(new Event(pitch,velocity));
+ events.put(time,templist);
+ }
+
+
+ //println(event + " " + time+","+pitch);
+ }
+ println("stored "+events.size()+" note events");
+
+ for (int i=NOTE_LOW;i<NOTE_HIGH;i++){
+ notes[i]=0;
+ oldnotes[i]=0;
+ }
+
+
+
+ //load audio file
+ minim = new Minim(this);
+ audioPlayer = minim.loadFile(audioFileName, 2048);
+ audioPlayer.play();
+ //audioPlayer.loop(9999999);
+ //audioPlayer is started when midi sequencer is started
+ startTime =millis();
+
+ iterator = events.keySet().iterator();
+ if(iterator.hasNext()){
+ noteTime = (Integer)iterator.next();
+ eventlist=(ArrayList)events.get(noteTime);
+ println("first event at time "+noteTime+" (time now "+millis()+")");
+ }
+
+ //the default tempo is 120 beats/minute, which is equivalent to tttttt=500000
+ //<delta_time>
+ //is the number of 'ticks' from the previous event
+ //and is represented as a variable length quantity
+ /*
+The formula is 60000 / (BPM * PPQ) (milliseconds).
+
+Where BPM is the tempo of the track (Beats Per Minute).
+
+(i.e. a 120 BPM track would have a MIDI time of (60000 / (120 * 192)) or 2.604 ms for 1 tick.
+*/
+
+//tempo = 530973
+//bpm = 127.43352
+//ms per tick= 60000 / (113 * 192) ms
+//2.765486725663717 ms per tick
+/*
+
+apparently logic is 960 ppq (hearsay)
+
+ms per tick = 60000 / (113 * 960) = 0.55309734513274
+
+
+strategy:
+create a data structure of events with time in ms
+AT EVERY FRAME
+check for a new event that has just passed
+turn on/off notes as necessary
+
+map data structure?
+given a time in millis, need to be able to find note with biggest time less than this time
+*/
+
+ background(0);
+ rectMode(CORNER);
+ //noStroke();
+ colorMode(RGB, 255);
+
+ frameRate(50);
+
+}
+
+void draw(){
+
+
+ loadPixels();
+ for (int x=1;x<width-2;x+=2){
+ for (int y=0;y<height;y++){
+ pixels[(y*width)+x]=pixels[(y*width)+x+2];
+ pixels[(y*width)+x+1]=pixels[(y*width)+x+2];
+ }
+ }
+
+ for (int y=0;y<height;y++){
+ pixels[(y*width)+(width-1)]=color(#000000);
+ }
+
+ int trackTime=millis()-startTime;
+ if (noteTime<trackTime){
+ eventlist=(ArrayList)events.get(noteTime);
+ for (Event e : (ArrayList<Event>)eventlist){
+ notes[e.pitch]=e.velocity;
+ //println(e.velocity+" "+noteTime+" "+e.pitch+" (time now "+trackTime+")");
+ }
+ if(iterator.hasNext()){
+ noteTime = (Integer)iterator.next();
+ }
+ }
+
+ NavigableMap laternotes = events.tailMap(millis(), true);
+ //println(laternotes.size()+" notes after "+millis());
+
+
+ for(int i = NOTE_LOW; i < NOTE_HIGH; i++){
+ int notecentre=((i-NOTE_LOW)*NOTE_SCALE)+NOTE_OFFSET;
+ if (notes[i]!=oldnotes[i]){
+ if (notes[i]>0) {
+ //println("startnote "+i);
+ }
+ else {
+ //println("stopnote "+i);
+ }
+ for (int j=notecentre-(NOTE_SCALE*2);j<=notecentre+(NOTE_SCALE*2);j++){
+ pixels[(j*width)+(width-1)]=cols[i-NOTE_LOW];
+ }
+ }
+ else if (notes[i]>0){
+ //println("note "+i);
+ pixels[((notecentre-(NOTE_SCALE*2))*width)+(width-1)]=cols[i-NOTE_LOW];
+ pixels[((notecentre+(NOTE_SCALE*2))*width)+(width-1)]=cols[i-NOTE_LOW];
+ }
+ oldnotes[i]=notes[i];
+ }
+
+ updatePixels();
+
+ //saveFrame("frames/img####.png");
+ if (!audioPlayer.isPlaying()) {
+ println("notes "+ln+"-"+hn+" velocities "+lv+"-"+hv);
+ exit();
+ }
+}
+
+//change rate of drop?
+//veering??
+
+
+void keyPressed() {
+ println("notes "+ln+"-"+hn+" velocities "+lv+"-"+hv);
+}
+
+
+