diff options
Diffstat (limited to 'TSITOplayer/TSITOplayer.pde')
| -rw-r--r-- | TSITOplayer/TSITOplayer.pde | 218 |
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); +} + + + |
