So I'm working on a little script (done in pure data)
I would love to have some feedback on strategies and how to make it in lua or js.
would be great if it could follow some drummer strategies like paradiddle, etc...
It is vaguely (cause mine is so much worse) inspired by this -> https://youtu.be/QHIhDP8pTkE
It's better to port this to js than lua, js has builtin slider graphic, so no need to make slider from scratch.
For the start take a look at js MIDI TOOL code, it's well commented and shows how to handle and manipulate real time Midi events.
Code:
/*******************************************************************************
* Copyright 2007 - 2011, Philip S. Considine *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/)for more details. *
*******************************************************************************/
desc: MIDI Tool
desc: MIDI Tool [IXix]
//tags: MIDI processing
//author: IXix
slider1:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Input Channel
slider2:0<0,127,1>Note Min
slider3:127<0,127,1>Note Max
// Note min/max (names) (disabled)
//slider2:0<0,127,1{C0,C#0,D0,D#0,E0,F0,F#0,G0,G#0,A0,A#0,B0,C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,B1,C2,C#2,D2,D#2,E2,F2,F#2,G2,G#2,A2,A#2,B2,C3,C#3,D3,D#3,E3,F3,F#3,G3,G#3,A3,A#3,B3,C4,C#4,D4,D#4,E4,F4,F#4,G4,G#4,A4,A#4,B4,C5,C#5,D5,D#5,E5,F5,F#5,G5,G#5,A5,A#5,B5,C6,C#6,D6,D#6,E6,F6,F#6,G6,G#6,A6,A#6,B6,C7,C#7,D7,D#7,E7,F7,F#7,G7,G#7,A7,A#7,B7,C8,C#8,D8,D#8,E8,F8,F#8,G8,G#8,A8,A#8,B8,C9,C#9,D9,D#9,E9,F9,F#9,G9,G#9,A9,A#9,B9,C10,C#10,D10,D#10,E10,F10,F#10,G10}>Note Min
//slider3:127<0,127,1{C0,C#0,D0,D#0,E0,F0,F#0,G0,G#0,A0,A#0,B0,C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,B1,C2,C#2,D2,D#2,E2,F2,F#2,G2,G#2,A2,A#2,B2,C3,C#3,D3,D#3,E3,F3,F#3,G3,G#3,A3,A#3,B3,C4,C#4,D4,D#4,E4,F4,F#4,G4,G#4,A4,A#4,B4,C5,C#5,D5,D#5,E5,F5,F#5,G5,G#5,A5,A#5,B5,C6,C#6,D6,D#6,E6,F6,F#6,G6,G#6,A6,A#6,B6,C7,C#7,D7,D#7,E7,F7,F#7,G7,G#7,A7,A#7,B7,C8,C#8,D8,D#8,E8,F8,F#8,G8,G#8,A8,A#8,B8,C9,C#9,D9,D#9,E9,F9,F#9,G9,G#9,A9,A#9,B9,C10,C#10,D10,D#10,E10,F10,F#10,G10}>Note Max
slider4:0<0,127,1>Input Velocity Min
slider5:127<0,127,1>Input Velocity Max
slider6:0<0,100,1>Random Velocity (%)
slider7:0<0,127,1>Output Velocity Min
slider8:127<0,127,1>Output Velocity Max
slider9:0<-60,60,1>Transpose (st)
slider10:0<0,100,1>Random Pitch (%)
slider11:0<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Output Channel
in_pin:none
out_pin:none
@init
statNoteOff = $x80;
statNoteOn = $x90;
statPitch = $xE0;
pitchCentre = 16384;
@slider
// Discard fractions
slider2 |= 0;
slider3 |= 0;
slider4 |= 0;
slider5 |= 0;
slider6 |= 0;
slider7 |= 0;
slider8 |= 0;
slider9 |= 0;
slider10 |= 0;
// Clamp to respectable values
slider2 = min(slider2, slider3);
slider3 = max(slider2, slider3);
slider4 = min(slider4, slider5);
slider5 = max(slider4, slider5);
slider6 = min(max(slider6, 0), 100);
slider7 = min(slider7, slider8);
slider8 = max(slider7, slider8);
slider9 = min(max(slider9, -60), 60);
slider10 = min(max(slider10, 0), 100);
// Set variables
inChannel = slider1;
outChannel = slider11;
noteMin = slider2;
noteMax = slider3;
inVelMin = slider4;
inVelMax = slider5;
velocityRand = slider6 / 100;
outVelMin = slider7;
outVelMax = slider8;
transpose = slider9;
pitchRand = slider10 / 100;
////////////////////////////////////////////////////////////////////////////////////////////
@block
while
(
midirecv(offset, msg1, msg23) ?
(
doPitch = 0; // Reset pitch bend flag
// Extract message type and channel
status = msg1 & $xF0;
channel = msg1 & $x0F;
// Is it on our channel?
channel == inChannel ?
(
// Is it a note event?
status == statNoteOn || status == statNoteOff ?
(
// Extract note number
note = msg23 & $x7F;
// Is it within our note range?
!(note < noteMin || note > noteMax) ?
(
t += 1;
osc = sin(t); // used to make random values positive or negative
// Extract velocity
velocity = msg23 >> 8;
// Do velocity. Zero velocity is considered a note-off so don't clamp it
velocity > 0 ?
(
// Clamp input velocity
velocity = min(max(velocity, inVelMin), inVelMax);
// Randomise clamped velocity by percentage
velocityRand > 0 ? velocity = floor(velocity + (rand(velocity * velocityRand) * osc));
// Clamp output velocity
velocity = min(max(velocity, outVelMin), outVelMax);
);
// Do transpose and clamp result if necessary
note += transpose;
note = min(max(note, 0), 127);
// Adjust message values
msg1 = status + outChannel;
msg23 = note | (velocity << 8);
// Flag to send pitchbend if needed
pitchRand > 0 ? doPitch = 1;
);
);
);
// Generate and send pitch bend message if necessary
doPitch ?
(
pitch = pitchCentre + floor(rand(pitchCentre * pitchRand) * osc);
midisend(offset, statPitch + outChannel, pitch);
);
// Pass message on
midisend(offset, msg1, msg23);
1; // Force loop to continue until all messages have been processed
);
);
I'm looking at it... seems pretty simple to translate from pd
Quote:
Originally Posted by Outboarder
Hi
It's better to port this to js than lua, js has builtin slider graphic, so no need to make slider from scratch.
For the start take a look at js MIDI TOOL code, it's well commented and shows how to handle and manipulate real time Midi events.
Code:
/*******************************************************************************
* Copyright 2007 - 2011, Philip S. Considine *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/)for more details. *
*******************************************************************************/
desc: MIDI Tool
desc: MIDI Tool [IXix]
//tags: MIDI processing
//author: IXix
slider1:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Input Channel
slider2:0<0,127,1>Note Min
slider3:127<0,127,1>Note Max
// Note min/max (names) (disabled)
//slider2:0<0,127,1{C0,C#0,D0,D#0,E0,F0,F#0,G0,G#0,A0,A#0,B0,C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,B1,C2,C#2,D2,D#2,E2,F2,F#2,G2,G#2,A2,A#2,B2,C3,C#3,D3,D#3,E3,F3,F#3,G3,G#3,A3,A#3,B3,C4,C#4,D4,D#4,E4,F4,F#4,G4,G#4,A4,A#4,B4,C5,C#5,D5,D#5,E5,F5,F#5,G5,G#5,A5,A#5,B5,C6,C#6,D6,D#6,E6,F6,F#6,G6,G#6,A6,A#6,B6,C7,C#7,D7,D#7,E7,F7,F#7,G7,G#7,A7,A#7,B7,C8,C#8,D8,D#8,E8,F8,F#8,G8,G#8,A8,A#8,B8,C9,C#9,D9,D#9,E9,F9,F#9,G9,G#9,A9,A#9,B9,C10,C#10,D10,D#10,E10,F10,F#10,G10}>Note Min
//slider3:127<0,127,1{C0,C#0,D0,D#0,E0,F0,F#0,G0,G#0,A0,A#0,B0,C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,B1,C2,C#2,D2,D#2,E2,F2,F#2,G2,G#2,A2,A#2,B2,C3,C#3,D3,D#3,E3,F3,F#3,G3,G#3,A3,A#3,B3,C4,C#4,D4,D#4,E4,F4,F#4,G4,G#4,A4,A#4,B4,C5,C#5,D5,D#5,E5,F5,F#5,G5,G#5,A5,A#5,B5,C6,C#6,D6,D#6,E6,F6,F#6,G6,G#6,A6,A#6,B6,C7,C#7,D7,D#7,E7,F7,F#7,G7,G#7,A7,A#7,B7,C8,C#8,D8,D#8,E8,F8,F#8,G8,G#8,A8,A#8,B8,C9,C#9,D9,D#9,E9,F9,F#9,G9,G#9,A9,A#9,B9,C10,C#10,D10,D#10,E10,F10,F#10,G10}>Note Max
slider4:0<0,127,1>Input Velocity Min
slider5:127<0,127,1>Input Velocity Max
slider6:0<0,100,1>Random Velocity (%)
slider7:0<0,127,1>Output Velocity Min
slider8:127<0,127,1>Output Velocity Max
slider9:0<-60,60,1>Transpose (st)
slider10:0<0,100,1>Random Pitch (%)
slider11:0<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Output Channel
in_pin:none
out_pin:none
@init
statNoteOff = $x80;
statNoteOn = $x90;
statPitch = $xE0;
pitchCentre = 16384;
@slider
// Discard fractions
slider2 |= 0;
slider3 |= 0;
slider4 |= 0;
slider5 |= 0;
slider6 |= 0;
slider7 |= 0;
slider8 |= 0;
slider9 |= 0;
slider10 |= 0;
// Clamp to respectable values
slider2 = min(slider2, slider3);
slider3 = max(slider2, slider3);
slider4 = min(slider4, slider5);
slider5 = max(slider4, slider5);
slider6 = min(max(slider6, 0), 100);
slider7 = min(slider7, slider8);
slider8 = max(slider7, slider8);
slider9 = min(max(slider9, -60), 60);
slider10 = min(max(slider10, 0), 100);
// Set variables
inChannel = slider1;
outChannel = slider11;
noteMin = slider2;
noteMax = slider3;
inVelMin = slider4;
inVelMax = slider5;
velocityRand = slider6 / 100;
outVelMin = slider7;
outVelMax = slider8;
transpose = slider9;
pitchRand = slider10 / 100;
////////////////////////////////////////////////////////////////////////////////////////////
@block
while
(
midirecv(offset, msg1, msg23) ?
(
doPitch = 0; // Reset pitch bend flag
// Extract message type and channel
status = msg1 & $xF0;
channel = msg1 & $x0F;
// Is it on our channel?
channel == inChannel ?
(
// Is it a note event?
status == statNoteOn || status == statNoteOff ?
(
// Extract note number
note = msg23 & $x7F;
// Is it within our note range?
!(note < noteMin || note > noteMax) ?
(
t += 1;
osc = sin(t); // used to make random values positive or negative
// Extract velocity
velocity = msg23 >> 8;
// Do velocity. Zero velocity is considered a note-off so don't clamp it
velocity > 0 ?
(
// Clamp input velocity
velocity = min(max(velocity, inVelMin), inVelMax);
// Randomise clamped velocity by percentage
velocityRand > 0 ? velocity = floor(velocity + (rand(velocity * velocityRand) * osc));
// Clamp output velocity
velocity = min(max(velocity, outVelMin), outVelMax);
);
// Do transpose and clamp result if necessary
note += transpose;
note = min(max(note, 0), 127);
// Adjust message values
msg1 = status + outChannel;
msg23 = note | (velocity << 8);
// Flag to send pitchbend if needed
pitchRand > 0 ? doPitch = 1;
);
);
);
// Generate and send pitch bend message if necessary
doPitch ?
(
pitch = pitchCentre + floor(rand(pitchCentre * pitchRand) * osc);
midisend(offset, statPitch + outChannel, pitch);
);
// Pass message on
midisend(offset, msg1, msg23);
1; // Force loop to continue until all messages have been processed
);
);