Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md → .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
File renamed without changes.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
2 changes: 1 addition & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

---

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.

Expand Down
4 changes: 2 additions & 2 deletions benchmarks/README.md → docs/benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|---|---|
Expand All @@ -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 |
|---|---|---|---|
Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading