home/ atoms/ angular-cumsum-phase-accuracy

Angular cumsum avoids phase drift in long synthesis by chunking cumulative sums and resetting with modular arithmetic

Phase synthesis via tf.cumsum accumulates small floating-point errors that become audible as pitch drift in long segments (>100k samples) or at high sample rates. DDSP provides angular_cumsum(), which splits the frequency sequence into chunks, applies cumsum within each chunk, takes the result modulo 2π, then adds the chunk-boundary offsets. This prevents error accumulation across chunks. The function is ~30% faster on CPU but 40% slower on TPU, so it is disabled by default during training and enabled for inference via the global gin parameter oscillator_bank.use_angular_cumsum=True. For typical 4-second training segments at 16kHz (64k samples), standard cumsum is accurate enough.

Examples

# Enable globally via gin for inference:
gin.parse_config('oscillator_bank.use_angular_cumsum = True')
# Or when constructing a synth:
harmonic = ddsp.synths.Harmonic(use_angular_cumsum=True)

Assessment

At what audio length does standard tf.cumsum start to produce audible phase errors? Why is angular_cumsum disabled by default during training?

“Just taking tf.sin(tf.cumsum(angular_frequency)) leads to accumulation of phase errors that are audible for long segments or at high sample rates.”
corpus · ddsp-differentiable-digital-signal-processing-magenta-code-c · chunk 20