andrew@50: andrew@50: andrew@50: void setup(){ andrew@50: markovStuff(); andrew@50: for (int i = 0; i < 16; i++) andrew@50: VPA[i] = new VPArray(); // creates the virtual playing array for Heresy AI. andrew@50: for (int i = 0; i < noteOnArray.length; i++) andrew@50: noteOnArray[i] = false; // makes sure there are initial random inputs from openFrameworks andrew@50: andrew@50: oscP5return = new OscP5(this,12346); andrew@50: andrew@50: frameRate(tempo); andrew@50: img = createGraphics(imageWidth,imageHeight,P2D); andrew@50: size(800,imageHeight,P2D); andrew@50: arial = createFont("Arial",32); andrew@50: textFont(arial,15); andrew@50: andrew@50: // initialize the tracks andrew@50: andrew@50: tracks[0] = new Track("Chord track", true, grid * beatsPerBar, 8, true, true); andrew@50: tracks[1] = new Track("Drums", true, grid * beatsPerBar, 8, false, true); andrew@50: tracks[2] = new Track("Bass", true, grid * beatsPerBar, 8, false, true); andrew@50: tracks[3] = new Track("Pizz Strings", true, grid * beatsPerBar, 8, false, true); andrew@50: tracks[4] = new Track("Synth", true, grid * beatsPerBar, 8, false, true); andrew@50: tracks[5] = new Track("Voice", true, grid * beatsPerBar, 8, false, true); andrew@50: tracks[6] = new Track("Voice", true, grid * beatsPerBar, 8, false, true); andrew@50: chordsTemp = new Track("Chord track", true, loopLength, 8, true, false); andrew@50: trSelected = 1; andrew@50: backgroundColour(); andrew@50: drawLines(); andrew@50: drawBarLines(); andrew@50: imgNoteFan = createGraphics(fanWidth,imageHeight,P2D); andrew@50: lastTrack = trSelected; andrew@50: clickTrackOn = true; andrew@50: // loadSequences(); andrew@50: // tracks[2].sequence[15][16] = new NoteEvent (14, 2, bar,beat,fraction,pulse); andrew@50: // tracks[2].sequence[15][grid * beatsPerBar -20] = new NoteEvent (14, 2, bar,beat,fraction,pulse, true); andrew@50: andrew@50: // tracks[3].sequence[13][16] = new NoteEvent (13, 3, bar,beat,fraction,pulse); andrew@50: // tracks[3].sequence[13][20] = new NoteEvent (13, 3, bar,beat,fraction,pulse, true); andrew@50: // tracks[3].sequence[12][16] = new NoteEvent (12, 3, bar,beat,fraction,pulse); andrew@50: // tracks[3].sequence[12][20] = new NoteEvent (12, 3, bar,beat,fraction,pulse, true); andrew@50: // tracks[3].sequence[11][16] = new NoteEvent (11, 3, bar,beat,fraction,pulse); andrew@50: // tracks[3].sequence[11][20] = new NoteEvent (11, 3, bar,beat,fraction,pulse, true); andrew@50: // tracks[3].sequence[10][16] = new NoteEvent (10, 3, bar,beat,fraction,pulse); andrew@50: // tracks[3].sequence[10][20] = new NoteEvent (10, 3, bar,beat,fraction,pulse, true); andrew@50: } andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: void draw(){ andrew@50: /* if (currentPulse % (grid * beatsPerBar) == grid * beatsPerBar -1){ andrew@50: int tempTrackSelected = trSelected; andrew@50: for (int j = 0; j < 16; j++){ andrew@50: trSelected = j; andrew@50: if (tracks[j] != null){ andrew@50: for (int i = 0; i < 16; i++){ andrew@50: noteOnArray[i] = false; andrew@50: finishNote(i); andrew@50: displayNoteOnArray[i] = false; andrew@50: for (int z = 24; z < 109; z++) andrew@50: outputToMax(z, 0, j); andrew@50: } andrew@50: tracks[j] = new Track(tracks[j].name, true, tracks[j].loopLength, tracks[j].quantize, false, false); andrew@50: imgNotes = null; andrew@50: } andrew@50: } andrew@50: trSelected = tempTrackSelected; andrew@50: } andrew@50: */ andrew@50: // tracks[0] = new Track("Chord track", true, grid * beatsPerBar, 8, true, true); andrew@50: // tracks[1] = new Track("Drums", true, grid * beatsPerBar, 8, false, true); andrew@50: // tracks[2] = new Track("Bass", true, grid * beatsPerBar, 8, false, true); andrew@50: // tracks[3] = new Track("Pizz Strings", true, grid * beatsPerBar, 8, false, true); andrew@50: // tracks[4] = new Track("Synth", true, grid * beatsPerBar, 8, false, true); andrew@50: // tracks[5] = new Track("Voice", true, grid * beatsPerBar, 8, false, true); andrew@50: // } andrew@50: workOutPosition(); // calculates current bar, beat and pulse position andrew@50: //println(bar + " " + beat + " " + fraction + " " + pulse); andrew@50: // if (chordAI && bar > 1) andrew@50: // chordCalc(); andrew@50: if (eraseOn) andrew@50: eraseNotes(); andrew@50: calcColours(); // calcs chord colours for background and grid andrew@50: heresyChange = false; andrew@50: heresyChordChanged = false; andrew@50: if (trackStorer != trSelected){ // resets display when changing tracks andrew@50: for (int i = 0; i < 16; i++) andrew@50: if (noteOnArray[i] = true){ andrew@50: noteOnArray[i] = false; andrew@50: displayNoteOnArray[i] = false; andrew@50: } andrew@50: trackStorer = trSelected; andrew@50: imgNotes = null; andrew@50: } andrew@50: if (imgNotes == null) andrew@50: imgNotes = createGraphics(tracks[trSelected].loopLength,imageHeight,P2D); andrew@50: background(0); andrew@50: image (img,width-x2-playArea,0); andrew@50: drawTempImageGrid(); andrew@50: createNoteFan(); andrew@50: drawNotes(); andrew@50: fill (0); andrew@50: noStroke(); andrew@50: rect (width-playArea,0,playArea,height); andrew@50: image (imgNoteFan, width-playArea+3,0); andrew@50: pulseFrame(x); // Draws a pulsing white line at the left edge of the edit area andrew@50: if (haveQuestion) writeQuestion(); // for input request messages andrew@50: x++; // counter for grid movement andrew@50: x2++; // counter for note image movement andrew@50: if (x2 == width - playArea + grid * beatsPerBar) andrew@50: x2 = width - playArea; andrew@50: if (x == width - playArea + tracks[trSelected].loopLength) andrew@50: x = width - playArea; andrew@50: andrew@50: andrew@50: /* if (clickTrackOn){ // click track andrew@50: if (fraction == 1){ andrew@50: if (pulse == 1){ andrew@50: String noteOut = ("37 80 1"); andrew@50: link.output(noteOut); andrew@50: } andrew@50: if (pulse == 2){ andrew@50: String noteOut = ("37 0 1" ); andrew@50: link.output(noteOut); andrew@50: } andrew@50: } andrew@50: } andrew@50: */ andrew@50: checkForMutes(); andrew@50: checkCycled(); andrew@50: playTrackEvents(); andrew@50: andrew@50: fill(255,255,255); andrew@50: textSize(15); andrew@50: text(bar + " " + beat + " " + fraction + " " + pulse, 10,20); // draws current time position to screen andrew@50: andrew@50: fill(200,0,0); andrew@50: textSize(15); andrew@50: // this section draws current track and track info to screen andrew@50: if (tracks[trSelected].ducking) andrew@50: text(tracks[trSelected].name + " ducking", 100,20); andrew@50: else andrew@50: text(tracks[trSelected].name, 100,20); andrew@50: if (tracks[trSelected].muteIn > bar) andrew@50: if (!tracks[trSelected].mute) andrew@50: text("mute in " + (tracks[trSelected].muteIn - bar), 200,20); andrew@50: else andrew@50: text("unmute in " + (tracks[trSelected].muteIn - bar), 200,20); andrew@50: andrew@50: if (haveQuestion){ // asks input questions andrew@50: writeQuestion(); andrew@50: } andrew@50: // println(currentPulse + " "); andrew@50: andrew@50: andrew@50: currentPulse++; // advances the sequencer to next pulse andrew@50: } andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: void eraseNotes(){ // erases notes in current track if selected andrew@50: if (trSelected != 0){ andrew@50: for (int i = 0; i < 16; i++){ andrew@50: if (tracks[trSelected].sequence[i][(currentPulse%(tracks[trSelected].loopLength))] != null){ andrew@50: tracks[trSelected].sequence[i][(currentPulse%(tracks[trSelected].loopLength))] = null; andrew@50: } andrew@50: } andrew@50: } andrew@50: if (trSelected == 0){ andrew@50: for (int i = 0; i < 16; i++){ andrew@50: if (chordsTemp.sequence[i][(currentPulse%(tracks[trSelected].loopLength))] != null){ andrew@50: chordsTemp.sequence[i][(currentPulse%(tracks[trSelected].loopLength))] = null; andrew@50: } andrew@50: } andrew@50: } andrew@50: } andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: void workOutPosition(){ // works out current position andrew@50: if (currentPulse%(grid*beatsPerBar) == 0) andrew@50: ++bar; andrew@50: if (currentPulse%grid == 0) andrew@50: ++beat; andrew@50: if (beat > beatsPerBar) andrew@50: beat = 1; andrew@50: if (currentPulse%(grid/fractions) == 0) andrew@50: ++fraction; andrew@50: if (fraction > fractions) andrew@50: fraction = 1; andrew@50: ++pulse; andrew@50: if (pulse > (grid/fractions)) andrew@50: pulse = 1; andrew@50: } andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: public void finishNote(int noteArrayPosition){ // writes note offs into the sequencers andrew@50: if (trSelected != 0) andrew@50: tracks[trSelected].sequence[noteArrayPosition][(currentPulse%(tracks[trSelected].loopLength))] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse, true); andrew@50: if (trSelected == 0) andrew@50: chordsTemp.sequence[noteArrayPosition][(currentPulse%(chordsTemp.loopLength))] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse, true); andrew@50: displayNoteOnArray[noteArrayPosition] = false; andrew@50: } andrew@50: andrew@50: public void finishNote(int noteArrayPosition, int channel){ // writes note offs into the sequencers andrew@50: if (trSelected != 0) andrew@50: tracks[trSelected].sequence[noteArrayPosition][(currentPulse%(tracks[trSelected].loopLength))] = new NoteEvent (noteArrayPosition, channel, bar,beat,fraction,pulse, true); andrew@50: if (trSelected == 0) andrew@50: chordsTemp.sequence[noteArrayPosition][(currentPulse%(chordsTemp.loopLength))] = new NoteEvent (noteArrayPosition, channel, bar,beat,fraction,pulse, true); andrew@50: displayNoteOnArray[noteArrayPosition] = false; andrew@50: } andrew@50: andrew@50: andrew@50: //----------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: public void finishNoteCutOff(int noteArrayPosition){ // writes note offs for unfinished notes in to the last track if track is changed and note ons are active andrew@50: tracks[lastTrack].sequence[noteArrayPosition][(currentPulse%(tracks[lastTrack].loopLength))] = new NoteEvent (noteArrayPosition, lastTrack+1, bar,beat,fraction,pulse, true); andrew@50: } andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: public void writeNote(int noteArrayPosition, int veloc){ // writes note ons into the sequencers andrew@50: if (trSelected != 0){ andrew@50: int quantizeOffset = getQuantizeOffset(); andrew@50: if (quantizeOffset >= 0){ andrew@50: tracks[trSelected].sequence[noteArrayPosition][(currentPulse+quantizeOffset)%(tracks[trSelected].loopLength)] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse); andrew@50: } andrew@50: if (quantizeOffset < 0){ andrew@50: tracks[trSelected].sequence[noteArrayPosition][(currentPulse+quantizeOffset)%(tracks[trSelected].loopLength)] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse); andrew@50: andrew@50: VPA[trSelected].VPArrayNotes[noteArrayPosition].VPNoteOn = true; andrew@50: if (trSelected !=1 && trSelected !=5) andrew@50: VPA[trSelected].VPArrayNotes[noteArrayPosition].VPNotePitch = heresyPitch(noteArrayPosition, 3); andrew@50: else andrew@50: VPA[trSelected].VPArrayNotes[noteArrayPosition].VPNotePitch = heresyPitch(noteArrayPosition, 1); andrew@50: VPA[trSelected].VPArrayNotes[noteArrayPosition].VPNoteVelocity = veloc; andrew@50: sendNote(VPA[trSelected].VPArrayNotes[noteArrayPosition], trSelected); andrew@50: displayNoteOnArray[noteArrayPosition] = true; andrew@50: andrew@50: } andrew@50: } andrew@50: if (trSelected == 0){ andrew@50: int quantizeOffset = getQuantizeOffset(); andrew@50: if (quantizeOffset >= 0){ andrew@50: chordsTemp.sequence[noteArrayPosition][(currentPulse+quantizeOffset)%(tracks[trSelected].loopLength)] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse); andrew@50: } andrew@50: if (quantizeOffset < 0){ andrew@50: chordsTemp.sequence[noteArrayPosition][(currentPulse+quantizeOffset)%(tracks[trSelected].loopLength)] = new NoteEvent (noteArrayPosition, trSelected+1, bar,beat,fraction,pulse); andrew@50: andrew@50: if (noteArrayPosition > 3) andrew@50: currentChord = 15 - noteArrayPosition; andrew@50: displayNoteOnArray[noteArrayPosition] = true; andrew@50: } andrew@50: } andrew@50: } andrew@50: andrew@50: public void writeNote(int noteArrayPosition, int veloc, int channel){ // writes note ons into the sequencers andrew@50: VPA[channel].VPArrayNotes[noteArrayPosition].VPNoteOn = true; andrew@50: VPA[channel].VPArrayNotes[noteArrayPosition].VPNotePitch = heresyPitch(noteArrayPosition, 1); andrew@50: VPA[channel].VPArrayNotes[noteArrayPosition].VPNoteVelocity = veloc; andrew@50: sendNote(VPA[channel].VPArrayNotes[noteArrayPosition], channel); andrew@50: } andrew@50: andrew@50: andrew@50: andrew@50: andrew@50: //------------------------------------------------------------------------------------------------------------------------------- andrew@50: andrew@50: public int getQuantizeOffset(){ // tells write note method the quantize offset. andrew@50: int quantizeInPulses = pulsesPerBar/(tracks[trSelected].quantize); andrew@50: int quantizeOffset = currentPulse % quantizeInPulses; andrew@50: if (quantizeOffset > quantizeInPulses/2.0){ andrew@50: return ((quantizeOffset - quantizeInPulses) * -1) ; andrew@50: } andrew@50: else{ andrew@50: return quantizeOffset * -1; andrew@50: } andrew@50: } andrew@50: andrew@50: andrew@50: