HISE Logo Forum
    • Categories
    • Register
    • Login

    Emulating vintage DACs with bitcrusher & μ-law compression

    Scheduled Pinned Locked Moved ScriptNode
    6 Posts 3 Posters 209 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.
    • MorphoiceM
      Morphoice
      last edited by Morphoice

      following up on yesterday's thread I wanted to post the results here, so anyone can find them should they need them. Those are great to emulate a vintage DAC of old drum machines and 8 bit samplers, just the way Tal DAC or Decimort would do it.

      Why prefer this over regular bitcrusher? μ-law has a higher dynamic range and much better SNR (signal to noise ratio) which means more values are spread among quieter levels, and less values among peak values. This massively improves artifacting while still giving the nice retro 8-bit crunch and sizzle we love.

      This is the c++ code:

      void process(float* samples, int numSamples)
         {
             for (int i = 0; i < numSamples; ++i)
             {
                 float val = samples[i];
                 int max = 255;
      
                 // μ-law compression
                 float valmu  = sgn(val) * log( 1.0f + max * abs(val) ) / log( 1.0f + max);
                 // bit reduction
                 float valmu8 = valmu - fmodf(valmu, 1.0f / max);
                 // μ-law expansion
                 float valex = sgn(valmu8) * (1.0f / max) * ( pow(max + 1.0f, abs(valmu8)) - 1.0f );       
             }
          }
      

      there is also a faust version Stephane Letz over at faust Discord made

      import("stdfaust.lib");
      
      mulaw_bitcrusher(mu,nbits,x) =  x : muLawCompress(mu) : ba.bitcrusher(nbits) : muLawExpand(mu)
      with {
          // μ-law compression
          muLawCompress(mu, x) = ma.signum(x) * log(1 + mu * abs(x)) / log(1 + mu);
      
          // μ-law expansion (decompression)
          muLawExpand(mu, x) = ma.signum(x) * (pow(1 + mu, abs(x)) - 1) / mu;
      };
      
      process = mulaw_bitcrusher(255,8),mulaw_bitcrusher(255,8);
      

      this has also been added to basics.lib so in the future you will simply be able to use ba.mulaw_bitcrusher

      The same expansion formula/technique can be used to read μ-law compressed wav files or eprom binaries made using μ-law, which are probably most of them if not all.

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

      LindonL 1 Reply Last reply Reply Quote 3
      • LindonL
        Lindon @Morphoice
        last edited by Lindon

        @Morphoice said in Emulating vintage DACs with bitcrusher & μ-law compression:

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

        interesting - sort of... Here's a slightly more friendly-to-HISE faust version, tho I cant seem to get it to behave correctly above 8 bits... so I probably dont understand what nBits is here...I foolishly assumed it was the number of bits - and I'm pretty certain 12-bit doesnt sound this clean...and 2-bit wouldnt sound like this at all...

        import("stdfaust.lib");
        nBits = hslider("Bits", 8, 2, 16, 1);
        mulaw_bitcrusher(mu,nbits,x) =  x : muLawCompress(mu) : ba.bitcrusher(nbits) : muLawExpand(mu)
        with {
            // μ-law compression
            muLawCompress(mu, x) = ma.signum(x) * log(1 + mu * abs(x)) / log(1 + mu);
        
            // μ-law expansion (decompression)
            muLawExpand(mu, x) = ma.signum(x) * (pow(1 + mu, abs(x)) - 1) / mu;
        };
        
        process = mulaw_bitcrusher(255,nBits),mulaw_bitcrusher(255,nBits);
        

        HISE Development for hire.
        www.channelrobot.com

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

          @Lindon probably mu needs to be bigger than 255 if you go above 8bits. I haven’t tried to be honest, I’ll check in a bit.

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

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

            @Morphoice yeah I tried 512 but no difference.

            HISE Development for hire.
            www.channelrobot.com

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

              @Lindon it should work fine, just above around 10 bits the difference is not really audible anymore with average audio

              try this in faust IDE, it renders a very low sine wave, which makes the artifacts clearly audible even if you go above 8 bit you can hear the them gradually disappearing

              import("stdfaust.lib");
              nBits = hslider("Bits", 8, 2, 16, 1);
              mulaw_bitcrusher(mu,nbits,x) =  x : muLawCompress(mu) : ba.bitcrusher(nbits) : muLawExpand(mu)
              with {
                  // μ-law compression
                  muLawCompress(mu, x) = ma.signum(x) * log(1 + mu * abs(x)) / log(1 + mu);
              
                  // μ-law expansion (decompression)
                  muLawExpand(mu, x) = ma.signum(x) * (pow(1 + mu, abs(x)) - 1) / mu;
              };
              
              test = os.sinwaveform(8192) : mulaw_bitcrusher(255,nBits);
              
              process = test,test;
              

              Screenshot 2024-12-10 at 21.43.48.jpg
              8 Bit steps are clearly visible

              Screenshot 2024-12-10 at 21.45.19.jpg
              10 bit barely visible stepping at the peak

              I can hear artifacts up to 13 bit, as of 14 it is gone

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

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

                @Lindon said in Emulating vintage DACs with bitcrusher & μ-law compression:

                @Morphoice yeah I tried 512 but no difference.

                Since the mu law is a weighted repartition of a signal, the ratio oscillate between linear at mu=0 toward logarithmic for higher values. So the higher mu the less impact on higher signals. All that to say the difference lies in the tiny signals like reverb trails, etc... So you can keep crushing higher signals like falling fire from hell on a nursery while enjoying delicate small signals with a warm latte

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

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

                35

                Online

                1.7k

                Users

                11.7k

                Topics

                101.9k

                Posts