Rendering a "sequence" in the DAW not working
-
Okay i spent some more time on this and reviewed the code...
At least part (if not all) the problem is the sequencer has variable step lengths....each made up of a number of segments.
So I start out by getting the segment lengths like this:
switch(LengthSelection.getValue()) { case 1: // a 1 bar pattern... segmentLength = Engine.getMilliSecondsForQuarterBeats(0.125); break; case 2: // a 2 bar pattern segmentLength = Engine.getMilliSecondsForQuarterBeats(0.25); break; case 3: // a 4 bar pattern segmentLength = Engine.getMilliSecondsForQuarterBeats(0.5); break; case 4: // an 8 bar pattern segmentLength = Engine.getMilliSecondsForQuarterBeats(1); break; };
Then in each sequencer step I read the number of segments in the step, calculate a millisecond period from that, play what needs to be played, and then tell the timer to wait this period before starting the next step....
So in high-speed renders I'm assuming its getting the timing all wrong...as the number of milliseconds in a segment is now incorrect...or does HISE manage to compensate for this?
What is Engine.getMilliSecondsForQuarterBeats(n) returning when its a high speed render?
I've also rerendered with a midi file used for playback and it renders perfectly at high speed - so its not a hardware issue...
-
@Lindon I'm not much help here because I haven't used any of these functions or done this kind of thing.
What is Engine.getMilliSecondsForQuarterBeats(n) returning when its a high speed render?
Debugging through Visual Studio might be the way to gain some more insight here.
-
Okay well heres a trivially simple project that displays the milliseconds for a quarter beat ever time it gets a note...
compile this and run it across a midi file (with a note) in it in reaper and it displays 500.0 at 120bpm.
reset it to zero and do an off-line render ---and it again displays 500.0 -- which is making me think :
Engine.getMilliSecondsForQuarterBeats(1);
ISNT playing nicely with off-line rendering.. so all my timings are screwed up...
HiseSnippet 770.3ocsUssaSCDDc2jrPSfJQk3IdxpOkJUprgRAIDhPtghnWBjREuUs0dc7pZuq050sMBgDex7G.yZ6F6TRqPQT+PTlKmwmLyYlLVIcYIIREB273YwLD9wjIyD5fdATt.MpOB+LRDOLjmvbkBui782mKXZVh11A0cVLMIg4gv35ezjOtYCT1yudeWZHU3xJcgPmH4tr84Qbco2wc9DT8gTO1w7nJYuamQv6qmLTlBbqNwFEScOmNkcH0jVMBB+fAdbsTMQSA5fvM5J8lMIPdoHO+S3I7yBYFCGzDnP4tGJC8LL13E0KfG5M95dPBBpx3xNR87NxSIGv83y8W1YdRV.qRDU6G3ZKRu5KPOmpzytB8VBkvUnTibJsAYhqhGqKiX3yiHiDZlxmBs8pTIOWTscwjdRHCgdmH54rgJvXNh16YausE7wVusUKn0mnstfpr1mdFKzw5cVWibJS2SFEKEfQ6MyCuoASK+TgqlKEVRwgRM6HQ6sZ88VMySYmDFjtlckdyssFHlBhHSoNvHsljIsRFJUeNkp.9zkQ0Isc1BJ6OZYcy556mW3aDyPPkLLjoVZXi7RcW.aKRiNio1F9YGlxlmHzyWbPRt8AYUclad+pRhRwHAWeTLSbapOTQSF91WG0mpoloegOHuXlRyMT.2mcArJkqEZR5yRNWKiyxsXxfvOTmEc8BkR1T.wA8vZj7IB5p4aa+zuyrRiS5bI2SGL2QGYm.FeZft51oYRhvsH1EOvl7eoRg8CoWZHUu3Ri4RQQ.X.rfR0nFEIb8rpWR9usI8uRwMHi4Z2fkywZKgivX59fiE2eVmLv2m4pKIXCxvuc+brA8EYplKld.Uq3f.gbXZzD3DrKCd6BAKzr.fqYjp411FaSGXBS3kY7a3oHniwFWDz45fnHpqRdpa9Zm4B2ZYd.NIxNt2jbfw1xAksJB3H16Xihfism55Z94+bX6Y4XdwJf4kq.lcWALuZEvr2Jf40q.l2bmXL+O2GR0xn70Avw3AY2mv3ABJnrxTgn+rea6PA
-
@Christoph-Hart -- OK I have my t-shirt on, is there any way you can help with this one???
-
Ok so more testing in this one , and clearly I dont understand timers AT ALL...or they are broken badly...
heres a simple snippet that waits for MIDI note 60 then uses a timer to play a quarter note evey 1/2 bar until the MIDI note 60 off...- this works fine in HISE, but as soon as I compile it and run it in Reaper it fails (it just plays the held note...)
HiseSnippet 1110.3oc2W89aaSDF9bSMBmwPLzDhOZj.oTotn3xnfDZZsMMYJhklPc1fuMc090IG09Ny4yAhP4+Q9SY+G.u24jZ6RVUHhgXjOT468G2879bu2yccrTD.YYBIwxYxhTfX8A19K3pYcmQYbxfyIV22dBKAjSfLUmiHmsHklkAgDKqFOSGhky9DyuW+zynwTd.TZhPdofE.OmkvTkVGex2whi6SCA8DWZ+wmLHPv6JhE4HbZX2gjRCtlNEtfpCaOah060KjoDReEUAYDq8OSDtvel3W3Ew+RVF6pXPOvi3iSTg49h3PMh0VIcmwhCGutryHDK6wkjPiBR3g1CYgrarWRFejwgaYFU4Cq8pCuF0fmWU30oB71.jrp.o8KfzCr8CjrTUoGMdtm8.tBjQTj1qBkhXI68EMr6JvH3p1Izqg9RbvMYz53NcNzE+yAeaylyoR2jEWHTvfyceh6i7Pa31QlxsvyXPxDgnmd7oLNzdJnFhaiLe.iJLquP984TINymATUVKuCtU9llnxzCjXXlF.4nq9IHP0RmvpvZmAJyGcowwWgMAshx4AJlf25feqoSSmzX5hgFvpSyo4RcxqiwspWLbVTqxBSWYGzzAM6ToZMs7s04Yx53NG5cjlUbVBwYfN3hH3n2QQQmsn2bjRGDdyDqi04VzmyRGMztAVBt18HrFZhy3PbSD6saylxERvLesTxbPWIZHu1Oxy5ztHO4JP15.cEbbmUUvsnAmanOEtSX9r05MNieDRMW1z81HJJp.Ra4pVagDoEqiY9YQtkT8m8DCSaRYqnukajCqQf5dYoHNVufZDeqpYET1fmUI1haJnCwdxXjpWGHdHq9IW627I2pBKAEGspDnfOfyTiRA9aRtgr57H90KFbNUQ0G2WYCiKEjJlFBVmCyQsyhC+N1mCYWijMpd9WTFPMIQXdLUUWnRqNuxAxA0TGzJ.7LlZQU06+wTu1VH9.6wLUvrMiw81.FQl5sAFWo4ee6dQQnPTI.22t+O91Qfu5x+gEK+8r8QcQy4Dyh+Ilwt+.cN39LfCRM44cG2+96a68uoa88uiBT3xOQR4YohrZSrOjvlH3ZVnz3KxvaXfe9R8tYU6cET4Fc85m1GKxMliOUkKMsEmlHx4pZsAMtq2A3siuCX++y8Nf2ANrW6oJNqwnOKIMF5wmCwnhlAieLJgEQyiUqsVuWdnfKRmI3rfpazWBJIa5TPVE6arfNUov2ITZ4gmbIDCzpMse9IOGa1nRjmfcjK79a+rsMte8o1Ev0Ue.z8cWQ5F++Vj9RQthwmNjhMg+J9n.70P9n1X.fqNmiuLDsYsmVeqXbG83BwQdnYvef+V4zSO1ZkSu0N+WYMRnARwqBJdBjtO88MVv5la9OqbrGpG65QLOKByytS6NjDTg6UAAZJ9Qnf4ly4ncHmubGx4w6PNe0Njyw6PNe8Njy2bm4nub4zbkHo3HGZXbOyaEsr5woX2qoSm7mfWyiji
Can anyone else test this is the behaviour they are seeing(hearing) too?
And any pointers about timers would be a great help...
-
@Lindon I get the same thing. I didn't bother testing as a plugin, I just built a standalone and the note plays continuously. I'll see if I can find a solution.
-
@Lindon I solved it. You're only getting the period in
on init
but you need to get it inon note
. I'm not 100% sure why this is but I can see it would be good practice to get the tempo at the time you need it as it might change after the plugin has initialised.function onNoteOn() { local myPeriod = Engine.getMilliSecondsForQuarterBeats(1); Message.ignoreEvent(true); if (Message.getNoteNumber() == 60) { playMyNote(); myTimer.startTimer(myPeriod); } }
-
@d-healey thankd - slightly odd though - why would setting the time period have any effect on the playback?
-
All will be revealed.
const myPeriod = Engine.getMilliSecondsForQuarterBeats(1); Engine.showMessageBox("time", myPeriod, 0);
Basically the timer never runs.
-
@d-healey sadly it still never runs in the compiled VST3... no matter where Im setting the timer....so its still broken.
-
@Lindon I shall investigate
-
so:
function onNoteOn() { Message.ignoreEvent(true); local myP= Engine.getMilliSecondsForQuarterBeats(1); if(Message.getNoteNumber() == 60) { playMyNote(); Engine.showMessageBox("time", myP, 0); myTimer.startTimer(myP); } }
gives this output:
-
It's working here. I added a visual indicator so we can see that the timer is running.
HiseSnippet 1250.3oc2W80aaaCDmJNZnxcYXcnXXOpUrGjARMrx5xVPwPchicgwpS7hS61SqfQh1lKTjpTzoynH.6q2daeT52fsijRVxYNAYFqCqynnP73c79c+g+3kgRQDIKSHQNdmNOkfb9P2Qy4poclhobT+CQNa4dJMgHOkjoZsC5f4o3rLRLxwo1S0p33sIx76sO4.LCyiHkhPnWHnQjmQSnpRoCa+cTFqGNlnO3R4Opc+HAuifIlAvolaKTJN5b7DxQXsZa3hb9ftwTkPNRgUjLjylGHhmOZp30bq9uflQOiQzKBQifCxJtmfEqQrVJpyTJKdXQXmgPNtCKSB0rIg66NfFSWHuLY7wlM7KsnZ9vYikgWskfWXU30pB7VAjbp.oMsP5dtihjzTU4NZ7bW29bEQNFCo8pPwpKZieqlaGAnAW0LAeNomDVrvhfca0Zae3+Z7350kjI9IyORnH8Oz+a8e3d6ABg5QlBDa5..oc4SnbRyHIAhPiviO6mIQp.8IjqVyLhx7QGLicFTACFOiGonBdPi5uwqtWJCOefwSZy7Fh4DVXSIIERxlS5R8oQ4LvU9E15W0JywPG6GTBXChaT26M087pDFld4lZaMVtKDug6niWuKq6QXYDqEV03fJGOd7Ay6dAjv5Gu33056c0jCbBWVjgt.K8swAraQBeBQ0QjjJ3vhfGX29A5PKOhg7zPcHehXlBB0xzzDH.q6Mo4X3Zx9LVv.L.NIlGCUtfvV1ea6uW9WsZXyYKRUBtFoGax208XhHLCpgCIRpHtrHBva.3.5HBDCwY8DxueFVBsFG.E2rfPMR8F.sZvMvlzIbgjXxKAJ4LhYScEnPA3zzN8nYImQjAMzEjcakWOtRA2aQihB7m4yfB303wdd1Lq+UCmwiswysxq5SoheDoV2XbO7uk5c97hdmaSev0zHTAr5xuTvXZ2ow6UhkbfrhcxMLfahlsglJFjnKTDHBVlcw85YWpR9EY6Fqnnf2mSUGmR3WGkHJuEF9548ODqvZJobYfdoDohpgfygjK.9cKAkm6gjrygTsQ279dfxVY1cqB5KcuOhBjT2w0dO.8KkOAD2dd0EulFqltPvu9p1SIzISq7TxO0F8WYJANZQ7LFVsLws90p7Mf78RrkZFQdFUMu5qY+iwleag38bGRUQSWMF2XEXDpJuKvX9afa41c7XfauDfa516Ge27fWU2+QV2eW2Q.Kk4Bow4epYs+Ofuf3+TBmH0IuvaXdje+1NOR5sddjiiTf6OEnhyREYKcviHIzSgV9rpBedF7hK4UmnqlUk2Qfkqbq29jdPPtRaFgUyjl1h8SDy3pkZCpcSyEEtlyEs4+4lK58fK6KM5lWAFGQSRYjt7KHLf8zfwOAnKGimwTERWtWdffKRmJ3znpE5SHJIcxDhrJ1WY.suRAidUJ49sOgvH3pMseQ6mAMaXIjmHqYtH7u8Xrqrd8YtV35qu.5+9KIcs+eSRaGTcBLNpjBOZ6BicMB3FiHf24vS45gRb1PyuYW2Ru1RNxiMK9C3W9lg50N4aFVr4+J9HAGIEuLxNtktO8NFIPbyM+kldtCzq8CQlQv.6ba0rEJAX3dYTjNE+Pfvb01ryZXyWtF17n0vluZMrY20vludMr4atQazOtr+LkHwdkCDLrqYtTGmtbLz8Z5zQ+IXoWQx.
-
thanks and so now we get to the ACTUAL problem....
Load this into a track in reaper, and render the track....this is what you get:
So the timer DOES NOT WORK in off-line renders....and this is very very bad because some DAWs(I'm looking at you Logic) are really bad at real-time rendering... and some (I'm looking at you Reaper) do not offer out-of-the-box real-time rendering for tracks....
Can you please go confirm this is correct...(that this is what is happening for you too..)
-
@Lindon I get the same result with offline render. Realtime render works as expected though.
-
@d-healey thanks -- so yes, same as my results - so this is a BIG problem...
@Christoph-Hart !!!!!!
-
so this is a BIG problem...
Yes I think so too. I also tested using a fixed interval of 500ms and the result is the same, so it's not related specifically to the tempo functions but is a problem with the timer in an offline render.
-
@d-healey yeah this all started with a plugin I wrote that uses fixed time rendering -in truth there's more than one of them, and they are ALL failing in this way...
-
@d-healey -- I'd imagine this breaks your legato scripting badly....
-
@Lindon said in Rendering a "sequence" in the DAW not working:
@d-healey -- I'd imagine this breaks your legato scripting badly....
I am testing that right now :) Actually I think the legato will be ok because I'm using the built in fade functions, but the portamento/glide is controlled with timers. I'm also going to double check older versions of my plugins to see if it used to work. If so there is hope :D