@Morphoice you out anything you want to be able to bypass into parentheses and then pipe it into control(bool). That's the syntax, where bool is a variable which can be linked to your interface parameters or anything else like filterGain > 0.
Posts
-
RE: soft_bypass and faust
-
RE: soft_bypass and faust
@Morphoice You can still pipe individual expressions into the control(bool) primitive which is undocumented (it was an attempt to create this sort of processing segmentation years ago but they abandoned it because it clashed with Faust semantics, if I understood correctly).
It still works, though.
process = _, _ : (si.bpar(2, filter) : control(filterEnabled));
Although I found it leaves a little bit of performance on the table for especially hungry algorithms, so if you're gonna be repeating your Faust dsp program many times inside the network, you're introducing unnecessary CPU overhead.
For stuff like filters, it's great. An algo that eats 3-10% of the realtime CPU, you're leaving 0.1% on the table (those are my readouts for my specific usecase).
-
RE: Things I've Learned about ML Audio Modelling
@scottmire you can right click the soft bypsss node to adjust the fade time
-
RE: A couple of zip file additions
@orange no. Zip is integrated in the systems by default. Any other format and it's questionable.
You could ship the 7zip exe if the license permits and call it with BackgroundTask.
You can also use BackgroundTask to extract files if you're running into the size issues using the JUCE/HISE unzip method.
-
RE: same note - same voice?!
@Morphoice you need to call
Synth.setShouldKillRetriggeredNote(false);
in the MIDI processor of a Silent Synth. In this case the Synth class refers to the sound processor the script is a part of.HiseSnippet 2185.3oc6Y0saabbEdWIM1RrN0MHAH8tN2YpFYZQZYYE3ZDYQIESzJYASE0.XXXLZ2YIGnkyvNyPRwFHfdYeExc8tdSeA5KQQA5KPupWm2f1yYlcI2UhRVPHooHUzFRb987c986rq3mZ4xXd76LRQ+9baPP37GnUQbiQoCBqb3397fv6QZOVZ61rKSHCZscP38I6H5z0Nts3zC4FavVi6yLFdbPX37eAtovkVHv84a+7sXoLYDe5TAAGoDQ7einmvNc1C17WKRS2kEyOTzqvtWayVQJYSUpZ..n4IqFzmEcBqCeeFts4HAujY5FD9KIw0WqdxFQr02n9ZMhhZrwSa7YOMhyRR3qW+IOcsMRVKgEsZifv6rSrvpzssLK2DDtvVp3ws6pFI8B3HgQbbJGGTOnMHY+z6pRiQUDmMnYWQZ7DKkArajB1s481sOlrmHVLY9o1uelaA5zSTz.FNWY3MeI3UuH7Vs.7lAjBK.oE7P5CIsizh91oqf34mPZIsbMXd3kfheuAysHgzTA6PZq0icBeWMLXxIpt9pqtBE9wxOqRkG8H5dvNLTaWNUprbpRtR1WRRVgZAmqdEJ3RsZUZJWSiXooGCtTCrK4C0bVJtG7hNrqvPg+qjoioCL7jAoTQBcD+AZNsiRJY3rnjfeN8ZrJJ5yirNLHxgYEWLbsXdBW2LeyUs5A7Lb+pAZZmT0wrTJeHnpvwYVPZvUKorHzbQSzpdTlb7ntbsCiawiXHHdYq16PiUbi7AVZLjSnUiyusgLsfAdLTSn69DP460WjxWgJrOvP4LyXDyc3N.2iNRoOQH6PAYHgqJJko4wkE5.KMQoo7S6qztSMlZ5pFjBaKcDargdLe5ISDZisRFV1woYOm90m4U5lfAG7MnFp0rwtq0.AeH.bdMQroFE24qAqrdnybSMPNHGDhW2iGKY8DQY2flaD+d73fmafTxQ6FX..WH.WtzHFhhKNGv.RYCUhXTEs.7SAyiwB9cIMOVfp5y0LqPIMUb3uFhrVwFPOdyaeFs7j0zdfVsdiMx7r+VHTjCBnmRi3GTVkjm4jgq1qnFUVjUDZRPE.t.uNgnw.PjB0fn8fjXvp3WYEv8E0kNRX6RebCpIUYMUPaXUA.tUeFU7qfaA90m9oKW4qqrTIj9Fwa8ZvEmehR73FfNblSKdI38yCGAqVtWBwTV5DDokN.ByP.j4u8ws4d+l98cDtsBAAO+Z8I2TNBpSmk3IbYaHRxMmZdJDOESiYVVE.VFaFRdsZfyn9b5NxNBIuFDu+EEWYOlDppqqh9rjAxHzeC9o8AaxqjUcVOvPPO+RIIybslSJvLykQNF8UcvpxA8NFqT4LoS1HTGsbwYxkWbtH2Qju5YgMpjsjB6qfLhKiQIHqjK7sur01f8DqnmMGrOHv0JPHDtMeHvm5quuDYat4DqpOvndgh+.siJd.3fJyEgL1YK.1fRD.XQdHz2NtHi92YDTWWH9gjCD1ntyFiyMCLBVpuOvXFs9GP1wwuLEfKP18q99gCun3W7R5F6C7Sf0c45KqWr+4Y+4+00sWr9W6dwBm+1VoJ2J0GkM6TDUelsT8WlmPKziiiaGqtGqbUzcTRopNhHf8k5K7hE9gkEVeaHk5tgZ7R8Xn0.WORzQLrEFEdBn2AnVMRIKm8oxZT6QPKZEajB6+Q35nwUrQx82nQM.3u4mxiFfIiqjwaNhYbU3advW5ZyqhG36HwdeNG26PLpaB2aEJ02blgikHg1Bv3uWysZQGfRfGiU5qlvRMXuZT3dAdFPabTr9w2PplKgnYOrmkN7ZhNR.1Nx47NEWpxRfRcPJzoicjxy54YbcMFAOThWkNGkd9MBPAEz9N1kpK+12rJ1CfW66CWpSSujMuBsvBGwSUQPQupKu7yt1Bq92IBqRkytTZ3qxxk0WDDDd8f6xUVBtwk73U5kxVicmsUbUAdkmcKs+sz9++AsOvxCOzHDLgoCYuEF+L9L55WFy+eX7G82+uMye8aHy+B+nh4uwrX9C+ajqOYGM+ysOQz+aTZbtaKM9CbowYkP9SIGnRG6Sv.4h.3SbS0uqRJhnYIl69UyrW7veAYVw6EBwIWarW+pMcSCf2mawWzmSgx9dP3cQjeOx1l94S8hzT0noZRl73ZC5yCuKY0Zv+76po60J5iF.kyOjCtDojm9hdPS6fpRBmCD9KYlCYhTLVo8.CjwE+JoiKAYHPe09pX3a2YWVDn1iOfALNPLGlyBNXttVzDGcIzN03h5u+MzWZC38lyhPBCbVjd8PKB9l7CmGWGMI4..kvcIIrAFaPIvbO.LZdM+JE8odglel2m7JT0.lIaDj1LGJ3kHMSg6sUbf6ElEDVwequpcSWRPw8deBz15ALMHc3YqL4mvKyfBKfhIeDfy8DxrsNMScO1omatu8yaa48aCOeeo4NgOxaTJNKhl6P5.QpAW3l2lCJPp8ByGb0PZsMu.j9i+iMOGj9Sey27WuRHkn4+tyCIwlyFRhMCZOBqvcHSCOV.l5THh39Diqwm2ch.4yJGY7yIb4P34U5yqUdWyJ3772z6IdYtK0QdmoVsEIOrdCLqbpQ6tjGtNNyTSFgTGF6+aubXWM2zEZLJnvMrJt+xFmISGLaASHkkpWFyRlKRdATsa3jHD+JkkletfhYHkhiKshqnbw7g6QZYNBWMhklKEnzyVJ0I8Xtxd2LJ7IOAOztzo.Hgrt1f2JJuNmIuDW13Uy8isghbtA+a3S1h0wwgYKVOewezHidrHs5cY+sAPmzhtYf3eoK3eIxd3XZ8fgmufPOny52EEU9ptvAabSO3iuoGbsa5AexM8fqeSO3SuoGbi2+AwG74ECrpdd1dfx3fcbISgg9W2liJLfCMrGCOtkuOGLmaxLR9o6BU9botIBr2k4ve4QxG644dTNaWsXS+7F1cEBC9OWHkV8.
-
RE: same note - same voice?!
@Morphoice if you're talking about what I think you are, check out the continuous event modulation snippet that I posted in the snippet room (or the snippet browser) and check out the call in either the interface or the synth script that disables note killing.
I can't remember what the method is called and I won't have access to a computer for a few more days to check.
-
RE: Can FAUST have dynamic channel count?
@ustk that's even better. Nice one.
-
RE: Can FAUST have dynamic channel count?
@ustk in that case you might want to have two copies of the dsp file, one single channel, one dual channel, and switch between them using the branch node.
-
RE: Filter instability?
@Morphoice because it'll get the job done, you just might need to also apply smoothing to the noise osc to get the correct curve.
Instead of using just noise, there's a faust function for outputting a random value at a given interval, so check that out maybe. I forgot what it's called, and I'm on the phone.
-
RE: Filter instability?
@Morphoice said in Filter instability?:
Just introducing random lfnoise on the cutoff frequency seems fishy
It seems fishy because you didn't mention smoothing.
-
RE: Can FAUST have dynamic channel count?
@ustk where are you changing the matrix? The right click on the channel meter thing?
-
RE: Crazy Cubase <=10 Bug That Messes Up The Variables
@ustk Yes.
@d-healey It doesn't happen in other DAWs at all, and doesn't happen in Cubase 12+. We haven't checked 11.
-
Crazy Cubase <=10 Bug That Messes Up The Variables
I have one guitar plugin in testing. It's got a lot of feautes for tweaking the playback, multitracking, performance articulation stacking etc. It's 9 groups in a sampler for the main guitar, then another two samplers for releases and noises.
The main sampler playback logic is pretty hefty - the way it picks the correct string, then the correct sample etc.
All works great everywhere, except Cubase versions 10 and lower on Windows. If a loop is playing, and I switch away from the window, Cubase closes the plugin interface (or hides it). If I switch back to Cubase, the interface pops up again, but the playback sometimes hicks up for just a moment, But what always happens is it starts picking the wrong samples. Particularly the groups - wrong strings are playing, and sometimes no note plays at all, which means that it adjusts the variable of the correct RR group for that particular note, which is calculated in the on note function.
I'm using global variables all over (David will finally get some gloating material, if they're at fault here).
How or why would this happen? Why would a DAW interface refresh mess up any variables that I'm referencing to pick a correct group?
Disabling Plugins Always On Top in Cubase helps , but sometimes it still happens. We'll have to try Disable Suspend Audio Device in Background, but that's a feature some people might wanna use still.
-
RE: How to Create Artificial Notes of a Specific Duration
first of all, let's address your variable initializations inside the function callback. I don't know whether that's something that was recently changed, maybe I missed it, but that's an unnecessarily intensive call for a realtime function that needs to be as fast as possible.
- use reg, declare them in on init, you have 32 per namespace
- if using arrays, call .reserve() to reserve the space for what you want to do, because dynamic expansion is expensive
- if using objects, initialize the properties in on init as well
- avoid string operations
The Audio Thread Guard should warn you about all of this, but it seems to be busted on MacOS (it's enabled in my Settings but even string operations are not tripping it).
Anyway, let's continue.
The HISE Event Guide
Please correct any mistakes I make; this is based on my own experience with multiple containers involving different amounts of children and grandchildren and writing complex event logic.
I also think we're in a need of a Glossary of Terms which would contain any current or past terminology.
Here's a very simple architecture of a plugin. There's a container with two WGs. The reason one would put two or more of anything into a container is to not have to duplicate the MIDI and FX processing, as well as to possibly use delays or policing of events.
Before propagating events to child processors, HISE checks the Event Queue. Event Queue is a list of all the events that need to be send to the child processors, and they have a type and a timestamp.
When HISE receives MIDI, it enters the very first MIDI processor in the Master Chain container, which is always the topmost container in any project. All Sound Processors not parented by a Container module are direct children of the Master Chain container. The master chain reacts directly to external MIDI input.
You now have the ability to process MIDI. If you wish to react on note inputs in the interface script, you should defer it so that any repaints or whatever are not executed on your realtime thread. This means that any playback logic, delaying or filtering needs to be done in subsequent or child processors.
Once the event leaves the queue, it travels through the MIDI processors in order. This is how you do filtering.
Once it executes the final processor, it propagates to the children, if any.
playNoteFromUI and noteOffFromUI simulate real event input and no matter where you call them, it'll be as if a real event was received.
Here's a funny snippet. Just play one note. Do not, by any means, turn off the Dynamics/Limiter. Maybe even turn your speakers down for good measure.
The print message is only in the interface script. If you change it to isArtificial, it will return 0 for all events, even though they were created in the child processor, because these methods are meant to replicate an external note event coming into HISE. You should only use them to simulate that (like clicking on a pad, a note on a custom keyboard etc).
HiseSnippet 1168.3oc4XszaaaDDlzxzHVosn4QQ5QdnGjaMLDUjeTjBXGaYmHzHaAKGm1SoaVNzZgI2kfboaEJ5+s9Sn+D5sdMW6o1YIoLWJw3JK3ljlpCFZdsy2NO1Yj6GInPbrHxvr9IiBACyOxZvHtb3dCILtQ2NFlehUORrDhryXs6nPRbL3ZXZV6IJFlKunQ5mWu8tDeBmBErLLNUvnvyXALYA2967sLe+CHtvIr.MsauSWpfumvWjf3olUSiPB8bxYvgDkZKXY7TR7PCyuzx0osi2VTxFa4ztEk1ZqMa80aRAhmGrgy5a1dKu1dDZyVFlKsuKSJhFHIRHFOzcEtiFLT7i7LGbJKl8JePQ3XL.8bFai8Fx7c6ON3DaXXZ0uHTUKKTceqdLW1k7KBYeZp.6BKzCZlKbUPx4Z.ISMHsXFjti0.ZDKTVHQgmaa0kiYPLj.kfRltFl+g0dBTAtbs.x4vAQHwkFzXilMW0F+yJOxKgSkLA2VvOTHgi3MVo9OWeYz1XgOrVXDiKazCcKlxV6LPpT5vjfWAQMVYkGU+WpaO4I34kcDSHSglHguuxvJDqpZhtJCavS85p1WP7SfKUDiRkC8KMagdZVvQSQAuKmIOJDxoOP36pBopuOchxHO5he64c6PjDUtKmGpWHDIYJ3X1At.6VxxjKa0AhOWJBw9koRyXAlvMwmHKW0o5GyEfwiRoZU9jGyjiz6WuFkhMuxRwYEh2wpOSRGVMFWnBLhQp+MvXdC7GasO9hAUV.vEsN36l2t0lyd25cy7ecqNi3j.FMNuMcLoyDOyJg84DzMt5QFE6SFFAwCwpuIE7XoDe6TOYq3dL3CjXsmb+9c1SDDFkBqJbQgvJcTg3iUYScuUHZRj7EZtrB7jNq.lFLud6bIShjevy6a90bYSeqyELkizQQO7QujP8KVtUSKvr1Mzi2FGKRjL9Y8HxH1OgiWvGJGfy8n.VLx4fOd3VlKnBxYzMUzJHL.3toD+E9IWnih1LWnyXg5U7OHqh61VufbAjNgOsj6yRo8DQA1OA3Pjpc04Jlw+ay5L9vYdF+QTIBgShH73PQL3nexCf.1IBNDWh6DVzpRKJwsCHS3kO5LVkzREJN.CEZ5cqcFyrkNy9DdoCCoKcR8Tozwj+91YEyC.7l6dTLECLp3rdYZ+D+X3ELW4PGcCKX2Rm8SIQtXNjdUUlKNaUlkGYnoeEufsz6fUfZdCsBz8x4VfHmJWE5OsreCq4j1zrVnOYjhKtjTvy6pusSdqXiUV09MrCzWsdIQmB9BJNs68zkirtoVN5+iKDUpvb4wXb.KHzGGkeAl4QNJLdW7V4QR7ki4VtrrmfKBGJ3rR85GC3PiyNCJ8DRkWnIGHd+cpXR3yXbfDgwIXNiEW+emRk4qO2JCt1pZX6+6tHasOnWjc169vofuemEefENMtkcZpz9cSt7swZfuM7Q.gFIdIMaDipo+Vobv6MO8edyxV8Tz1NFoiczClA3hBujRKeTSYXq40vGNuF1ddMb840vMlWC2bdMbq+YCU6w83DoHHq2.Wts+9oyrMMu7GoYVy3uAKaAdnB
Any other playNote methods will inject the event into the event queue. It will not be picked up by the subsequent sibling processor.
HiseSnippet 1160.3oc4X8taaaCDWxIJn1caXsqCceTnXevYHH0x0MICECM+wNsFqNwHNKc.CCErTmrIhDo.IcZMF1qzdV1ivdD5av1QI4HoTCOWutlNL+g.eG4c2Od+2ouTPAkRHsrqc5jXvx9SbFLgqGcvHBia0ssk8m4zinzfzMk09ShIJE3aYauxSLLrqtpUxm2738IgDNExYYYclfQgmwhX5bt8286YggGR7gSYQEtcqc6RE7CDghwHdVwogULgdNYHbDwbsJNVOknFYY+MN9ds7B1gR1ZGuVMozl6rcyucaJPBBfs7d31s1InU.g1nok8Zc7YZgbflnAEpz8E9SFLR7JdpANioXuLDLDdVCPKmx15fQrP+9ScNJKKam94tpURcU2woGymcI+bW1mmbfatDEcZ1UlGj7dGfTkBPZ0THcKmATIKVmehAO2zoKGifnKAJAkz6ZU42rcNPf2fq2LhbNbnDItTh5a0nwFt3eV+Q0pIggtvE3EY9OJXLmpYBtqfejPCGyqudseoVUTSJQHrYrjw006gn.ifaxT6I0r.FkQBquNpppWdxPtPBcLJstVNFLmUqZlQb+N2jzwMiCISLV4RENDzF5iFG8RPVe8MbKbvYPnfxzSRMTpB3FHFDzFPEA96OIwfc8qmYnMb6vGx3IhOfDEGBpCExdXdJa.fYk9p5dMPe.pvesl6Ue5AAou8qblwoJEggF.NiiMY+x4IXcdxqaC2KHgniY5Ewnc4Tn0VrTHZZLtvEE7tbl93XHi9PQnuI0v782NgyJKIA+1OzsMQSvbP6Ld38hALBafica3BrpOMirpSaPctVDi08KX55WjwMu.xaVos1uwwjN9ZLG4dJe08xROIH8O8y+yxNcu+8ceEF6cwrFWsjMbHH+HLt679Jt+gHViMEE9iCI5xcJMyPxN.8AkhylVPbEVGWbFy6P6yFys84hBwa4zmooilMFqLCLZ5L+u.FyF57oNcvobTcN.W04vebYmvr3l+tol+lNOmbAjzRMw3eYBcfPF49DfCRiuyaNKI76K5RBwK7RBGS0HDNUR3pXgB7Jp4APD6TAGTk3dEIZNSIJwsMnGyKq5TVktkwUfSMhJbuar6TlMKxrOgWRYHcIM0i85bx+3wc3DLfkNH5XEEcLF+bwxh9iCUvyY95QdEELmcyhreJQ5iwPZoj1UJm0r5h0bob8ag6OiEVV6ZXGp2OMAtF6SYaW.iUmhwALyNJc3Wfq5fbLX71X22.x3P8TtkqC6I3h3QBNqTT+DHa7VQrOyGzdZMtMdNm6r6IPHPTEpM+5ceFtBEQh9IXI8EdKtuXdwquxIEttllGt+2c9xJ+uY9x7q9v9gebGEuqC1WtoaRnz85IVdhXrlwG1ifUz3zCG7mFM.GRRADkbNDZVXzthY0tT5FF5zQdb+Dh+D+jcnmg1N6PuoG9AwFQDpT7BZ5pvlh9ajvAe27j+O.Uc5Ync8rRVOtnyLBGY7BJsrpdKAatrB9fkUvVKqfObYEbqkUvsWVA24uWPyD88FqEQo0F3ZN86j7aKrsS2vIoLw5u.nPNWjB
The same thing happens if you call delay on an event (even the event that triggered the callback. That specific callback will have all of its code executed, and if you didn't ignore it, the event's timestamp in all the event queues after will be adjusted by the given delay value.
Again, where does the event queue get evaluated? That's right, right after the final MIDI processor of a container is processed and the event gets propagated.
This means that if you now want to do logic involving your artificial event, you need to do it in a child processor. This is where containers come in, as they are the only type of processor, along with the Synthesizer Group, that are capable of having children.
Synthesizer group offers you voice-grouping so that you can propagate modulation to the children as well.
If you wish to delay an event, you need to do it in a Container which contains your targets.
Containers are also useful for filtering events and addressing edge cases in weird user input, as you can filter out events for given scenarios and prevent them from propagating to any of your synths or samplers.
To summarize:
- events travel from one processor to the next, and then propagate to child processors, if any
- all processors are children of the Master Chain container (also known as the Daddy/Mommy Container)
- ignore event prevents it from leaving the MIDI processor that called the method, so even subsequent sibling MIDI processors won't receive it.
- Event Queue is a list that holds all the events that are to be handed off to the child processors
- Event Queue is evaluated after the final MIDI processor within a container is executed, but before the event gets propagated to any child processors,
- ...FromUI methods simulate external events
- any artificial events are not executed immediately like in Kontakt, but instead get put into the Event Queue
- any processing or logic involving the artificial events needs to be done in child processors, once these events trigger the corresponding callbacks
-
RE: How to Create Artificial Notes of a Specific Duration
@clevername27 said in How to Create Artificial Notes of a Specific Duration:
Synth.playNoteFromUI(int channel, int noteNumber, int velocity).
I'll get back to you on the code but this one will trigger the note on function in the processor that you call it from (at least if you call it from the control callback), so that's also worth keeping in mind.
-
RE: How to Create Artificial Notes of a Specific Duration
@d-healey yes.
Also, keep on mind that this delayed note off will not trigger the note off function of this processor, but only that of its children.
-
RE: Scriptnode Parameter Aliases
@clevername27 well yeah.
This ain't a JetBrains IDE, references don't automatically change everywhere.
It should throw an error (because the property you're now referring to returns
undefined
), then you know you gotta change it there. But no, it's not automatic.Same thing if you change the ID of a component in the property editor. Any script references to it are now invalid (because you're getting the reference by means of ID).
-
RE: Scriptnode Parameter Aliases
@clevername27 I don't think this is a bug, setAttribute is always expecting an index, and the network reference object contains properties named after the parameters which just hold their respective indexes.
So network.myGain will just return the index of that parameter.
If you change the name of the parameter (or should I say its ID), how would the unchanged call be able to fetch the index if a parameter with that ID no longer exists?
-
RE: LAF for a good lookin LED?
@Morphoice here's a very quick example using lens reflections and glow.
The glow is pretty simple: you decide what will glow and what the radius is. Generally this means that colors approaching FF value will glow. Set the threshold for yourself and stick to it. This also means you'll have to adjust your color scheme a bit, i.e. your text can't be 0xFFFFFFFF white and not glow. If you don't want the text to glow, change it's color so that it's below your imaginary threshold.
If in doubt, you can screenshot it, put it into resolve, see how it looks there and just replicate it in LAF.
The lens reflections are also pretty simple. They're glows, with color changes, mirrored horizontally and vertically against the center point. This can look particularly cool if you have a slider that glows and the lens reflection moves with the slider.
This was done in Fusion in DaVinci Resolve. Here's the chain
If you want to further accentuate your lights, go wild with lens flares
Resolve has a full lens flare designer, but it's fully custom so you'll have to design them yourself. These could be very hard or impossible to replicate in LAF, so it might be better to render them out as a PNG and then put them on top. You'll want to render it to a black background in resolve, and you can do this effortlessly by just setting the lens flare plugin to show the flare elements only.
.
You can now either export it or set the scale to 100% and screenshot it, save it to PNG, open it in GIMP, and use Color to Alpha to convert the black color to transparent.. Now you can import this into HISE and load it into a panel above the entire interface.
Depending on the complexity of your lens flare, you can still decide to do it entirely in LAF. This will let you tweak it on the fly and save you some RAM usage. Be wary of using many different full-screen lens flares, especially for very high resolutions (2k+) and these will each use 20mb of RAM or so once loaded. If you're just reusing the same image, that's fine.
In the end, go wild, check the RAM use, decide if that's shippable, and if not, scale back from there.
-
RE: LAF for a good lookin LED?
@Morphoice no, you can have an overlay panel the size of the interface where you draw all the glows and flares, and just repaint it whenever you turn on any of the lights.
Just make sure to make it let the clicks through so you can actually interact with the interface that is now beneath it.