Skip to content

About

Closed-loop, measurement-driven drum lug balancing

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

LugBalance

CI Python 3.11+ License: MIT

LugBalance turns measured tuning rounds into one bounded adjustment and a remeasurement checkpoint

Measure. Nudge. Remeasure. Let your own drum teach the model.

简体中文 · Session specification · Repair guide · Research

LugBalance is an offline command-line tool that turns repeated near-lug frequency measurements into an explainable next tuning step. It starts after your tuner has produced readings. One declared adjustment followed by another measurement round teaches a small circular response model how this head moved. LugBalance then emits one bounded action—or the exact evidence gate that says it should not.

No audio capture. No account. No cloud. No universal drum-response preset.

Why this exists

“The low lug should be tightened” sounds obvious until the neighboring and opposite readings move too. Existing drum tuners are good at measuring pitch and matching lugs. LugBalance owns the next question: given what the last small turn actually did across the whole head, what is the smallest useful experiment now?

The feedback loop is deliberately closed:

measure all lugs -> record a small turn -> measure all lugs again
        ^                                      |
        |        one bounded recommendation   |
        +--------------------------------------+

It never produces an open-loop recipe. After every recommendation, remeasure.

Try the real example

Install uv, clone the repository, then run:

uv sync --locked --dev
uv run lugbalance validate examples/calibrated-session.json
uv run lugbalance analyze examples/calibrated-session.json
uv run lugbalance recommend examples/calibrated-session.json
uv run lugbalance compile examples/calibrated-session.json demo-output

The recommendation is calculated from the two rounds in the file:

RECOMMEND: loosen lug 2 by 0.125 turn
Current RMS: 6.375 cents
Predicted RMS: 4.340 cents
Predicted improvement: 2.035 cents
Fit RMSE: 0.000 cents
Remeasure every lug before another adjustment.

The clean-install path uses the wheel from the latest GitHub Release:

python -m pip install lugbalance-0.1.0-py3-none-any.whl
lugbalance version
lugbalance recommend calibrated-session.json

Session format

A session contains 4-16 readings per round. Positive turns mean tighten; negative turns mean loosen. Every non-final round declares exactly what changed before the next complete measurement round.

{
  "schema_version": 1,
  "name": "Eight-lug practice head",
  "target_hz": 240.0,
  "tolerance_cents": 5.0,
  "max_fit_rmse_cents": 2.0,
  "rounds": [
    {
      "id": "baseline",
      "readings_hz": [238.893523, 241.669332, 239.446122, 240.416249,
                      239.031553, 240.277419, 240.694149, 239.861411],
      "next_adjustment_turns": [0.125, 0, 0, 0, 0, 0, 0, 0]
    },
    {
      "id": "after-lug-1-probe",
      "readings_hz": [240.277419, 242.018568, 239.532581, 240.416249,
                      238.997038, 240.277419, 240.781059, 240.208034]
    }
  ]
}

Input is strict by design: UTF-8 JSON only, 2 MiB maximum, unknown and duplicate keys rejected, positive finite frequencies, equal vector lengths, and at most half a turn recorded per lug in one transition.

What the model proves

For each transition, LugBalance converts Hz changes to cents and groups applied turns by circular distance from each measured lug. It solves for one influence coefficient per distance class. Before using that model, it checks:

  • the design matrix has full rank—regularization never disguises missing evidence;
  • fitted residual RMSE stays under the session's declared limit;
  • one single-lug or same-direction opposite-pair action of at most 1/4 turn predicts the configured minimum RMS improvement.

If any check fails, the result is NEEDS_CALIBRATION, MODEL_TOO_NOISY, or NO_IMPROVING_ACTION, with no adjustment attached.

Commands and exit codes

Command Purpose
lugbalance validate SESSION Validate the strict session contract.
`lugbalance analyze SESSION [--format text json]`
`lugbalance recommend SESSION [--format text json]`
lugbalance compile SESSION OUTPUT_DIR Atomically write the evidence bundle.
lugbalance version Print the installed version.

Exit 0 means validation succeeded, every lug is within tolerance, or a bounded recommendation/report was emitted. Exit 1 means invalid input, I/O, usage, or output collision. Exit 2 means valid evidence is not at the goal and cannot emit an accepted action yet. Existing output directories are never overwritten.

Evidence bundle

compile creates a new directory only after the session has parsed and the analysis has completed:

File Use
report.json Versioned machine-readable analysis, model, and action.
lugs.csv Latest reading and deviation per lug.
chart.svg Standalone polar error view.
report.html Self-contained, script-free review report.

All user labels are escaped in SVG/HTML. Compilation occurs in a temporary sibling directory and becomes visible with one rename, so a write failure does not leave a report that looks complete.

Failure-first examples

# Valid measurements, but no response evidence yet (exit 2)
lugbalance recommend examples/needs-calibration.json

# Duplicate keys are rejected before analysis (exit 1)
lugbalance analyze examples/invalid/duplicate-key.json

# Existing output is protected (exit 1)
lugbalance compile examples/calibrated-session.json demo-output

For exact recovery steps, see docs/REPAIR.md.

Development and acceptance

The repository has zero runtime dependencies. The complete release gate is:

uv run python scripts/check.py

It performs locked sync, Ruff lint/format, strict mypy, branch coverage, the native dependency audit, wheel and sdist builds, deterministic demo packaging, and fresh isolated installation/execution of both distributions.

The software gate proves deterministic behavior and packaging. It does not prove subjective sound quality or validate a recommendation on your physical drum. See CONTRIBUTING.md for field-evidence contributions.

Boundary

LugBalance is a local linear planning aid. It is not torque advice, a head or hardware safety guarantee, a substitute for the manufacturer's limits, or a claim that frequency balance alone produces a good sound. Use small changes, stop if hardware behaves abnormally, and remeasure every lug after every step.

License

MIT © 2026 KanadeK.

About

Closed-loop, measurement-driven drum lug balancing

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages