HISE Logo Forum
    • Categories
    • Register
    • Login

    Calling multiple functions with delay on a Knob's Callback

    Scheduled Pinned Locked Moved General Questions
    33 Posts 9 Posters 1.9k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • resonantR
      resonant
      last edited by

      Hello everyone

      There are 3 different functions: functOne() functTwo() functThree()

      These functions need to be attached to a knob and run them one after the other with small delays, for example;

      1. Firstly run functOne()
      2. Then wait for 30 ms and run functTwo()
      3. Then wait for 50 ms and run functThree()	
      

      What to do in this situation?

      HiseSnippet 1771.3oc2Y06bSbDE+Nae.RDXfLvjjFlcHoPPrE5jr4iggQBrsHd.iksbfzAqOsxZGeZWwcqLXHLCEgRlTSG+Gj5LoHLolhzjTSQlLgIMoMUIucu67smzYYg4iDiZf880868w912ttlG2g36y8LLyr7FcHFlefU8MXhVS2BSYFyMig49rlF65R7LtzFcv99jFFllidYIWyLiYn98WkuD1EybHwjLLtNm5PtJsMUDSsVkqPccqhaPVl1VS5IqLmCmMM2k2EPxnVEL5fcVCuJ4ZXoXiXYXtmYaPEbu5Brf3aXN1k3M1ndK9cXAxecpOcEWhbgsQcvPAjqxcaHQr7+aLcKpaiZQdruggoUsX+ez.++HVySaP2jdbb3PJFnXMziGlijDdil.d1aE7RARlZPZr.HcXq5NdzNhXNR7req4XBhWSLD10gRfrFiTZuVSyAIXh7swqQp5AK1TibkJTXbTwBENw4ylEB89Bz5XOTMrGd1EQW.opAxuJQLaylDGQtiGv43f3wRWm1tiKQVJP7RSGc9I0bIx5DuUHdPvJME0XK0SGgWgwWwFzIx0.sll2tCmAKxcbEWoJTlK7UQM6xbDTNCwYJVRs73t4bhTYbvntcImH68yl4TmLS1L14QUod9B2MPdcYAFXAFI2IxloXdzxsHLzcvTApI2CUp.psOByZDK5x2gKEsTuhNUJh1xi.1E9lm7TYe.3kCzkx6KopPub63Jv1ibIcJUfR9qWeWyGtO70b4NXWDk0fb2aBTuoL+.AzfDb9KAXbglMguF5jHazmGQWJ04SprxAFj5k5S8rYBWCBbQgvitRWAIWRrLNxtT9SCpqbNYz35xTTtS.N3.TOFMiilvtP9ykpE.DnUbkzN5LVhyaWmdOx3HvRSgl.9mhagAevVFyCJFte+g7pdjau8gboToFxGf5k5S8sKjKECB4EJ.ZZCMD1gA9.yLEn+DnI2Bq.XQukPRikfyMnMDshP0TEdsRkyfa2gxVErV9BpD4Tu5IxfspxT4P5.A0gRzWLeosB98WXr31WUrXpkDKt80CKNDECKFGkJM4NrRPZCkemdbVFl0ZKeMtfr.KH1BrP8xpYyT4E1yCFKIU1xoK7Fjh4XcaC0G5s+kBBG4l7b78Lbmi6Dz5VSPNaNFUrPGR353AQrS4Teivd+xy+CQHHpPc5+ACO8utKsALEFELxdsTwUCE3Cmh5VMa96kM9x4lAKvQlArH7U5P7DToyXNCYcXlrfgJxXMCweMAuiR1via.+ea+n2MdrskqrQ7hqUwn+QWfgl3M55hEImjRt8HjAjVRL9hbDElOUrg93k8Nd0XacZoPpS+kZPeHg6gspQENsRGuijBdgv+aa7FNr5ArBFYJFriYU8qF3joiMbUzayfyipgkOIpfZ5tdqSl81g2ZHnOQBrbstsqRcgQPAbXYJiVxlUEzibRB1gDd127CyWQRnXxqZvZTpWBSFS3PJUlJZawEx9oJBmdSIt0iUDNSHgWL+J+gxFmsWidtdMpcDTew2cpe4GUThv5sdL8qCjoOvZ2GZs6Ct1Q38oG6QG6YJJw.9gqEHyYh0ZOAT5Cx1Ivb0pKOKCCY2fJgQeCcGEik3cEvQpyig9+P6.KHuVGt4lCApCYLhqJ8NhrsVv5Bx0RHUmnR2Vl+C7KjosbsYHS6Hl5E66ayalt4QrpZrCZoel6Vc+zG9s+zeWdFhKNwNT0DFaR3E2pRJ2fcNFLEgnF2E606962TgRywF5lPpAs20zz7CsTg7cS.VURr6AvGB5v9+gBh2wMCBelpn89AS5qBHGvRar+DQinayEFLPO5OeY4vqEDcTyye9uU9FDwUAK3FOQ0uVdFuMzoEHmVuim9jm7xxvkeH2i.oBRL0uu7t19sGMHDueqafWmndbFU78np0M4dsQWlvjQYtm8.dUvedXeUvNC8qBtfi.fvxdXleGtOwV2x8vqnNuYHhtrjhGPJgTR2qJ3dZxsuJQDKpSD14kvXv5DVZdp1Txunbvgv0If2zXAeGvYkwN8sl0555ST0U15JFStnN4u.60.xKNC5HogbNujShqIeJmUsm2VuV5639lut29XzgCtayi6lIBiAMxlEF1vEtq1lmd1D20UDQM49r44LdmVbFMQEvRDn8vpqRRTXkpCAWbG6rVLkiTYIhKA6qs26ypbUXnJrmVSsW0Xwq9CcmZ95isBfKR1b.89wsFG88naM91XGJz+b2Sl9irfd5EQpzM5+9786hgEdW7MZic732zI30vjML1mhB32L0eTvLVyKWi17YvrrJjufQa3Xma53Hqom.hOoqSwcfNk1A5L4NPmo1A5b5cfNmYGnyYGnNxS7uXWAucP8OPn1rpmizzT6YHL9W84WR..
      
      Christoph HartC FortuneF 2 Replies Last reply Reply Quote 0
      • Christoph HartC
        Christoph Hart @resonant
        last edited by

        You can do this with a timer, but in this case function two and three might not be called if you move the knob within the 80ms timeframe (take a look at the console output and you'll see that two and three are skipped).

        function functOne()
        {
        	Console.print("ONE");
        }
        
        function functTwo()
        {
        	Console.print("TWO");
        }
        
        function functThree()
        {
        	Console.print("THREE");
        }
        
        const var TIMER = Engine.createTimerObject();
        reg STATE = 0;
        
        TIMER.setTimerCallback(function()
        {
        	if(STATE == 0)
        	{
        		STATE = 1;
        		functTwo();
        		this.startTimer(50);
        	}
        	if(STATE == 1)
        	{
        		STATE = 0;
        		functThree();
        		this.stopTimer();
        	}
        });
        
        const var Knob1 = Content.getComponent("Knob1");
        inline function onKnob1Control(component, value)
        {
        	functOne();
        	STATE = 0;
        	TIMER.startTimer(30);
        };
        
        Content.getComponent("Knob1").setControlCallback(onKnob1Control);
        ``
        resonantR 1 Reply Last reply Reply Quote 1
        • resonantR
          resonant @Christoph Hart
          last edited by

          @Christoph-Hart Thanks! Actually the above snipped is very simplified, so I will have to use lots of timers (with also skipped ones) with this case which will be no good.

          I see callAfterDelay API, is there any alternative solution similar to this (without using timers) or broadcasters maybe?

          Christoph HartC 1 Reply Last reply Reply Quote 0
          • Christoph HartC
            Christoph Hart @resonant
            last edited by Christoph Hart

            No, but maybe the broadcaster's callAfterDelay function is a bit simpler to use (and to scale). You can also put the timer logic into the functions you call which might help a bit. This should be simple enough to be used multiple times with a bit of clever thinking:

            const var Knob1 = Content.getComponent("Knob1");
            
            inline function createDelayBroadcaster(knob)
            {
            	return Engine.createBroadcaster({
            		"id": knob.get("id") + " Delayer",
            		"args": [ "unused" ]
            	});
            }
            
            const var Knob1Broadcaster = createDelayBroadcaster(Knob1);
            
            function functOne()
            {
            	Console.print("ONE");
            	
            	// You need to call it with a new argument (random number) or
            	// it won't fire...
            	Knob1Broadcaster.callWithDelay(30, [Math.random()], functTwo);
            }
            
            function functTwo()
            {
            	Console.print("TWO");
            	Knob1Broadcaster.callWithDelay(50, [Math.random()], functThree);
            }
            
            function functThree()
            {
            	Console.print("THREE");
            }
            
            
            inline function onKnob1Control(component, value)
            {
            	functOne();
            };
            
            Content.getComponent("Knob1").setControlCallback(onKnob1Control);
            
            
            resonantR 1 Reply Last reply Reply Quote 2
            • resonantR
              resonant @Christoph Hart
              last edited by

              @Christoph-Hart I'll look at it thanks!

              Christoph HartC 1 Reply Last reply Reply Quote 0
              • Christoph HartC
                Christoph Hart @resonant
                last edited by

                @resonant Oh and if you want to deactivate the delayed calls, you can use Broadcaster.setBypassed() for this - if it's bypassed it will not call the delayed functions.

                1 Reply Last reply Reply Quote 1
                • FortuneF
                  Fortune @resonant
                  last edited by

                  @resonant said in Calling multiple functions with delay on a Knob's Callback:

                  1. Firstly run functOne()
                  2. Then wait for 30 ms and run functTwo()
                  3. Then wait for 50 ms and run functThree()

                  Just out of curiosity, why would you need this function workflow?

                  resonantR 1 Reply Last reply Reply Quote 1
                  • resonantR
                    resonant @Fortune
                    last edited by resonant

                    @Fortune

                    As you see in the snippet, on each knob I am using multiple functions and each function contains lots of setAttribute APIs. Also there are lots of knobs, so this means tons of setAttribute APIs.

                    I've just discovered that the more setAttributes are assigned to the knobs/buttons, the more crashes happen while loading DAW Projects with multiple plugin instances.

                    These crashes happen on Windows and it's a memory corruption error. Because while the DAW project is loading, all of the parameters are trying to load the setAttribute functions and this causes a bottleneck that causes the crash.

                    I think delaying these functions will prevent crashes because the functions aren't being loaded simultaneously.

                    Or this might be a bug, I am not sure. But these crashes are happening with multiple plugin instances, on Windows and while loading the DAW project.

                    ustkU 1 Reply Last reply Reply Quote 0
                    • ustkU
                      ustk @resonant
                      last edited by

                      @resonant So if this work around succeeds it's a good alternative, but it might also mean we're lacking of a possible Hise optimisation so this bottleneck doesn't happen... @Christoph-Hart?

                      Can't help pressing F5 in the forum...

                      Christoph HartC 1 Reply Last reply Reply Quote 0
                      • Christoph HartC
                        Christoph Hart @ustk
                        last edited by

                        Yes I agree. If you manage to make a minimal example that recreates this I can take a look. This shouldn‘t be a reason to hack around with timers.

                        Christoph HartC 1 Reply Last reply Reply Quote 1
                        • Christoph HartC
                          Christoph Hart @Christoph Hart
                          last edited by

                          I've pushed an experimental build flag that might help with the issue. Please pull HISE and export your plugin with the HI_DONT_SEND_ATTRIBUTE_UPDATES flag set in your Extradefinitions. This should deactivate the internal messaging and hopefully fix the crash. Let me know if that helped.

                          resonantR ? 3 Replies Last reply Reply Quote 3
                          • resonantR
                            resonant @Christoph Hart
                            last edited by resonant

                            @Christoph-Hart Thank you for the update.

                            Unfortunately, this update is not a solution for the crash. The plugin seems a little bit relaxed but the crash still happens.

                            I sent you a minimal project of this FX plugin privately.

                            We tried this crash problem on different users and different computers. My advice to replicate the problem there is if possible, on Windows in Cubase 9/10/11 or Studio One 5/6 create 3 individual DAW projects (Using this FX plugin on the channels of a real song project will give a much more realistic result):

                            • 3 plugins
                            • 8 plugins
                            • 20 plugins

                            Some computers crash at 3 plugins, some at 20.

                            I also discovered that, if I insert only a ShapeFX module at the begining of the project (no setAttribute or parameter usage for this module), it reduces the crash because the loading time increases and this prevent crash. But the plugin seems still unstable.

                            I think the real cause of the crash is all of the parameter settings, UI elements...etc. are being called simultaneously at the same time on DAW project loadings. A little bit delayed calls can solve this issue.

                            d.healeyD 1 Reply Last reply Reply Quote 0
                            • d.healeyD
                              d.healey @resonant
                              last edited by

                              @resonant So the issue doesn't happen in a single plugin instance but when multiple are used?

                              Libre Wave - Freedom respecting instruments and effects
                              My Patreon - HISE tutorials
                              YouTube Channel - Public HISE tutorials

                              resonantR 1 Reply Last reply Reply Quote 0
                              • resonantR
                                resonant @d.healey
                                last edited by

                                @d-healey said in Calling multiple functions with delay on a Knob's Callback:

                                @resonant So the issue doesn't happen in a single plugin instance but when multiple are used?

                                Yes exactly.

                                d.healeyD 1 Reply Last reply Reply Quote 0
                                • d.healeyD
                                  d.healey @resonant
                                  last edited by

                                  @resonant Are you doing realtime stuff in the UI thread?

                                  Libre Wave - Freedom respecting instruments and effects
                                  My Patreon - HISE tutorials
                                  YouTube Channel - Public HISE tutorials

                                  1 Reply Last reply Reply Quote 0
                                  • resonantR
                                    resonant @Christoph Hart
                                    last edited by

                                    @Christoph-Hart Any progress for this issue?

                                    Christoph HartC 1 Reply Last reply Reply Quote 0
                                    • Christoph HartC
                                      Christoph Hart @resonant
                                      last edited by

                                      No, I need to test this. Can you give me a list of all host / OS combinations. I know Cubase is very critical when it comes to UI CPU pressure but I can‘t est on Cubase at the moment.

                                      resonantR 1 Reply Last reply Reply Quote 1
                                      • resonantR
                                        resonant @Christoph Hart
                                        last edited by

                                        @Christoph-Hart I understand. We've tested on 11 different Windows 10 machines.

                                        • 8 crashes are coming from Cubase version 9 or 10 or 11 unfortunately.
                                        • 2 crashes from Studio One 5 and 6.
                                        • 1 crash from Reaper 6.

                                        For other DAWs and macOS, no known crashes for now. But I can definitely say that, if the plugin works in Cubase, it will work on everywhere.

                                        For the NFR License, as a Developer you can write to Steinberg and ask from them, they are giving NFR Licenses to the Developers for free. If you get version 11, you can rest assured because you will reproduce the issue in there.

                                        Christoph HartC 1 Reply Last reply Reply Quote 0
                                        • Christoph HartC
                                          Christoph Hart @resonant
                                          last edited by

                                          @resonant yeah I wrote them for an NFR but never heard back, then I stopped caring.

                                          d.healeyD orangeO 2 Replies Last reply Reply Quote 0
                                          • d.healeyD
                                            d.healey @Christoph Hart
                                            last edited by

                                            @Christoph-Hart Have you used up your free trial?

                                            Libre Wave - Freedom respecting instruments and effects
                                            My Patreon - HISE tutorials
                                            YouTube Channel - Public HISE tutorials

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            50

                                            Online

                                            1.7k

                                            Users

                                            11.7k

                                            Topics

                                            101.9k

                                            Posts