Interactive PySide6 + manim demonstration of how an ADC works
Project description
cicadc
An interactive desktop program that demonstrates how an analog-to-digital converter (ADC) works. It shows two side-by-side panels rendered with manim inside a PySide6 window:
- Left panel (analog) - the analog signal drawn as a path that scrolls past "now" (the middle line), with the future at the top and the past at the bottom. A blue car drives along the (clean) analog signal and turns to follow the path. A "shadow" car marks the converter output at now - pale green when a decimator is active (the coarse quantizer/modulator output) or white/gray otherwise (the digital output). Noise is added before the converter, not on the displayed analog curve.
- Right panel (digital) - the digital signal as a sample-and-hold staircase. Pale green is the coarse quantizer/modulator output and white/gray is the decimated/filtered digital output (normalised to unity gain at the signal frequency). A white/gray car follows the digital output, trailing by the filter's group delay so it lands back on the analog curve (delay-compensated).
Two analysis strips run along the bottom of the view:
- Quantization noise (bottom left) - the error
analog - digital outputsampled at each instant and held as a staircase, with time on the x-axis and "now" on the far right. The y-axis is scaled to the quantizer's LSB (±1 LSB), with the LSB-in-FS value annotated. - Digital spectrum (bottom right) - a Hann-windowed FFT of the digital
output on a logarithmic frequency axis (
f / f_s), with magnitude in dBFS (0 dB = full scale). The transform uses a long window (1024 points) and is recomputed only when a new sample arrives.
The ADC can run as a plain Nyquist-rate uniform quantizer or as a 1st- or 2nd-order sigma-delta modulator (with optional dither); a sigma-delta bitstream is decimated by a cascaded sinc^N (CIC-style) moving-average filter matched to the modulator order. When reconstructing, both the decimation filter's gain/group-delay and the modulator's measured in-band signal transfer (gain/phase) are de-embedded, so the quantization-noise strip shows the true noise rather than a residual signal-transfer error. (The 2nd-order loop's coefficients are chosen for single-bit stability, so some residual harmonic distortion of the signal remains visible - a real modulator artifact.)
Project layout
src/cicadc/ package (src layout, mirrors cicwave)
cli.py click console entry point (`cicadc`)
app.py QApplication bootstrap
main_window.py PySide6 window + controls
manim_scene.py offscreen manim renderer
signal_source.py analog signal model (sinusoid + noise)
quantizer.py N-bit quantizer
render_widget.py Qt widget + animation loop
assets/car.png car sprite
tests/unittests/ unittest suite
Requirements
- Python 3.9-3.13 (manim does not yet support 3.14). A
python3.12venv is used by the setup steps below. - A working manim install (Cairo backend). On macOS you may need the system
libraries
pkg-config cairo pangovia Homebrew if the wheels do not cover your platform.
Setup
python3.12 -m venv .venv
source .venv/bin/activate
pip install -e . # or: pip install -r requirements.txt
make dev-install runs the editable install for you.
Prebuilt binaries
Standalone, self-contained bundles (no Python install required) are built for Linux, Windows and macOS (Intel + Apple Silicon) and attached to each GitHub Release. Download the zip for your platform, unpack it, and run:
- Linux -
cicadc/cicadc - Windows -
cicadc\cicadc.exe - macOS -
cicadc.app(the bundle is unsigned, so the first time use right-click -> Open, or runxattr -dr com.apple.quarantine cicadc.app).
The bundles are produced by the Build binaries workflow (PyInstaller); you can
also build one locally with pyinstaller --noconfirm packaging/cicadc.spec.
Run
cicadc # installed console script
# or, from a checkout without installing:
python main.py
Controls
- Frequency / Amplitude - the input sinusoid (sliders; amplitude is a fraction of full scale).
- Speed - how fast the signal scrolls past "now".
- Bits - resolution of the quantizer / modulator.
- Sample period - the ADC sample clock interval.
- Noise - additive noise amplitude, applied before the converter.
- ADC type - Nyquist quantizer, or 1st-/2nd-order sigma-delta modulator.
- Dither - deterministic dither for the sigma-delta quantizer (ΣΔ modes only).
- Avg - decimation/averaging length on the digital output (1 = off); uses a sinc^N cascade matched to the ADC type.
- Play / Pause - start or stop the animation.
A signal-chain bar above the view highlights the active path (Analog → Noise → Quantizer/ΣΔ → Filter → Digital).
Development
make test # run unit tests
make check # import and print version
make lint # ruff (if installed)
make build # build wheel + sdist
Acknowledgements
Big thanks to Domen Visnar for the idea behind this project!
Rendering
The manim scene is rasterised offscreen (Cairo) and painted into the Qt widget. Cost scales with pixel count, so resolution and frame rate trade off; the default is 1280x1152 at 30 fps (the taller frame makes room for the bottom analysis strips), with the static scenery and the FFT curve cached so only the moving content is rebuilt each frame.
Status
Single sinusoid input, adjustable bit depth, noise, Nyquist and 1st-/2nd-order sigma-delta ADCs, a sinc^N decimation filter with delay compensation, the signal-chain bar, and the quantization-noise / FFT analysis strips are implemented. Random / multi-sinusoid inputs and a configurable bandwidth filter are planned follow-ups.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cicadc-0.3.1.tar.gz.
File metadata
- Download URL: cicadc-0.3.1.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a73a290426f6fa51e2e7691274ba70ec520fdf9ba70155b86bf80e97010cb91e
|
|
| MD5 |
f0fedae2cf4ddd71000698979ca449ec
|
|
| BLAKE2b-256 |
6ef3375cf8b484c50d3394ff989a0a36ba4a82a668a4131bba386f800ea9b518
|
Provenance
The following attestation bundles were made for cicadc-0.3.1.tar.gz:
Publisher:
release.yml on wulffern/cicadc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cicadc-0.3.1.tar.gz -
Subject digest:
a73a290426f6fa51e2e7691274ba70ec520fdf9ba70155b86bf80e97010cb91e - Sigstore transparency entry: 1739982204
- Sigstore integration time:
-
Permalink:
wulffern/cicadc@95b5da74d09d32414f43a8987cc394d26c0dec62 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/wulffern
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@95b5da74d09d32414f43a8987cc394d26c0dec62 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cicadc-0.3.1-py3-none-any.whl.
File metadata
- Download URL: cicadc-0.3.1-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9300983c9ff4d3def0806838aff1358fda499d90ef78cf0d6a0bfa4482948534
|
|
| MD5 |
2689c62a4147ecddbad9de7dead79595
|
|
| BLAKE2b-256 |
47752f62f570f5cafa8d37335f054ca448492b6b0b73821021e02c0d8b0d0ed3
|
Provenance
The following attestation bundles were made for cicadc-0.3.1-py3-none-any.whl:
Publisher:
release.yml on wulffern/cicadc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cicadc-0.3.1-py3-none-any.whl -
Subject digest:
9300983c9ff4d3def0806838aff1358fda499d90ef78cf0d6a0bfa4482948534 - Sigstore transparency entry: 1739982214
- Sigstore integration time:
-
Permalink:
wulffern/cicadc@95b5da74d09d32414f43a8987cc394d26c0dec62 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/wulffern
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@95b5da74d09d32414f43a8987cc394d26c0dec62 -
Trigger Event:
push
-
Statement type: