Unsolved Spectrum ballistic (display buffer)
-
The problem with your snippet is that there is no synchronization between your slow Hisescript loop that creates the path and the audio thread that pushes new signals to the FFT - this is why I added the special
createPath()
method (that also tries to reduce the path points to optimize the drawing performance).If I use the
ScriptRingBuffer.createPath()
method the artifacts will disappear completely and I can render it with 30fps.HiseSnippet 2245.3ocyYEzaajaElx1TNRqSPVffhdbpwdPAvqxLxxN1cQajksksPrcDr75cMBVDPMCkDgmYn5LTwVcQ.ROz+.81dq+B58dK+E5Oidp6+fzGImQyLxRwxt6FTYaLhju2ie7wG+dONtU.2lFFxCP4Jb1nATTtUvsG4K5uaeByG0bOTteCtQiyLpOraWZfwdAjqX98L1.Uez.RXH0AkK2hGHkMWgkPpO+7KpSbI91zjtPny4La5QLOlHo2V0dIy0sAwgdFyKkzUq0zl6uK2kODv0hXSz.h8kjdzSHRwV.ixkeeGlfGzVPDzPTtkpycF0tO+Jes7myBYcboxFVn1fgzc2f65HQrrWzt8YtNshW+gHvJsR7FKp8FOAeLygMt+DuxiUCXjnQZ+QtExBuEy.OqzvyLE7lBjxkBRXMj9Rba6.1.QxHR77E3l9BZPWB31SCkSF5sGKbfKYjdGDPCN2BfSVaDzB+0Ew6xAU8Ek8HWRaD.MFapRVULMWyXSSym9MEAwB4tzx1tTRPInihvtTnv3sj.iVDepqkwevH1V8nhc4dC39PiRqpGdUPmDUBgcWaJnhJdSpPFf1VMboU03znw2qTun1RkcHBR4NJAMASns0MrQIIrSqw.hnuYJTZGPgcnVPux0S.smgzllv7DqVHUzB1yEmxGJX9zRcG5aKXb+R8dZwerXgdRAzQpkzOBKyCH98nf8fQcfyKJyK5yBSgg0LdM7G7qpe.2eGyQBhjNNjx50WT5o+.HV4MjKj2IW+oAl7TSvtDW2NvwiDjo.1ydlZk.q0jYNxeIs9ozP1el5D4lrLqTcMCKIjuEsHwpHksXA49XmtSSb0v5elXoCR2oaZOe7J9HtMwsNenuSHrwI8PkAGjUYsi5qsTdBym9MorZ.cfbyoTj2I10HHAZmSo0M0NsnOw9HCt+IbA8UQNqhuqnwjC0s6TGSF4DvccktfoLrdV+DJVxenWGZvZvQ.2gzwBBjOYoLvylxHMilsNPNkfb+l9LwqFP8mEOGJJ5G9121bOXeQxyD0GH2.ZffIgPt8nuEHs0rNEv6QCuTvGnjM5fMvCKTi9vXNI4F.hALOO.q2LPWmlWeT5FWIC4G2gweqVeUH+3dd+eoFJE82RZf.DubmgtDQV1XYJnnA.+cFJPIaleHSLJcJpewnnmWH9k3VLgc+oiwElBFgckeMvXThsGh2GNmZKR.3R3Fe+mgrX40yewnHFXNkS9J3Dd9IyecFAlEUdqbvR4VSn8uV.mJKiOU.DN662CHuiHc1KbvITwU7fKKsZnRo2z8ZU1EPXIuZCdvUj.mnSrgmwaQBfJOfbhgk5RbCoYy8cZcyImhc7cNk1iEBpbJTtTprQoUyZ9TyJ6z4Mp8.pMi3lbVEryOVzvXUsBGQ86I5u5u2XKqsqr1yd15Ud9laslb7ui46vuRtA.itZcWHsgGw2+PRP.KbUkH6AltC08TYJLPnWC8Y.bulRtX02gu.O+AkveaHsEkbInCYDHrx2DOPjgZCb5RCIBFpG5hCHddDnGKsEWMVaHKWrtGw6QBXh9dL6FAz+zNWCnSahhuC7EfCWtMk3hR7Dklh2Abefu9NpwjILFHS0DPgXAHxqTHwafK8TXKaMiNtb6KaCYSuIq+.cXecoDkr6CtZpa38I4P949jn0mlHPWFSuiIh.FvLigSS5Bs1MBcwmlhZaJaK4hZS8cTM9H7IZPq3yjxAshGLI8Rt7QqK.NhHlQ8oTHCRGdc90pTEOF2IUb6tcPpUeBQ3usFZtryivWMN99lV4w2zJOJxJscYNz.kMVAqJd6H9K8ugEt3C2AKbHaJVHJ26sXgu.qOiLMCLWKhkwNxyTYT9u+S+z+9EnHdOIm7BQeG1kzDvITgnyAlNYFJvRvw8xlncbc4WIS6yhxcALyp9ZwcGMnO2mYK6RKQbrzNdPsbh3.pCIgmQXtxjcvbyc.fgaPrgn5Qxp.kIHkEy.YinAksGmUJCtRRLHCukFI9Rh5fTX98TkkHuh3hxwUWqKZ1zliGZCW5TlaFcioOfVN0v2sYSt1coWGWO0D4nlrGncSeG50xzteMTjVRFF4wlwsfo5Xl+458Qrby.cL45wsqBsaKnCjrOx1.kpxokWV.BEkQOTJilOwn4wUxZ0BPGlR59TV9IfErL0erptsok0l.OykzqzdPs.Upr81lU2XyJUVu5VOeqMhtVpj.eH02dTLbJrzG+3yvHzaqgl05zJChxis1bFKzUTl23TYPIJi5n40GZMSe3A.Y6rM5R2lQkFYYbq9jvOwNwbYk7ppamDJIUpiPohvw3tcEYCseHl3SbGERKKG5ySXsJ+S5n5YB37R.a8+CH151Qbd8tp5UfjExqf8fm5WNxDHN8qc5VP+BYHBxc2i2zcMQ7V50wLWgppzksf6frf9vUyvykiBkvEaQfJuNmCUMpRhfxlCIOFpNQ7qd1ibye1iHDcuxa7+tm5dc657otc8CtKUMk5h1eU5KZ+U07HxR8xkGZvDTOXx+cX4q7oXEypaUrp41aVTdUghVat9VUKptt.J6kye+qm7x4n+nrTj4BoSTW1rv4Iw3b4DbVCeJbGUndJWZwIttRwCgZjfRYgm99EeIgERCJdV.SKbCHR6LvcdGWFOZ9JLL0RfkdIzrlGywwk1hCWkWEnGOwm8gvw4XhqG6e9Buzu17K9fZ8O127gPX+UUjN1voNxSEzKCTT2q51WYMqInWKj2z9zcN4f8MN5UHGZWxPWw4Sot1wtfGNeU1NKW.BMCW.pxs5Bd+4YcAHzuvtfCahRuTKLWkfmBPilXklFr0hlqB3KLNXmiOdmY3sQyJFA8yobFJeSZrt7sVs+rvYyZI378O4e7edwTvk51AZ7uLdu82cmK97bUQOhc.+M1QunEfo7Apd.RXe0+pmB3iksMrhuKiNiF3AYuw1Nt34oqSk6gNqeOzo58PmMtG5r48PmmeOzYqOoNx+qW6LTv8zYxgNZsuJKWtb66KeQcp2ZG5+B7.yn4C
Edit: the second example you posted somehow creates the glitches with the createPath method too. I'll check again if I can spot something.
-
Alright I think I solved it.
The problem was indeed a multithreading issue, but not between reading and writing (this was already handled), but between reading into the buffer and then applying the FFT. The createPath() could be called between those steps and then you would get some glitch values (I could reproduce it very reliably in Debug mode with the 32768 sample size).
I've fixed it now so it should not glitch anymore, but I might have to do a bit of profiling to find out whether the two threads wait on each other for too often.
-
@Christoph-Hart It's building at the moment so I'll test this right away.
Your snippet usingcreatePath()
strangely crashes (before I could test the fix commit at least), but this might be because I was compiling at the same time, it's strange nonetheless...The reason I don't use
createPath()
is because I want to perform my own interpolation in order to smoothing out the blocky look of the path. I remember looking to add a smoothing option to the method and not succeeding, but I might try again since this would be way more efficient if made natively rather than in a paint routine... -
@Christoph-Hart Nothing changed here
- I still have the same glitch when using a readBuffer,
- Hise still crashes after a few seconds to 1-2min with your snippet (so using
createPath()
)
-
I remember looking to add a smoothing option to the method and not succeeding, but I might try again since this would be way more efficient if made natively rather than in a paint routine...
Yes, definitely. Painting a path with thousands of data points in a 30 Hz framerate is pushing the scripting engine a bit too much.
I'll see if I can add a quick smoothing option but the
createPath()
function should be used definitely (we'll address that crash later). -
@Christoph-Hart said in Spectrum ballistic (display buffer):
Yes, definitely. Painting a path with thousands of data points in a 30 Hz framerate is pushing the scripting engine a bit too much.
Only the number of pixels in a panel if downsampling, but still a native smoothing would be better for sure
getReadBuffer
is still needed, like for instance when making 3rd octave frequency bar graph or with other step values, you need to make a custom downsampling function.
I'm just not surecreatePath
will answer all cases -
Alright, two early christmas presents for Greg:
- I've changed the
createPath()
method (and the default FFT path rendering) to use quadratic curves for lower bins so the days of the ugly tetris visuals are over. - I've added a function
copyReadBuffer
that makes sure that there is no multithreading issue when using the readbuffer. So instead of callinggetReadBuffer()
you need to callcopyReadBuffer()
with a preallocated buffer object and then use this for further path calculations.
I needed to change two lines in your example to make it work with the new method (see the comments):
// Create a buffer with the same length as the read buffer reg buff0 = Buffer.create(Panel1.data.buffer0.getReadBuffer().length); // [..] Panel1.setTimerCallback(function() { // use copyReadBuffer which uses the synchronisation locks // like createPath() this.data.buffer0.copyReadBuffer(buff0); // ... from then on it's the same
- I've changed the
-
@Christoph-Hart looks great thank you!
-
@DanH Anyone have snippet for this so I can have a look?
-
@lalalandsynth the default analyser has changed so you should be able to load it up and see, unless you mean rolling your own curves
-
-
@Christoph-Hart I'm sorry to bring bad news the second day of the year, but unfortunately we're not done yet with our friend the buffer...
After a little while (about a minute on my system), the buffer Max/RMS value suddenly cranks up to burn its wings into the sun with a gain of several millions and an erratic spectrum:
This was expected instead:
I remember this was happening already before, so it doesn't seem to be related to the recent mods you've made.
Also the newcopyReadBuffer
method doesn't solve this and it happens even if you don't use it (I just put it in the snippet so we can see the buffer in the watchtable). The problem still happens even if you just call thecreatePath
function so my guess is that it's happening way before at creation of the buffer maybe...HiseSnippet 1581.3oc6Y0raaaDDdoroRjpMPRQO1CD4jLfCiniaZAJZiiksScarifkqQ.JJBVStRZgH2kkbkkUKBPA5k7Jja80nOD8TeQxaP6LbIEIkbbhEpSQPkNocmY14a94aVJp1QRWVbrLhXT63wgLhwJlcFKT8a0mxEj82gX7wlc3Ag9rVQLph0lp5S1dbHMNl4QLLV5wndF0Vlj740ObapOU3xx2hPNQxcYOgGvU461dqui66uG0icLOnf1at09tRQKoubHfokLaRBotCn8XGRQ0pXRLptqGWIi5n.3DSLVdao23N8kiDZ8OgGyO0mgKbHcfCRu8dReODw3tjV849dsyh8XBbJsyyDKoyDeh4AbO9j8yyH2JQfUtEEyGFUJCukJAOmhvqYA3cAPxn.jVVCoaa1wMhGpxkf34iL2WnXQcoPZuHTz5RpDujYKIngPYGPGv1KBVLwhFOnYy0s1rYy09x50gTerx5LZjULj+cYVekUR2fcOlZGdbnOc71C61kE0IQbi6ncg0dOy4Nf84l2lJX9Nf4YNFNfVxfPo.Vz3NZwnI5uY6QUT6Pn2pfItSZ3ZTFad.Rzv.zVCzY.Xij3Ih0y5TX8Ffh58SO0F4mAZ5QLpWpcqY6yD8T8QyyPWLS0FJ9pijCUbAqQ2gBWEWJZzas5+R8Z8r6B8xOx2ugtuM19TenoENAPTLF33tSDJinhdLsTuH5njHT0mGmmEV2p7ZDiaKGJ7ha3X2bs0sZZee3.dwTfDoRQsn99mBtOGkIfr7AB4iBYfBY5D0.u8DoK0O0kMSb4O.sINfmW25tN+Hh.LCqO1HVHldvxTs50t28r91gPoJVZMhYAmkE05LNajEW.gEyZDU41WQARfssc8ZEwgLbbgRQRkKMLyBREMRGlM1.8eVLZIEGJUrmlFr0eQcqoE0s6EJC61hj99Xo+BDq80kXXCwvfSYQqCcl9CYSTDnrkmCX9lmCTbLkqt4ufhRw9Bt5ogLwaZ3EIkw.e662eGnDiCOR2CzKjEo3HDL1gcFLIVOJol4Nr3AJYXhtoLSX3pJQ5pYCZvzNgCiStootDPNOeX8Wu03hKFw8fKGLLM9zJDReFuWeEt5XCbd+LyxfonRug9TU4Qq38IoBf7bo4Y3LKQLWMt38M+qMu8cEh21rMGZfuXLV4BvHTMtNvX5sTqZtKPVbU4.bYy8d16gqjL09udZmB3Sz4qXlekPIPb3vfRCnQJgA1YjdKkwKMyYWg3DkH1wx1f9Mho3yebD.90sN0W5NnC+mYyRIC0XaaTiFt8oBncMddXtUemSWNWd0ReeQuCnpHNPaLgbf9hyVonCyAUPBrdcSbM1vzgI7RV72vmTgNSRXfPmLgE39GxTijQCRpSoeGhEcQINII+7tm6Pf6ojiPFOOs8EJNI60V5ONruTvcwszZjgzGE.WEnxf62PiOlx8w98SfJYxgbCS3FAa.zUNT5AIGy8ntPRbbxCLBjFbvFzghS4mzoVBWkZVfiH6Y.0YD.NAICnvm.boBS0zMk3JfxUQep6GeBJEtAibBVaQfRvyDUuZJ9zpJicg6tQFNYF.GwrKHddwGJBZeOOav7Trfo2ACBgG67rB7tPOpG7jqIlmUzaSifGGVosu5jUv2OfKRC47wOGPOep8t0VcTrPjFUbTZmArQ5jPwcw7TUbPHiLyoPtbWu4Vy35W9WS65e+Uu5Ol00a8aA+4C0Ob6dQreZHS3NdJ++qCda9+0Ob1Pu4ULzWIw+VGgbExLmO4pm6AmcEy8OFlCcs4ZXdxaz02vrceZ7L9FuG5Z22USdRfKHrKPeWs.889K3uWU96kWGMu13ullNMaRVvcWvcS4larf69gB2sJxcWPdWPdmPNcVPd+Pg7diDx6B16+yYullc6pJyZW0jJn9iiY1nn+CXr3A+VYroAQUcR10mQm5WsuhY.91x0Rd2ihr+aHiJFUJEOkFWX79nyQe.WRmCBqskxAAzjW0yb8Feeu7hoBntQxm6peWaX96lI6.sLhj+JuZlGfqsbHmk8yBv2eT.2i+bWW70XdWGB4hsYi4vl6OG1r4bXymMG17f4vlOeNr4KtTav+UyGMTICzuWPXi16p4hF6Jv+ulDpD4e.Iz0bV
-
-
@Christoph-Hart Apparently this isn't even related to the buffer, but to the oscillators that don't like to be stacked... Muting the last oscillator in the chain made the strangeness disappear... False alert confirmed?