HISE Logo Forum
    • Categories
    • Register
    • Login

    Best Practice for Creating a Draggable Filter Linked to Scriptnode

    Scheduled Pinned Locked Moved General Questions
    14 Posts 5 Posters 490 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.
    • HISEnbergH
      HISEnberg @Noahdeetz
      last edited by

      @Noahdeetz Okay here is my hacky solution to creating a draggable filter

      HiseSnippet 2683.3oc2ZzzaabbcojWmH53TaizlzdZfPQAoirLIk+rJFlRhhVBVRlzT0N5TvpcGRNvK2Y8tCkDcgA5Qeq8VO1dqmKP+Aji8PKPAxef9Sn+CTeuY1OlkZEEsbZbb2CFZdy66ul2LzsB31zvPdfQgh6NxmZT3SL6LxSzes9VLOiMaXT3plMBr50yZeWZSlqfFXr5HeqvPpiQgBy9HDsBycAC42+4gqZ4Z4YSSAYX7LNyltEa.SjBsU8GybcaZ4P2kMPC6aUeSat2ZbW9PPkl0rhguk8Kr5Q2wBQaFSiMrB6aT35lcumSUaq6eKGZkaSocqbGq6T8d62sxsueMmkpYW6N2892s18pV0nvEW2gI3AcDVBZHvzU4Ni5zmenmR.OiEx.aCWT0nCHYEXi05ybcZE6eBMLJX1J0aMqxa8YlaybXIvS8ZWQtAIkBcmVgYljJU8sPkJnoRWPoRW0ric.yWjtCpOWxbSOH100BhM5phBWiYtwmZdya9f79HIgehJ9GRxEuhmF8Oakmt4Jqt05cNE5f.dnfbfUPD+qRd.QlCtXOpX8tco1hRyGs07kWtHHH0JRCVnuq0HcNHTaEsCxp03fg6IPlsFefO2CV.7aLDQFqXSWwSogBUJHPdkitWklxuTDVwVvNfpgRylwnTbbFuXHEDGSPGnve9ExHAk8PZY4Qc0riVdtnaO0gjuUjEsTavGYml9sTE0mTXO1iuenlrdr29MCnu7zkRLBo7Ohr1Sjl1wQKxldLAyxEHycHMjzkGP5phf9VAPgMlTULf1iXOTv61EE1PpmsL7UUp13lurokMTzHAtnxTHOkJBXzCn.kAAff0EghYDKOGRaR2.9.hnebNbQzBTH7LjBfmQNQzNVQ.bc+gBZopfEfn9xIhUsxINVo6Hf6VrHyyk4QIcG5AYKbOB2K1OFgRI6X20BJ0tbweaw4hEPnt.hAl3YhoX4huFD8YE1PlEIz0rbc2GZoV5DpCZC4qzseGz31Sol1dRpY6L53o0mo0J6r9VjMVYmFas4NO5TaRQtA9EgcU0phYKjPEoEzIW7T9PA3OJE6OJ0CsXB7gIEGxbD8gbBQeVHZQOGWWBzwXD5SY85KzvXCIfXTj+SuEgRA2UbcKoUzh1ItInsfmvdnKbNAwmGxjAEL4FSkU4uIRylEX6R+ZPbk11B5d5x6UROE+ljZUJC+axlXoU4xjqqLj7D4doBk2UISoPH6aAme.YGPkkL7lnDiZwCUVGqKoTTYyWIqXKSTtN7CQCUzXLtAoxhKgJWI.wnU3xZKq7RulPcComjAUV71juTmMR4.r49Kd+nUJ1n3xX9p8.NDEitdrjQFWFjZwWG07Za9PPxwIjDAmzGZo.9.G7bQlWOYGl97CnAvhbxjjLHIgNIUB5Z4IjEPnBM.QBicRvKdzxZf2KA7H.bw4.kZcuvgATYDQhBgEBQQHMySBSlJQ1mOzywB5OFpXlDZ0mGk0Nlhpm+pg8FwovmD8zj4j3sRKk9Bn9iTsrJ5kF1lpSG0OdEBEXFI3x6QQeukbOhMrY.l+IkUB6GSICn9XUbb81qUZiLSJGssx4Sa0OKmHORB3m.00.XmHM8v9TOhGWjlmLkp739VLoq76tSMg1j7NYWgAVGUpxBQ+MyqjVFyBQnVdbh2axDqxRhnduxwYKQsZ1h2CRPE8GvrICr78wxozytSvDyG8nGtl5D8G.MxfBVof74GJ6iEqdPwtlROlzvibfCmhaZk1EaTZeNrJB6aPrDjALGeNDMxnGQcdTcKJE4BtYlxkxQcszZTkqGp5Bp1M53GYpsS8xXvWxkuBa2o2EE+PbkMBWBaDl18D6nIo55jZZgrSzHUiGHweodqSjGJlbCknGiWoN2bmA.LujflFY4haMIts0PKd7DDOY28R4wL4zAYPQmGSeUVb29cgSpI9AxhsPsdox4G2mh4mx99XdyPQHyAZk.HBywhSeJwMmi.ZDcTwpXG4vRS2v7kWVaLrc3B5S7JIOunHbN13a0sat6EM2jKMH2swKeGLIBK4Mbv9z.8w8PDgKal8FrWb5tAqsxv0Pj6gWN3I9zn0M4tN3MSw+9j220HxyA27clHMDPUHu26mFcu2NtPPIvfALonYbRjgT+w2Y3u8W+KKeSu+Tciof9OxTldkR7+7efeyU232rYCKgEdA7HMBzRensOCcFEZPOfYSUWGeNyFzvWH39FELSB1FE9DQz6GnDZSWtELoYucYfSCE8kMaJVwyxczqfbAiizeOkQoK1qdj3Ux5mXtxPGFWRWHXC62K9kTl6hKszRGijjdr.B8Mu4MiAsFBtQiFRvB5QhTjiU.ooWXKSrIx7IgmMcl+WSlOV1UmeAb2M8bnGAvqIWAAWW9gOmG7hPeKaJ.uqEzMp3qMjSfBdnB+gBFFpQxvU+cCYLOwqcoyvqcMywOKbBttIHyrNoiO93emQZxWruNifx3qiE2XdUfOZ9uGmq+Kt5Oi26FUOC2mtOpnxGc43mABaIIcNWwLaGlymqwB0g3oYgj8eg4ZtL3uVfrgbPpeEItY23lugwwUP1Olm5iNYVYrNYbxBlIWkej9KIlZQ+YQcLSFeErjaPaLf6PGCh9SYdq5vo0IKey2UOTP86vdEU+0NCG1sKCvxzjrwq.5cf6EzJZRBDuBHZ9+w5NztVCcUmQkPe8eeccCbtyrMjl04jm0MqYaCck1fTOxjVR98cO7jZXrkjqFBvMN4CLdEys4N38Cy9dm3KAGsAxa8GYDe5QOPliz47awifVYhOB5zphW0rESX2OecblbzQ7Tl+GniQOc7kMUusYpBdAyle848chmr3KLil7mSI+qY1h6NxuO2iYG8v9nRLmYb6gS+Y9MLRKZT.qiGo1NZw2hGQtsr7Jlhund6gVti4cWk4ycsBdW87mwSjegoL83mk1If7tjGegoKHcFC5L04zXj4CG88maFEzIny9CG89SMa+iKk0TorEMSF1S8q7jL+UFcbU3bJZP1Su915sfq4vnGFMmZD3qTuvreOU5Ynd9zdv8cCjmRtyvAcfi3so364.ikDhCULCdNuZcEbMpDcndNxEvHSGGsYUbcgnMqFuotO4yUVxkLet0AT4ufjzo7Skq6xCFPdD0iFfQ1I0c6eMs+Hl9S8Oh4SrEfJrafkWnOOjVUmycnCX6By.DlA5XTTKWJx.sAULzKKqUfxfE5JZBtBM7935w.qoCDFbLCyf0Y3z1LsIM92ObcO7mHrCErbmmDZCNFzOqWSzZHLrp7YYppSXJ3Z5f2vJvAhg1YNTX1otpROyL6jIZ3myoEW78vuw62Oi27dbBrL+LzyEqicXC7coq6c.0EtarTGuFbYX4blwPyVGtM2iqFHQOpK+M950ilIYJWCZEg.tTRJjOq9SotTqPsZyeY8sXdTqfrim7V4Kd6+I4yMd8ElJ0kfMOHe3N47r+e8jySe0GzO7G2QwO2D5KWiHCkj2OwxeHFH3GBYLvxNf+M1pWPDK5+XIDvt8j++TZNysw0DsmNL1YBWAm8M11YY0IHr14kvkNuDdqyKg297R3cNuDd2yKg26rIDOQekgB9.UsALlSq0UuWWA0DNxxDi+KcEp4GB
      

      This example uses HISE's stock filter, so it will have to be readjusted for controlling a Scriptnode filter. The code should support this ( I have done this in other projects). I have also added modulation to it in the past and it should, in most cases, display correctly.

      I wrote this about a year ago so there is definitely some things I would do differently (the Q calculation is just an estimate based on the HISE stock filters, so will have to be readjusted depending on the filter algorithm you use), but this is a start on a potential solution.

      I think it would probably be best to script a draggable filter using just the scriptPanel, or possibly incorporating an external C++ module from JUCE. That would certainly improve accuracy as well as allows for different slopes.

      Either way I haven't had it crash on me and it performs well enough imo, here is the code:

      //===================== Draggable Filters =====================
      //===================== VARIABLES =====================
      const var Filter1 = Synth.getEffect("Filter1");
      
      //Filter Display
      const var FtFilterDisplay1 = Content.getComponent("FtFilterDisplay1");
      const ftRestColour = 0x80FFFFFF;
      const ftActiveColour = 0xFFFFFFFF;
      
      FtFilterDisplay1.set("itemColour", ftRestColour);
      
      // Panel
      const var PnlDragFilter1 = Content.getComponent("PnlDragFilter1");
      const panelColour = 0x30000000;
      
      //Knobs
      const var KnbFreq1 = Content.getComponent("KnbFreq1");
      const var KnbQ1 = Content.getComponent("KnbQ1");
      
      // Initial values for filter parameters
      reg cutoffFrequency1 = 1000;
      reg qFactor1 = 1.0;
      
      // Retrieve current values for cutoff and Q from the Filter
      var cutoffValue = Filter1.getAttribute(1);
      var qValue = Filter1.getAttribute(2);
      
      //Knob Control
      
      inline function onKnbFreq1Control(component, value)
      {
      	Filter1.setAttribute(Filter1.Frequency, value);
      };
      
      Content.getComponent("KnbFreq1").setControlCallback(onKnbFreq1Control);
      
      
      inline function onKnbQ1Control(component, value)
      {
      	Filter1.setAttribute(Filter1.Q, value);
      };
      
      Content.getComponent("KnbQ1").setControlCallback(onKnbQ1Control);
      
      
      //===================== PANEL HANDLING =====================
      // ----- PANEL 1 -----
      PnlDragFilter1.setPaintRoutine(function(g)
      {
          var width = this.getWidth();
          var height = this.getHeight();
          
          g.fillAll(panelColour);
      
          // Calculate position for the cutoff
          var circleX = (Math.log(cutoffValue / 20) / Math.log(1000)) * width;
      
          // Calculate Y position of the circle based on Q value
          var yPos;
          if (qValue <= 1.0) {
              yPos = ((qValue - 0.3) / (1.0 - 0.3)) / 2; 
          } else {
              yPos = 0.5 + ((qValue - 1.0) / (9.9 - 1.0)) / 2;
          }
          var circleY = height * (1.0 - yPos); 
      
      });
      
      // Mouse Callback to handle dragging and hovering
      PnlDragFilter1.setMouseCallback(function(event)
      {
      	var mouseX = event.x;
      	var mouseY = event.y;
      	
      	// Ensure the mouse is within the panel boundaries
      	var panel1Width = PnlDragFilter1.getWidth();
      	var panel1Height = PnlDragFilter1.getHeight();
      
          if (event.hover == 1) 
          {
              FtFilterDisplay1.set("itemColour", ftActiveColour); // Change to active color on hover
              PnlDragFilter1.repaint();
          } 
          else if (event.hover == 0) 
          {
              FtFilterDisplay1.set("itemColour", ftRestColour); // Revert to rest color when not hovering
              PnlDragFilter1.repaint();
          }
      
          if (event.drag)
          {
              FtFilterDisplay1.set("itemColour", ftActiveColour);
              mouseX = Math.max(0, Math.min(panel1Width, mouseX));
              mouseY = Math.max(0, Math.min(panel1Height, mouseY));
      
              // Logarithmic mapping for cutoff
              var newCutoff = 20 * Math.pow(1000, mouseX / panel1Width);
      
              // Compute Q value based on y position with 1.0 at midpoint
              var yPos = 1.0 - (mouseY / panel1Height); 
              yPos = Math.max(0, Math.min(1, yPos)); 
              var newQ;
              if (yPos < 0.5) {
                  newQ = 0.3 + (1.0 - 0.3) * (yPos * 2);
              } else {
                  newQ = 1.0 + (9.9 - 1.0) * ((yPos - 0.5) * 2);
              }
      
              Filter1.setAttribute(1, newCutoff);
              Filter1.setAttribute(2, newQ);
              KnbFreq1.setValue(newCutoff);
              KnbQ1.setValue(newQ);
              
              PnlDragFilter1.repaint();
          }
      
      });
      
      // This prevents the panel from being dragged outside its parent panel
      PnlDragFilter1.setDraggingBounds(Content.getComponent("PnlDragFilter1"));
      
      LindonL 1 Reply Last reply Reply Quote 2
      • DanHD
        DanH @Noahdeetz
        last edited by

        @Noahdeetz there's a thread on here which uses broadcasters and the draggable filter display. Via this and global cables you can recreate the eq inside scriptnode. I did this for LFO-EQ. With LAF I just had the nodes visible from the filter panel, and used a filter display behind to show the eq curves. Only issue is creating more nodes as I had a pre-assigned amount (5). It can be done, however.

        DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
        https://dhplugins.com/ | https://dcbreaks.com/
        London, UK

        orangeO 1 Reply Last reply Reply Quote 0
        • LindonL
          Lindon @HISEnberg
          last edited by

          @HISEnberg said in Best Practice for Creating a Draggable Filter Linked to Scriptnode:

          HiseSnippet

          You might want to add this on the front of it...

          Content.makeFrontInterface(600, 600);
          

          HISE Development for hire.
          www.channelrobot.com

          HISEnbergH 1 Reply Last reply Reply Quote 0
          • HISEnbergH
            HISEnberg @Lindon
            last edited by

            @Lindon haha thank you yes that really makes a big difference 😊

            N 1 Reply Last reply Reply Quote 0
            • N
              Noahdeetz @HISEnberg
              last edited by

              @HISEnberg Thanks so much for the snippet!

              1 Reply Last reply Reply Quote 0
              • orangeO
                orange @DanH
                last edited by orange

                @DanH said in Best Practice for Creating a Draggable Filter Linked to Scriptnode:

                @Noahdeetz there's a thread on here which uses broadcasters and the draggable filter display. Via this and global cables you can recreate the eq inside scriptnode. I did this for LFO-EQ. With LAF I just had the nodes visible from the filter panel, and used a filter display behind to show the eq curves. Only issue is creating more nodes as I had a pre-assigned amount (5). It can be done, however.

                I am new to the Global modulators.

                I am looking at this to start: https://forum.hise.audio/topic/7117/modulator-level-broadcaster/12

                How can we control the intensity for each parameter for FX plugins?

                develop Branch / XCode 13.1
                macOS Monterey / M1 Max

                DanHD 1 Reply Last reply Reply Quote 0
                • DanHD
                  DanH @orange
                  last edited by

                  @orange In Scriptnode? There is an Intensity node...

                  DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                  https://dhplugins.com/ | https://dcbreaks.com/
                  London, UK

                  orangeO 1 Reply Last reply Reply Quote 0
                  • orangeO
                    orange @DanH
                    last edited by

                    @DanH Similar to this?

                    HiseSnippet 2203.3oc6ZEzaabbEdVRMTRzotw0pIAEs.KT5AkTCAxUxRVnnPThRzlnhRzlLJAnFvcztCIWnc2Y6tKkMSPO0BzzS9ru0CoW6gBDfdq9GPJP.LJPOl9Ov8WP5a1YWtyRRISQIw5zDJ.ANu48l4Mu226MuYFV2ioS88YdHk7M64RQJuAtQOmfNk6PLcPU2AobcbMhe.0SUPZ6dtDeepARQI6c4DTleFT3mWt41DKhiNMgDBcHyTmtmosYPB05k9klVVUHFzll1RbuZop5LmxLKVWPexhKfbI5GSZS2mvYKCFcOheGjx6i0VeihqcjVAsMNZc5pTsVEoqbTq0MJVXkBqRztyJq0hrVQxFHkb6ZXFv7ZDPBn9HkY1lYzqQG1icDSvgl9lGYQ4MJhZ.yrfbElkAeIx+NpbGSKi5wFJeDLn0SLaYElsEv0LML6SOw78lgcnlHgrATISZ0KaJ0q3oodiPkTjToYDpzMvMz8LcCR5gqOWCW0A7lsHfeRVUD7hx7mUvkY.GNAKaSNlVwCZzWhkVqPgaoB+68944yC9J+.0SHdpssU+Ep65z1zgtbaZvcsXGQrd.qafoS6ZDGvC5sDHQh.5EAAZayYtLAVfKsnPF08pbfZwESyq1Yvq1hgZRwkA9cn5AMYhNqwL5ZQ.K6RKBrUbwaoF30kxGWsylUsDVgOs55nGXxbTYN6yBnG3rz6k+SxOe9ead0A6pUqQ1G2V5wrr3VfQzMO.v6rDbImt1GQ8tEXJr.sJlQvImF4ja7PN5BWqDiLmpNlAG3RiZm.8KNBbFJBa.e6CptCIfvgdQz.9bodAlb0QYG5IPfu.HNOdGp+wALWHzeHTJDeD6.jCZ3oVh5.rGoPpbzniuYPO4TOCFIMyoaOJLx.8QtZGS08F35lA5cFs9lYD5KX0tp02n7ReO7tsZAn8DkcFbkOZRSBU3bmDJeTRHXN4S9aD0TsxGUbToeT9TbRPfqG0k3QaxpaQ5sjOw10h9.PGuk5QVL8iaX9wzgibbEpv1bNVRuCAh0s7mj.rbWRolQ8SDF3Y9DjBd+t1Mfc3zokizNflRFdrkncAdaNFoA0wHrwWCeh5rHusRTmEi6TJrbeZviYdGG5Nh9NRYVwF4636FQRaEzVVVrGWlY6ZFgYAuPHs5LqdtcXNl5bRBNh00srYcgoIRggsiaRLs3f7Fc8gTHFG3z.XNrF.krGR87CG3YwEVF9C.86yLftlsBQGLs8pSB5vid3Yk.3I0aYcoxNRosxXEQ4.Cv.ejiKcPX9.M2laS3ENvcb0IdffvNY77SYTxJkuR.c4sffzLBfZU+C48pSrPGxgFbgBmEN6yHVH4DZZ6vMRdjNe6ITp01ag8Dd+kSwynVMoXPd0LetG9Wu2WO3J5Up+kEaywc.Q5+0wx6bhPI4qZR7fsW8iRlGKlvcU0fWzfY+jX8Mi7NlEKFajjwkqLws.NpY5DM+IY+pQdx.zd4lMBnt7PZY9ZbL8wB6oLm70W7DOzvrCsEoqUvPzQRdL4kSJ20MCghPVgkSXXXekr3mMrKsS5bXvuN10l7ntN9.7Cl5T1773ZvBzz0p2.l8LRl84lplcDZzlcDZqtALaHCZ3NgnqdETTdqv2L1XizJYpP6TtgABsiwJo3YTg1oX3JBwLG1hXX.V1TXkqgq3Q+McgLxCBVxd19hUKMju3SeQoWkuXAHQul1FaTX0aull1Jqdm0uysQiD27IK7Wt6me+OqzqK3FofpID1b147d4e+hqiX7VFFienmLPtO5HED9MwsLs33gki5cXvaeAOWvVdQCVzmDe.gJhYI4q7MobLnOIt9kcgRvfYwHTf3ZZRAWycU.WCoV52Y+OhRcjDqjdnJ8zQiSA5iMFnzJq7hMGPIe9W7Eu63ojn28+7kgJYV78STtO+E+yG9u9CuUoScOuyFSp87gwjZkNeXxbgmT6b.JuxJM3WeycdQjergMiEzAp5JkdU5e+w+9QEKGRGc0WxRN9QGoScSEP6TUo4w65vq2z3bTG0oVxwrRkVoy2+8x2LN1Zo7ljSPYsxUQfFbIlKLOA5xKIDjraSdRn9h9YO8Guw0+iOqzEa0cV0P1ut8sYrisIgmW7BeiNyI57GgG3h0JGe7tvRA9IwmBoe+p8Yn3Yb8xe43d8xti80Kqj8x55Wm4p5Fgmp2i0MGx03eodyamiqXOijJeCgJiwv4VQhHP9k59pUssMcYVDOd+Ias2u+uZSNFoZLD6O8rm88K8gjSnsXd1Qv79izdz1f4PF40jZ6xZzyQOUbc7FOoQdKTZOFyMNUqzvVuCwme0w9zfTCCLrMYhmcoL+hrj6rZaGlGUbczxzK20GJEIdAHt0CH0injpeEdsUWF9z5mw++Fkg+sxAWNsQWdOhQlwFmxuAi9tbNb807aHVnw8AgulnwiNvR6BEXo9vm9NkREX8U2+uk66Br9t.quEEXMwOVT1uo8XQWNpxz3IRjVtusX4dMLOnN7m6P3h8GhiCxUuKEpFk62lxUjdfd.nBM8HN9tLeZQoQ94Mn1lMYNTeYpCJgl7UN0WBszm2LnqSpgNhTJt3lhJfoPhu4JESTSlXchSpACZmZjpwcoIEcIxV2fBqbiC70ACCYfS4UuqkO8CMMB5TTVvDxZxjuGwyXvsKFrv9wrlzzO5rD+SyeCHS0jQW7GZ+x40hmOVGaXxu4vccNgZAm8LTG+A3nyAGSMcLYMlCK94JSP.OfBoRZ2ll9JOF0BZqf.hbg.KT5ATKJT9PBoeZo8fSmR7Bu+lIyVb9+46LR+06fEpqJOQh5+e7Cj3ao64M1QnP9yu43oeaLjSWSMzcq9+d+8znvhowbXSz8XOJ5AG4ILlKjBrtcBell4w03sUKhNYvab0F154Q55oGpgDTaREbkIUvUmTAu8jJ3ZSpfqOoBdmWsf7JChdDIdbBTtT8cEGsTo+4ZUxh9u.VNSXcA
                    

                    Screen Shot 2024-11-13 at 23.50.17.png

                    develop Branch / XCode 13.1
                    macOS Monterey / M1 Max

                    DanHD 1 Reply Last reply Reply Quote 0
                    • DanHD
                      DanH @orange
                      last edited by

                      @orange Yes looks good to me.

                      Also try the Bi-Polar node instead of Intensity for bi-polar behaviour.

                      FYI there is a Global Mod node in scriptnode itself - no need for the Global Cable. However you can't compile the network with a Global Mod inside it...

                      DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                      https://dhplugins.com/ | https://dcbreaks.com/
                      London, UK

                      orangeO 1 Reply Last reply Reply Quote 0
                      • orangeO
                        orange @DanH
                        last edited by

                        @DanH Yes bipolar does it better. But I guess we can't choose between different modulators with Global Mod?

                        develop Branch / XCode 13.1
                        macOS Monterey / M1 Max

                        DanHD 1 Reply Last reply Reply Quote 0
                        • DanHD
                          DanH @orange
                          last edited by

                          @orange you can. Change the index. And I think you must make sure all the Global Modulators are in the same Global Mod container.

                          DHPlugins / DC Breaks | Artist / Producer / DJ / Developer
                          https://dhplugins.com/ | https://dcbreaks.com/
                          London, UK

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

                          20

                          Online

                          1.8k

                          Users

                          11.9k

                          Topics

                          103.9k

                          Posts