Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Logic & CV Processing

Modules for gate logic, CV comparison, and signal routing.

Logic Gates

LogicAnd

Outputs HIGH only when both inputs are HIGH.

let and_gate = patch.add("and", LogicAnd::new());
InputsOutput
0V, 0V0V
0V, 5V0V
5V, 0V0V
5V, 5V5V

LogicOr

Outputs HIGH when either input is HIGH.

let or_gate = patch.add("or", LogicOr::new());
InputsOutput
0V, 0V0V
0V, 5V5V
5V, 0V5V
5V, 5V5V

LogicXor

Outputs HIGH when exactly one input is HIGH.

let xor_gate = patch.add("xor", LogicXor::new());
InputsOutput
0V, 0V0V
0V, 5V5V
5V, 0V5V
5V, 5V0V

LogicNot

Inverts the input.

let not_gate = patch.add("not", LogicNot::new());
InputOutput
0V5V
5V0V

Comparators

Comparator

Compares two voltages.

let cmp = patch.add("cmp", Comparator::new());

Inputs

PortSignalDescription
aCVFirst signal
bCVSecond signal

Outputs

PortSignalDescription
gtGateHIGH if A > B
ltGateHIGH if A < B
eqGateHIGH if A ≈ B (within threshold)

Use Cases

// Trigger envelope when LFO rises above threshold
patch.connect(lfo.out("sin"), cmp.in_("a"))?;
patch.connect(threshold.out("out"), cmp.in_("b"))?;
patch.connect(cmp.out("gt"), env.in_("gate"))?;

Min/Max

Min

Outputs the lower of two signals.

let min = patch.add("min", Min::new());

$$\text{out} = \min(a, b)$$

Max

Outputs the higher of two signals.

let max = patch.add("max", Max::new());

$$\text{out} = \max(a, b)$$

Use Case: Limiting

// Limit modulation depth
patch.connect(lfo.out("sin"), min.in_("a"))?;
patch.connect(limit.out("out"), min.in_("b"))?;  // Maximum value

Rectifiers

Rectifier

Converts bipolar signals to various forms.

let rect = patch.add("rect", Rectifier::new());

Outputs

PortDescriptionFormula
fullFull-wave rectified$
half_posPositive half only$\max(x, 0)$
half_negNegative half only$\min(x, 0)$
absAbsolute value$
Input:      ╱╲  ╱╲
           ╱  ╲╱  ╲
Full:      ╱╲╱╲╱╲╱╲

Half+:     ╱╲  ╱╲
           ──╲╱──╲╱

Half-:       ╲╱  ╲╱
           ──  ──

Audio Applications

  • Octave doubling (full-wave rectify audio)
  • Envelope following (rectify + lowpass)
  • Distortion effects

Signal Routing

VcSwitch

Voltage-controlled signal router.

let switch = patch.add("switch", VcSwitch::new());

Inputs

PortSignalDescription
aAnyFirst signal
bAnySecond signal
selectGateWhich to output

Output

PortSignalDescription
outAnySelected signal

When select < 2.5V: output A When select >= 2.5V: output B


BernoulliGate

Probabilistic gate router.

let bernoulli = patch.add("bernoulli", BernoulliGate::new());

Inputs

PortSignalDescription
triggerTriggerInput trigger
probabilityUnipolar CVChance of A (0-100%)

Outputs

PortSignalDescription
aTriggerProbabilistic output A
bTriggerProbabilistic output B

When trigger arrives:

  • With probability P: fires A
  • With probability 1-P: fires B

Use Case: Random Variations

// 70% chance of normal note, 30% chance of accent
patch.connect(clock.out("div_8"), bernoulli.in_("trigger"))?;
patch.connect(prob_cv.out("out"), bernoulli.in_("probability"))?;
patch.connect(bernoulli.out("a"), normal_env.in_("gate"))?;
patch.connect(bernoulli.out("b"), accent_env.in_("gate"))?;

Ring Modulator

Four-quadrant multiplier for metallic sounds.

let ring = patch.add("ring", RingModulator::new());

Inputs

PortSignalDescription
carrierAudioCarrier signal
modulatorAudioModulator signal

Output

PortSignalDescription
outAudioProduct (ring mod)

Mathematics

$$\text{out} = \text{carrier} \times \text{modulator}$$

Creates sum and difference frequencies: $$\cos(f_1 t) \cdot \cos(f_2 t) = \frac{1}{2}[\cos((f_1-f_2)t) + \cos((f_1+f_2)t)]$$

Sound Character

  • Bell-like tones with related frequencies
  • Metallic, robotic sounds with unrelated frequencies
  • Classic AM radio sound

Sequencing

Arpeggiator

Captures held notes on gate edges and replays them across selectable octaves and patterns on each clock pulse. type_id: arpeggiator.

let arp = patch.add("arp", Arpeggiator::new(44100.0));

Inputs

PortSignalDescription
v_octV/OctInput note to capture
gateGateCaptures/releases the note on rising/falling edge
clockClockAdvances the sequence
patternUnipolar CVPattern select (Up / Down / UpDown / Random)
octavesUnipolar CVOctave range (1–4)
resetGateResets the sequence and clears held notes

Outputs

PortSignalDescription
v_oct_outV/OctArpeggiated pitch
gate_outGateGate output (follows the clock)
triggerTriggerPulse on each step

Chord Memory

Generates four V/Oct voices from a root note across nine chord types, with inversion and octave spread. type_id: chord_memory.

let chord = patch.add("chord", ChordMemory::new());

Inputs

PortSignalDescription
rootV/OctRoot note of the chord
chordUnipolar CVChord-type select (9 types)
inversionUnipolar CVInversion (rotates the bass note)
spreadUnipolar CVSpreads voices across octaves

Outputs

PortSignalDescription
voice1V/OctChord voice 1
voice2V/OctChord voice 2
voice3V/OctChord voice 3
voice4V/OctChord voice 4

Chord types: Major, Minor, Seventh, MajorSeventh, MinorSeventh, Diminished, Augmented, Sus2, Sus4.


Euclidean

Euclidean rhythm generator: evenly distributes a pulse count across a step count, with rotation and a per-cycle accent. type_id: euclidean.

let euclid = patch.add("euclid", Euclidean::new(44100.0));

Inputs

PortSignalDescription
clockTriggerAdvances the pattern on rising edge
stepsUnipolar CVStep count (2–16), default 0.5
pulsesUnipolar CVPulse (fill) count, default 0.25
rotationUnipolar CVRotates the pattern
resetTriggerResets the step counter

Outputs

PortSignalDescription
outTriggerPulse output for active steps
accentTriggerAccent on the first pulse of each cycle