|
|
|
06-22-2016, 11:04 AM
|
#1
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
JS: Midi Events sent at the same tick are not recognized separately
I am currently working on a guitar strumming JS script and right now facing one problem. When I place two or more notes on the same PPQ tick, only the first note is recognized by midirecv command, and I could not find the reason why this is happening, since occasionally all notes are recognized as well. Is there a specific thing I need to put after midirecv for it to trigger per note?
|
|
|
06-22-2016, 12:18 PM
|
#2
|
Human being with feelings
Join Date: Feb 2016
Posts: 232
|
Quote:
Originally Posted by RCJacH
I am currently working on a guitar strumming JS script and right now facing one problem. When I place two or more notes on the same PPQ tick, only the first note is recognized by midirecv command, and I could not find the reason why this is happening, since occasionally all notes are recognized as well. Is there a specific thing I need to put after midirecv for it to trigger per note?
|
I'm running into the exact same issue. I have numerous instances of midirepeat. When it's repeating a note, I find that when I use input quantize (this is all live playing btw) if a new note hits when the repeating note is playing, the new note is almost always ignored.
It's the "almost always" part that's driving me nuts! If it was always the same it would be easier to figure out what's going on...
|
|
|
06-22-2016, 11:17 PM
|
#3
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
You would need to post code to be sure, but a wild guess: Are you using while()?
|
|
|
06-23-2016, 12:01 AM
|
#4
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
How do I post as code block? Anyway the below is a stripped down version of the problematic code.
desc: MIDI/MIDI Guitar Strummer
slider2: 34<0,127,1> Lowest note of Chord input
slider3: 77<0,127,1> Highest note of Chord input
slider36: 0<0,16,1> Counter //Chord note Counter for debugging
in_pin:none
out_pin:none
@init
// Constants from the MIDI specification:
NUM_CHANNELS = 16;
NUM_NOTES = 128;
STATUS_CC = $xB0; // control change MIDI message code
STATUS_NOTE_ON = $x90; // Note On Message
STATUS_NOTE_OFF = $x80; // Note Off Message
CC_ALL_NOTES_OFF = 123;
// Variables of strum engine:
i_susPed = 64; // CC number that act as sustain pedal
b_susPed = 0; // Boolean of whether sustain pedal is on
a_NotesPressed = 0;
memset(a_NotesPressed, 0, NUM_CHANNELS * NUM_NOTES);
a_NotesPendOff = a_NotesPressed + (NUM_CHANNELS * NUM_NOTES);
memset(a_NotesPendOff, 0, NUM_CHANNELS * NUM_NOTES);
@slider
i_loLmt = slider2; // Lowest chord note
i_hiLmt = slider3; // Highest chord note
slider36 = 0;
@block
while(
midirecv(offset, msg1, msg2, msg3) ? (
// Break up the MIDI message into its component parameters.
in_ch = msg1 & $x0F;
in_type = msg1 & $xF0;
in_pit = msg2;
in_vel = msg3;
// By default, we pass all MIDI messages on.
b_passMsg = 1;
(in_type == STATUS_NOTE_ON || in_type == STATUS_NOTE_OFF) ? (
// Chord Notes
in_pit >= i_loLmt && in_pit <= i_hiLmt ? (
// Block output, since we only need a reference of notes
b_passMsg = 0;
// Calculate the memory position of input notes.
v = in_ch * NUM_NOTES + in_pit;
// Note On Message
(in_type == STATUS_NOTE_ON && in_vel > 0) ? (
slider36 += 1;
// If retrigger while susPed is On, rePress the chord key
b_susPed == 1 && a_NotesPendOff[v] > 0 ? a_NotesPendOff[v] = 0;
// This Causes Problems, only one note is recognized by the script, while other notes are passed directly to the next FX in chain. Problem vanishes if this line is deleted.
) : (
// Note Off Message
slider36 -= 1;
);
); // Chord Notes
); //in_type
); //midirecv
); //while
|
|
|
06-23-2016, 01:15 AM
|
#5
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by RCJacH
How do I post as code block?
|
Just place [ code ] [ / code ] tags around your code (without the spaces).
I am too lazy to test, but this might fix things:
Code:
); //in_type
1; // Force repeat while midirecv() is true
); //midirecv
); //while
I say this because the while syntax you use repeats while the last (not the first!) executed statement within its subblock returns true.
Another option would be to use the more C-style while syntax:
Code:
while(midirecv(offset, msg1, msg2, msg3)) (
...
); //while
|
|
|
06-23-2016, 08:18 AM
|
#6
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
Quote:
Originally Posted by Tale
I say this because the while syntax you use repeats while the last (not the first!) executed statement within its subblock returns true.
|
Thank you! That solved the problem!
Another quick question, right now the MIDI notes sent with this JS will not send midi note off msg (hanging notes) when I stop the host playback midway through a midi clip which functions pretty well otherwise, is there a way to deal with this?
|
|
|
06-23-2016, 10:21 AM
|
#7
|
Human being with feelings
Join Date: Feb 2016
Posts: 232
|
Quote:
Originally Posted by Tale
You would need to post code to be sure, but a wild guess: Are you using while()?
|
Here's my modified/mangled version of the Midi Repeater... It does what I need, except the "let's ignore a note if another note is coming in."
And as you'll note, my version only works for one note per instance, so in my case, if there is a second instance for another note (I'm using this for drums which is why I needed note filter), so it does this ignore thing on played notes, or notes "played" by another instance of the JS.
Code:
desc:Mangled MIDI Note Repeater
//tags: MIDI processing
//slider1:1<8,0,0.03125>Beats
//slider1:1<8,0,.0625>Beats
slider1:1<8,0,.001>Beats
slider2:60<0,127,1{0: C-1,1: C#/Db-1,2: D-1,3: D#/Eb-1,4: E-1,5: F-1,6: F#/Gb-1,7: G-1,8: G#/Ab-1,9: A-1,10: A#/Bb-1,11: B-1,12: C0,13: C#/Db0,14: D0,15: D#/Eb0,16: E0,17: F0,18: F#/Gb0,19: G0,20: G#/Ab0,21: A0,22: A#/Bb0,23: B0,24: C1,25: C#/Db1,26: D1,27: D#/Eb1,28: E1,29: F1,30: F#/Gb1,31: G1,32: G#/Ab1,33: A1,34: A#/Bb1,35: B1,36: C2,37: C#/Db2,38: D2,39: D#/Eb2,40: E2,41: F2,42: F#/Gb2,43: G2,44: G#/Ab2,45: A2,46: A#/Bb2,47: B2,48: C3,49: C#/Db3,50: D3,51: D#/Eb3,52: E3,53: F3,54: F#/Gb3,55: G3,56: G#/Ab3,57: A3,58: A#/Bb3,59: B3,60: C4,61: C#/Db4,62: D4,63: D#/Eb4,64: E4,65: F4,66: F#/Gb4,67: G4,68: G#/Ab4,69: A4,70: A#/Bb4,71: B4,72: C5,73: C#/Db5,74: D5,75: D#/Eb5,76: E5,77: F5,78: F#/Gb5,79: G5,80: G#/Ab5,81: A5,82: A#/Bb5,83: B5,84: C6,85: C#/Db6,86: D6,87: D#/Eb6,88: E6,89: F6,90: F#/Gb6,91: G6,92: G#/Ab6,93: A6,94: A#/Bb6,95: B6,96: C7,97: C#/Db7,98: D7,99: D#/Eb7,100: E7,101: F7,102: F#/Gb7,103: G7,104: G#/Ab7,105: A7,106: A#/Bb7,107: B7,108: C8,109: C#/Db8,110: D8,111: D#/Eb8,112: E8,113: F8,114: F#/Gb8,115: G8,116: G#/Ab8,117: A8,118: A#/Bb8,119: B8,120: C9,121: C#/Db9,122: D9,123: D#/Eb9,124: E9,125: F9,126: F#/Gb9,127: G9}>note
slider3:.0625<1,0,.0625>Beat Quant
slider4:1<8,0,.001>Qtz'd Beat
@init
status=0;
status2=128;
memset(status,-1,128);
memset(status2,0,128);
@slider
div=slider1;
note_slider = slider2 & 127;
beat_quant = slider3;
quant=div/beat_quant;
quant_test=div/beat_quant==floor(div/beat_quant);
div/beat_quant != floor(div/beat_quant) ? (
div=ceil(quant)*beat_quant;
);
slider4=div;
@block
midirecv(ts,msg1,msg23) ? (
m=msg1&240;
note=msg23&127;
while(note_slider==note) ? (
(m == 9*16 && msg23>=256) ? (
status[note]=0;
vel=(msg23/256);
vel<1?vel=1:vel>=127?vel=127:vel|=0;
status2[note]=vel;
midisend(ts,9*16,note+vel*256); // send note on
) : (m == 8*16 || m == 9*16) ? (
status[note]=-1;
status2[note]>0 ? (
midisend(ts,8*16,note); // send note off
status2[note]=0;
);
)) : (
midisend(ts,msg1,msg23);
);
bla=1;
);
inc = (samplesblock/srate*(tempo/60)*2/div);
x=0;
loop(128,
status[x]>=0.0 ?
(
status[x] += inc;
status[x] >= 1.0 ?
(
status[x] -= 1.0;
status2[x]>0.0 ? (
midisend(0,8*16,x);
)
:
(
midisend(0,9*16,x - status2[x]*256);
);
status2[x]*=-1;
);
);
x+=1;
);
@sample
|
|
|
06-23-2016, 01:57 PM
|
#8
|
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
IMHO you always need to do midirecv() within a loop.
Look at many example given.
I usually do:
while (midirecv(offs, m1, m2) ) ( // m2 contains both note and velocity
s = m1&$xF0; // Status
....
)
-Michael
|
|
|
06-24-2016, 01:41 AM
|
#9
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by RCJacH
Another quick question, right now the MIDI notes sent with this JS will not send midi note off msg (hanging notes) when I stop the host playback midway through a midi clip which functions pretty well otherwise, is there a way to deal with this?
|
I guess you could add All Notes Off (CC#123) support:
Code:
msg1 & 0xF0 == 0xB0 && msg2 == 123 ? (
// To-do: Release notes still playing here.
);
Of course you would have to track which notes are still playing (but maybe you are already doing that?). Or, if the receiving parties also support All Notes Off, maybe you could simply forward the All Notes Off message.
|
|
|
06-24-2016, 03:49 AM
|
#10
|
Human being with feelings
Join Date: Apr 2016
Location: Beijing, China
Posts: 215
|
Quote:
Originally Posted by Tale
I guess you could add All Notes Off (CC#123) support:
Code:
msg1 & 0xF0 == 0xB0 && msg2 == 123 ? (
// To-do: Release notes still playing here.
);
Of course you would have to track which notes are still playing (but maybe you are already doing that?). Or, if the receiving parties also support All Notes Off, maybe you could simply forward the All Notes Off message.
|
Thank you, I have added CC123 Chunk in the script, but the problem is that I'm not receiving the CC123 when I stop the host, even when I put the chunk right after midirecv (using a slider as boolean to check if msg received), and I cannot figure out why. I even separated the chunk, but I'm not receiving any CC or any msg2 == 123 when I stop the host.
|
|
|
06-24-2016, 04:42 AM
|
#11
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by RCJacH
Thank you, I have added CC123 Chunk in the script, but the problem is that I'm not receiving the CC123 when I stop the host, even when I put the chunk right after midirecv (using a slider as boolean to check if msg received), and I cannot figure out why. I even separated the chunk, but I'm not receiving any CC or any msg2 == 123 when I stop the host.
|
Assuming the host is REAPER, then you can enable/disable All Notes Off, and I guess the same goes for other hosts. Maybe you can use a MIDI logger to see if the hosts sends All Notes Off or not?
|
|
|
06-25-2016, 01:10 PM
|
#12
|
Human being with feelings
Join Date: Feb 2016
Posts: 232
|
The "magic 1;" worked! I added it to the note repeat and it no longer ignores notes at same time!
Yea!
|
|
|
06-25-2016, 03:20 PM
|
#13
|
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,793
|
Quote:
Originally Posted by DruMunkey
The "magic 1;" worked! I added it to the note repeat and it no longer ignores notes at same time!
|
I had been hit by this issue as well, and needed support from this forum.
It is due to the two different kinds of while - constructions (with one and with two bracket clauses). The one with only one bracket is "bottom controlled", which is not exactly obvious in the code. If using the two-bracket-clause variant, the "magic 1;" is not necessary. (See my example above.)
-Michael
|
|
|
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 10:57 AM.
|