Old 10-30-2008, 02:31 AM   #1
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default Q - MIDI Note truncation in JS FX

Here's a JS poser for you guys. I've tried a few things but canot solve it.

Let's say I have two consecutive notes and shift the first one later in a JS FX, so that the notes overlap. The first note then ends when the second one starts but the second note ends when the Note Off for the first note is read. The Note Off for the second note is redundant and is ignored.

Here's a screenshot:
[IMG]http://img112.**************/img112/4920/dsmiditruncatemp7.th.png[/IMG][IMG]http://img112.**************/images/thpix.gif[/IMG]
Big pic:
http://img112.**************/img112/4...runcatemp7.png

- look at the dark blue notes only,
- the 2 notes at C1 are my starting position,
- the notes at G0 are what I want to achieve,
- the notes at A-1 are what I end up with.

- now look at the light blue notes,
- I have moved the second notes down a semitone to show what I believe is happening
- the notes at C1/B0 are my starting position,
- the notes at G0/F#0 are the positions after the shift,
- the notes at D0/Db0 what I want to achieve,
- the notes at A-1/G#-1 are what I end up with.
- the first note is ended by the second and the second is ended by the first's Note Off.


Is there any way that I can get what I want?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...

Last edited by DarkStar; 10-30-2008 at 02:32 AM. Reason: (missed the title !)
DarkStar is offline   Reply With Quote
Old 10-30-2008, 05:24 AM   #2
MichaJo
Human being with feelings
 
MichaJo's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 1,772
Default

The midiSwing plugin does it. Here is a textual explanation of the different ways to handle the note-off events, quoted from the kvraudio forum (http://www.kvraudio.com/forum/viewto...=asc&start=620)

midiSwing update:

http://thepiz.org/xt/midiSwingX4.zip


among some other minor improvements (including useless presets), i added a "NoteOff" parameter which sets how note-off messages are handled.

- Equal Delay: old mode, note-offs are delayed by the same amount as note-ons, so original note length is preserved, but this causes notes to overlap

- Stingy Delay: note-offs are delayed only for short notes (when the delay is longer than the original note), so swung notes are usually shortened

- Legato: note-offs are delayed by the same amount that a note-on would be at that position, meaning that if you input notes without any gaps between them, it should stay that way (the note before the swung note becomes longer)


The legato mode should be it and works fine in Reaper.
But it was really nice if this functionality could be a part of midi-editing/handling in Reaper's Midi-Editor.

Last edited by MichaJo; 10-30-2008 at 05:40 AM.
MichaJo is offline   Reply With Quote
Old 10-30-2008, 05:39 AM   #3
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

Thanks, MichaJo, I'll give that a go.

... but I should make my question clearer "How do I do it in JS"?


-----------
almost works for swung notes, but it truncates some notes too.

[img]http://img207.**************/img207/428/dsr253piz01gm8.png[/img]

__________________
DarkStar ... interesting, if true. . . . Inspired by ...

Last edited by DarkStar; 10-30-2008 at 05:49 AM.
DarkStar is offline   Reply With Quote
Old 10-30-2008, 06:26 AM   #4
MichaJo
Human being with feelings
 
MichaJo's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 1,772
Default

In legato-mode it should work but i've noticed too, that it doesn't all the time...maybe a bug.
So just write the JS for Reaper!
OT: How did you manage to display the midiswing with it's own GUI??
I just get it that way no matter how often i click on the UI button:
Attached Images
File Type: jpg MidiSwingUI.jpg (18.8 KB, 277 views)
MichaJo is offline   Reply With Quote
Old 10-30-2008, 07:03 AM   #5
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,889
Default

MIDI_DuplicateFilter tracks note on/off messages. If I remember correctly ( it's been a while since I wrote it) I think it would give one long note starting at the first note-on and ending at the second note-off but I don't think it would be too difficult for you to adjust the behaviour to achieve the result you're after.
IXix is offline   Reply With Quote
Old 10-30-2008, 07:04 AM   #6
helpdeskeddy
Human being with feelings
 
helpdeskeddy's Avatar
 
Join Date: Apr 2008
Location: Grunn (NL)
Posts: 234
Default

I don't know if there's an easier way to do it, but one way would be:
- count-up (in an array for every note) when the note-on command is received
- count-down in that same array when an note-off command is received
- let the note-off command pass through, only when the counter (of that particular note) is <= 0

You should probably add a couple of safety nets for this counting (like reset, no counting below zero, sustain pedal...)

Haven't tried this... but it might work.
helpdeskeddy is offline   Reply With Quote
Old 10-30-2008, 07:25 AM   #7
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,889
Default

I think something like this is what you need. If I had more time I'd knock up some actual JS but...

Code:
if event == note-on
{
   if noteTracker[note] == 0
   {
     pass note-on
     noteTracker[note] = 1
   }
   else
   {
     send note-off
     pass note-on
   }
}
else if event == note-off
{
      pass note-off
      noteTracker[note] = 0
}
IXix is offline   Reply With Quote
Old 10-30-2008, 08:02 AM   #8
MichaJo
Human being with feelings
 
MichaJo's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 1,772
Default

@IXix:
if in your MIDI_DuplicateFilter you would just omit the condition tracker[note] == 1 ?,
wouldn't that have the desired effect?
Code:
while
(
  midirecv(offset,msg1,msg23) ?
  (  
    //Reset pass flag
    passThru = 1;
    
    //Check status byte
    status = msg1 & 240;  //High four bits is message type (240 == 11110000)
    channel = msg1 & 15;  //Low four bits is channel number (15 == 00001111)
      
    //Is it on our channel
    channel == inChannel ? 
    (
      //Is it a note event
      status == statNoteOn || status == statNoteOff ?
      (
        //get note number
        note = msg23 & 127;
        
        //Get velocity
        velocity = ((msg23/256) & 127);
        
        //Update counters and flag to pass if needed
        status == statNoteOn && velocity > 0 ?
        (
          //Note On Event
          tracker[note] += 1;
          tracker[note] == 1 ? midisend(offset,msg1,msg23);  
        )
        :
        (
          //Note Off Event
          tracker[note] -= 1;
          tracker[note] == 0 ? midisend(offset,msg1,msg23);
        );
        
        fix = 1; //If there's no code here it stops working. Weird.

      ):midisend(offset,msg1,msg23); //Not a note, pass thru
      
    ):midisend(offset,msg1,msg23); //Not on our channel, pass thru
  );
);
MichaJo is offline   Reply With Quote
Old 10-30-2008, 09:43 AM   #9
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

Guys,
Thank you for the pointers. I'll go and explore those approaches.
Quote:
OT: How did you manage to display the midiswing with it's own GUI??
Ah ha - I used asseca's very powerful mGUI to create a wrapper for the VST and designed my own graphics (not published).
http://www.asseca.com/mgui/index.html

and some examples, including several for LOSER's VSTs
http://www.asseca.com/wiki/MGUI/HomePage

That gives me an idea ...
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 10-30-2008, 11:07 AM   #10
MichaJo
Human being with feelings
 
MichaJo's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 1,772
Default

Aaahh...okay - (me still clicking the UI button, can't stop it) - thanks!
MichaJo is offline   Reply With Quote
Old 11-02-2008, 04:36 AM   #11
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,889
Default

Quote:
Originally Posted by MichaJo View Post
@IXix:
if in your MIDI_DuplicateFilter you would just omit the condition tracker[note] == 1 ?,
wouldn't that have the desired effect?
No, that would just produce the normal behaviour. I think the following would work but I haven't tested it.

Code:
status == statNoteOn && velocity > 0 ?
(
   //Note On Event
   tracker[note] == 0 ?
   (
      midisend(offset,msg1,msg23);  
      tracker[note] = 1;
   )
   :
   (
      midisend(offset,statNoteOff|channel,msg23);
      midisend(offset,msg1,msg23);  
   );
)
:
(
   //Note Off Event
   midisend(offset,msg1,msg23);
   tracker[note] = 0;
);
IXix is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:10 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.