Skip to content

Add audio support, the v2 header, and automated publishing - #7

Merged
aravpanwar merged 9 commits into
mainfrom
audio-support
Sep 17, 2026
Merged

aravpanwar merged 9 commits into
mainfrom
audio-support

Conversation

@aravpanwar

Copy link
Copy Markdown
Owner

Adds the .adcy<x> audio file type backed by a version 0x02 header, fixes two
gaps in the open flow, and wires crates.io and PyPI publishing to a version tag.

Opened so CI runs across all three platforms before the v0.2.0 tag. Merging
directly once green.

Adds the adcy<x> file type: sources are decoded to interleaved 16-bit PCM
with symphonia (wav, flac, mp3, ogg), corrupted like any other payload, and
re-encoded to wav with hound for playback.

Header version goes to 0x02. Bytes 6..14 become a per-type metadata region
read according to the file_type byte, so images keep width and height while
audio stores sample rate, channel count, and bits per sample. Version 0x01
files are refused rather than reinterpreted.

Also plainer comment prose throughout these files, and the test suite
consolidated from 45 cases to 33 by merging ones that differed only in their
input. Both touch the same lines as the audio work, so they land together.
Same pass as the readme: drop the defensive framing, the restated premise,
and the theatrical phrasing, and replace the em dashes the repo does not use.
Also documents the adcy file type and the windows 10 minimum.
Both registries use trusted publishing, so a github oidc token is exchanged
for a short-lived registry token and no api tokens are stored in the repo.

A v* tag now builds the wheels as well, so one tag ships the binaries, the
crate, and the python package. py-v* still publishes the bindings alone.
Each publish waits for its own build matrix, since neither registry allows a
version to be reused.
The read and the write-back went through separate handles, so two opens could
read the same starting payload and the later write discarded the earlier one:
both opens together cost a single corruption. One handle now serves the whole
sequence under an exclusive advisory lock.

The test drives four simultaneous opens of a 4 MiB payload at x=10 and counts
surviving bytes on disk. Without the lock about 37% survive, meaning three of
the four opens were lost; with it, under 2%.
The sweep ran only inside open, so the temporary file from the last display
survived an encode, a failed open, or a library caller that never reaches
open_file. It is a copy of a less corrupted state, so it should not wait for
the next successful open to be cleared.

The current open's file still has to outlive the process, since the viewer is
launched asynchronously and needs it.
A 16-bit sample is one value across two bytes, not two independent bytes, so
byte replacement made x mean something different for audio than for text and
images: at x=1 roughly half the replacements hit the high byte and threw the
sample across the full range, which is heard as a full-scale click. Measured
against a music excerpt, x=1 already put the injected noise louder than the
signal, so the gentlest setting sounded like the harshest.

Each selected sample is now displaced by a bounded random offset that scales
with x and saturates rather than wrapping. Noise sits about 20 dB below the
payload at x=1 and above it by x=10, which is the span the other payload types
cover.
The chunks_exact allow in corrupt.rs is crate level, so it did not cover the
playback loop in open.rs. A newer clippy than the local one flags it.

The smoke test asserted a hardcoded 0.1.0. It now reads the version from
python/Cargo.toml, so a release does not break it.
It asserted that the first pixel had at least one corrupted channel. At x=10 a
channel survives about 37% of the time, so all three surviving was a roughly 5%
chance of failing on any platform. It now counts corrupted rgb bytes across the
whole payload.
@aravpanwar
aravpanwar merged commit c1acec9 into main Sep 17, 2026
8 checks passed
@aravpanwar
aravpanwar deleted the audio-support branch September 17, 2026 13:19
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