Dup Goto 📝

MidiKeyboardMonitor

To Pop
169 lines, 494 words, 2712 chars Thursday 2024-07-11 13:58:47

As simple as possible. Note that it doesn't distinguish channels, and the range is fixed to an 88 key keyboard.

desc: jda midi note mon

@init
// note range
lo = 21;
hi = 21+87;

// look up table for colour of note
notes = 100;
colours = 10;
colours[0] = 0;
colours[1] = 1;
colours[2] = 0;
colours[3] = 1;
colours[4] = 0;
colours[5] = 0;
colours[6] = 1;
colours[7] = 0;
colours[8] = 1;
colours[9] = 0;
colours[10] = 1;
colours[11] = 0;

function handleNoteOff()
(
  notes[msg2] = 0;
);

function handleNoteOn()
(
  ( msg3 == 0 ) ? (
    handleNoteOff();
  ) : (
    notes[msg2] = 1;
  );
);

// expand range if high or low notes are black
( colors[lo%12] == 1 ) ? (
  lo -= 1;
);
( colors[hi%12] == 1 ) ? (
  hi += 1;
);
nn = hi-lo+1; // number of notes
nwn = 0; // number of white notes

// count white notes (used to compute width of white note)
i = lo;
loop(nn,
  ( colours[i%12] == 0 ) ? (
    nwn += 1;
  );
  i += 1;
);


@block
while(midirecv(offset,msg1,msg2,msg3)) (
  channel = msg1 & 0xF;
  status = msg1 >> 4;
  ( status == 0x09 ) ? (
    handleNoteOn();
  ) : ( status == 0x08 ) ? (
    handleNoteOff();
  );
  midisend(offset,msg1,msg2,msg3); // pass all through
);

@gfx 880 100 

// white background
gfx_set(255,255,255);
gfx_rect(0,0,gfx_w,gfx_h);

// compute sizes of notes
note_w = gfx_w / nwn;
note_bw = note_w/1.6;
note_bw2 = note_bw/2;
note_h = gfx_h;
note_hb = note_h * 0.6;

// first pass, draw the white notes
i = 0;
note_r = 0;
loop(nn,
  j = i + lo;
  s = notes[j];
  pc = j % 12;
  col = colours[pc];
  pos = poses[pc];

  // set colour
  ( s == 0 ) ? (
    ( j == 60 ) ? ( // middle C light yellow
      gfx_set(1,1,0.4);
    ) : (
      gfx_set(1,1,1);
    );
  ) : (
    ( j == 60 ) ? (
      gfx_set(1,0.25,0);
    ) : (
      gfx_set(1,0,0);
    );
  );
  ( col == 0 ) ? (
    gfx_rect(note_r,0,note_w,note_h);
    note_r += note_w;
  );
  i += 1;
);

// middle pass
// draw the separators between the white notes
note_r = 0;
i = 0;
loop(nn,
  s = notes[i];
  j = i + lo;
  pc = j % 12;
  col = colours[pc];
  pos = poses[pc];

  // draw line between white notes
  ( col == 0 ) ? (
    gfx_set(0,0,0);
    gfx_line(note_r,0,note_r,note_h);
  );

  ( col == 0 ) ? (
    //gfx_rect(note_r,0,note_w,note_h);
    note_r += note_w;
  );
  i += 1;
);

// third pass, draw the black notes
note_r = 0;
i = 0;
loop(nn,
  j = i + lo;
  s = notes[j];
  pc = j % 12;
  col = colours[pc];
  pos = poses[pc];

  // set colour
  ( s == 0 ) ? (
    gfx_set(0,0,0);
  ) : (
    gfx_set(0,0.7,0);
  );
  ( col == 1 ) ? (
    gfx_rect(note_r-note_bw2,0,note_bw,note_hb);
  ) : (
    //gfx_rect(note_r,0,note_w,note_h);
    note_r += note_w;
  );
  i += 1;
);