diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 93% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md index 9d47de8..ef21c03 100644 --- a/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -65,7 +65,7 @@ and instead picks up everything in a configurable input directory. - Target `main`. - One topic per PR. Don't bundle unrelated fixes. - Update docs if your change is user-visible. -- Update `benchmarks/conversion-results.json` only if you actually re-ran the validation campaign (no synthetic numbers — see the [validation chapter](docs/03-validation-campaign.md) for the philosophy here). +- Update `docs/benchmarks/conversion-results.json` only if you actually re-ran the validation campaign (no synthetic numbers — see the [validation chapter](../docs/03-validation-campaign.md) for the philosophy here). - The CI must pass. If you can't make it pass locally, push anyway and we'll help. ## Credit diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6462cf8..6bbbc8f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,4 +16,4 @@ Brief technical approach if non-trivial. - [ ] Docs updated if user-visible behavior changed - [ ] `CREDITS.md` updated if a new third-party dependency was added - [ ] No real credentials, real client data, or real file paths in the diff (placeholders only) -- [ ] No claims of test coverage that weren't actually measured (`benchmarks/` stays honest) +- [ ] No claims of test coverage that weren't actually measured (`docs/benchmarks/` stays honest) diff --git a/SECURITY.md b/.github/SECURITY.md similarity index 100% rename from SECURITY.md rename to .github/SECURITY.md diff --git a/.gitignore b/.gitignore index 55d4d4d..4d88306 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ # ...with an explicit exception for the FATE sample we ship for upstream # FFmpeg submission (public test artefact, not a production file). -!submission/fate/*.ds2 -!submission/fate/*.DS2 +!ffmpeg-upstream/fate/*.ds2 +!ffmpeg-upstream/fate/*.DS2 # Node node_modules/ diff --git a/CREDITS.md b/CREDITS.md index 027fb83..ee260c9 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -30,7 +30,7 @@ The hand-written C port of the DS2 decoder + demuxer for FFmpeg — `libavcodec/ This is the work that closes the loop: once Patrick's C lands upstream, **DS2 / DS2 Pro becomes a first-class audio format in any FFmpeg build, anywhere**. No more decoder bundling, no more native binary in our Dockerfile, no more "first install this dependency". Just `ffmpeg -i recording.ds2 out.wav`. -Patrick has asked to stay off the `ffmpeg-devel` mailing list. The mailing-list submission (cover letter, FATE sample, validation campaign) is being prepared in this repo at [`submission/`](submission/) and will go out under the submitter's name, on Patrick's behalf, with his explicit consent. See [submission/README.md](submission/README.md) for the chain of credit going to FFmpeg. +Patrick has asked to stay off the `ffmpeg-devel` mailing list. The mailing-list submission (cover letter, FATE sample, validation campaign) is being prepared in this repo at [`ffmpeg-upstream/`](ffmpeg-upstream/) and will go out under the submitter's name, on Patrick's behalf, with his explicit consent. See [ffmpeg-upstream/README.md](ffmpeg-upstream/README.md) for the chain of credit going to FFmpeg. --- diff --git a/LICENSE b/LICENSE index 62804dc..9740216 100644 --- a/LICENSE +++ b/LICENSE @@ -44,7 +44,7 @@ documented in this repository. URL: https://github.com/gaspardpetit/dss-codec License: MIT - FFmpeg DS2 C port (used in submission/ for upstream FFmpeg merge) + FFmpeg DS2 C port (used in ffmpeg-upstream/ for upstream FFmpeg merge) Author: Patrick Domack URL: https://gist.github.com/patrickdk77/330dd3f593696d103e831c4c1d78d1f9 License: MIT / public domain (explicit relicensing grant: diff --git a/README.md b/README.md index 54ca591..66964ae 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Three months later, this repo shows how to take that work and put it in producti - **(4)** [**cracking the re-sync block**](docs/07-cracking-the-resync-block.md) — the sequel: we ran the closed-source Olympus decoder *inside a debugger we built from its own DLLs*, hooked it at the instruction level, and read the format's last undocumented demux rule straight off the silicon — then deleted the Windows fallback for good; - **(5)** [**the bug that wasn't**](docs/10-the-reckoning-the-bug-that-wasnt.md) — the saga's twist, and the chapter we're proudest of. A residual "decoder bug" on paused recordings was cornered across [a full research paper](docs/09-the-resync-excitation-anomaly.md) — *analysis-by-synthesis* proving the filter bit-exact, nine falsified hypotheses, a hidden state machine — and then **overturned**. We did what the paper said was impossible: ran the closed Olympus decoder under our own instrumentation (Linux + Wine + gdb), watched a reference lie to us in the *exact shape* of the symptom, and finally settled it the cheapest way there is — by **listening**. There was no bug; the "seven-second wound" was a person stepping away from the microphone. We kept every wrong turn in the record, framed. The most honest read in the repo, and the most useful if you reverse-engineer for a living. - 🛠 **[src/](src/)** — the actual integration code: CLI, cron job, HTTP daemon, admin web UI. Sanitized of organization-specific bits; the patterns are reusable as-is. -- 📊 **[benchmarks/](benchmarks/)** — performance comparison (WASM vs native, the chain we use vs the commercial Windows chain), and the validation campaign run on 35 real-world files. +- 📊 **[docs/benchmarks/](docs/benchmarks/)** — performance comparison (WASM vs native, the chain we use vs the commercial Windows chain), and the validation campaign run on 35 real-world files. ## Pipeline at a glance @@ -122,7 +122,7 @@ The intellectual heavy-lifting belongs entirely to: - **Kieran Hirpara** — [hirparak/dss-codec](https://github.com/hirparak/dss-codec) — the reverse-engineering that made all of this possible. MIT, February 2026. - **Gaspard Petit** — [dss-codec-wasm](https://github.com/gaspardpetit/dss-codec-wasm) (WASM build) and [dss-codec fork](https://github.com/gaspardpetit/dss-codec) (Rust crate with CI, streaming, decryption — the one our Dockerfile uses). MIT. -- **Patrick Domack** — [FFmpeg C port gist](https://gist.github.com/patrickdk77/330dd3f593696d103e831c4c1d78d1f9) — independent C implementation of the spec, being [prepared for upstream FFmpeg submission from this repo](submission/). MIT / public domain. +- **Patrick Domack** — [FFmpeg C port gist](https://gist.github.com/patrickdk77/330dd3f593696d103e831c4c1d78d1f9) — independent C implementation of the spec, being [prepared for upstream FFmpeg submission from this repo](ffmpeg-upstream/). MIT / public domain. - **lamejs** ([@breezystack/lamejs](https://www.npmjs.com/package/@breezystack/lamejs)) — pure-JS MP3 encoder. LGPL. - **[FFmpeg](https://ffmpeg.org/)** — the encoder we use in the native chain. LGPL. diff --git a/benchmarks/README.md b/docs/benchmarks/README.md similarity index 97% rename from benchmarks/README.md rename to docs/benchmarks/README.md index a2cddec..000abf8 100644 --- a/benchmarks/README.md +++ b/docs/benchmarks/README.md @@ -39,7 +39,7 @@ Each entry contains: ## Speed (WASM chain measurements) -These are the WASM-chain numbers — what we shipped with on day one before [the switch to native](../docs/04-wasm-vs-native.md). +These are the WASM-chain numbers — what we shipped with on day one before [the switch to native](../04-wasm-vs-native.md). | Metric | Value | |---|---| @@ -51,7 +51,7 @@ These are the WASM-chain numbers — what we shipped with on day one before [the ## Speed (native chain — same files, after the switch) -After switching to the native binary + ffmpeg (see [docs/04](../docs/04-wasm-vs-native.md)), the same conversion is **~3-5× faster** depending on the file: +After switching to the native binary + ffmpeg (see [docs/04](../04-wasm-vs-native.md)), the same conversion is **~3-5× faster** depending on the file: | Test | WASM chain | Native chain | Speedup | |---|---|---|---| diff --git a/benchmarks/conversion-results.json b/docs/benchmarks/conversion-results.json similarity index 100% rename from benchmarks/conversion-results.json rename to docs/benchmarks/conversion-results.json diff --git a/examples/README.md b/examples/README.md index 49317df..ca65562 100644 --- a/examples/README.md +++ b/examples/README.md @@ -16,7 +16,7 @@ docker compose up --build Use the FATE sample we ship for the upstream FFmpeg submission: ```bash -cp submission/fate/sample-qp.ds2 examples/ +cp ffmpeg-upstream/fate/sample-qp.ds2 examples/ ``` It's a 37-second DS2 QP file (16 kHz mono, 129 KiB), originally hosted as a public test artefact on dictate.com.au's CDN, with neutral content ("DICTATE" as author metadata, no third-party identification). We use it both as a FATE regression test for the FFmpeg patch and as a known-good starting point for anyone trying the toolchain. diff --git a/submission/00-cover-letter.md b/ffmpeg-upstream/00-cover-letter.md similarity index 100% rename from submission/00-cover-letter.md rename to ffmpeg-upstream/00-cover-letter.md diff --git a/submission/01-fate-sample-plan.md b/ffmpeg-upstream/01-fate-sample-plan.md similarity index 97% rename from submission/01-fate-sample-plan.md rename to ffmpeg-upstream/01-fate-sample-plan.md index 0c1bb51..117ecfd 100644 --- a/submission/01-fate-sample-plan.md +++ b/ffmpeg-upstream/01-fate-sample-plan.md @@ -37,7 +37,7 @@ and the corresponding reference output as `0x604`, parsed cleanly by both Hirpara's Rust reference and Patrick's C port. 2. **QP is the format we want covered first.** In the in-the-wild - corpus we have access to (see [`../benchmarks/conversion-results.json`][bench]), + corpus we have access to (see [`../docs/benchmarks/conversion-results.json`][bench]), QP dominates DS2 traffic; SP is a long-tail mode. A FATE rule for QP covers the high-leverage case. 3. **Public, persistent URL.** dictate.com.au has hosted this file on @@ -48,7 +48,7 @@ and the corresponding reference output as vendor produced specifically as a public artefact for codec testing. -[bench]: ../benchmarks/conversion-results.json +[bench]: ../docs/benchmarks/conversion-results.json ## Licensing position @@ -121,7 +121,7 @@ pipeline) ``` Decode success: 35/35. Mean conversion ratio: 1.5x real time on a single core (Rust path). -Full per-file results: ../benchmarks/conversion-results.json. +Full per-file results: ../docs/benchmarks/conversion-results.json. Note: this dataset measures decode success and timing, not byte-for-byte diff vs Rust. The byte-for-byte argument is the FATE-sample analysis above. diff --git a/submission/02-changelog-and-doc.md b/ffmpeg-upstream/02-changelog-and-doc.md similarity index 100% rename from submission/02-changelog-and-doc.md rename to ffmpeg-upstream/02-changelog-and-doc.md diff --git a/submission/03-v3-empty-block-fix.md b/ffmpeg-upstream/03-v3-empty-block-fix.md similarity index 100% rename from submission/03-v3-empty-block-fix.md rename to ffmpeg-upstream/03-v3-empty-block-fix.md diff --git a/submission/04-resync-block-byte1.md b/ffmpeg-upstream/04-resync-block-byte1.md similarity index 100% rename from submission/04-resync-block-byte1.md rename to ffmpeg-upstream/04-resync-block-byte1.md diff --git a/submission/README.md b/ffmpeg-upstream/README.md similarity index 100% rename from submission/README.md rename to ffmpeg-upstream/README.md diff --git a/submission/fate/fate-ds2-qp.ref b/ffmpeg-upstream/fate/fate-ds2-qp.ref similarity index 100% rename from submission/fate/fate-ds2-qp.ref rename to ffmpeg-upstream/fate/fate-ds2-qp.ref diff --git a/submission/fate/sample-qp.ds2 b/ffmpeg-upstream/fate/sample-qp.ds2 similarity index 100% rename from submission/fate/sample-qp.ds2 rename to ffmpeg-upstream/fate/sample-qp.ds2 diff --git a/submission/patches/README.md b/ffmpeg-upstream/patches/README.md similarity index 100% rename from submission/patches/README.md rename to ffmpeg-upstream/patches/README.md diff --git a/submission/patches/email-body-v3-followup.txt b/ffmpeg-upstream/patches/email-body-v3-followup.txt similarity index 100% rename from submission/patches/email-body-v3-followup.txt rename to ffmpeg-upstream/patches/email-body-v3-followup.txt diff --git a/submission/patches/email-body.txt b/ffmpeg-upstream/patches/email-body.txt similarity index 100% rename from submission/patches/email-body.txt rename to ffmpeg-upstream/patches/email-body.txt diff --git a/submission/patches/email-subject.txt b/ffmpeg-upstream/patches/email-subject.txt similarity index 100% rename from submission/patches/email-subject.txt rename to ffmpeg-upstream/patches/email-subject.txt diff --git a/submission/patches/v2-0001-avcodec-avformat-add-Olympus-DS2-decoder-and-demu.patch b/ffmpeg-upstream/patches/v2-0001-avcodec-avformat-add-Olympus-DS2-decoder-and-demu.patch similarity index 100% rename from submission/patches/v2-0001-avcodec-avformat-add-Olympus-DS2-decoder-and-demu.patch rename to ffmpeg-upstream/patches/v2-0001-avcodec-avformat-add-Olympus-DS2-decoder-and-demu.patch