HISE Logo Forum
    • Categories
    • Register
    • Login

    Recreate Bitcrusher Module in Scriptnode

    Scheduled Pinned Locked Moved General Questions
    31 Posts 7 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.
    • Christoph HartC
      Christoph Hart @JL.LV
      last edited by

      @JL-LV No you don't get rid of DC offset by clipping to -1...1. What you need is a high pass filter (DC offset is a signal with the frequency 0Hz, so even a simple one pole high pass set to 20Hz will get rid of this).

      Casey KolbC 1 Reply Last reply Reply Quote 1
      • Casey KolbC
        Casey Kolb @Christoph Hart
        last edited by

        @Christoph-Hart Great! That works for removing the phantom signal from the meter, but I'm still experiencing this weird static noise in my CUBE project: https://www.dropbox.com/s/n3ehwtbvx18syii/Scriptnode Bitcrusher generating noise even without input.mov?dl=0

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

          @Casey-Kolb Hmm, the problem is still the DC offset that the bit crusher introduces.

          I've made another bitcrusher as snex_shape node which behaves better when modulating (and there's no DC offset introduced).

          The snippet export doesn't work with SNEX nodes yet, so you have to do it manually:

          1. Add a snex_shaper node.
          2. Make sure you have a "SNEX code editor" floating tile somewhere (best place would be a tab in the scripting editor tabs).
          3. Create a new file (call it bitcrush2). Click on the SNEX button. Then you should see the shaper class in the SNEX editor.
          4. Enter the code below and press compile.
          5. Add a parameter and set its range to 4-16 (or whatever bit range you want to support
          6. Use and compile the node like any other.
          template <int NumVoices> struct bitcrush2
          {
          	SNEX_NODE(bitcrush2);
          	
          	// Implement the Waveshaper here...
          	
          	float getSample(float input)
          	{
          		const float invStepSize = Math.pow(2.0f, bitDepth);
          		const float stepSize = 1.0f / invStepSize;
          			
          		if(input > 0.0f)
          			return (stepSize * Math.floor(input * invStepSize));
          		else
          			return (stepSize * Math.ceil(input * invStepSize));
          	}
          	// These functions are the glue code that call the function above
          	template <typename T> void process(T& data)
          	{
          		for(auto ch: data)
          		{
          			for(auto& s: data.toChannelData(ch))
          			{
          				s = getSample(s);
          			}
          		}
          	}
          	template <typename T> void processFrame(T& data)
          	{
          		for(auto& s: data)
          			s = getSample(s);
          	}
          	void reset()
          	{
          		
          	}
          	void prepare(PrepareSpecs ps)
          	{
          		
          	}
          	
          	void setExternalData(const ExternalData& d, int index)
          	{
          	}
          	
          	float bitDepth = 16.0f;
          	
          	template <int P> void setParameter(double v)
          	{
          		bitDepth = v;
          
          	}
          };
          
          Christoph HartC 1 Reply Last reply Reply Quote 2
          • Christoph HartC
            Christoph Hart @Christoph Hart
            last edited by Christoph Hart

            @Christoph-Hart NVM, I've added this as additional mode to the bit crusher node. You can now choose between DC and Bipolar. I couldn't just change the bit crusher algorithm because it sounds very different, but when you want to modulate the bit depth, the new Bipolar mode is much better because it doesn't create a DC offset that is dependent on the bit depth parameter.

            (If you load an existing network, it will complain about a wrong parameter structure, but this is OK in this case).

            Casey KolbC 2 Replies Last reply Reply Quote 3
            • Casey KolbC
              Casey Kolb @Christoph Hart
              last edited by

              @Christoph-Hart Amazing! Will give this a spin :) Thank you

              1 Reply Last reply Reply Quote 0
              • Casey KolbC
                Casey Kolb @Christoph Hart
                last edited by Casey Kolb

                @Christoph-Hart @langermarc19 We're hitting a snag here with the bitcrusher in scriptnode. In the compiled VST plugin, it will output only the left channel when the bitcrusher is active, regardless of the mode, DC or Bipolar, and regardless of the bitrate. It seems to happen in most DAWs, but not in standalone.

                We're going to take a look at the node code for the bitcrusher, but any immediate thoughts?

                Matt_SFM orangeO 2 Replies Last reply Reply Quote 0
                • Matt_SFM
                  Matt_SF @Casey Kolb
                  last edited by

                  @Casey-Kolb I won't be of much help, but I built a simple bitcrusher here and it works fine (I recall I'm using the bipolar mode)

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

                  1 Reply Last reply Reply Quote 0
                  • B
                    blezzbeats
                    last edited by

                    Kinda related: Is there any way to access the in-between sample rates of the bitcrusher effect with an integer or float? To get at the rates between 22-44khZ for example, and not just jump that big notch.

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

                      @blezzbeats Do you mean the sample and hold module? The bitcrusher allows float bit rates.

                      B 2 Replies Last reply Reply Quote 0
                      • B
                        blezzbeats @Christoph Hart
                        last edited by

                        @Christoph-Hart I mean the Degrade processor, the samplerate parameter takes big leaps first. Is there another module that has that option? Where I can decide to set the samplerate to 24504 Hz instead of 24000 Hz for example

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

                          @Casey-Kolb Have you tried processing for the L - R channels individually?

                          float getSampleL(float input)
                          {
                          	
                          }
                          
                          float getSampleR(float input)
                          {
                          	
                          }
                          
                          
                          // Process the signal here
                          template <typename ProcessDataType> void process(ProcessDataType& data)
                          {
                          	auto frame = data.toFrameData();
                          	    
                          	while(frame.next())
                          	{
                          		frame[0] = getSampleL(frame[0]);
                          		frame[1] = getSampleR(frame[1]);
                          	}
                          }
                          
                          

                          Also I reckon that in the above example, float getSample(float input) is used.

                          With an extra "s", float getSamples(float input) is working here for both channels.

                          develop Branch / XCode 13.1
                          macOS Monterey / M1 Max

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

                            @Christoph-Hart Nevermind I misunderstood, sample and hold will do it for me! Didn't realize we were talking ScriptFX so I just learned that. Sorry for cluttering the thread .

                            1 Reply Last reply Reply Quote 0
                            • langermarc19L
                              langermarc19
                              last edited by

                              @Christoph-Hart where in the codebase is polyphonic_base located? Want to look at how prepare is implemented to see if I can write breakpoints/debug output to find where this is getting reduced to mono. Thanks!

                              langermarc19L 1 Reply Last reply Reply Quote 0
                              • langermarc19L
                                langermarc19 @langermarc19
                                last edited by

                                @Christoph-Hart nevermind I found FXNodes_impl and I think that has what I need

                                1 Reply Last reply Reply Quote 0
                                • Casey KolbC
                                  Casey Kolb
                                  last edited by

                                  @Christoph-Hart After a lot of debugging, we realized it's not the bitcrusher node but actually the split node that's creating issues in certain DAWs and only allowing the left channel to pass through. We're using the exact configuration of this dry/wet example, just with the bitcrusher instead of the reverb: https://docs.hise.audio/scriptnode/101/drywet.html

                                  When you add a second chain the split container, it won't properly split the channels and the chain on the right will only output the left channel in certain DAWs, including Cubase and Bitwig. This only seems to happen with the node below.

                                  We've tried removing everything and added every node back until the right channel broke. The instant we added a split container with another chain, one of the chains would stop outputting a right signal. This doesn't happen in standalone, and this only seems to happen with the following configuration. Any ideas for things we could try?

                                  Screen Shot 2022-09-07 at 9.34.51 PM.png

                                  Matt_SFM 2 Replies Last reply Reply Quote 1
                                  • Matt_SFM
                                    Matt_SF @Casey Kolb
                                    last edited by

                                    @Casey-Kolb I've created a bitcrusher here, with almost the exact same structure. I didn't face any problems (ableton, reaper) but I didn't try the plugin with Cubase or Bitwig (plugin still in development stage). I'll be able to try tomorrow and I'll report back.

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

                                    1 Reply Last reply Reply Quote 1
                                    • Matt_SFM
                                      Matt_SF @Casey Kolb
                                      last edited by

                                      @Casey-Kolb Just tested my plugin with Cubase 12 and Bitwig and didn't face any problem with the bitcrusher. The only thing I made differently from your graph is I added a saturation node, and put the bitcrush node before the sample&hold node :

                                      66ae179a-6874-4bff-9ccc-20272a5854a9-image.png

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

                                      Casey KolbC 2 Replies Last reply Reply Quote 1
                                      • Casey KolbC
                                        Casey Kolb @Matt_SF
                                        last edited by

                                        @Matt_SF Thanks for sharing Matt! Something funky is going on with our project. I can't see why the split node would break only this effect for our plugin. We'll do some more digging.

                                        1 Reply Last reply Reply Quote 1
                                        • Casey KolbC
                                          Casey Kolb @Matt_SF
                                          last edited by

                                          This post is deleted!
                                          1 Reply Last reply Reply Quote 0
                                          • Casey KolbC
                                            Casey Kolb
                                            last edited by Casey Kolb

                                            We've confirmed this is not just specific to our project but happens with any project on both Mac and PC in certain DAWs (Cubase, Bitwig, Live) using the most recent develop branch. We've tested on many different computers with all the permutations. I'm really not sure what's going on here, but it doesn't have anything to do with the bitcrusher. It happens when using the split node in any project. In certain DAWs, the VST will only Output the left channel, regardless of the effects in the chains.

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

                                            19

                                            Online

                                            1.7k

                                            Users

                                            11.9k

                                            Topics

                                            103.3k

                                            Posts