HISE Logo Forum
    • Categories
    • Register
    • Login

    Faust Aural Exciter

    Scheduled Pinned Locked Moved Faust Development
    8 Posts 3 Posters 708 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.
    • clevername27C
      clevername27
      last edited by clevername27

      Has anyone tried to use Faust's built-in aural exciter? I tried it using their web api, and got the same hing—so I know it's not a HISE thing. I noticed it got some love on a semi-recent build, so I'm wondering if it's a Faust bug in the macOS version (which is what I'm running).

      The exciter is based on this paper, which explains the implementation in-depth, and what/how it's supposed to work.

      Since it's built into Faust's standard library, this is the only code you need to use it in a Scriptnode.

      process = dm.exciter, dm.exciter;
      

      I've encountered two problems:

      1. It doesn't seem to generate harmonics! Specifically, the "Harmonics" knob doesn't seem to do anything. (The high-pass filter and mix knobs seem work, though.)

      2. The levelling doesn't work. The output gets quieter as you increase the mix level—presumably because it's simply crossfading to a high-passed version of the original signal. But according to the paper, the circuit automatically compensates for level changes within itself (so there's basically gain stages at the front and back end).

      To use the Faust exciter, it's just one line of code:

      MorphoiceM 1 Reply Last reply Reply Quote 0
      • MorphoiceM
        Morphoice @clevername27
        last edited by

        @clevername27 doesnt seem to do anything for me either indeed. Tested on audio and sinewaves, the latter is a dead giveaway - no harmonics.
        I don't know about this demo in particular, we'd have to check its source to see what it's actually supposed to do, but the simplest way to add harmonics is the tanh function, if you want to go for the Aphex Aural Exciter approach best follow the steps from the paper and build it yourself. It's just a separate path for a filtered signal passing a soft clipper, which might not even be the best approach by today's standards, but still works suprisingly well for vocals and some synths etc. They put a compressor in later versions to even out the creation of harmonics on different levels. Should be fairly simple to reconstruct

        https://instagram.com/morphoice - 80s inspired Synthwave Music, Arcade & Gameboy homebrew!

        clevername27C 1 Reply Last reply Reply Quote 1
        • clevername27C
          clevername27 @Morphoice
          last edited by

          @Morphoice Great take, cheers. If you know how a good, specific way to build this in HISE, you're welcome to any of my code. Actually, everyone here is welcome to it anyway, so that's not much of an ask, lol.

          Matt_SFM 1 Reply Last reply Reply Quote 0
          • Matt_SFM
            Matt_SF @clevername27
            last edited by

            @clevername27 You can do something like this. It's very basic but it should get you started.

            HiseSnippet 1997.3oc0Ys7baaiFGzxvuR5Na56iZl1C1cx30x1IoY5Ay3GpwSqr0Z40oc1CIvjfVXLI.KIniUebZ2C8VOmdZ283dpW6s7GP6Lcl7OvtG6sz+BZ+.AoDoHsrjrR1tJyDS7A7A7CeuAPy.gEMLTDfLV3vN9Tjw0ws5vks2pMgwQ6tMx3OfaPBkzfpZRa1wmDFRsQFFU9PEAi4mFE+64arIwkvsn8HgPGIXVzOl4wj8n1z7iXtt0I1zCYdYF85l6ZI3aIbEQ.dpfWA4SrNkbBcOhZXSgQ2mD1FY7dXxZqY6b6a+9201Z8aU6tNj6Xac7Z28VT6UWeM5co112YM6icbPFyriMSJBZIIRZHLoaJr6zps3wb8BbDKjcrKU0nFpErxZxnsZybsalJbBQHCbydhpJZQ0qiavrYco2Sj8Gi6nZONxJzLlZPPp1H.IiLPZZMjtAtkU.yW1qGEdtFdWNnAcHftIKTziEY7T7VBX.b4xdjSo0CfFcYXwauxJ2rJ7eK8ANQbKISvqJ36Ijz84KtzBewByuvWsP096xwoz9TKSfv0kFTZ2JygfAw3h7HuioA2r5YD2HZ2ABa+7xzYFNYpkdWmYfB9tblbeeZR65BWakrR8cQM.JQrAe8W1cahjnTJIzfw4SCjLEbL1ldF3FnUQyi2lFdpT3CNBEzefkivNxkHyaNobzR5.jG4zgJEEOjI6j0QbDrwVYf1XCKDuAtISZ0tbLNUIXDjTuHvXhm4qf2wwgZI6Avow0+jw0MbkQ1MbgD2PXMUK90SZVs9mTqTGvuF2yX2Of5SBnGJZ5R5rXHwy2kd.fwaV8XWg0osXeNsnGhuFBapFwhVsIbN0MbbbjlYBEbBcfHRx3mzfHCXmCgO2KxqEDW2htUB5.ZFSo7gzsWQ0VYWzhxsia7qvujNqoZajzYszNy39sGU9XQvowpijuQFypj8uIlqa+PRT.wcmysXPjMzQzfPkYpwr3UVF9G5dtthGukvymkX.CpmXZMEtc7aK3LKEI8HR2D2ySDAqexNAxNcHg4pr3aEEBwPr2m2BFbbJQkE2dBa3qYqSr.QbmlDYakmiJJDXlRCV1pq45Ef5d1NJotNs3ELT0ZklJUKXAn6ojVpDoJUZSR.LAvXUQnlxnhhCk.LAlynvwr3PeWH28EBYc2Yso0nJkwACCiJYBShPki.sT4RDZkg.cOiBBh8kUsfHUSo8b2M7HUuVDWzQJeEkrpKPMx.TL1KxMOLW.6A+cYE8h3SO9KAcSkS9jQiofZZKXu1fwSPWu.rMHm2GsmuQKI0WEAI63ZcJ8wZXmcjZYudBJLMaScHQtxBzygPTh4tZllSqLp8hRMllmF7xtRJzoynPmAeRACuqAHNft7Iki0DNFecZkL5z4JpS+zmVTmB5u75z+wSdx2uQAc5SO46dCS8tJtp8Byb4pTD5dQRAXEqSjiFYaNyuwbnv2idsse1F5ZUa4IDx1Pti9A45lkCx0MuDbMIjaWGe.MjJK0g.gtHoGJi8zBXAm9PeAj9LmM0qhcXtJCfk61eQSqLLORgTU4qbommVbZc8J06SkaA2lddZN0cfxBrAWoXFRyylyFclAaittYAY8W+LygJti4ey6GSrApGP+rHHwYGTAyoRE0.8g1P0bs0d1F8Axm9C+v6LbfD8N+xOECxJ3+73DXrTCzUKw.cUyQKXc4N1Cvz7EV9iK0W17+94+8xDUwzmP354aLHQUCka4Pp8lXhpAAo4w6vIPk01ifMUtbUzy8C5OWUb0GwcTVtp3NFkbUcaklLcF7VYjiKganVOIg2dw3iU7dLtejbo+TejWJ9DaYmmYgiDebTWaDiJWbkN4h37sOQ8662njn6lWwJcRm5KR3mOZSNMATVWsQnNvDFlLEBN2uSJD7BBF2O1Q4pe1wouCZ7JXBm31IjtrpqxJgVQ+pjObaFbLERmMibbRDl4nLxYGyqYlNabCcYvpXz2uIZxWixPF2+4aDeCUbZ7EBDlbgUIMSN40t1cKks6FPSKNCCp+cEFe+l0QStRA9wu7muipTftr9o+yG8c+0+0+17pskxTBUtsU1pMJr2lGuIb.d6RUYWUOqg1aZXUYwARxs2RcbKrufPtArynnIe3zBrdU2Uw4otfc0XbTuMEhS8Hw2UzU9VaeKcmWC+.xYz32MI91adi31Nh.upeHENbq5tRqMfWN4mF1WNwene4j8sj.DNLfvC8EgzZ4zaTO1gfuPXNp8wwpkxwp4ivHi34mZMobiRIJpChhriyLkXlQNmYSBO2jAsyMSMTWjXul5BlZQgct89gVffgzmoXyH2P5CX1x1Yl2+SFxqlk78IA1fNzJ2kTWI+8gN8vcen4uu9LiujqOdlWTOrzzC2MZeIOwwu+eihbW.+7oXrESkneG9YTWvkNFiuJNITTJ079jMDbQ5E81yB3.pLfcxIz70DU1F5dRIw5zdTdcyCntTRXF+z207iYbJIH93GimrXzeSvR0WuMVC2pp.IUuJ5sWplYC7clpLTuyzDGui+aN8R1CEhe9+OZ52BCwzWsZr5t5+602uLdNqWFqgGwJP7PK8q.pBXLWLEXeyiOR07vg3g1UqgNq+hc8fTOOzxJ+TUfwUGWFWabYb8wkwaMtLd6wkw6LtL99WNipJCRN1sxOAJWp4N5yoZjd0RpaV42noKcsL
            

            Develop branch
            Win10 & VS17 / Ventura & Xcode 14. 3

            MorphoiceM 1 Reply Last reply Reply Quote 0
            • MorphoiceM
              Morphoice @Matt_SF
              last edited by Morphoice

              @Matt_SF that is about it! I believe the highpass of the Aphex is around 5k.

              You can then try pushing your signal with a compressor to help quieter parts get evenly "excited".

              bear in mind the _expr nodes need to be compiled into a hardcoded network in order to work in an exported plugin. I learned that the hard way ;) took me weeks to figure out =)

              this being said, it might even be easier doing those steps in faust and ignore the demo exiter altogether

              this is the full source of dm.exciter

              exciter = _ <: (fi.highpass(2, fc) : compressor : pregain : harmonicCreator :
                  postgain), _ : balance
              with{
                  // TODO: rewrite to use the standard compressor from compressors.lib
                  compressor = ba.bypass1(cbp,compressorMono)
                  with{
                      comp_group(x) = vgroup("COMPRESSOR  [tooltip: Reference:
                          http://en.wikipedia.org/wiki/Dynamic_range_compression]", x);
              
                  meter_group(x) = comp_group(hgroup("[0]", x));
                  knob_group(x) = comp_group(hgroup("[1]", x));
              
                  cbp = meter_group(checkbox("[0] Bypass  [tooltip: When this is checked,
                      the compressor has no effect]"));
              
                  gainview = co.compression_gain_mono(ratio,threshold,attack,release) : ba.linear2db
                      : meter_group(hbargraph("[1] Compressor Gain [unit:dB] [tooltip: Current gain
                      of the compressor in dB]",-50,+10));
              
                  displaygain = _ <: _,abs : _,gainview : attach;
              
                  compressorMono = displaygain(co.compressor_mono(ratio,threshold,attack,release));
              
                  ctl_group(x) = knob_group(hgroup("[3] Compression Control", x));
              
                  ratio = ctl_group(hslider("[0] Ratio [style:knob]  [tooltip: A compression Ratio
                  of N means that for each N dB increase in input signal level above Threshold, the
                  output level goes up 1 dB]", 5, 1, 20, 0.1));
              
                  threshold = ctl_group(hslider("[1] Threshold [unit:dB] [style:knob] [tooltip:
                  When the signal level exceeds the Threshold (in dB), its level is compressed
                  according to the Ratio]", -30, -100, 10, 0.1));
              
                  env_group(x) = knob_group(hgroup("[4] Compression Response", x));
              
                  attack = env_group(hslider("[1] Attack [unit:ms] [style:knob]  [tooltip:
                  Time constant in ms (1/e smoothing time) for the compression gain to approach
                  (exponentially) a new lower target level (the compression `kicking in')]",
                  50, 0, 500, 0.1)) : *(0.001) : max(1/ma.SR);
              
                  release = env_group(hslider("[2] Release [unit:ms] [style: knob]  [tooltip:
                  Time constant in ms (1/e smoothing time) for the compression gain to approach
                  (exponentially) a new higher target level (the compression 'releasing')]",
                  500, 0, 1000, 0.1)) : *(0.001) : max(1/ma.SR);
                  };
              
                  //Exciter GUI controls
                  ex_group(x) = hgroup("EXCITER  [tooltip: Reference: Patent US4150253 A]", x);
              
                  //Highpass - selectable cutoff frequency
                  fc = ex_group(hslider("[0] Cutoff Frequency [unit:Hz] [style:knob] [scale:log]
                      [tooltip: Cutoff frequency for highpassed components to be excited]",
                  5000, 1000, 10000, 100));
              
                  //Pre-distortion gain - selectable percentage of harmonics
                  ph = ex_group(hslider("[1] Harmonics [unit:percent] [style:knob] [tooltip:
                      Percentage of harmonics generated]", 20, ma.EPSILON, 200, 1)) / 100;
                  pregain = * (ph);
              
                  // TODO: same thing: why doesn't this use cubicnl?
                  //Asymmetric cubic soft clipper
                  harmonicCreator(x) = x <: cubDist1, cubDist2, cubDist3 :> _;
                  cubDist1(x) = (x < 0) * x;
                  cubDist2(x) = (x >= 0) * (x <= 1) * (x - x ^ 3 / 3);
                  cubDist3(x) = (x > 1) * 2/3;
              
                  //Post-distortion gain - undoes effect of pre-gain
                  postgain = * (1/ph);
              
                  //Balance - selectable dry/wet mix
                  ml = ex_group(hslider("[2] Mix [style:knob] [tooltip: Dry/Wet mix of original signal
                      to excited signal]", 0.5, 0, 1, 0.01));
                  balance = (_ * ml), (_ * (1.0 - ml)) :> _;
              };
              

              looks incomplete, maybe you can thin this down and apply your own algorithms. the cubicnl function should do a good job

              https://instagram.com/morphoice - 80s inspired Synthwave Music, Arcade & Gameboy homebrew!

              MorphoiceM Matt_SFM 2 Replies Last reply Reply Quote 0
              • MorphoiceM
                Morphoice @Morphoice
                last edited by Morphoice

                @Morphoice also consider lowpassing the left chain signal, otherwise you'll just double everything above your cutoff frequency instead of just adding harmonics. as with all analog models, the parameters are probably not perfect, you'll need to run a variety of good test audio files which you're accustomed to through this and tweak it to what sounds and feels right to you for most use cases

                https://instagram.com/morphoice - 80s inspired Synthwave Music, Arcade & Gameboy homebrew!

                1 Reply Last reply Reply Quote 0
                • Matt_SFM
                  Matt_SF @Morphoice
                  last edited by Matt_SF

                  @Morphoice I'm not comfortable with faust yet but it's on my to-do list for 2025 :)

                  @Morphoice said in Faust Aural Exciter:

                  bear in mind the _expr nodes need to be compiled into a hardcoded network in order to work in an exported plugin. I learned that the hard way ;) took me weeks to figure out =)

                  Yes the expr node must be compiled.

                  I used a simple tanh function but yes, the cubic function should work too.

                  Quick modification of the script node effect:
                  This one uses phase cancellation so the harmonics only are fed into the original signal.

                  HiseSnippet 2527.3oc2Z07aaibEenkG4XuIEY2jcQQAJJOzC1KhUE02pEsV9KkXrwd0Zo5l.Xffwjir3ZJNrjT1VaQA5w8ufdn+OTzhdoGW2dnnnWZA5kdoE6wdLnn.8X5a3PJQJQIQoj3tnJ.wbdyLb9MuueyvF1LUpiCyFIsVq9VTjzcwM6a51Y2NDcSzA6gj9Z3CINtTaYAoc5aQbbnZHIoTOlSPZ0kQd+d4V6PLHlpzgjPnSX5pzmp2U2cH0F09HcCi5DMZK8tgFcgZGnxL2kYv5A3IENKxhndA4b5QD9vVBidBwoCR5Cwj740ZWpTkpZpEJpTsMorl5Y4qVjpkqPdZUplV47Zm0tMRJ89Z5tL6ltDWpC7R2go0uYG1UlhE3DcG8yLn7FJnlvJKHi1sitgVi.liCBIgaLjUkRvpdH9PcM8AzGxxtuWGxCmQXllzRSCRJyAjjBAokEP5cwMUs0sbG1CGOuC9.SPB1l.xlvPQLVjzM3cYv.LcyzkbAstMzXvDVuT1rORF9uM9ds6Yp5pyLkYlGwboer45ar1OYsUW6mtl7nc0tcr8wWFalgA0N1t4pC1Sahqa1q6YT6GIeIwnGcv.gseTdZ5jwSUE65PCjYdfot6GaQ8aWmYnw4U7mGWBf7YavS+vC1i3R3BEeZv3rn1t5b3HsG8RvLPHhVEuG04BWlEXHLl7CzbXZ8LHtQUm3FZ9c.7iHxPtfxzQ2seXCw4PGK6T0wRJDeWbCcW0NwiwkhAi.m5sAF8sLuGd+1soptCA3x35OaQMCyN2lgq4aFBqIewuqeS45OSIVCvOGOTY2xlZQrosXMLH8W2gz0xfdLfwGIelAS8hl5eFcbKDKAD1gOh0U6PLMoFNKhgT52PNmPGy54pad9gDWa8qA2mG0qaSvutJcWezAzjVhaCIZmk2lqWzjZp403UvO+NU3sk76TInyPleGQcuhYegm3v+YjzJbd+GfMEseAomMwX+qU0AOanSn1Nb0ToUvYy.+CssgA6pcYcsz8UfAwiGsFLi9VcXl5pbRhQDrI1tKqGr996DH5TKhtAWiuYOGvGh1Ga1DFrWHQtF2QLM3oUpSTAVb+FD2NbKGtWHPMkZmQcf55DP8PcGNWWDVbBCkKzZPrgg.sbDBL95GDdUvrgsSWNGjGbUJEueNKzGno4HYErikAD8dhfVzcbHKXpK1xJXFyfWE+xJ5KoKqTnkEi61yH5htFtK72Lb5wsZhYLi0ZoPRBtCifVvfOT27DtMH+Mw0COjb8f1JPaAyPPxuig942i1lzyvMxDPgh7.MBsvQ5wysEuE3TdIgSpCbNg2qJwHXk.05PLm6HXrJ2FBkzgV26g+TUvryV3iMxh+d3OUywJS39C6eUr1Qm+LPvxQXeCCn0hXeN0UDzm6R95f386oCZ4j96zCh3HDuQnv4tlZzqCbZsO32UCxova5ANxhndrbH0i6LT8HPp+7aFphLLZZSWpEOzPDZWPuRvs7ody4+52uFmitFtEvM5.I2DRm5W8K9lO4nUtIpN0v2118bYfkfHhNJDFWYbL9xsFGi0pkHLV6W9m+6aIT5Oly3GBv126el5m+stes3A3K2ZFXBgFCS2XmPLk62+21RXArsqKTSxPP8I+r+wW9e9Ae++G.pa92u+exCTqhOlZPINg7O769C+w+02PxXBn540BaUmFe9XNZeGvl1ll47IYM6Om4xqWp34D2AuoR1nN9Bv45gXDODbNBiy6mRgpYUTJoDgm7.bwLExkKW4rkKWnRAk7YqhDaOupTCo8xiDFgwflfPZTGx2AyQ.PZNfEe.4ypjMOLfpUqTnZ4rJ90j0rKi41AxQJPtkFmi+1iJz7IhRL2Sf52.bt6B5UNT2HgdDu7QC6jcrvN9Y5H70vLouvhAYMNhq615FbciLC5ONUsPSe5paAkpAIZkZDWz0EKzvGgG7cJuLv.iFkTJcHVc5grZeAQH0Tffu9vHB7b4pVMaghkxkKegJkqTzWfW2l9i6AYC1eDF3.8pQTRQwCjG3oRIjmJUyksZtpgP0CvUyToJ+WIkJEymMW47iiuREJqTthR47YKUToRIO7kB+InHIRDexEwl5xJ.WrRDlSZrGgPVfIPCJ1sa7oEsn1Xe.+sksp3W4xkJTIWwJ4FAOSXPyG.GX.NLOtz7RmoSmKO+bhXVnUw6aRf5zzRhDcb6V+r87xdWI4Y9Gju0fYNqj8FaoGsJ.+LNym7LNGhA+YNOXXdxIdrjqGG1E9pIrivgSioWaYOZzeuJd75H9n+dcMyn+gg3Ri.wz3cCYJrA9P9J5RL6rt2IR7g5lV8b236LB4MFntF7dVAuG8rdCLu8NLhjVrkRDaobiTrUbFKi5fNBiDpCLWBJcLPT6OgovEyia0gJen+qP1DFort4kvt2Q1E5wpCjzmLqsWCG8yMAocT19jYEwkz9WLdJXubqDkKp2HmVkpewryOdZFTd7Jk4ptb+ob6TXdRzUljeVOfVbdUbJNsc1iiQwwoid6Iq2HeFS8BYWlGIls945+efxzB3hbhu.TjCIpc6QNPr6gI.CquCMCuq3OmHdOyxs97d1BSNM1IeLPR3vhNQ7JdFZOoA51orrguuW8pqpl+uF6wX4cQJlTuys1AEooeDrCzFTH5fMjflW9lQRhRH1dRi5nWmD5KVoPoJkxCoBNXKrF5yW+2142Taw2BgJvIx1Hb8BQR6Vjf2NFTSsHhr3cSknyLLoLaOWpQPYfM5XHDBLaqeIEMqPtidfH0dcvmWdIyDeqHpMnUmfy.6M+grM1TmjKqjsyhdBlQ1fgNJuExi2NL1EcIdWcxq8kX9ffaea6dZ5rmx3S1KN4CETj4jj42qE0VYJeIA+kj9kDXk3ujfl8MU8J9JDu26JKaYSTufWfXnkhCyfBnBQ9XnVR9saG9KYno28y0zkX6Bu9HilBYp4D8MTW2v+iYPE+3u6oatobysOrwS2uo7lad5N5mKWW2oyoezwOuQqC1cPeGu+ie716K+L4VGucC4bmprYSnjV.ymJVc40KUQ9Lqtab5d18O8D10x4ybE4RTWNOEK0+yVE0k3c.z2+GsFx.1bd3MnOCucqVP+RohdEfKmrq.L5UTGZ7wbioK+15aoX4jcIty3V8+p+0xG4NmWM.iM04ZC6CUHX.VddX78v9NdBnF0r6PlIK3tMCq45BY.dNMZBYwsg7OM7ATdXsfihd.oucsmBU7RrG036s5mASrxqut+g2Ky8UH+5H2tUUyl5mVQpD8oU7FGuK9mYwaFnba7wEbarFcIp1rWnJ9lL35x2wiBruM8hRrJ9PdaYEzkilPQWvq3KTUi9pFah4VzIleQmXgEchEWzIVZQmX4EchUl8D4As7OA.tIKBcXi8EW4qzfLKjRg9uooL8ZB
                  

                  @Morphoice also consider lowpassing the left chain signal, otherwise you'll just double everything above your cutoff frequency instead of just adding harmonics

                  Indeed, thus the phase cancellation addition :)

                  Develop branch
                  Win10 & VS17 / Ventura & Xcode 14. 3

                  MorphoiceM 1 Reply Last reply Reply Quote 0
                  • MorphoiceM
                    Morphoice @Matt_SF
                    last edited by

                    @Matt_SF brilliant, I didn't notice, so you beat me to that with an even better solution ;)))

                    https://instagram.com/morphoice - 80s inspired Synthwave Music, Arcade & Gameboy homebrew!

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

                    37

                    Online

                    1.8k

                    Users

                    12.0k

                    Topics

                    104.4k

                    Posts