ComfyUI Node

ByteBeat Synth

Generate chiptune noise from a one-line math formula

By c0ffymachyne·Created 2 years ago·Updated about a year ago· 11
ByteBeat Synth
    • audio
    • sample_rate
    samplerate8000
    duration15.0
    expression(t * (t >> 9 | t >> 13) & 16) & 255

    Most audio nodes in ComfyUI want a model, a checkpoint, or a sample file. BytebeatSynth wants none of that - you give it a one-line math expression and it turns that formula straight into a waveform. No GPU, no download, no training data. It's the audio equivalent of a fractal: a tiny piece of arithmetic that unfolds into something that sounds like a chiptune console having a small breakdown.

    If you know the term, this is bytebeat - the demoscene trick of treating raw audio as a function of an incrementing integer counter, popularized by one-liners like t*(t>>10|t>>8)&128 that people were pasting into C putchar loops and browser toys for over a decade before anyone thought to wire it into ComfyUI. The node's author, c0ffymachyne, also builds ComfyUI_SignalProcessing (convolution reverb, audio stacking) - that pack shows up in real community dubbing workflows, so this isn't a one-off toy repo; it's part of a small but genuine audio/DSP corner of the ComfyUI ecosystem. Reach for BytebeatSynth when you want cheap, deterministic, glitchy or chiptune-flavored sound - background texture, a transition stinger, alien SFX, game-jam music - generated instantly inside the graph instead of hunting down a sample.

    How it works

    The mechanism is dead simple and that's the whole appeal: for every sample index t, starting at 0 and counting up at your chosen sample rate, the node evaluates your expression and the result becomes that instant's amplitude. Bitwise shifts (>>, <<), AND/OR/XOR (&, |, ^), plain arithmetic, and modulo all interact in ways that overflow and repeat - and that overflow-and-repeat behavior is where the rhythm and melody come from. Nobody designs these sounds top-down; you nudge a shift amount or swap & for | and listen. It's closer to tweaking a synth's feedback knob than writing music.

    The inputs and outputs that matter

    Only three inputs, all required:

    • expression - the formula itself, as plain text (default (t * (t >> 9 | t >> 13) & 16) & 255). This is the only thing you'll actually spend time on. Start from the default or a known-good formula and change one operator or shift amount at a time.
    • samplerate (8000–96000, default 8000) - 8000 is deliberately lo-fi and chiptune-appropriate; push it up if you want a cleaner top end for something less retro.
    • duration (1–60 seconds, default 15) - how long a clip to render.

    Two outputs: audio (AUDIO), which you wire straight into a Save Audio or Preview Audio node - or into another c0ffymachyne DSP node if you want to reverb or stack it - and sample_rate (INT), a convenience pass-through so downstream nodes that need the rate explicitly don't have to hardcode it separately.

    How to install it

    The README is entirely a tutorial on bytebeat composition - operators and example formulas - it doesn't include an install section, so use the standard path: ComfyUI Manager, search "Bytebeat Synthesizer" or the repo name, install, restart. Or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/c0ffymachyne/ComfyUI_BeatByte
    

    then restart ComfyUI. No models to fetch and nothing GPU-bound - it's pure computation over an integer counter, so it should show up on your node list immediately after restart.

    Common issues & troubleshooting

    It sounds like pure static. The author's own advice, straight from the README: simplify. A formula with too many combined operators collapses into noise - strip it back toward the default and reintroduce one operator at a time until you find the pattern you want.

    A formula you copied from an online bytebeat archive sounds different here. Classic bytebeat one-liners are usually written for C, where every intermediate value silently truncates to 8 bits. If this expression evaluates in Python, intermediate results don't wrap the same way unless the formula explicitly masks with & 255 at each stage - which is why the default expression ends in & 255. If you're porting a formula, add that mask yourself rather than assuming it's implicit.

    It's louder or harsher than you expected. Bytebeat waveforms swing unpredictably - there's no envelope or normalization built in. Preview at low volume first, especially before it hits headphones.

    An expression using % or / throws an error at the start. t begins at 0, so a sub-expression like t >> 10 is also 0 for the first several samples - dividing or modulo-ing by a term that can be zero will crash right at t = 0. Guard it (add a constant) rather than dividing by a raw shifted t.

    CategorySynthesizer

    Inputs (3)

    NameTypeDefaultDescription
    samplerateINT80008000–96000
    durationFLOAT15.01–60
    expressionSTRING(t * (t >> 9 | t >> 13) & 16) & 255

    Outputs (2)

    NameTypeDescription
    audioAUDIO
    sample_rateINT