Create colored circle based on midi note

I’m trying to create code that will let me input a musical note (via midi) and have a corresponding small circle appear that has an assigned color value. The circles will appear next to one another in succession, so that the resulting image looks like notes on a score. I want each note to always have the same color value (for example, A# is always red).

I’m pretty new at this so any insight would be appreciated!

2 Likes

Sounds beautiful.

Can you please show your code so far?

Heh- when I say I’m pretty new I really mean I have no idea what I’m doing! I know basic html and that’s about it. I understand this code and it seems pretty logical; I just don’t know enough about the language to know how to set something like this up. I just feel like it can be done!

1 Like

Do you have this already?

Ok so, there’s this code below, which isn’t exactly “hearing” the midi notes, but theoretically I could just manually input all the notes as numerical values, with middle C = 60, etc. It’s just very time consuming. I tried to add a circle, but I only got as far as placing a single one in the corner that won’t change color or position depending on the note, (which is what I want).

Underneath this there’s another code I found that uses something called WebMIDI.js to hear the midi input. This is closer to what I would like, but again I don’t know how to also have a shape “read” the notes and change accordingly…

let midiNotes = [60, 61, 62, 63];
let noteIndex = 0;
let midiVal, freq;

function setup() {
  let cnv = createCanvas(100, 100);
  cnv.mousePressed(startSound);
  osc = new p5.TriOsc();
  env = new p5.Envelope();
}

function draw() {
  background(255);
  text('tap to play', 10, 20);
  if (midiVal) {
    text('MIDI: ' + midiVal, 10, 40);
    text('Freq: ' + freq, 10, 60);
    circle(20,20,20);
  }
}

function startSound() {
  // see also: userStartAudio();
  osc.start();

  midiVal = midiNotes[noteIndex % midiNotes.length];
  freq = midiToFreq(midiVal);
  osc.freq(freq);
  env.ramp(osc, 0, 1.0, 0);

  noteIndex++;
}
............................................................
/*
Play midi notes using WebMIDI.js
*/

let midiVal, midiVelocity, freq, osc, env;

WebMidi.enable(function (err) {
  
    //check if WebMidi.js is enabled
    if (err) {
        console.log("WebMidi could not be enabled.", err);
    } else {
        console.log("WebMidi enabled!");
    }

    // name our visible MIDI input and output ports
    console.log("Inputs Ports: ");
    for (i = 0; i < WebMidi.inputs.length; i++) {
        console.log(i + ": " + WebMidi.inputs[i].name);
    }

    // choose an input port (0 means use the first device we see)
    inputSoftware = WebMidi.inputs[0];
    
    // listen to all incoming "note on" input events
    inputSoftware.addListener('noteon', "all",
        function (e) {
            // Play the note recieved
            startSound(e.note.number, e.velocity);
        }
    );

    // listen for noteoff events (not used) 
    inputSoftware.addListener('noteoff', "all", function (e) {} );
});

function setup() {
    let cnv = createCanvas(640, 480);
    osc = new p5.TriOsc();
    env = new p5.Envelope();
}

function draw() {
    background(220);
    text('Note info;', 10, 20);
    if (midiVal) {
        text('MIDI: ' + midiVal, 10, 40);
        text('Freq: ' + freq, 10, 60);
      
        circle((midiVal * 5) ,(midiVelocity * 3.8), 20);
    }
}

function startSound(noteVal, velocityVal) {
    osc.start();
    midiVal = noteVal;
    midiVelocity = velocityVal;
    freq = midiToFreq(noteVal);
    env.setADSR(0.001, velocityVal);
    osc.freq(freq);
    env.ramp(osc, 0, 1.0, 0);
}

Here is one method of changing the note color and location using mousePressed():

let c; // note color
let noteX = 0;
let noteY = 0;
let midiNotes = [60, 61, 62, 63];
let noteIndex = 0;
let midiVal, freq;

function lineGrid() {
  for(let k = 0; k < 5; k++) {
   lineY = 100 + k*(30);
   line( 30, lineY, width - 60, lineY);
  }
 }

function displayNote(){ 
  fill(c);
  circle(noteX, noteY, 20);
}

function setup() {
  let cnv = createCanvas(400, 400);  
  cnv.mousePressed(startSound);
  osc = new p5.TriOsc();
  env = new p5.Envelope();   
}

function draw() {
  background(255);
  fill(0);
  stroke(0);
  lineGrid();
  text('tap to play', 10, 20);
  if (midiVal) {
    text('MIDI: ' + midiVal, 10, 40);
    text('Freq: ' + freq, 10, 60);
    displayNote();
  }
 
}

function startSound() {
  // see also: userStartAudio();
  osc.start();

  midiVal = midiNotes[noteIndex % midiNotes.length];
  freq = midiToFreq(midiVal);
  osc.freq(freq);
  env.ramp(osc, 0, 1.0, 0);

  noteIndex++;
}

function mousePressed() {
 // console.log("note = " + midiVal);
  switch(midiVal){
    case 60: c = color('rgb(0,255,0)'); 
      noteX = 100; noteY = 220;
      break;
    case 61: c = color('rgb(255,0,0)');
      noteX = 130; noteY = 190;
      break;
    case 62: c = color('rgb(0,0,255)');
      noteX = 160; noteY = 160;
      break;
    case 63: c = color('rgb(0,255,255)');
      noteX = 190; noteY = 130;
      break;
  }
//  console.log("color = " + c);
  
}
1 Like

So, through a bunch of googling and falling down a rabbit hole of music visualization, I came across this guy who made something incredibly similar to what I’m looking for. It hasn’t been updated since 2006, but I’m wondering if it’s possible to reverse engineer this to make something similar? Maybe I wouldn’t even need to use js?