npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@miadi/ava8-measure

v0.1.0

Published

Read a rendered artefact and hold it to a claim. Standard MIDI decoding with register, mode, drum-position and note-for-note measures; spectral share and f0 over PCM; and OSC movement analysis whose first act is always to drop held values. The family's ot

Readme

@miadi/ava8-measure

Read a rendered artefact and hold it to a claim.

Every other package in the ava8 family writes. @miadi/ava8-core writes MIDI; @miadi/movement-conductor records and summarises a take; @miadi/capture stores one. Nothing read a rendered artefact back and asked whether it is what it said it was.

That is this package.

ESM only. Zero runtime dependencies beyond @miadi/ava8-atelier. No DOM, no filesystem — bytes in, numbers out — so it runs in a browser, in a test, and on a capture device.

npm install @miadi/ava8-measure

The rule that defines it

Read the rendered artefact, never the source. A generator's header states an intention. Three tools sit between that intention and the file, and each has silently changed something at least once: an accidental contaminated its bar and moved a note a semitone; a bare Q: line was ignored so a tempo change existed only in a comment; a container refused a codec and wrote zero bytes while reporting success.

A count that comes out right is not proof. The right number of drum hits can land off the beat. Read placement, not totals.

Three surfaces

| subpath | reads | answers | |---|---|---| | ./midi | Standard MIDI bytes | registers per track and their overlap, band occupancy, duration-weighted pitch classes, mode purity, drum position within the bar, note-for-note and multiset identity between two files | | ./audio | PCM WAV bytes | spectral share in a named band, stridence, f0 by autocorrelation with octave folding, held notes, motif versus drone, recurring interval cells, crossfade seams | | ./movement | OSC capture text | held-value ratio and the real new-value rate, per-second magnitudes, onsets, unwrapped heading, compass sextants, stillness spans |

The first act on a movement capture is always dedupe

A capture requested at 100 Hz delivered 1627 packets in 16.6 s — 98 Hz of packets, of which 1232 were repeats of their predecessor. 395 new values: 23.8 Hz, median gap 41 ms.

Onsets computed on the raw stream returned 28 attacks spaced 120–133 ms: regular, credible, and entirely false. That was the staircase of the held values, not a body. On the deduped stream: 15 attacks, spaced 153 to 1481 ms.

So dedupe is not an option and it is not a filter you may skip. onsets deduplicates by default and reports whether it did.

What the numbers mean, and what they do not

stridence is comparable to itself. It does not reproduce two figures published by the session that invented the method — it reads 15–25 % low against them — because the spectral code was never committed and the candidate renders are gone. Re-measure every candidate rather than quoting a figure from that day. The doc comment says so at the call site, where it is harder to ignore.

onsets reproduces the count and the shape of a published list; 11 of 15 timestamps land within 30 ms and four do not, because that session's peak-picking was never written down.

Movement captures carry no declared units. The capture's own field ledger says the channel semantic map is absent. Numbers are reported without units, and the music is built from ratios, so nothing is lost — but a unit invented here would be a claim nobody can support.

The conformance harness

This package is a port of three Python programs (atelier_midi.py, atelier_audio.py, atelier_movement.py). The port was checked against them — and the checking happened in a scratch directory that is gone, leaving a paragraph in a commit message. A claim nobody can re-run is a claim, not a proof, which is the exact failure this package exists to name, so the check now lives in the repository:

| | | |---|---| | test/fixtures/ | 19 committed fixtures, 195 KB — 8 MIDI, 6 WAV, 5 OSC captures | | test/fixtures/expected-*.json | 356 measurements (276 structural, 80 numeric), all written by the Python | | test/conformance.test.mjs | mirrors every one of them in TypeScript and compares | | scripts/regenerate-fixtures.mjs | rebuilds the corpus and the expected values, end to end |

Those 356 measurements expand to 1741 structural values and 454 numeric ones, because a measurement is often a list: every note of a rendered file as a six-tuple, every voiced frame of an f0 track, every sextant of a walked circle.

Synthetic fixtures only. Every byte of the corpus comes out of a counter or a table in regenerate-fixtures.mjs. No recording, no movement capture, and nothing out of a composition folder is committed, read, or compared against here — consent forbids a person's voice or recordings leaving the device they were made on, and "just to compare" is not an exception. The harness prints synthetic fixtures only on every run.

node --test test/conformance.test.mjs needs no Python and no numpy. It reads the committed JSON. Only regeneration needs the oracle, which is what makes the suite runnable on a host where numpy cannot be imported at all.

Two tiers, and they are not the same claim

Structural results are compared for exact equality: note counts, per-track registers and their overlaps, band occupancy, drum slots and their bar numbers, dedupe counts, onset counts and their rounded times, sextant sequences, heading wraps, stillness spans, held-note boundaries, and the formatted verdict strings. Both programs reach these by integer arithmetic or by a single division of two counts, so a difference is a defect and never a rounding.

Spectral and other accumulated results are compared within a published tolerance — a mean power spectrum, an autocorrelation, a compensated mean, anything summed over many floating-point operations, where the two languages accumulate in a different order:

| | | |---|---| | relative tolerance | 1e-9 | | absolute floor, for values near zero where a ratio says nothing | 1e-12 |

Both numbers live in test/fixtures/tolerances.json and the suite asserts that this table still states them, so the two cannot drift apart.

How they were chosen. The worst relative divergence this corpus actually produces is 1.6e-12 (a spectrum bin), and the worst absolute divergence is 1.4e-14 (an f0 frame in MIDI floats). 1e-9 leaves roughly three orders of magnitude of headroom over that, which absorbs a different libm on a different host without absorbing anything that could change a musical verdict: the stridence thresholds are 0.03 apart, seven orders of magnitude coarser. The run prints the worst divergence it observed, so the headroom is visible rather than asserted.

What the harness deliberately does not encode

The two figures named above under What the numbers mean are absent from the corpus on purpose, and test/conformance.test.mjs records them under NOT_REPRODUCED with the reason rather than leaving a silent hole that would read as coverage:

  • stridence against the session's published 7.60 % and 11.30 % — the spectral code that produced them was never committed and the renders are gone, so a fixture asserting 7.60 % would assert a number no program on this machine can produce. The corpus pins stridence against the Python oracle only: that proves the port agrees with atelier_audio.py, and proves nothing about that day's figures.
  • onsets against the session's fifteen timestamps — its peak-picking was never written down, and the take is a person's movement capture, which may not leave the device it was made on. The corpus pins onsets on a synthetic staircase instead, where the raw stream's three ghost attacks and the deduped stream's three real ones are both committed.

Regenerating

ATELIER_SCRIPTS=/path/to/atelier-jerry/scripts node scripts/regenerate-fixtures.mjs
node --test test/conformance.test.mjs

The first command writes the corpus, then hands it to scripts/oracle.py, which imports the three Python modules and writes the expected values. The TypeScript is never consulted during regeneration — a harness that generated its own expectations would be comparing the port against itself and would prove nothing.

The FFT is hand-written on purpose

About 120 lines of iterative radix-2 Cooley–Tukey over Float64Array. Every call site uses a power-of-two length, so radix-2 covers all of it.

The house builds with tsc and no bundler. A hand-written transform is smaller than the argument about which npm FFT package to trust, and it can be audited in one sitting.

Two details that would silently change every number if they were wrong, and are asserted in the tests: the Hann window is the symmetric one (n-1 in the denominator, as numpy writes it, not the periodic form every tutorial gives), and a band share sums magnitude, not power — power puts every piece under one percent and makes a 13.12 % threshold unreachable by any sound.

What it does not own

| | | |---|---| | the thresholds, the register plan, provenance, consent | @miadi/ava8-atelier | | writing ABC or MIDI | @miadi/ava8-core | | rendering or playing a score | @miadi/ava8-abcjs, @miadi/ava8-react | | recording a take, conducting movement into frames | @miadi/capture, @miadi/movement-conductor | | turning a MIDI into audio | @miadi/jeremyai |

This package measures. It does not decide what the measurement means — that judgement lives in @miadi/ava8-atelier, and the decision itself belongs to a person.