pretty sure this is a bug, i had claude help me troubleshoot it and eventually write this post, hope it helps.
Setup
TD 2025.32280, Mac. A Logic CHOP in “Off When Outside Bounds” mode is used as a per-sample threshold gate: boundmin is driven by a parameter expression reading a Slider COMP’s value0, boundmax is a constant. Its input is a single-channel audio-rate, timesliced CHOP (800 samples @ 48kHz) coming off a Select CHOP pulling y out of a laser XY/RGB stream.
Symptom
Dragging the bound slider produces a correct, smooth per-sample wipe (partial masking) at some points in the show timeline, and an all-or-nothing on/off flip at others, on content that is visually and numerically identical between the two.
Reproduction steps
Reproduced on two separate audio sources, ruling out format as the cause:
-
A Wave64 file (
.w64renamed to.wav, per your earlier confirmed workaround) -
A plain RIFF WAV, mono-per-channel, 5-channel, about a minute long, static per-frame content (a single non-animating shape, identical Y geometry every frame throughout the file)
With the project timeline fully paused, and the source Audio File In CHOP’s Play parameter also switched off (so no new audio blocks are being pulled through the engine), I read the Logic CHOP’s output channel via Python three separate times at the same frozen timeline position. boundmin, the upstream sel_y channel’s values, and the sample count (800 throughout the chain, confirmed at every stage: in1, sel_y, gate) were all identical across all three reads. The three reads returned three different results:
-
Read 1: 503/800 samples passing (matches manual
y >= boundmincomputed independently from the same data, i.e. the mathematically correct answer) -
Read 2 (forced recook via
op.cook(force=True)): 0/800 passing -
Read 3: 800/800 passing
Since the Audio File In CHOPs had Play disabled and the timeline was stationary throughout all three reads, this doesn’t look like a race against the audio device callback thread, everything upstream of the Logic CHOP was confirmed static and identical at read time.
Isolation steps taken before landing here
In case it’s useful context for narrowing this down: we initially suspected the audio-rate CHOP chain dropping to single-sample blocks (ruled out, numSamples checked at every operator, always 800), a race between the timeline and the audio engine’s own clock (ruled out per above, once both playback and Play were fully stopped), file length/EOF issues on a shorter stem file (ruled out, both source files confirmed same duration via soxi), and a stale parameter expression resolving to the wrong operator (ruled out, boundmin.eval() confirmed to match the Slider’s value0 exactly on every read).
Workaround
Replaced the Logic CHOP with a Math CHOP doing y - boundmin (via the same slider parameter expression, now on the Math CHOP’s preoff), feeding a second Math CHOP as a gain multiplier to sharpen the transition, feeding a Limit CHOP hard-clamped to 0–1. This has been stable in testing across all 13 lasers in the install so far, dragging the slider through the same problem timeline positions with no repeat of the on/off flip.
Happy to send the .toe or a stripped-down repro file if that’d help track it down, this is feeding a mask on a laser safety cutoff, so I’d rather understand root cause than just ship the workaround blind.