Skip to content

Rewrite in Rust with Python bindings (0.4.0) - #50

Merged
andrewchen5678 merged 7 commits into
mainfrom
rust-rewrite
Oct 6, 2026
Merged

andrewchen5678 merged 7 commits into
mainfrom
rust-rewrite

Conversation

@andrewchen5678

Copy link
Copy Markdown
Collaborator

Summary

  • Rewrite the detector as a single Rust crate (library + audio-pattern-detector binary); the Python package, native-helper and matplotlib debug charts are removed (charts are planned for v2, see docs/roadmap.md).
  • Add Python bindings (PyO3, python feature) built with maturin: Detector, MatchResult, clip_name. See docs/python.md.
  • Release workflow builds binaries, the GHCR image and wheels, and refreshes the GitHub Pages package index.
  • Version 0.4.0 (was 0.3.25).

Behaviour changes

  • Rounding uses Rust's f64::round (ties away from zero), so millisecond timestamps can be 1 ms later than 0.3.x output.
  • resample keeps the Nyquist component for even lengths, matching scipy.signal.resample.
  • A detection inside the overlap between two chunks is reported once instead of twice.
  • Debug file names use _ instead of : in the section timestamp and sanitise clip names.
  • Rejected input: target sample rate 0, non-finite numbers in .apd.toml, sine clips longer than 3600 s.
  • WAV reading no longer allocates from declared fmt / data sizes.

Testing

  • cargo clippy --all-targets -- -D warnings and with --features python
  • cargo test (287 tests), python -m unittest tests.test_python_bindings (11 tests)
  • The release workflow changes have not been run yet.

🤖 Generated with Claude Code

Andrew Chen and others added 7 commits October 6, 2026 08:59
Replace the Python package and its native helper with one Rust crate
(library + audio-pattern-detector binary). Detection output matches the
Python implementation on all sample audio; the Python tests are ported
to cargo integration tests.

- Debug mode keeps stderr diagnostics, audio sections and peak dumps,
  but draws no charts; docs/roadmap.md plans a minimal chart set for v2.
- JSON/JSONL output is compact, and --height-min now also applies on
  the ffmpeg path.
- WAV input is read natively, including WAVE_FORMAT_EXTENSIBLE.
- Remove Docker files and the wheel-index pages workflow; CI runs
  clippy and tests with cargo, and releases ship binaries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Continue the 0.3.x version line instead of jumping to 1.0.0.

Add a Dockerfile in the layout the sibling Rust projects use (builder,
runtime, runtime-prebuilt). The release workflow builds the
runtime-prebuilt image on the amd64 and arm64 runners from the binaries
it already compiled, pushes them to
ghcr.io/andrewtheguy/audio_pattern_detector and publishes a multi-arch
manifest. The image carries only the binary, for consumers to copy into
their own images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace round_ties_even (Python's rounding, kept from the port) with
f64::round, which rounds ties away from zero. This affects millisecond
timestamps, the whole-second time format, the reported clip duration,
the marker-tone window length, the synthesised tone sample count and
the verification window bounds: for a correlation curve of odd length
the midpoint boundary now lands one sample later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Match scipy.signal.resample: combine both Nyquist components when
downsampling and split the component across both bins when upsampling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An unknown data length (0 or 0xFFFFFFFF) made it allocate usize::MAX
bytes and panic. Read to EOF in that case, and at most the declared
remaining bytes otherwise, without allocating from the declared size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Expose the detector to Python behind the optional python feature:
Detector (match_file, match_wav_stream), MatchResult and clip_name.
The wheel is built with maturin, attached to releases and listed in
the GitHub Pages package index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Drop matches the previous chunk already reported instead of replaying
  them from the lookback; the CLI no longer needs its own dedup.
- Sanitise clip names and section timestamps used in debug paths.
- Reject non-finite numbers in .apd.toml and cap sine clip duration.
- Reject a target sample rate of 0.
- Read a bounded part of the WAV fmt chunk instead of its declared size.
- Document that Linux artifacts target current distributions only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andrewchen5678
andrewchen5678 merged commit 1460468 into main Oct 6, 2026
2 checks passed
@andrewchen5678
andrewchen5678 deleted the rust-rewrite branch October 6, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant