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
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ made this tree (sections 5–6). Do not re-derive what it settles.
three headers and the root `project()` together (0.5.0 came with `rational`'s M6, 0.6.0 with the
audit response's async vocabulary pass: `preset` retired for `profile`, `economy()` to `program()`,
the async C ABI in the siblings' shape).
- **The DspTap floor (A9).** Each umbrella header also defines `TAP_SR_DSPTAP_MINIMUM` (0.1.0)
token-identically and `static_assert`s it against DspTap's `TAP_DSP_VERSION`
(`tap/dsp/version.h`); `family.VersionMacrosAgree` checks the three agree. DspTap is tagged on its
own cadence (Q4): a commit that moves `submodules/dsptap` names the tag it pins, and raising the
floor updates the root README's tested pairs in the same PR.
- **Clean renames, no aliases (D7).** Retired options fail the configure
(`cmake/retired_options.cmake`); retired override macros hit an `#error`; retired words fail
the style job (`scripts/retired_words.txt`, `scripts/check_retired_words.py`). Do not add aliases.
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,19 @@ directory on the path, no public header names `srt/`, a sibling's
code (design math, traits, kernels, quantization, instruments) lands in
DspTap first; this tree bumps the submodule pin.

### Tested pairs

DspTap is versioned on its own cadence (`tap/dsp/version.h`, tags `vX.Y.Z`),
never in lockstep with this tree. Each engine's umbrella header states the
oldest DspTap the family was tested with, `TAP_SR_DSPTAP_MINIMUM`, and a
`static_assert` against the substrate's `TAP_DSP_VERSION` rejects an older
one at compile time (`family.VersionMacrosAgree` holds the three definitions
equal). A commit that moves `submodules/dsptap` names the DspTap tag it pins.

| SampleRateTap | DspTap floor | DspTap pinned |
|---|---|---|
| 0.6.0 | 0.1.0 | v0.1.0 |

## Provenance and license

MIT (`LICENSE`: Timothy Place and the SampleRateTap contributors). The tree
Expand Down
10 changes: 10 additions & 0 deletions async/include/tap/sr/async/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,18 @@
// README's table states all three ladders).
#pragma once

#include "tap/dsp/version.h"

#define TAP_SR_VERSION_MAJOR 0
#define TAP_SR_VERSION_MINOR 6
#define TAP_SR_VERSION_PATCH 0

// The oldest DspTap this family was tested with (the roadmap's A9; the root
// README's tested pairs), defined token-identically in each engine's
// umbrella header like the family version (D13) and checked against the
// pinned substrate's tap/dsp/version.h.
#define TAP_SR_DSPTAP_MINIMUM TAP_DSP_VERSION_ENCODE(0, 1, 0)
static_assert(TAP_DSP_VERSION >= TAP_SR_DSPTAP_MINIMUM,
"tap::sr::async needs DspTap 0.1.0 or newer (submodules/dsptap)");

#include "tap/sr/async/converter.h"
9 changes: 9 additions & 0 deletions bridge/include/tap/sr/bridge/ratio.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
// HANDOFF.md is the original design brief.
#pragma once

#include "tap/dsp/version.h"
#include "tap/sr/bridge/converter.h" // IWYU pragma: export
#include "tap/sr/bridge/design.h" // IWYU pragma: export
#include "tap/sr/bridge/phase_table.h" // IWYU pragma: export
Expand All @@ -44,6 +45,14 @@
#define TAP_SR_VERSION_MINOR 6
#define TAP_SR_VERSION_PATCH 0

// The oldest DspTap this family was tested with (the roadmap's A9; the root
// README's tested pairs), defined token-identically in each engine's
// umbrella header like the family version (D13) and checked against the
// pinned substrate's tap/dsp/version.h.
#define TAP_SR_DSPTAP_MINIMUM TAP_DSP_VERSION_ENCODE(0, 1, 0)
static_assert(TAP_DSP_VERSION >= TAP_SR_DSPTAP_MINIMUM,
"tap::sr::bridge needs DspTap 0.1.0 or newer (submodules/dsptap)");

namespace tap::sr::bridge {

/// The fixed rational ratio pair this library exists for: 44.1 -> 48 kHz
Expand Down
4 changes: 2 additions & 2 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ is this checklist, not an opinion.
| P9 | Non-finite input behaviour pinned | ✓ (A7) | ✓ (A7) | ✓ (A7) |
| P10 | Host hot path gated | ✓ (A8) | ✓ (A8) | ✓ (A8) |
| P11 | C ABI: one error model, extension rule, compat test, version probe | **open** (C3) | **open** (C3) | **open** (C3) |
| P12 | Versioned substrate pin asserted at compile time | **open** (A9) | **open** (A9) | **open** (A9) |
| P12 | Versioned substrate pin asserted at compile time | ✓ (A9) | ✓ (A9) | ✓ (A9) |
| P13 | Changelog, semver and deprecation statement reconciled with D7 | **open** (C3) | **open** (C3) | **open** (C3) |

## 3. Block A (weeks 1–2): contracts and hygiene
Expand Down Expand Up @@ -117,7 +117,7 @@ gated on shipping.
- **A8. A host ratchet.** *Landed 2026-10-14: `scripts/icount.py --target host` runs each engine's `tap_sr_<engine>_hostcount_*` workloads (`bench/icount/host_main.cpp`: the float converter in 128-frame blocks at 2 and 12 channels, `async`'s 12 on the channel-parallel path) under callgrind, counting only `tap_sr_host_counted()`, with eager binding and glibc's CPU dispatch and copy thresholds pinned. The counts are gated two-sided at ±3 % against the `host` key of each `bench/baselines.json` in the `host-ratchet` job (ubuntu-24.04, GCC 13). Two builds count identically. `async` at 12 channels runs about 30 M instructions per channel over the two-second stream, against 55 M at 2.* Deterministic `Ir` from callgrind (or `perf stat -e
instructions:u` with pinned flags) over the multichannel float pipelines, ±3 %, the same
`icount.py` mechanics, a hard gate two-sided like the QEMU ratchet (Q6).
- **A9. DspTap versioning.** Tag DspTap v0.1.0 at the tree this family pins (d7ebe4b or
- **A9. DspTap versioning.** *Landed 2026-10-14: DspTap's `tap/dsp/version.h` (tap/DspTap#62, `TAP_DSP_VERSION`, packed like the family's C ABI probes and pinned to its `project()` version by test) and its first tag, v0.1.0; each umbrella header here defines `TAP_SR_DSPTAP_MINIMUM` (0.1.0) token-identically and `static_assert`s it against the pinned substrate, `family.VersionMacrosAgree` holds the three equal, and the root README states the tested pairs.* Tag DspTap v0.1.0 at the tree this family pins (d7ebe4b or
its successor), add one `tap/dsp/version.h` (one tree, one header; the D13 triplication
exists only because the engines share no header), a `static_assert` in each engine
umbrella header against the minimum DspTap it was tested with, a "tested pairs" table in
Expand Down
9 changes: 9 additions & 0 deletions rational/include/tap/sr/rational/rational.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
// instruction-count ratchet (bench/).
#pragma once

#include "tap/dsp/version.h"
#include "tap/sr/rational/chain.h" // IWYU pragma: export
#include "tap/sr/rational/converter.h" // IWYU pragma: export
#include "tap/sr/rational/design.h" // IWYU pragma: export
Expand All @@ -40,3 +41,11 @@
#define TAP_SR_VERSION_MAJOR 0
#define TAP_SR_VERSION_MINOR 6
#define TAP_SR_VERSION_PATCH 0

// The oldest DspTap this family was tested with (the roadmap's A9; the root
// README's tested pairs), defined token-identically in each engine's
// umbrella header like the family version (D13) and checked against the
// pinned substrate's tap/dsp/version.h.
#define TAP_SR_DSPTAP_MINIMUM TAP_DSP_VERSION_ENCODE(0, 1, 0)
static_assert(TAP_DSP_VERSION >= TAP_SR_DSPTAP_MINIMUM,
"tap::sr::rational needs DspTap 0.1.0 or newer (submodules/dsptap)");
2 changes: 1 addition & 1 deletion submodules/dsptap
27 changes: 22 additions & 5 deletions tests/family/version_macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,49 @@
// D13 (PLAN.md): one family version, TAP_SR_VERSION_*, defined
// in each engine's umbrella header with no shared header (so the engines
// stay independent, 4.2 check 1). The three definitions must agree, and
// this is the family's pinned release. Compile-only: its static_asserts are the
// test (tests/CMakeLists.txt builds this target as family.VersionMacrosAgree).
// this is the family's pinned release. The same holds for the DspTap floor
// (the roadmap's A9): TAP_SR_DSPTAP_MINIMUM, defined in each umbrella header,
// must agree, be the release the root README's tested pairs name, and not
// exceed the pinned substrate's TAP_DSP_VERSION. Compile-only: its
// static_asserts are the test (tests/CMakeLists.txt builds this target as
// family.VersionMacrosAgree).
#include "tap/sr/async/async.h"

namespace {
constexpr int k_async_major = TAP_SR_VERSION_MAJOR;
constexpr int k_async_minor = TAP_SR_VERSION_MINOR;
constexpr int k_async_patch = TAP_SR_VERSION_PATCH;
constexpr int k_async_dsptap_minimum = TAP_SR_DSPTAP_MINIMUM;
constexpr int k_async_major = TAP_SR_VERSION_MAJOR;
constexpr int k_async_minor = TAP_SR_VERSION_MINOR;
constexpr int k_async_patch = TAP_SR_VERSION_PATCH;
} // namespace

#undef TAP_SR_VERSION_MAJOR
#undef TAP_SR_VERSION_MINOR
#undef TAP_SR_VERSION_PATCH
#undef TAP_SR_DSPTAP_MINIMUM
#include "tap/sr/bridge/ratio.h"

static_assert(k_async_dsptap_minimum == TAP_SR_DSPTAP_MINIMUM,
"TAP_SR_DSPTAP_MINIMUM must be identical in async.h and ratio.h (A9)");

static_assert(k_async_major == TAP_SR_VERSION_MAJOR && k_async_minor == TAP_SR_VERSION_MINOR
&& k_async_patch == TAP_SR_VERSION_PATCH,
"TAP_SR_VERSION_* must be identical in async.h and ratio.h (D13)");

#undef TAP_SR_VERSION_MAJOR
#undef TAP_SR_VERSION_MINOR
#undef TAP_SR_VERSION_PATCH
#undef TAP_SR_DSPTAP_MINIMUM
#include "tap/sr/rational/rational.h"

static_assert(k_async_dsptap_minimum == TAP_SR_DSPTAP_MINIMUM,
"TAP_SR_DSPTAP_MINIMUM must be identical in async.h and rational.h (A9)");

static_assert(k_async_major == TAP_SR_VERSION_MAJOR && k_async_minor == TAP_SR_VERSION_MINOR
&& k_async_patch == TAP_SR_VERSION_PATCH,
"TAP_SR_VERSION_* must be identical in async.h and rational.h (D13)");
static_assert(k_async_major == 0 && k_async_minor == 6 && k_async_patch == 0,
"the family version is 0.6.0 (D13); re-pin here when it is bumped");
static_assert(k_async_dsptap_minimum == TAP_DSP_VERSION_ENCODE(0, 1, 0),
"the family's DspTap floor is 0.1.0 (A9); re-pin here, and in the root README's tested pairs, "
"when it moves");
static_assert(TAP_DSP_VERSION >= k_async_dsptap_minimum, "the pinned DspTap is older than the family's floor");
Loading