Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 11-19-2017, 08:02 AM   #1
pcartwright
Human being with feelings
 
Join Date: Jan 2009
Posts: 1,030
Default MIDI String: problem pulling necessary note information from notation

I'm writing a JSFX effect that sends note-off messages early when articulations are encountered in the notation editor. For example, forcing notes with a staccato mark to be no longer than n milliseconds.

The code below is how I pull the note information from notation if the articulation is found. The MIDI string is #string.

Code:
match("%{foo}s*"
   " ""%1-2{channel}d*"
   " ""%1-3{notenum}d*"
   ,#string);
The code works as expected for most articulations. In the example below, channel receives a value of 0 and notenum receives a value of 62:
Code:
"NOTE 0 62 articulation staccato"
However, things get messed up when I add a slur into the mix. The example below returns a channel value of 0 (good) and a note value of 1 (not good).

Code:
"NOTE 0 62 articulation staccato phrase 1 slur begin"
Clearly, the notenum line of my code is capturing the third numeric found and not the second, but I'm not sure why. Any ideas?
pcartwright is offline   Reply With Quote
Old 11-19-2017, 01:34 PM   #2
ijijn
Human being with feelings
 
ijijn's Avatar
 
Join Date: Apr 2012
Location: Christchurch, New Zealand
Posts: 482
Default

This is because your matching approach is greedy for the * after channel: there's a suitable candidate for notenum (1) later on so it gobbles up the middle of the string. You'll want to use lazy matching with *? instead.
ijijn is offline   Reply With Quote
Old 11-19-2017, 07:17 PM   #3
pcartwright
Human being with feelings
 
Join Date: Jan 2009
Posts: 1,030
Default

Thanks! That did it, though I had to add the '?' to foo as well. I suppose for the same reason; another more suitable string that contains a decimal afterward?

EDIT:

This is the first time where the concept of greedy vs. lazy had any impact to a scrip or JSFX I developed. Why would the example above with the original code not return 62 for channel and 1 for notenum? Is it because the match function knows I'm looking for two integers?

Last edited by pcartwright; 11-19-2017 at 07:24 PM.
pcartwright is offline   Reply With Quote
Old 11-20-2017, 01:59 AM   #4
ijijn
Human being with feelings
 
ijijn's Avatar
 
Join Date: Apr 2012
Location: Christchurch, New Zealand
Posts: 482
Default

Glad you got it working!

Ah yes, you'll most likely need multiple ?s to get everything in place. I need to use lazy matching fairly frequently, as the greedy ones often get carried away! I typically like peeling things from the left of the string, and lazy matching works wonders for this.

Hmm, I agree that it does seem counter-intuitive. Just about everything is greedy in your example (the named string, the integer captures and the *s, but not the single spaces) so it would be hard to predict a particular result in advance.

I think that using a right-to-left lazy matching protocol for a greedy left-to-right effect would probably produce the 62 and 1 you would expect but maybe this is implemented slightly differently with some subtle priorities in play. I'm certainly no expert in this area so take with a grain of salt. Really, whenever I find myself in a situation like this I just look for ways to make the match more secure.

Also, if you removed the * between the channel and notenum, that would pin down that part more precisely as two adjacent integers, which can be helpful.
ijijn 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 07:19 PM.


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