xxxxxxxxxx
196
let rX = 0;
let rY = 0;
let rZ = 0;
// this corresponds to the note assigned to each pad and gives them a simple number relating to their physical positions
const padLookup = {
36: 1,
37: 2,
38: 3,
39: 4,
40: 5,
41: 6,
42: 7,
43: 8
}
// store the state (up/down) and the velocity the pad has last been hit
const pads = {
1: {
down: false,
velocity: 0,
},
2: {
down: false,
velocity: 0,
},
3: {
down: false,
velocity: 0,
},
4: {
down: false,
velocity: 0,
},
5: {
down: false,
velocity: 0,
},
6: {
down: false,
velocity: 0,
},
7: {
down: false,
velocity: 0,
},
8: {
down: false,
velocity: 0,
},
};
// store the value of each pot
const pots = {
1: {
value: 0,
},
2: {
value: 0,
},
3: {
value: 0,
},
4: {
value: 0,
},
5: {
value: 0,
},
6: {
value: 0,
},
7: {
value: 0,
},
8: {
value: 0,
},
};
// run this once to connect the midi
function connect() {
navigator.requestMIDIAccess().then(
(midi) => midiReady(midi),
(err) => console.log("Something went wrong", err)
);
}
// when midi is ready set up the device
function midiReady(midi) {
// Also react to device changes.
midi.addEventListener("statechange", (event) => initDevices(event.target));
initDevices(midi); // see the next section!
}
// figure out all the inputs and get ready to listen
function initDevices(midi) {
// Reset.
midiIn = [];
midiOut = [];
// MIDI devices that send you data.
const inputs = midi.inputs.values();
for (let input = inputs.next(); input && !input.done; input = inputs.next()) {
midiIn.push(input.value);
}
// MIDI devices that you send data to.
const outputs = midi.outputs.values();
for (
let output = outputs.next();
output && !output.done;
output = outputs.next()
) {
midiOut.push(output.value);
}
startListening();
}
// Start listening to MIDI messages with event listeners - this will constantly listen for any changes
function startListening() {
midiIn.forEach((input, index) => {
input.addEventListener("midimessage", midiMessageReceived);
});
}
// when a message is recieved from the MIDI do something
function midiMessageReceived(event, index) {
// codes for on/off are different on different devices and across different modes on a device - here's where you probably want to console log the event.data and change some values. For the AKAI LPD8 MKII in CC mode the following works
const NOTE_ON = 144;
const NOTE_OFF = 128;
const POT = 176;
const cmd = event.data[0];
const pitch = event.data[1];
const value = event.data.length > 2 ? event.data[2] : 1;
// You can use the timestamp to figure out the duration of each note.
const timestamp = Date.now();
// console.log(cmd, pitch, value)
// on the above device i want to decide whether its a Pot or Pad being used and do the following
if (cmd === POT) {
console.log("pot", pitch, "value", value);
pots[pitch].value = value;
} else {
const pad = padLookup[pitch]
if (cmd === NOTE_ON) pads[pad].velocity = value;
pads[pad].down = cmd === NOTE_ON ? true : false;
console.log("pad", pads[pad]);
}
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
connect();
noStroke()
blendMode(SCREEN)
}
function draw() {
clear()
background(0);
push()
fill(255,0,0)
rotateX(findRotation(pots[1].value));
rotateY(findRotation(pots[2].value));
rotateZ(findRotation(pots[3].value));
box(width/3);
pop()
push()
fill(0,255,0)
rotateX(findRotation(pots[4].value));
rotateY(findRotation(pots[5].value));
rotateZ(findRotation(pots[6].value));
box(width/3);
pop()
push()
fill(0,0,255)
rotateX(findRotation(pots[7].value));
rotateY(findRotation(pots[8].value));
rotateZ(findRotation(pots[3].value));
box(width/3);
pop()
}
// helper functions to map values from MIDI so useful canvas values
function findRotation(value){
return map(value, 0, 127, 0, PI/2)
}