Simultaneous array access between UI and real-time processing
-
You might get some race conditions, but the worst you can expect is some UI flickering (assuming you read from the UI and write in the audio thread, the other way around it would be more critical).
-
@Christoph-Hart Ouch... it is, in fact, the other way, writing from UI and reading from block processing... If not possible then how can we create an envelope on the UI and make it work in a script processor?
-
@ustk said in Simultaneous array access between UI and real-time processing:
If not possible then how can we create an envelope on
How are you creating an envelope?
-
@d-healey With a panel and a lot of caffeine :)
-
@Christoph-Hart Bumpy bump :)
About UI writing an array while process reading it? -
@ustk I'm doing this too and I think it does occasionally crash the plugin if you catch it in the wrong moment.
-
@Christoph-Hart What if I update the array in the noteOn, before the condition (isPlaying) that allows the processBlock to read it? Will the array be ready for the process function in time?
note on:
- update array
- isplaying -> true
then in the process:
- if isPlaying -> read the array
Safe enough?
I don't mind updating the array after a note is played... -
So I still get some rare errors when the process is reading the array, despite that the security is set after the array update in the noteOn, meaning the array has not finished updating when the process begins... That's bad... @Christoph-Hart How can I secure this?
-
Can you make a minimal example? There are a few synchronisation mechanisms built into HiseScript that allows locking multithreaded access, but I need to look at the exact use case here.
-
@Christoph-Hart Thanks, will do tomorrow morning ;)
-
@Christoph-Hart Here's a snippet of the principle. This is not throwing errors probably because of the simplicity of the thing, but imagine something bigger... A timer updates the array to keep the snippet simple.
HiseSnippet 1427.3oc4Xs0aaaCEVxIpn1cYXanEaOrGHJFJTPxLjxZ6Ff6kbuKX0MFwYsCnnnfVh1lKRjBTTYynn+w1Ka+T19Grm1qaGRJaIE6j5ZrrhsoGbDOWH+NmC4geJcD7.RZJWXYW+3QIDK62yo6Hlb3NCwTl0A6ZY+9NswoRh.YDs8nDbZJIzx1doGoDXWeYK8yu+vswQXV.oPjk0S4z.xiowTYgzNa9Mznn8wgjiowkr91adP.msCOhmA3YIGOqDbvI3AjmfUlUywx9J6ERkbQWIVRRsrWdad3ntC4+.yX+SoozdQD0.eqtvDYDuOOJTgX06V6LjFE1YbbmZYY6zoHKrjIKbcm1zP5D4EYiOPq.U3Q47gcsKBd9KH7rKAukMv6Cc5FHnIxBMJrcMmCXPgpOFJAkgkwVqZ+gsyNbvBlrYL9Dx9BXvDObuqm25n634sZqFMZLHh2CGghAziEjvsDB7Hz8QO+EsZTQVSAIkHNk356o7bEvUnDlJQmhEHITcEfW6wFPYjlABBjVTkbwg89dRfzUsTZiZlRjZE6fih5AEc29Yr.IkybWckFuZkFH3oOWfbo22qE8dpUqEcs0V0nALnt5uUf1you.V61X4vlBLKjG6pvmxrW230vJmuvRrvrzpPPG6K3yXDi3rmvkjCAn23UMp230MPmUU+9yTmp3H3QQ.VlkZCJu.GcYYw8Hh0gjeTFYhgvtlpaKu17ssLvrWojgb1ALp7vDR93hMtJclndrVOqIAaYQEwXYolMESaVgnoOWXkuWFd6aOXWrDqNpjKCrKgHjTUzZuK4TnGj4fScmcIomH4IPWnoNUAms4gYQXY0C7ptb4JfzckSVpSOrTpbT4tfuEcA7lYW.+YEsyIb+PmNTYvvYi2Zy.uPV6xFu48TWwYu98gi8EfcYm8+tEsA5hAkaXfx0bdF9Th9hNMPtgdLzfIF8HBiHT4T+y8pts13ml2q5Rl6q5NLPBP3XnUUZBOk3WZl+kynaiR6194cIxLVEysLh1nrHU3sODd9k2nNVXIKu5lcvrJSFLtxL0l9iEC+0GtGCCEjtDHZBOLM.BVUtq7pzIKJk7LZnbneYGKDuQYweMVDB0kfJaPWZgtVs541R1Oi6Xux6.J.+8e3+RsW0aAikZkvqiAueZNiE0wfmhETLSNI.zXGka.RYAJ2DzDa7eywxXZN+VMmBNHQzd.KfGS6IfYjj1LhiCcuY.WPtIbYegcCfDGXHXdNOE8JSbuYZLmKGRBeoxBhP4UC0qJJKcvBfYJPfxUKoq1TJafJDlvkRPFfB3YPvbejWK8PZZmH7HvPPTeLbNnUA6gDAIA3vbLWYhaJNNIhbDfm0Ql2S6PDaGwCNQe+tdcmeWZA7AJsR5hjViauLn2rPMmJFRz9HWCluWURUMiHrAxgnacqhfXUCGL8upmyI6n1Zt9YnnoWiW.vZruZAqsVqbdZpeIP9opdShrtVneSOzCd.x.+b9cSRKSGeUR.kIpY7rbgQJxf5R8Rq34xjaZmyqpmu2uAtdWNL5NK+sJabJ3ZUNwMEctEif2T74llb4kJCu5i6Z1kpNQrG6TRDLA5NOeTtPzXoU60zly3IC4LZk6jNhHEzACHUtpalsk1RJgOnoPx027HRDAmVhMvms4igdKXAzygbQcmWZ9Jyy22PNyaP9DGCbMcg+uAq2k9eOq2Kly.vn6eOU5O1AXYtARWtQu6q2GwyjPG+1Xna.vK14IYwcAJ8AD.wLFb0EHytlpUlYrmZrBNcIrP8f+DdxU5qFamqzerx+QViXbff+x.SWZUCiqpk.wMS++dqtSa0Xjuk9lHvOGuldVw.Q3WFDn1S+4P9Y19rwB3yWr.9b6Evm6r.9b2EvmubA74qtPeTeCxVYRdrY+OHnyd56HssMeSl9nf0eMg40aB
The second one benefits from a little "safety" I've made. It consists of updating the real time array only when a note is played. but to me, it's a bit dirty to copy the original array this way... Well, you tell me...
HiseSnippet 1449.3oc4Xs0aaaCEVJNZnVcYXcnEaOrGHJFJTPxLjxZ6Ff6kbuKX0MFwYsCnnnfVh1lKRjFTTYynn+w1Ka+T1Og8zdc6PRYKoXmTWukUrM8fi34B424bHO7SosfGRRS4BK65GOZHwx98c5LhIGry.LkYcvtV1efSKbpjHPFQaOZHNMkDYYaW6QJA10W1R+7aObabLlERJDYY8TNMj7XZBUVHs8leCMNdebD4XZRIqu8lGDxY6vi4Y.dp43aMDGdBtO4IXkYK4XY+d6EQkbQGIVRRsrWdadznNC3+.yX+SooztwD0f.qNvDYDuOONRgX06V6LfFG0dbbmZYY6ztHKTyjEttSKZDch7hrwGpUfJ7nb9vdoKBdAKH7rKAukMv6ZNcBEzgxBMJrcUmCXPgpGFJAkgkwVqk9camc3fELYiD7Ij8EvfId3cWe+0Q2w2e0lttt8i4cwwnD.8XAIZKg.OBcezyeQS2JxZHHoDwoDu.ekmq.tBkvTI5Tr.Igpq.7ZOVeJizHTPfzhpjKNr62SBkdpkRaTiThTqXGbbbWnn60KiEJobl2pq39pUbQvSOt.4QuueS58TqVS5ZqspQCXPc0eq.smSeAr1svxAMDXVDOwSgOkYu180vJmuvRrvrzpPPG6K3yXDi3rmvkjCAn69J25tu1EcVU85MScphifGGCXYVpMn7BbzikkzkHVGR9wYjIFB6Zpts7py21xPydkRFxYGvnxCGRxGWrwUoyD0i05aMIXKKpHFKK0roXZyJDM84Bq78xvae6A6hkX0QkbYfcCIBIUEs16RNE5AYN3T2YWR5IR9PnKzTmpfy17nrXrr5AdUWtbEP5txIK0oGVJUNpbWv2ht.9yrKPvrh14DtWyoMUFNX13coYfWHqcYi27dpq3rWudvw9Bvtry9e2h1.cwfxMLP4pNOCeJQeQmFH2POFZvjfdDgQDpbZv4dU2Va7Sy6UcCm6q5NLTBP3XnUU5PdJInzL+KmQ2Fk1s8y6RjYrJlaYDsQYQpvaeH7BJuQcrvRVdkMaiYUlLXbkYpE8GKF9qObOFFJHcHPzDcXZHDrpbW4UocVbJ4YzH4ffxNVHdixh+ZrHBpKgU1fVagtVs541R1Oi6Xeu2AT.96+v+kZup2BFKKUBuNF79o4LVTGCdJVPwL4j.PicTtAHkEnbSPSrI3MGKio4DTyofCRLsKvB3wztBXFIoMh43HuaFxEjaBW1WXWeHwAFBlmySQuxDuallv4xAjnWprfHTd4pdUQYoMV.LSABTdZIczlRY8UgvDtTBReTHOCBl6i7apGRSaGiGAFBh5ggyAMcWQqHYzQDbrx8wLtpPoo4j67GJHCAwGyUSjWJNYXL4H.0qiLum1lH1NlGdhlEfFcyuKMAVCkVIcoTqwqaFzAWnlSEOJZOjmIxt2YQdiXBqub.5V2pHXW0vUS+q54bxhpsvqe1464504E.zF6sVvZq0LmQm5WBjIqp2jxqqEFzvG8fGfLgPNSvIoloiwJIgxT5Ld9lpTFqJWnkhLnNWuDtNWlgS6b9tjy262.2wKGFhU4CBetV4sXkEWjdKHO9Whv3T7Cmlr5kJiw5i6B2gpN6rG6TRLLA5NYeTtPzXoU6c0hy3CGvYzJ2wcDQJn86Spb04LayskTBefTgjqu4QjXBNsD6hOayGC8pvBnGF4h51Wa9Jyy22jNyaj9DGCbMc0+uAK5Z+umE8EyAAXH9umJ8G6.rV2.oK2n2806i3YRnieKLzM.3Y67jrjNvmHDR.DyXvEbfL6kTsxLi8UiUvoCgEoG7GvStx.0X6bkAiU9OxZjfCE7WFZ5RqZXbEsDHtY5+Wd0cZoFiBrz2DA9432v2JAHV+xvP0d5OGxOy1mMV.e9hEvmau.9bmEvm6t.97kKfOe0E5i5aZ1JSxSL6+AAs2SeGoss4a7zGEr9SvJ57f3
Please note that this is a time-variant processor, not an envelope, which makes all of that very dirty anyway to create a scripted envelope...
(I tried a DSP network in a scripted envelope with no success. But since I need to update it from the interface...) -
it's a bit dirty to copy the original array this way... Well, you tell me...
Assigning an array to another variable doesn't copy the array, it just creates a reference to it:
var a = [1, 5, 6]; var b = a; b[0] = 90; Console.print(a[0]); // 90
But yes if you would copy the array, you would have a problem because of allocations in the audio thread. The second problem is using a global variable for the array (I'd suggest using a slider pack in the modulator script processor and connect it to the main UI:
HiseSnippet 2274.3oc4Y80aaibDmzN75Yc0E8NjBzG5CDAEGjASEnjsrjfubmskkcrOaSEKewN4vgfUjqj1XJR4kqjC8gf1OS8w9R6Gk9QnO0WamYWJQpDaGG0SsEs7AZMytyN+l+rC2cbSdnKMJJjqouzowCnZ5+biVwAhd06QXAZ6uil9uv3HRjfxMUr1Nd.IJh5ooqu3dHC8kdfl74u8MaS7IAtzTVZZOOj4ROj0mIR41byuk46uKwidJqelYu1l66FFTOzObHfmEMr0FPbufzkdLAm1BFZ5eRCOlHj2RPDzHM8GrcnWbqdgWEnl+yYQr19TjnnVKXgTr2Mz2CQLxUqdOluWyw1cjlltQyTuvhJuvCMNh4wlvO0a7KkCXlJQV+g9B2E7J9ggm8MAO8Lv6AJ384Fsb4rAhzQPr8YF6G.ApNDHDjEVp4psveW2ndHLi.Qg9jKn6xAhIRjeca6GaV11dkMxkKWW+v1Dey9.5Ibp2VbNI17Ile+OrQto3UfSin7Qz7EsQIWFDEBgQByQDto.htbPpFAcYAzBtbJ3VvPN2o8qoth7npjSpPDUHGnNw2uMDzy2YXfqfEFjekky8iKmyDd5DxMyydh8FruB01FLKqUTi.SXI7uSAsum8CftOhH5UfSB7B6mGwGNs2l6sflSTrfvUpFMAosOiOiQrYXvwgBpC.8b+Xtkx81blu6Pc5biigAGdnuOfkaZXEJuCAyGLreaJ+wfy2eHcxDgrloSKMteoktpbkLSLLX+.lvY.M311KokjfgosInBTuPlz9EIIss7YdTdSHJqwf7ykMRYTTSBc.h5ODVLOhfnsveLmQI60pVX8m08xZG1tZPY11m4Lv4jtW1uVvK7eQ4VG.bctxl0qVmK2qQ45EJTHvw4f1t0p.BsFCX56bT7gspMxls8Z0gkh4.u91ZA.iUY9uvuqS3H650p.LJgy2y4k9uXW03wdmtZOG9dMNVIeq3CiesS0fQeWsUK+rtqEuWCguReflKTttv6zD7ryYNGjfutWt2EJ7xNc0xgNHSk8fq+.GXQ40FA+rbc.JW5.iLpVSPp0Q8wcZH7tt10fsuNCFIxATxp0NGf95n9ENflpHw+50AWyPGDJVHdqf3YjCrvaYg3oBtdij1qEv7YUZAutBsmFVH9pfq+Un+cOKz9pf962f38oVn9pDCq5abnmt5AVfSQTIFTRLh+CsP8WA8uwNOsg3XqlfTUv3w0n8zzBiOUqilB5eNw5ZPnpn+4Zz9N0ZG3U0VftrQ++ysNGUK5urQ68bKLdTkAfrnS8ybdoEFeqh9uhn821BVt3pw.fKgwKOqNfnUQ+YIzezwBcpIyGv+KsP+ex5IWe.zdUQ6OQ+n+tZKvSXi9qVI3ED5Zze9rD6QZeuF7RR8kX+.bNRpuJn9R7Wn9pf5Kweh5Kwei4aR8kDOjwGTeUP8kD+P8UAr7CFg92Zp3M5+GhqeYU9.l+Jv3ocMDjI4OvOuRl+tNhuKU4aX7qLFOGnxGQ7TF0eHpelJ+UkOi9ur6mj4+H9VCwyqU6Ov0KY+hb+0Ogzn+JY+J3omWzPnIodfZ++7iVVuASZVEy+6Lenw7kUw3WGGHnt07jFcfUk0Ow8ez4CMVOJo9LV+a9Pi6WZieuHtJleOOow58Ew8iDb+iX9Pi42uTt+FqIvlmzX9WQL+6bY8i4CMlObl76sx7C64CMddAY7xFiWmNGoQ+2Ix5OR+40yGZjQEz9hQ6yYNRijGHyGPR1alazOUROBo2d9PWXldzz9t82AO7ZxwfgSDCmRd.kKX3Av02gNBtVr5tbKYrCM5BQ3.4b6OHL.O+r9O6i3PyuI6MtiSI9zMGL9r46CBYlrVl3MILeNgyHAByiB8F5SfqGTT6JlmnWp3+gM6QYc6Ivii+6kWb+8tHJbc3whm8NxXiARF.tgxTWFEuvYPDSDmswAeDWb19deu96Kb+bilLgauaFuKbC3Ehpya7lzFhkMZzoCbS4Tv9.icOeV64vrAkGpfxmYbFYDU1aHIP9URZ3N48M2iFP4pLnaq6PaU5Oce6Nzf6c2gbbE.DNEtcezfvHZwLq7e4cFqTlrs+7NTwvfoltlhUorrPyaWv7JlMQcLyRY2j0jDL0hAzSsRGwxrA8u9MMBHP.oEErFOmHWvXQeWVszbneD8LbyXwrBlxtTV15KNO55z+IZJ1O86s+WuTzh2Ou4M3AWHCF+DEF+MIUfwL6j5uS.sDuevRzeP7e7v9oeZ.a1itNvebK.OXQiz9y4yZa9DyCYs4fdnQE7CId4ejaHm9nU1HSe75BtPXhvzS5gmDOz7OJpeXnnG06U3LnbTpb3Ow140jvI8oBJOujSK4TYAcQCaReF4ztltgCAS7Il1aHIYQM8IwvDAVcHPB+F4VNCVhF7tMTbq.uSncYXKpSMb7iu4kMjLZ.hlIdkn7kKVB4Oo8YC3zADN8zPTu4iH8G3SOAV2Gap9cTSJea+P2KjMTSZL2eQ1H2aypIY9fbj7sGBU14qLt4l.OhuoOXb.f6NEfG21R4KVGy7JO1WAy9K+xT+0JpVgJeiO2Rf.2O73Dk7brYapkaE.pikTxvxZijlkhuoPfX5wUQrkjLKVv17q+ZSkIMFsicUuuMOkSIa2RURlMCPvGBI.KkQi2Z6TeegSRetco+.Mb8irsp4teUJltIp1ZSkLkkcpiKk6XuUZOXm3CxNoTC6F3lx5t5e6LcB1rkkWZbY4VLbOQifQTeXAjk49hDlli4NcgsiBCBGzKLf4l8ynmPEbV2tzo9T4MVCbKg.On7DNObySn9TRTlSS7a27PnDBgCkxnymx+52yOQ8qMTvUUx++MN07h+e+olu6Ck.mH7+BhzmDNT.UJOh.6qfSnZfeyANbsKEfZP.TxGO8vBXQAEsMRi.pEMvSR7OfmjAKN4nFvfEGO3+VzQehKO7Utppa3VuOUxAr6.4+33kLNBoMS+uKYXWvVqObl0W45hYG+Nv+byxTZFjY0YPl0lAYJOCxr9LHSkYPlp2oL30E1ZnHruJ+GXzrg7qM55paGI2Jn8OQNPgV2
You are of course free to change the slider pack values through a custom panel if you want a special UI, but unless you change the size of the slider pack you should be fine (if you change the envelope during playback it might use the start of the previous envelope, but that shouldn't be too critical).
-
Assigning an array to another variable doesn't copy the array, it just creates a reference to it:
-
@Christoph-Hart Yep sorry I forgot to clone() in the snippet but it is in my actual project... Is there a reasonable limit not to reach for a slider pack? I actually have a resolution of 1024 for my envelope (which is not too big considering an envelope time of 3 seconds, it gives approximately 3ms/step
-
Yeah, don't clone anything in an onNoteOn callback - the audio thread guard should prevent you from doing so anyway.
1024 should be fine - it might just not get displayed anymore on a slider pack because the width of a slider will be less than a pixel.
-
@Christoph-Hart Yeah cool ;)
I don't need to display the slider pack anyway... So what if I register an spData as global so I can directly set it without the need of a component? Or is it better to keep a hidden component and not have a global? -
@ustk Use the component and it will saveInPreset (if you need that).
-
@d-healey No my system that sets all values is already saved in presets, I just need the best way to make those values readable from the real-time processor ;) By best way I mean safe (now it is) and cpu friendly
-
Whenever you can avoid using globals, go for it and in this case a hidden UI element is the better option.