|
|
|
06-14-2017, 08:09 PM
|
#1
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
[JS fx] does a CC controled transpose JS exist?
Hi.
Anyone know if someone has made a JS that transposes incoming MIDI notes with the transpose amount being controlled by CC?
If not can someone please do it?
Similar to this VST but with the transpose amount being user defineable.
Thanks
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-14-2017, 10:33 PM
|
#2
|
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,688
|
I did something like that and use it in my live setup.
It uses a CC on/off switch.
Off: no transposing
On: transposing on.
The initial transpose offset is taken from a slider and hence stored/recalled by Reaper.
If the first note on event after setting "on" is within the lowest two octaves of an 88 key keyboard, this note is not played, but sets the transpose offset.
(Moreover another on/off CC is used to optionally add a note one octave below the one played.)
-Michael
Last edited by mschnell; 06-15-2017 at 02:07 AM.
|
|
|
06-16-2017, 05:09 AM
|
#3
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Hi Michael.
Would you be so kind to share the code? So I can look at it... Don't know if there's much point because I'm not familiar to JS.
But unless anyone wants to make it for me I'm going to have to take a crack at it...
Did some copy pasting already after looking up a few JS fx code but so far no results. JS is a bit alien for me right now.
Code:
desc:Transposer
slider1:1<0,127,1>CC Up
slider2:0<0,127,1>CC Down
slider3:0<0,127,1>transpose
@init
CC_MSG =11;
CCValue = 0;
@slider
ccup = slider1;
ccdown = slider2;
transpose = slider3;
@block
while (
midirecv(mpos, msg1, msg23) ? (
CCValue = (msg23/256)|0;
msg3 = (msg23/256)|0;
msg2 = msg23-(msg3*256);
(msg2 == ccup) ? (
msg1 = 9*16;
msg2 = note;
msg3 = vel;
trig = 1;
transpose = transpose + 12;
msg23 = (msg3*256+msg2)|0;
midisend(mpos,msg1, msg23);
);
(msg2 == ccdown) ? (
msg1 = 9*16;
msg2 = note;
msg3 = vel;
trig = 1;
transpose = transpose - 12;
msg23 = (msg3*256+msg2)|0;
midisend(mpos,msg1, msg23);
);
);
);
If anyone want to give some pointers, I'd appreciate it.
the above was just to see if given the input CC I could move the "transpose" slider.
I thought I'd worry later about the actual transposing
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-16-2017, 06:46 AM
|
#4
|
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,688
|
Here you are:
Code:
desc:MIDI Octave
//tags: MIDI processing
slider1:0<-11,11,1>Transpose Semitones
slider2:-5<-11,11,1>Previous Transpose
slider3:21<0,127,1>Lowest Key (MIDI Note #)
slider4:65<0,127,1>Midi CC Transpose
slider5:66<0,127,1>Midi CC Octave
// these lines tell Reaper the effect has no audio input/output,
// which enables processing optimizations.
// MIDI-only FX should always have these lines.
in_pin:none
out_pin:none
@init
global_info = 0;
notebuf = 0; // 4 entries per open note: orignote, channel, vel, transnote
buflen = 0;
last_transpose = 0;
gmem[global_info] = last_transpose;
last_samplepos = 0;
last_oct=0;
oo=0;
att=0;
oct1=slider3;
lowc=(((oct1+13) / 12) | 0) * 12; // if lowest key is a C -> one octave up
@slider
att=0;
oct1=slider3;
lowc=(((oct1+13) / 12) | 0) * 12; // if lowest key is a C -> one octave up
@block
samplepos = play_position*srate;
samplechg = samplepos-last_samplepos;
samplechg < -samplesblock/2.0 || samplechg > samplesblock*3.0/2.0 ? (
buflen = 0; // clear state on seek
);
last_samplepos = samplepos;
slider1|0 != last_transpose || oct != last_oct ? (
last_transpose = slider1|0;
gmem[global_info] = last_transpose;
last_oct = oct;
i = 0;
loop (
buflen,
n = notebuf[4*i]|0; // original note
c = notebuf[4*i+1]|0; // channel
v = notebuf[4*i+2]|0; // velocity
t = notebuf[4*i+3]|0; // transposed note
midisend(0, $x80|c, t&0x7F); // clear the sustaining transposed note
t & 0x80 ? ( // octave had been sent
midisend(0, $x80|c, (t&0x7F)-12); // clear the sustaining octave note
);
t = (n+last_transpose)|0; // new transposed note
t < 0 ? t = 0 : t > 127 ? t = 127;
// midisend(0, $x90|c, (v*256)|t); // send the new transposed note
notebuf[4*i+3] = t; // update the buffer
oct ? (
t-=12;
// midisend(0, 0x90|c, (v*256)|t); // send the new octave note
notebuf[4*i+3] = t|0x80; // update the buffer
);
i = i+1;
);
);
while (midirecv(offs, m1, m2) ) ( // m2 contains both note and velocity
s = m1&$xF0; // Status
s != 0xF0 ? (
s == 0x90 || s == $x80 ? ( // note-on or note-off
n = m2&0xFF; // original note
v = (m2&$xFF00)/256; // velocity
no = s==0x90 && v != 0;
att && no ? ( // we are special
att = 0; // next key is normal
(n >= lowc) && (n < lowc+24) ? ( // transpose request
n -= lowc+12; // +0 ... +11
slider1 = n;
m1 = 0; // no output
);
);
m1 ? (
n >= 0 ? (
c = m1&0xF; // channel
t = (n+last_transpose)|0; // transposed note
t < 0 ? t = 0 : t > 127 ? t = 127;
m2 = m2+t-n; // apply transposition
oo && (t>12) ? (
mo = m2-12; //Sub - Octave
) : (
mo = 0;
);
i = -1;
while ( // look for this note|channel already in the buffer
i = i+1;
i < buflen && (notebuf[4*i]|0 != n || notebuf[4*i+1]|0 != c);
);
no ? (// note-on, add to buffer
notebuf[4*i] = n;
notebuf[4*i+1] = c;
notebuf[4*i+2] = v;
notebuf[4*i+3] = t | oo;
i == buflen ? buflen = buflen+1;
) : (// note-off, remove from buffer
i < buflen ? (
memcpy(notebuf+4*i, notebuf+4*(i+1), 4*(buflen-i-1)); // delete the entry
buflen = buflen-1;
);
);
);
);
):(
s == 0xB0 ? (
m2 == 0x017E ? (
oct =1;
oo = 0x80;
m1 = 0;
):(
m2 == 0x007F ? (
oct = 0;
oo = 0;
m1 = 0;
):(
(m2 & 0x7F) == slider4 ? (
(m2 >> 8 ) < 64 ? (
slider2 = last_transpose;
att = 0;
slider1 = 0;
m1 = 0;
) : (
slider1 = slider2;
last_transpose = 0;
gmem[global_info] = last_transpose;
att = 1;
m1 = 0;
);
);
);
);
);
);
m1 ? (
midisend(offs, m1, m2);
no ? (
att = 0; // next key is handled normally
);
mo && (s == 0x90 || s == $x80) ? ( // Sub-Octave
midisend(offs, m1, mo);
);
);
nb0 = notebuf[4*0]; // why does this kill the error ?!?!?!?!?
nb1 = notebuf[4*1];
);
);
|
|
|
06-16-2017, 10:18 AM
|
#5
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Is there some reason you don't want to just use Parameter Modulation for this?
|
|
|
06-16-2017, 11:33 AM
|
#6
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Tbh I don't get the request because sliders of any JS can be MIDI learned and thus controlled via CC no ? (So I'd think any MIDI transpose JS would do, and there are a couple in Reaper's stock JS).
What am I missing here ?
edit:
If you want to control with CC's from MIDI tracks and not an external controller you could use MIDItoReaControlPath.
Last edited by nofish; 06-16-2017 at 11:54 AM.
|
|
|
06-16-2017, 12:46 PM
|
#7
|
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Quote:
Originally Posted by nofish
edit:
If you want to control with CC's from MIDI tracks and not an external controller you could use MIDItoReaControlPath.
|
Well...You could just use Paramater Modulation.
I prefer that anyway because you have a lot more control and it keeps the routing all discrete rather than spamming the global control path.
Edit - And of course this will work with an external controller as well. You don't have to enable it for control or anything. Just route the midi signals around as necessary, PM|MIDI Link, done.
|
|
|
06-16-2017, 03:21 PM
|
#8
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Hi.
Little insight on what I'm trying to do:
I've set up a OSC template for when I need to do quick midi melody or whatever.
So since I've only fitted two octaves on the screen I was thinking I'd set two other buttons in that template that would send CC to control a transposing plugin and that would allow me to access other keyboard ranges.
I thought there's got to be a JS fx because like almost everything been done there. Oddly enough didn't find one. There's that J's VST midi plugin but it won't do octaves and I couldn't find any other one.
Does ReaControlMIDI or Parameter Modulation work for this?
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-16-2017, 09:54 PM
|
#9
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Quote:
Originally Posted by mschnell
Here you are:
|
Thanks so much Michael.
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-17-2017, 03:58 AM
|
#10
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Well, incredibly, contrary to my expectations, I was able to do it
If anyone wants to comment on the code I'd appreciate it, it's my first JS-fx and it's more of a hack job than anything else, so I'm sure there's lots of room for improvement...
The options I think are self-explanatory. If not:
* down CC -- select a CC from dropdown list and when sent from keyboard, ipad, etc, it subtracts x semitones from current range.
* up CC -- same as above but inversely
* Factor -- number of semitones added/ subtracted (as a unit) when transposing
* Amount -- number of semitones currently added/ subtracted as a total
If you are feeling up to it could use an explanation (like draw me a picture type) of exactly how MIDI bytes and all that work. I could gather some understanding from the JS docs and from here https://ccrma.stanford.edu/~craig/ar...essenmidi.html but some down to earth 1+1 explanation would be greatly appreciated.
EDIT: It's here https://stash.reaper.fm/v/30982/MIDI%...Transposer.zip
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
Last edited by Spacemen Tree; 06-19-2017 at 03:12 AM.
|
|
|
06-17-2017, 04:30 AM
|
#11
|
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,688
|
Great ! Congrats,
-Michael
|
|
|
06-19-2017, 03:10 AM
|
#12
|
Human being with feelings
Join Date: Mar 2013
Posts: 515
|
Made some small corrections/ alterations to the code. Also, added a version of the JS-fx with a simple slider instead of a dropdown list for CC, if like me you dont need the CC info and don't want to scroll to get to higher CC numbers. Upped it to the stash: https://stash.reaper.fm/v/30982/MIDI%...Transposer.zip
__________________
"After silence, that which comes nearest to expressing the inexpressible is music", Aldous Huxley
|
|
|
06-20-2017, 01:47 PM
|
#13
|
Banned
Join Date: Sep 2015
Posts: 1,650
|
Quote:
Originally Posted by Spacemen Tree
If you are feeling up to it could use an explanation (like draw me a picture type) of exactly how MIDI bytes and all that work.
|
What exactly is unclear and I'll happily fill in the blanks?
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 05:18 PM.
|