Forum
    • Categories
    • Register
    • Login

    Phase Correlation Meter

    Scheduled Pinned Locked Moved Scripting
    14 Posts 4 Posters 255 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 resonant

      Yes there is a good GonioMeter.

      But how can we create a Phase Correlation Meter similar to the one below?

      alt text

      ustkU U 2 Replies Last reply Reply Quote 0
      • ustkU
        ustk @resonant
        last edited by ustk

        @resonant you'll need to run your own algorithm. It's not too hard to make, go search google for something like phase meter algorithm or left-right correlation algorithm you should definitely find something. There are several ways for doing this depending on the complexity and the response needed.

        Hise made me an F5 dude, browser just suffers...

        1 Reply Last reply Reply Quote 2
        • U
          udalilprofile @resonant
          last edited by

          @resonant Hello. Somewhere on the forum there is an algorithm you are interested in.)

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

            @udalilprofile I think this is what you are referring to: https://forum.hise.audio/topic/10913/correlation/5?_=1765392189920

            U dannytaurusD 2 Replies Last reply Reply Quote 0
            • U
              udalilprofile @resonant
              last edited by

              @resonantNo) Someone from the user created a meter from the panel

              1 Reply Last reply Reply Quote 1
              • dannytaurusD
                dannytaurus @resonant
                last edited by

                @resonant There's a phase correlation meter in the HISE master output panel.

                The HISE source might give you some clues.

                CleanShot 2025-12-29 at 10.44.03@2x.png

                Meat Beats: https://meatbeats.com
                Klippr Video: https://klippr.video

                1 Reply Last reply Reply Quote 2
                • resonantR
                  resonant
                  last edited by

                  I'm trying to create a Correlation Meter using the method below. However, the meter gets stuck at +1 even if the signal is mono.

                  I'm getting the gain levels using getCurrentLevel Where do you think the mistake is?

                  L*R / sqrt(L² * R²)
                  
                  HiseSnippet 1764.3oc6Y8zaaTDEe2DugD2+nVTQkCHzpJN3TUkl0IosnJjciSRSDNMV1gT3TY7tiiG55cbmc1TRPEwQ9JzaHwM9D.mnW4FRbfKbnHNgDH0KbFdyLq8NqyFW2PZgT08Pj22adu4898dy68lM0XTWbXHkYXleyc6hMLOoUicC3sqzFQBLVaICySasNJjiY1JRKtaWTXH1yvzb7aJHXNUNC4ySJsHxGE3hSHYXrEk3hqR5P3ITqU98I99qf7vaR5ns54KulKMnB0mFA1y3VyZzE4dWz13agDKaLKiUQgsMLunkq27ty6dkly6fPstpSyqfadMmq5ful6BduqqKxcgltNyMGxvbhk8HbJqAGwwgFl4Vj5sai1z6Gn1fsHgjl9XwKNFMfcVQdEpumvEE+1nRahuWsd.UnggoUsDXabErcNq0Idj9zSfuyHYXmHgN.ZNVZya7TlmyAYdYXRlZlTNkIcVqFtLRWdBGg8bBq0BfnYKDDmzME0ZMF6axYUgBqHfOSGzcwqvfW5KQghyN6krKVb1oudd34xW1tBkwv9HNgFXuNFVVdHDFxs2AAILLlujl86Y2Smai4Unc5RCfWJbg9q3BfBSDbiHd2HtH6BjTlNJja4VsvtfPIbERM39wE61xAaSBvy3xv.tJRxXaz7SDBKDHdYyDh4RVUP99MgDsBshBbENRgoy+YSkeJgJqBJKY+jVeD3vA7p3cv9E3rHLnR4RqO7k1B4GJWqZ0tfQrkOHR0KV29x1EVGANY38X79+pP0osunc+2pO8zJoAjLj5imoKi.PnROwb5glBWaKjeDNgc9GH9CDvfTMF2l2FayENu88I711e9bKr5dyjfLh0HwlBysfJT26IAsaP5z0GK7UmrhRZrSGba.FHldfoDJ1BQHA9PPztWTwlFn3IjiQ8K31SnKA5EbVHpkeJssUfB2fyYjlQbbAcF2l3waeIamYE4wO354GtkHzS7d1OUY.aQhQIt35zfC1AELy18DbNxbtg5ZJaHaGSyJTgdMK7VTNdC44CHe6A4sGjUqVYxKVc9P9TVrUYZCQvBAQcZhY5PgXgPktzkOmXzJe5pvDsERCVKfv2nKN98j5+NYTr0HFTgxtiGagvu3xhtmNtnaCehGlYP7DUb6evzP5.5sLMNHErXDmSCjJXBKQLomrVlRQGA4lzRkjlwt9AqsDhiD8Mh8Ev+5hYbh.FMWBuCz0V0EYJqkvg2kS6Jc13LHvlFI28SS1zaTdW8N8cRM4v22g344iqQCIhHu9.DFZap0SChR1uunh198nVkYHOB8lLZT2dQ0QQs8QvCRwn8q382HFFAf5EAMISOWf33ZLCgOq2LVzvM.vhc0CZCNrPtCNae1LmkIyb4QzbOqUMB2sc116XYXuPt0ya6MdzqSYo54jXr4rV4COryYM6nOm0j8mXte4W41eRqj4.Fx7xFFKASNkBxj0tSH7QkyXh50B1ANnVi5iXCB3ieTMMYtQNqPNj1wlr3W2RB4GmLXYJwwGC9LV0P+eHgnNMhSB1FFelQfh2V2JpSC3ZktXvTCBv9ghFoiIZunde1dMVafC7ju72vSLSGw6lwLc5wTGRNuBRNg0sQ6fkyBKQi2P9dKJqi8MwAXl.qbFRIgebTuBc2Q9Jza3xASXSFJHrKMD6nq4F3NjMglfgonNfDE038n9RTLccLdTPZUqHkZUBnXE.JzV2jk6QrnNQHEJkxf2Soo0IZCV73RKGffDjFXvy81HzE.FANqmiUKBt7k7jjitfIjKpSdUDyChgtCq1ZtQq1Z5d7ZqOihtS775qJLh15QUAf+sy0bzzbdpd1np47xPWSeXD29sAZgh748nl9LoXTxtsoAjTY.0wPojs2FmJwJSGBtWFbUpDJmqbcrOFEpcN8cJWEt7GhA3D9PhEO6ePnLiWuokxbsEERre4XdzwOtMO5y7IzLC4iu+z+SGm9WGCCM1L9.phjshV5T+5TZmFj85kS9we6a+mkVB0oKzJMlT44l62Jcar5qZES6qd3C+gRKw1c.Z+dI84YK+q68GkVggw6g0x5gk8ckNxFb8Eca+SnP4WSMVoDdmT86zvpjj3.VUbKst3uU49LpS1tMWujwJXrm3KxnKwO+0OtTO55B7n+pvuTpJ890fMDP360WOe4OUdUx9nZrT4A5ftIFtLb5VdO43aT4ftW1ozH37pKl8pKl8pKl8R+EyFNj.kAO9DAOuEb4lh1x4dr+uevmWDAxWD6QGjKidGW0mSWTicRIEvuCj+ammxZcw61NC9YzML5.2A6NttoU09Dr3gUv4NrBN+gUvENrBdkCqfW8vJ30d5BJth7Mh3zNpyIFFqWaY4+1CSS0mLPdjw3efQSF.Z
                  
                  dannytaurusD 2 Replies Last reply Reply Quote 0
                  • dannytaurusD
                    dannytaurus @resonant
                    last edited by dannytaurus

                    @resonant Looks like the correct formula for correlation is:

                    1.0 - (abs(left - right) / max(abs(left), abs(right)))
                    

                    From the HISE source StereoInfo::calculate function:

                    void MainTopBar::ClickablePeakMeter::PopupComponent::StereoInfo::calculate(float left, float right)
                    {
                    	auto normGain = hmath::max(hmath::abs(left), hmath::abs(right));
                    
                    	if(normGain > smoothedGain)
                    		smoothedGain = normGain;
                    	else
                    		smoothedGain *= coeff;
                    
                    	if(normGain > 0.0f)
                    	{
                    		auto thisPan = hmath::abs(left) * -1.0f + hmath::abs(right);
                    		thisPan /= normGain;
                    		auto thisCorellation = 1.0 - (hmath::abs(left - right) / normGain);
                    
                    		auto idx = jlimit(0, 100, roundToInt(101.0f * (thisPan * 0.5f + 0.5f)));
                    
                    		panPos[0][idx] += normGain;
                    
                    		smoothedPan = coeff * smoothedPan + (1.0f - coeff) * thisPan;
                    
                    		smoothedCorrellation += thisCorellation;
                    
                    		min_c = jmin<float>(min_c, smoothedCorrellation);
                    		max_c = jmax<float>(max_c, smoothedCorrellation);
                    	}
                    }
                    

                    You would also need to implement some smoothing too.

                    Meat Beats: https://meatbeats.com
                    Klippr Video: https://klippr.video

                    1 Reply Last reply Reply Quote 0
                    • dannytaurusD
                      dannytaurus @resonant
                      last edited by

                      @resonant FYI +1 is the correct value for a mono signal.

                      It means there is 100% correlation between the left and right signals, which is the same as saying mono.

                      Meat Beats: https://meatbeats.com
                      Klippr Video: https://klippr.video

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

                        @dannytaurus Thank you for the idea.

                        Even if I don't use the Smoothed function for now and only use the formula, there's still an issue.

                        While HISE's own master analyzer correlation meter occasionally shows values ​​less than 0, this correlation meter never shows values ​​less than 0.

                        Also even when the signal ends, it remains stuck at positive values ​​again.

                        HiseSnippet 1752.3oc6Y8zaaTDEe23rkD2+nVTQkCbXUEGbPkTuNIsEUgrabRZiHowxNjBmZGu633gt6LlcmMsInh3BRbiy8FeMfKTgDG3FH9B.BIjPvg9Mn7lYV6cVGaWSnjlhpOT048l2adueu27duYSsPlKNJhEZXleyc6fMLOgUico71UaiHTiUWxv7TVqih33PaEoE2sCJJB6YXZl65BBlSOog72iKuHxGQcwojLL1hQbwqQBH7Tp0p7dDe+UPd3MIAZ6d9Jq5xnUY9rXvdxYUznCx8tnsw2DI11DVF2.E01v7srb8l2cd2K0bdGDp0kcZdIbyq3bYG7UbWv6cbcQtKzz0Yt4PFlGaYOBmE1fi33HCyIWj4sai1r6QUGvVjHRSerXgiQC3jUjWg46IbQAUipsI9d05BTQFFlV0RgsbJX6rVqS7H8nmBemVxvNUBc.zbhrlWtLlmit4UTy7FfIYpYRSpLoyX0vMjzgmxQXOG2ZUJDMagf3jton1qwDeyjVUYvNn7YCP2EuRHrnmDEJUr3ErKUp3LWMO76hWztJKLD6i3DF0dcLrs7PHLhauCBRXBC8kzreW6t5baLuJKnCiBKJb9d637fBSEbiXdmXtH6BjTlNJja4VsvtfPobER0+4wEm1xzsIT7rtgX.WEIYgaz7iDBKDHYayFg4RVUQ99MgDsBshotBGovL4+joyOsPkqAJK87jVeL3vT9Z3cv9E3gwXPkxsVezasExORtW0tcAiXKePDmYKZ+11EVGANIpYTg0fU0mw9h1RJAn6qwZlKX2aQ8YlQoM.YiX93Y6DR.HUo2DNcQWgqtExOFmxN+CD+CD.gTuPtMuM1lK.C66Q3ss+z4V3F6MaJRI1iDqJL2BpPe2eoneCRPGerv2cFTTSic1fcCv.wrglhnXKDgP8gfpc2njMip3IjKj4WvsqPW.zK3rPTL+zZGq.EtFmGRZFywEzYbKhGuMjWWTjW+fqlezVhPOImYuTm9rEIFk5hqynC2AELGr6I37Ly4FoqorgA6XZVgJzqYg2jwwaHuu.4aOHuc+rZ0Zf7RTmOjOMH1pLsQHXAZbPSbnNTH1HT4Ka4TqgWNUuZuqBSz1HitJkv2nClNrd.FI.IT5MWhUA+Otrv6oRJ71vm3gCMHdhpt8tLZHMZs1lOwXXJXwXNmQkJ3XVh3PWYsLkhNFxMkkJwbemZYi2e0kPbjn2Qhu.9WGbHmHfNykv6.ctUcRl1ZIbzc4rNRmMIqArowxcue5gdsJ6ltXgJAYld3aCHdd93ZrHhHZqODgg1gZ8zfnzy6yppcdOpUkPjGgc8PVbmL3vXo7d33vTOZXpe+MlgQBXdwPSyryIHttlvP3+5MmEMfo.trqtlelM7v3ZhmwpFg61dv13DCvFgbq+KrwjQtNokp2RpANo0Jevgv7US0aR4dkYkG+IrR6+Oh4jMLVBlXJCLIqQmR3CqLfIoWktCb4rFyGE1OHmar8RmQ6kSN1YBxgyNRms9pVRX9ntQJC8GsMxSaUC87JXWmEyIzsgwdCIPoWqaFGz.ddnKFLOJE6K5xaNgnEgZcwtMGafodxEOA9kvzQr1LgoSWl5vv4TvvwstEZGrbFVIB7Zx0sXgA1WGSwgB7wYDWw+ww8ovcF6mBugKGLgMCQznNrHritlafCHaBsvhxPsOIJow6Q8jnT15R7XZVUqHkYWBnXE.Jz12TU5RrjNQHsIixf0Yzz5DsgC9kxKSQPRQCL34daD4B.i.m0yqpECOhRdiwQWvTxkzIeCTnGDCcGUsxIGuZkOkOHvwNx8AAdAXriL8TmtqMp5otLzryGlFsWk7VnXedWpYu5Il5qSaFkjIPWGCUL1dabl7mA5PvylfW5jR4rUpi8wnHsqiuYk0f2lgBAbBe.wBm+we+lAFudcKk4ZKpWX+h63h49+83h41ep8oRRsqig43Zlb4SQxVQKaZccFKnAYut4a2oUqeu7RnfNP2vDRUlateq7svpOvTBsu5gO7GJuT3t8Q6OJqOhYkecu+p7JgX7dXsLZXaec4mYyRdX2493JT9UTS8Ig2oT++rvpjj3xyZ3VZMheiJ8XTmrcatd4fUvXOwGCQSB6O+O+oxcoqKvc9xu66KuF6d0fCDP3Otmd9hetxMH6ipwRU5qI3lX30nY6Z83WbiJC6oRmTify+p2JQd4akd4akd4akdNb2dzv.TV6ncj5bVvaLJYKmQw94yPJGFArCiyH.4Fxtsq5qQKpMNkjB32T4e41osVWr11o+uBsgQ.7Vna65lUU6SvRGTAm6fJ37GTAW3fJ3kNnBd4CpfW4oKn3opWKlyBT2MfmrWaY4e0.SS0q0kWSL9afCFdsF
                        
                        dannytaurusD 1 Reply Last reply Reply Quote 0
                        • dannytaurusD
                          dannytaurus @resonant
                          last edited by

                          @resonant Here's a solution using ScriptFX processBlock() (no nodes) and a global cable. It's a mashup of Claude code and my own, and it works quite nicely.

                          Just put a knob in the UI called knbCorrelation with range -1.0 to +1.0, or use the snippet below.

                          // Interface inInit()
                          
                          const rm = Engine.getGlobalRoutingManager();
                          const corrCable = rm.getCable("correlation");
                          const knbCorrelation = Content.getComponent("knbCorrelation");
                          
                          corrCable.registerCallback(function(vNorm)
                          {
                              Console.print(vNorm);
                              knbCorrelation.setValueNormalized(vNorm);
                          
                          }, AsyncNotification);
                          
                          
                          // ScriptFX 1 onInit()
                          const var rm = Engine.getGlobalRoutingManager();
                          const var corrCable = rm.getCable("correlation");
                          corrCable.setRange(-1.0, 1.0);
                          
                          reg correlationSum = 0.0;
                          reg sampleCount = 0;
                          reg smoothedCorrelation = 1;
                          reg prevSmoothedCorrelation = smoothedCorrelation;
                          
                          // ScriptFX processBlock()
                          function processBlock(channels)
                          {
                          	var left = channels[0];
                              var right = channels[1];
                              var numSamples = left.length;
                              
                              correlationSum = 0.0;
                              sampleCount = 0;
                              
                              // Process each sample pair
                              for (var i = 0; i < numSamples; i++)
                              {
                                  var leftSample = left[i];
                                  var rightSample = right[i];
                                  
                                  var normGain = Math.max(Math.abs(leftSample), Math.abs(rightSample));
                                  
                                  if (normGain > 0.0)
                                  {
                                      var thisCorrelation = 1.0 - (Math.abs(leftSample - rightSample) / normGain);
                                      correlationSum += thisCorrelation;
                                      sampleCount++;
                                  }
                              }
                              
                              // Average correlation for this block
                              if (sampleCount > 0)
                              {
                                  var avgCorrelation = correlationSum / sampleCount;
                                  
                                  // Apply smoothing (same as backend: 0.8 * previous + 0.2 * current)
                                  smoothedCorrelation = 0.8 * prevSmoothedCorrelation + 0.2 * avgCorrelation;
                                  prevSmoothedCorrelation = smoothedCorrelation;
                                  
                                  corrCable.setValue(smoothedCorrelation);
                              }
                          }
                          
                          HiseSnippet 1650.3oc2X0sTaaDEVBPYJNoYZ5jNs8NML8BQf.VDBgVZZLXfDlFCdvz7yjoSl0qVasCR6pQZsab6vyPeE5aRyiPeDx08p9Fzd1URVq.kTvSaZR8EF1yO64aO+sm0si4XRRBO1vr1QihHFlWwpyHlvuoOhxL1aaCyqZ0BkHHw1oj1ZTDJIg3YXZN88kDLmcFC0m+3dagBPLLofjgwi3TL4gzPpnfZ6FeKMHXWjG4HZnlzq1XOLm0jGvG.3YZq5FQH7wn9j8QRwlxx3AnDeCyaXg8VEuJdstq5hP8tia20HcW28Ntj0w216KwXD91cwt25VHCyKsiGUvi6HPBRhg4Law8F0wm+CrTC7HZBsa.Qtv0nCX4Tx6xC7jGQIUil9z.u14NpDCCSq1EtsoScaW2pE0iNldg66iTLrKzP2AZNUY3McI34pCu5ZvqBHYpAoYRgz0r5fioQhBNR7bYq8XPzrGBhS5PIUVio9cSqlbPBlXoPzwjcigEi0vYs50WzF9Z9MpUChUIB63P66ZuCqOkQVpOQb+.dWTvg7ABJqeKDChdwNfzoBi4wwMQvIBzINTJuZkybRFj.jfxYyMV5iYcaVPGTIGXR83gQbFrvYtxhMWJzxryRwj9TY1aSTPPWHaxo2.FVJmyv84wgyW6mpYCefcNgChGESgsLk0FJNk28kRHhGgBFPjRfBn+Hwarz0NYQ6MSFwv6yEzdTrRAfdtEs4LfC4.lizpyV6jZ1mlUudUxSdti4AARWYErkUQwuIEcXCB6RhWzdnD5iEDxTJm9Y85S+zqNvogAMA4r8XTwAQD1qqlwHK1ISUyPEHpPknd0rD0NATORrA0SV0T1uanPtdiEiuausQBT99AaMXtHRrfJOIlaSFBMdRKDl0ZaRxwBdjR1r7Fn0v425uXrk+kdMFMdwq50HrTGveMj54EPZySnJ8zw6YKPgVCbuAfIJ2uP1UMigbOzKRkEhLXuGo208erlHmWHdMq1TA1uZLNUEXDBR+afwrVuen0N85QvhB.Ni0tO4sWe1ZYIPfMkF+JYKs28ItU1g8msrR6uMDEewZeJU372BMuEHzx5PDqOw4ltKAcugujMqfFi1ZpzYfDH0Wp9FJNInvn.RS9.lPRNiXHmK7IdkaJ6lxLJlLrSkBTgZaLtGEnVDJlbDuc.ZjSpYODBRKZ2MfiOtCzg8rM1hRiAaIkvA6iXLRPhRLoGJfzSB5b5Oq92m1IW4to88KwzUiIzkriB.IfDxcYo.BquvOUB0WU6wjbNiGarNKub9s+1DD1OSR6HDMVwuGO11QZepRQ3OesFTf0Krv7JASupJGsR.lJSFZeFM6rT5vNVD0pRxTRXFbIlryCHYKjvGt7+ENp+A0MwovVyun8XpZ6+7yWw1R6Y6Lda+FoqZ9w7JNK4.P3SSNUl0R0suocUn.Hqab6kGCeMbTQ7Zg6dZyTVbsf3BKTv5jZEemGR2bHIFpN0sfJRJ2+zb2Z49.8TCvMTUvDMre4y9o.9x5PqBWsDPQQAixJ1flGJyRrQ.XfwdHLuuBB.qaeCUgJkOHwdAfvJ.A7.vTLQQro557BsqpLOeyJePJP5Eq8vYOfkZmol.yoBEyh9mbAGCx5be6f6a9xowMtEwTXlAq8gxX3wLXRyr9M.MyojSCktttbs79wNP.Rs3OgOYLckqMyX5lyrXPpIZBH86O+7TlW15wngD0q9TWf8Ip0Ptbn88ILHKGbMtug288am228Ecte22AXA.gihQrjHdBwUameYGRH8HXDtDcpmViUpTCcpFaSDCX5a8pMRIURJoqXWvU3pOwUNwUzI1FwzD5ouDVqw+oMZQKlhz3U2aGlLatCAN4dGjfAGizOWZCGDjPdL0S36pqXA4UzI+.TrGDCw5fGRniEs8Qk8fZjKcTMm9M8VY2I7sxW5ct2J+dvj3kFyb1bL1gJuBXG1PR.Tmqv3GCE18PCBD4TKWn1hy3Q9bFsTZwgDn8TeXxRcrW4AZSg.t7nfx0abHIf.INEj9hFODlcEEC9IxD5KbuvibWY75yrRgqsr6h86uufZ5+W+Bpye0Gzv7c6n3mZAMtWwVEJs+uIV91Xfi2F1HDgi4OGmNmlrn+CTTfyMS8a+NqUK4Za2y9CAEBWY7bLt7VcFEWYRU7VSphqNoJd6IUw0lTEuyjp35+8JJuQeyABdXZsggQq16nFa0zLcDHUYhweQsTysb
                          

                          Meat Beats: https://meatbeats.com
                          Klippr Video: https://klippr.video

                          dannytaurusD resonantR 2 Replies Last reply Reply Quote 1
                          • dannytaurusD
                            dannytaurus @dannytaurus
                            last edited by dannytaurus

                            Note that the above code spams the UI quite a lot with new correlation values.

                            You would probably add some throttling with a UI timer and/or on the processBlock end.

                            Meat Beats: https://meatbeats.com
                            Klippr Video: https://klippr.video

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

                              @dannytaurus Thank you su much for this useful tip, it is so sweet! That is exactly what a correlation meter do.

                              Do you think using Claude with Hise is useful? Are you using the paid plan?

                              dannytaurusD 1 Reply Last reply Reply Quote 0
                              • dannytaurusD
                                dannytaurus @resonant
                                last edited by

                                @resonant I find Claude very useful when coding. I use it every day in the Cursor IDE when I'm building web applications in Ruby on Rails. I'm about 5-10x more productive with Claude.

                                I'm on the $20/mo plan with additional OnDemand pricing for extra requests. Given that I use it every single day, often for hours at a time, $20/mo is a bargain.

                                If you open the HISE source in Cursor, you can ask Claude questions about code locations/definitions, workflows, how to write scripts in HISE, etc.

                                Meat Beats: https://meatbeats.com
                                Klippr Video: https://klippr.video

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

                                15

                                Online

                                2.1k

                                Users

                                13.2k

                                Topics

                                113.9k

                                Posts