gary
Oracle
 
SuperPower
Posts: 130
|
Post by gary on Sept 30, 2017 20:58:50 GMT
Hi Nic, I am stumped and not sure if/how this can be done using the new syntax of Stream Byter II. I looked at this today and tried to work it out but hit a few roadblocks in my logic. I can load an array (can you load an array in a loop?) and I am unsure how to step through that array evaluating a particular value (namely velocity), add those values together, assign that resultant value to a var so i can then ultimately plug it into a midi note message. I didn't see a simple local var I could use (perhaps I missed how to obtain it) and I didn't see how the If/then construct as a loop would get me what I needed. Your the streambyter guru so... Nic, impress as you always do! In any case, Nic, here it goes an explanation. Premise: a simple old stream byter code example: # note on channel 1, note number D6 velocity 65 (studiologic has a finicky velocity D6 key) 90 62 XX = 90 62 41 This is brute force way taking a predetermined value, 65, to take the edge off the velocity of that key Here is what I want to do. # take an aggregate say of 10 prior note velocities played # add those then average or find the mean of those velocities # assign that value into 90 62 [?] similarly as above... 90 62 XX = 90 62 VAR # My thought is that by "learning" prior notes values/velocities that a value will be closer to match the previous played velocities of notes leading up to that key press sounding a bit more musical Perhaps there is a cleaner better way of helping this poor velocity key out; I welcome your thoughts....besides trying to get it repaired....  Thanks for your help Nic! [edited additional question] Can MidiFire receive a CC value from an external source, and that value be assigned to a VAR used for whatever purpose? If so, could you also give an example? I am thinking you can, but not as easy as this, keeping with the above example: 90 62 XX = 90 62 [var] # as var is set by an external source say mididesigner. If there is a cool way,please share. Class wishes to learn a bit more thanks nic!
|
|
nic
Soapbox Supremo  
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 2, 2017 11:51:07 GMT
Hi @gary , I'm going to answer you in reverse order! (since that will make more sense) Yes, you can retain elements from incoming messages into an array variable using the Stream Byter II extensions. Let's say you want to retain the most recent value from CC 60, channel 1 (hex 3c) into a variable (we will use L0): # store value of CC60,CH1 into L0 IF M0 == B0 3C ASS L0 = M2 ENDNow that L0 can be used in subsequent messages (or even the current message). You could also store this value into G0 and that value would then be set globally and could be read by other Stream Byter modules on the canvas too. Note that variables cannot be used with Stream Byter I rules. So, on to what you really want; find the average of the last 10 notes played. You probably want to average out only within a specified time interval since you could have played it softly 30 seconds ago and then when you hit it hard, it will average out with that soft note you played ages ago. Maintaining a time limited FIFO of note velocities probably could be done in the Stream Byter (would take a lot of coding), but I think there is a better way: What you want is actually what the Tracking Clamp does. You could filter just that note into the tracking clamp, set it up to clamp only on velocity and it will average out that note's velocity in a time limited fashion. Finally, I do intend to add internal looping in Stream Byter II, but you can actually do looping using SND +I. I attach an example scene where once loaded, it sends out program changes 0 to 3 with 100ms delays in a loop. I've commented the Stream Byter code in that. Regards, Nic. Attachments:Scene-Looper.mfr (1.68 KB)
|
|
gary
Oracle
 
SuperPower
Posts: 130
|
Post by gary on Oct 2, 2017 13:37:00 GMT
Hi Nic, Thanks for your comments and suggestions. I jumped right into this to give it a spin... Here is the approach using the Tracking Clamp module; I'm not seeing a difference. I filtered out and isolated that one key and applied the Tracking Clamp, velocity compression only. I set it's degree to Heavy, with hopes to see a dramatic change (i tried other settings too with same results). It's possible I am not understanding how this could/should work or my configuration is not correct, but logically it's clear I've isolated the key to send through the clamp. Here is a quick screen shot below; I forked out the logic as you can see..event monitors before and after clamp...{SEE EDIT BELOW}   [edited] ..after looking into this further, I realized(i think) the Tracking Clamp needed to evaluate all the played velocities as they rolled through... that point was not clear to me before. Anyway, so i routed ALL pitches to the Tracking Clamp (see pix: from the upper left quadrant block-event monitor) as well as from my filtered pitch segment of code. That seemed to work, okay, with a setting of Light, after a bit of trial and error. Cool caveat: if I am understanding correctly how the Tracking Clamp works, if I decide to repeat D6 the velocity compression module becomes 'not helpful' with nothing to compare from before, ending in undesirable results. Further, if the passage starts say on D6, the outcome will be the same undesirable result. It appears that further smoothing would be needed and be accounted for, so I'll need to accommodate for that with other coding ... sigh, work in progress. It seems that moving 'up to/towards that Pitch/D6..,' I can use the Tracking Clamp to help a lot with 'averaging' of notes velocities etc. However, all of that logic is no help if the passage starts with D6 or that pitch is repeated, without placing a brute force velocity limiter if you will, on that key. I smelling a Stream Byter II logic module to help with that... OR, "Hello, Studiologic tech support..."
|
|
nic
Soapbox Supremo  
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 3, 2017 11:35:19 GMT
Hi @gary,
So, I've been deliberately vague about the inner workings of the Tracking Clamp as I'm still experimenting with this myself. Both the Tracking Clamp and Robotic Knob are going through a refinement process as I have certain plans for them!
Anyhow, let me detail exactly what the velocity clamping is doing first:
There is an internal list maintained of previously received note ons in the module; the history list.
When a note on comes in the following happens.
- The history list is first purged of all events that have occurred in the past over a certain threshold. Heavy = 100ms, Medium = 500ms, Light = 1000ms (so, Heavy means you are playing quickly and Light means you are playing slowly) These numbers are arbitrary!
- The 'current' events in the history list are then used to calculate a velocity average. The maximum number of events used is Heavy = 12, Medium = 6, Light =4 (again based on the speed of play)
- The received note on's velocity is then rewritten with the average just calculated (as long as it isn't zero).
- The received note is added to the history list
So, if you stop playing, the history list is emptied over time depending on the degree (Heavy/Medium/Light) and averaging doesn't start until there are at least 2 notes in the history. But (I think this is a bug) the second note will have its velocity rewritten to that of the first note in the history.
Explaining this has been helpful to me! I need to think about this some more (for my own purposes)
Having explained the above, let me focus my attention on your issue in the next post!
Regards, Nic.
|
|
nic
Soapbox Supremo  
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Oct 3, 2017 11:45:35 GMT
If your goal is fixing a broken key that is generating wild velocity fluctuations, maybe this can be settled more easily by clamping the entire velocity range. You could do this with a 128 byte lookup table (ie. a velocity curve) or maybe just some simple range clamps are sufficient?
Something like:
9X 62 01-0F = XX XX 10 9X 62 10-1F = XX XX 20 9X 62 20-2F = XX XX 30 9X 62 30-3F = XX XX 40 9X 62 40-4F = XX XX 50 9X 62 50-5F = XX XX 60 9X 62 60-7F = XX XX 70
So you do lose some velocity resolution on that key, but maybe that's sufficient?
I guess I'm trying to avoid trying to write a tracking clamp type module in Stream Byter code :-)
Regards, Nic.
|
|
gary
Oracle
 
SuperPower
Posts: 130
|
Post by gary on Oct 8, 2017 14:10:23 GMT
Thanks Nic for your insight, I'm going with a simple table range clamp to suffice for now. In the mean time, I found a 'local dealer' who can assist in fixing the problem for my controller until then I'll use the simplest approach. Thought we could use this as a 'teachable moment' but ... meh, why? Thanks for the more in-depth explanation of the Tracking Clamp; I'm happy to help. I hope talking 'aloud' has helped you in some way.
|
|