Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Audio Validate

ASecurity

Validates a change to the audio output path against measured on-device ground truth. Use after any change to FIR generation, gain staging, filter parameters, or the EasyEffects / PipeWire output chain, before adopting or shipping it — and whenever the user asks to "test on device", "capture the EE response", "compare against DAX", or confirm a change didn't regress audibly. This skill gates on an audio handoff and drives the live-EE capture → DAX/EE compare → listening route end-to-end. Do NO...

141 stars
0 votes
0 copies
0 views
Added 10/6/2026
testingpythonrustgobashnodegit

Works with

cli

Security Analysis

A100/100

Scanned 10/6/2026

$npx -y skills add antoinecellerier/speaker-tuning-to-easyeffects --skill audio-validate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Audio Validate?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Audio Validate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/antoinecellerier-audio-validate/badge)](https://www.skillsdirectory.com/skills/antoinecellerier-audio-validate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: audio-validate
description: >-
  Validates a change to the audio output path against measured on-device ground
  truth. Use after any change to FIR generation, gain staging, filter
  parameters, or the EasyEffects / PipeWire output chain, before adopting or
  shipping it — and whenever the user asks to "test on device", "capture the EE
  response", "compare against DAX", or confirm a change didn't regress audibly.
  This skill gates on an audio handoff and drives the live-EE capture → DAX/EE
  compare → listening route end-to-end. Do NOT run tools/measure_ee/ scripts or
  any live capture outside this gated flow.
---

# audio-validate

The pytest suite catches structural regressions, not audible ones. Every
change to the audio output path is decided on **measured on-device ground
truth**, DAX captures plus a live-EasyEffects loopback, not on offline math.
This skill runs that validation safely and reports a verdict.

Linux EE capture lives in `tools/measure_ee/`, and Windows DAX capture with
the shared `analyze.py` in `tools/measure_dax/`. Before running, read
`tools/measure_ee/README.md` for the exact current invocations and flags. The
commands below show the shape of the flow, not a frozen copy. Default all
output dirs to `./localresearch/measure_ee/`, never `~/` or `/tmp/`. That tree
is gitignored.

## 0. Offline pre-screen (optional, never decisive)

When comparing several variants, run `compare_ee_analytical.py` first to
narrow the set. Offline analytical scoring, from the FIR magnitude and the
biquad chain model, **only predicts direction**: it ignores the dynamics
stages and real hardware. Never adopt a change on offline metrics alone.

## 1. Audio-handoff gate — STOP here first

Before running ANY tooling below, **ask the user to take over audio**: "I'm
about to run the EE capture route — it mutes your speakers, reroutes sinks,
restarts EasyEffects, and plays a stimulus battery. Ready for me to take over
audio?" Wait for an explicit yes. These scripts disrupt the live session, and
an unannounced interruption can leave routing broken.

## 2. Capture-validity check

- DAX captures are converter-independent ground truth, so they stay valid
  across `dolby_to_easyeffects.py` edits. Reuse the existing ones.
- **EE-side captures go stale** after any FIR, scaling or gain change to the
  converter. If the EE capture you'd compare against predates the change under
  test, regenerate it with steps 3–4 before comparing. Otherwise the diff
  measures the old preset.

## 3. Live-EE capture route

1. Run `bash tools/measure_ee/setup_null_sink.sh`. It loads
   `module-null-sink ee_capture`, points
   `~/.config/easyeffects/db/easyeffectsrc` at it with
   `outputDevice=ee_capture` and `useDefaultOutputDevice=false`, and restarts
   EE. EE 8.x reads `db/easyeffectsrc`, not the legacy top-level file. The mic
   indicator pops once on restart, as expected.
2. **Smoke-gate the route** with a bypass preset before trusting any capture:
   `python3 tools/measure_ee/smoke.py --target ee_capture.monitor`. Expect
   PASS, with gain ~0 dB, flatness < 0.5 dB and residual < −35 dB. If smoke
   fails, stop and diagnose the route instead of running the battery.
   `smoke.py` does the `pw-record --target 0` and the manual `pw-link` itself,
   because WirePlumber treats `--target` as a hint and would otherwise reroute
   to the mic.
3. Run the battery with the real preset:
   `python3 tools/measure_ee/capture_battery.py --preset <Name> --target ee_capture.monitor --out-dir ./localresearch/measure_ee/ee_captures …`.
4. Play no other audio during a capture, because anything hitting
   `easyeffects_sink` contaminates the measurement. The sample rate is locked
   at 48 kHz.

## 4. Compare

- Run `analyze.py` on the EE captures, then
  `python3 tools/measure_ee/compare_ee_vs_dax.py --ee-dir … --dax-dir …` for
  the frequency-domain overlay. Use `compare_ir_time_domain.py` for envelope
  and peak.
- Judge on the measured **EE−DAX** and EE−XML result across all bands, not a
  single number.

## 5. Listening pass

Tell the user what to listen for, based on what the change touched, from
this symptom → past-trap checklist:

- clipping / level jumps (convolver autogain +50 dB, MBC output-gain)
- pumping on quiet→loud transitions (why autogain is bypassed)
- ripple / muddy mids / harsh highs (parametric-bell IEQ stacking)
- loudness loss (over-conservative PEQ output-gain / headroom)
- noise-floor boost in silence (LSP MBC upward-compression)

Confirm audio quality with the user. The meter and the ear are both required
to sign off.

## 6. Restore audio

1. Always run `bash tools/measure_ee/teardown.sh`, including on failure, so
   the user's speakers come back. It restores the db rc from backup and
   unloads the null sink.
2. Verify that EE rebuilt its pipeline, not just that it runs:
   `pw-link -l | grep ee_soe_output_level` must show links into the speaker
   sink. If they're missing, restart EE once more after the graph has settled.

A live process, a listed sink and a correct rc are **not restored** audio; the
output links are. An EE restarted amid graph churn, as sinks and chains are
torn down around it, can come up with `easyeffects_sink` present but no
processing graph behind it. That sink is a silent black hole: it swallows
every app routed to it, while short event sounds on the raw default sink still
play. It once cost the user ~40 min of app audio after a teardown.

## Dead ends — don't retry (capture route)

Each was ruled out in an earlier session, and `smoke.py` encodes the working
fix:

- `pw-record --target=easyeffects_sink` / `easyeffects_source`, or
  `-P node.target=` / `target.object=`: WirePlumber policy overrides them all
  and reroutes to the mic. `easyeffects_sink:monitor` is the *pre*-processing
  port anyway. Only `--target 0` plus a manual `pw-link` works.
- For repeated preset switches, use `easyeffects -l <name>`, which doesn't pop
  the mic indicator. Only a `--service-mode` restart pops it. That reload also
  picks up a regenerated FIR, because the kernel name carries a content hash.

`lv2apply` and `module-filter-chain` are not dead ends. Both host the LSP/Calf
plugins this project uses, as tested on 2026-08-19, and `work:schedule` is
optional for them. Calf Saturator aborts at teardown *after* a complete render,
so validate an offline render by its frame count, as
`tools/measure_ee/render_vbe_chain.py` does. Offline renders stay a
pre-screen, not a validation.

## Report

State what changed, the measured EE−DAX and EE−XML deltas with the plots
written under `./localresearch/measure_ee/`, the listening result, and a clear
adopt / reject / needs-more-data verdict. If you only got to the offline
pre-screen, say so: that is not a validation.

Attribution

antoinecellerierantoinecellerier
View sourceSee grades on GitHubMore from antoinecellerier →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Screen Reader Testing

Practical guide to testing web applications with screen readers for comprehensive accessibility validation.

401991 votes

Tdd Workflow

在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,包含单元测试、集成测试和端到端测试,覆盖率超过80%。

2456590 votes

Eval Harness

克劳德代码会话的正式评估框架,实施评估驱动开发(EDD)原则

2456590 votes

Python Testing

使用pytest、TDD方法、夹具、模拟、参数化和覆盖率要求的Python测试策略。

2456590 votes

Django Tdd

Django测试策略,包括pytest-django、TDD方法论、factory_boy、模拟、覆盖率以及测试Django REST Framework API。

2456590 votes
View all in testing →