English | 日本語 | Français | Español | Deutsch | 简体中文 | 한국어
Integer-PCM protection tool for audio processing — archiving analog transfers (records, reels, cassettes) digitized to 24-bit PCM.
Preserving 24-bit PCM exactly as captured. Not audio enhancement — audio preservation.
intwav inspects, trims, and losslessly archives integer PCM without floating-point conversion, requantization, or resampling. It is not a DAW and does not "improve" audio — it preserves the PCM exactly as captured and stores it as lossless FLAC, with an explainable, logged processing path.
Implemented commands:
| Command | Purpose |
|---|---|
intwav info <in> |
Format, parameters, duration, peak, clip count |
intwav check <in> |
Full inspection: info + DC offset + silence detection |
intwav peak <in> |
Per-channel peak level (dBFS + raw) |
intwav clips <in> |
Clipped-sample counts |
intwav trim <in> [out] --from <ts> --to <ts> |
Extract a range, sample values unchanged |
intwav split <in> --out <dir> (--cue <f> | --by silence|ab) |
Split into tracks (CUE list, silence, or A/B side) with metadata |
intwav gain <in> <out> --db <n> |
Fixed-point gain, integer dB (-96..=24); + gain needs --allow-clipping |
intwav fade-in <in> <out> --duration <d> |
Linear fixed-point fade-in |
intwav fade-out <in> <out> --duration <d> |
Linear fixed-point fade-out |
intwav dc-correct <in> <out> |
Remove per-channel DC offset |
intwav export16 <in> <out> [--dither tpdf] |
16-bit derivative output with TPDF dither (not a master) |
intwav verify <a> [b] |
Checksum PCM, or prove two files carry identical PCM |
Timestamps are HH:MM:SS.mmm, MM:SS.mmm, SS.mmm, or plain seconds; durations also accept 5s / 250ms.
All processing commands accept --output-format flac|wav (default: infer from the output extension, else FLAC) and --report <path> for a JSON processing report (§13/§22) carrying PCM SHA-256 checksums and a processing-log hash.
Gain, fades, DC correction, and 16-bit dithering are all fixed-point integer operations. Gain coefficients come from a precomputed Q31 table (no pow); TPDF dither uses an integer PRNG with a reproducible --seed.
- Input: WAV and FLAC, 16/24/32-bit integer PCM, mono or stereo.
- Output: FLAC (default) or WAV.
- Float WAV, compressed WAV, MP3/AAC/Opus, DSD, and multichannel are rejected with an explicit error — never silently converted.
All sample math lives in intwav-core, which is no_std + alloc, has no dependencies, and uses no floating point — including dBFS, which is computed with a fixed-point integer log approximation (accuracy < 0.004 dB). FLAC decoding uses the pure-Rust claxon; FLAC encoding is delegated to the external flac binary so libFLAC's internal float analysis never enters this process.
scripts/check-no-float.sh enforces this in CI: it scans the core source for float constructs and disassembles the compiled core object, failing the build if any floating-point arithmetic instruction (x86-64 SSE/x87 or aarch64 FP) appears.
crates/
intwav-core integer-only DSP: analysis, windowed silence, dBFS, slicing, gain/fade/DC, TPDF dither (float-scanned)
intwav-codec WAV (hound) + FLAC (claxon decode / flac-CLI encode) integer I/O, metadata, header probe
intwav-engine shared CLI/GUI engine: ops, frozen JSON report, coded errors, verified atomic writes, decode-once scratch + waveform pyramid, non-destructive project (.iwproj) + undo/render (float-free source)
intwav-playback preview playback (cpal): integer op-chain preview, float only at the device boundary — off the save path, NOT float-scanned
intwav-cli the `intwav` binary: thin front-end over the engine
The intwav-engine crate is the foundation for a forthcoming GUI (Tauri +
React): every operation is synchronous and caller-driven (progress + cancel),
every write is verified (pcm_verified), and the CLI and GUI share it verbatim.
open_source decodes a large source once into a seekable scratch file while
building the waveform and PCM hash in a single pass. intwav-playback previews
from that scratch, running the same integer op-chain the export would, with float
only at the final device conversion (native-rate-first, float resample fallback).
A desktop GUI lives in app/: a Tauri v2 backend (src-tauri/, a crate
detached from the core workspace so its heavy build never slows CI) that
exposes the engine as commands, and a React + TypeScript frontend (Japanese-
default, bilingual). It opens WAV/FLAC via open_source (decode-once scratch +
waveform), shows the waveform and an Integer-Safe status panel driven by the
frozen report facts, and runs trim/gain/export16/verify with live progress and
cancel — all through the same engine the CLI uses.
cd app
npm install
bash scripts/prepare-flac.sh # vendor the flac sidecar
npm run tauri dev # dev (needs a desktop session)
npm run tauri build # bundle .app/.dmg/.msi/.AppImagetauri build bundles the engine + a flac sidecar into a native installer
(e.g. intwav_<ver>_<arch>.dmg). For distribution — a self-contained flac
per platform, code signing, and notarization — see
app/RELEASE.md; a tag-triggered multi-platform build
lives in .github/workflows/release.yml. The
frontend also builds headlessly with npm run build.
cargo build --release # binary at target/release/intwav
cargo test --workspace # unit + end-to-end tests
bash scripts/check-no-float.sh # verify the float-free guaranteeRequires the flac command-line tool for FLAC output.
Apache-2.0