The idea of this script is that I can write a melodic pattern in the C Major scale, and this will then transpose it to a given key, and turn it from major to minor if desired.
Version 1
This is controlled by a single slider which offsets the output notes. This has the limitation that notes will stick if the offset is changed while playing. (This was my first sketch of this script.)
desc: JDA Major to Minor 1
slider1:0<-12,12,1>Note Offset
// takes notes input in C major scale,
// 3rd, 6th, 7th are lowered by a semitone
// notes will stick if offset is changed while playing.
@block
while(midirecv(offset,msg1,msg2,msg3)) (
status = msg1 & 0xF0;
ch = msg1 & 0xF;
status == 0x80 ? ( status = 0x90; msg3 = 0; );
status == 0x90 ? (
pc = msg2 % 12;
( pc == 4 || pc == 9 || pc == 11 ) ? msg2 -= 1;
msg2 += slider1;
msg2 < 0 ? msg2 = 0;
msg2 > 127 ? msg2 = 127;
msg1 = status | ch;
);
midisend( offset, msg1, msg2, msg3 ); // pass through
);
Version 2
The next version is slightly more refined. Notes on channel 16 are control notes.
Sending midi notes from 48..72 changes the note offset, and 47 (B below C below middle C) toggles on/off.
This version remembers which output note corresponds to which input pitch, so notes do not stick
when changing the offset.
desc: JDA Major to Minor 2
slider1:0<-12,12,1>Note Offset
slider2:1<0,1,1{off,on}>Active
// takes notes input in C major scale,
// 3rd, 6th, 7th are lowered by a semitone
// midi chanel 16 controls:
// 48..72 ( C below middle to C above ) change note offset
// 47 ( B below C below middle C ) toggles
@init
noteson = 100;
loop(i=0;128,
noteson[i] = -1;
i += 1;
);
@block
while(midirecv(offset,msg1,msg2,msg3)) (
status = msg1 & 0xF0;
ch = msg1 & 0x0F;
ch == 0x0F ? (
( status == 0x90 && msg3 > 0 ) ? (
p = msg2;
( (p >= (60 - 12)) && (p <= (60 + 12)) ) ? (
slider1 = p - 60;
sliderchange(slider1);
);
(p == 60-13) ? (
slider2 = 1 - slider2;
sliderchange(slider2);
);
);
) : (
(status == 0x90 && msg3 == 0 ) ? status == 0x80;
status == 0x80 ? (
p = msg2;
noteson[p] >= 0 ? (
p = noteson[p];
noteson[p] = -1;
);
msg2 = p;
msg1 = status | ch;
) : status == 0x90 ? (
p = msg2;
pc = msg2 % 12;
slider2 > 0 ? (
( pc == 4 || pc == 9 || pc == 11 ) ? msg2 -= 1;
);
msg2 += slider1;
msg2 < 0 ? msg2 = 0;
msg2 > 127 ? msg2 = 127;
msg1 = status | ch;
noteson[p] = msg2;
);
midisend( offset, msg1, msg2, msg3 ); // pass through
);
);