Thu Oct 15, 2020 6:20 pm
so a few more words about timers and such in Scripter...
First, generally any of the javascript functions you normally might use in say a browser to set a "timer" that triggers a function call later at a predetermined amount of time.... these won't work in Scripter. Scripter operates in a very short period of time called a "process block". This is how all AU plugins work actually. Scripter is no different. When you have a chain of plugins, they each take turns doing their work on the current process-block..which will be some short period of time, likely closely resembling your buffer size.
Scipter is the same way. ProcessMIDI is called once for every process-block of time. During this short period of time you can call many javascript functions, but it has to execute very short and quickly...in much less time then the actual process-block...since other plugins also need time to do their work for that process-block, etc. So the idea is ProcessMIDI does some work, hopefully nothing taking too long, and then control is passed back to LogicPro...and there is no javascript context to fire off a timer event..
So what CAN you do...
you can use event.sendAfterMilliseconds or event.sendAfterBeats for one thing. For the actual sending of events, that works good for scheduling them in the future.
But what if you need to execute some Javascript code at some point in the future? Well that is the question then.
what you can do is use the Date.now() function to look at the current timestamp (in ms since 1970). Every time ProcessMIDI is called you look at Date.now() and you will know when so many ms have gone by, when enough have gone by, then go ahead and fire off your javascript.
That will work, but it's imprecise. For one thing, that will fire off javascript code to happen at the time the code is actually executed, which will always be ahead of the actual real time music. Javascript doesn't run in real time like you hear the metronome going by. LogicPro is always trying to run all kinds of calculations ahead fo the music. All plugins process their part of the process-block ahead of time and fill the buffer and finally when the buffer is flushed to your sound card later, then the results are heard. But the exact timing of when each plugin will have its turn on the process block, ahead of time...is not knowable. You will never know exactly when this code is executing in non-realtime ahead of the music. So this will definitely work...but its not completely precise. Depending on how accurate you need to be, this may work totally fine.
If you absolutely want sample accurate timing of things to happen, then you have to get used to working with the beatPosition every time ProcessMIDI is called. In that way you always run whatever javascript code you need to do, but the main thing is, if you plan to send out some midi, you schedule it on the proper beatPosition (which is a sample accurate fractional value) and the results will be exactly in the timing you want.
One downside is that beatPosition is not an exact amount of real time. 1.5 beats represents a completely different mount of time at one tempo compared to 1.5 beats at a different tempo. So how can you know when so many ms have gone by? You'd literally have to calculate it each process-block, look at the tempo for that process-block and use the beatPosition delta and guess at how many ms have gone by. But this is a little imprecise too.
well anyway, It depends on what you're wanting to do, but generally I would recommend you work with beatPosition if you are planning to output midi using correct timing. But there you have some options to play with.
5,1 MacPro 3.46ghz x 12 128gb ram, OSX 10.15 on OpenCore, Logic Pro 10.5, Mainstage3, Cubase10.5, StudioOne4, Reaper, DP10, VEP7, VSL, too many plugins to list