Skip to content

Releases: alexnodeland/auracle

Auracle v0.2.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 14:30
3b14669

The first release under the name Auracle, and the first one that is a
patcher rather than a patchbay with a splice tool behind it. Since 0.1.0 the
instrument gained wiring as a gesture, node identity that survives evolution,
a navigable canvas, destructive verbs you can see and undo, a model that says
what it believes and how sure it is, and an exported picture that is itself a
patch. The prebuilt web bundle is attached below — unzip, python3 serve.py,
play.

Renamed — Ricercar → Auracle

The project is now Auracle (aural + oracle): it listens, it learns, and it
tells you what you are going to like. "Ricercar" was a musician's in-joke that
most people could neither pronounce nor spell.

  • Crates ricercar-*auracle-*, wasm artifacts auracle_wasm*, worklet
    processor auracle-voice, the workspace and every intra-workspace path dep.
  • The wordmark is AURACLE with the final E as the "model is listening"
    light — the same one mark, two jobs the final R used to do.
  • Nothing a player saved is lost, and nothing of theirs is deleted. The
    IndexedDB autosave is now auracle, with an adopt-on-boot chain that reads
    ricercar then evosynth; every ricercar-* / evosynth-* localStorage
    preference is copied to auracle-* at import time, before any of it is read,
    and never overwrites an answer this build already has.
  • Exported patches are .auracle.json, PNG tEXt keyword auracle, SVG
    metadata#auracle-patch. Files exported by any older build still open:
    the JSON path never read the marker (a patch is recognized by its shape), and
    the PNG and SVG readers try the old names after the new one.

Fixed — a hole that stays a hole, a view that cannot be stranded, and a patcher that fits on a laptop

The rest of the closing gate: the dissenting panelist's two named blockers (M2,
M3), the one-line durability bug the chair pulled in on impact (m1), the two
polish items ruled to ship alongside M2 (p4, p5), and the demo gate (M4).

  • An empty socket is named by the node standing in it, not by where that node
    sits.
    placeholderKeys was a set of trace addresses, so it survived exactly
    as long as the addresses did: the client-side rewrite path carried holes
    across by object identity and every StructOp — insert, delete, replace,
    set_mod, swap_mix, at any key in the patch — forgot them. Unplug, then insert
    anything anywhere, and the dashed EMPTY plate silently became a full vco with
    knobs on it. A hole is now keyed by uid, the same identity locks are keyed
    by and for the same reason, so it rides through any edit inside the node that
    moved. Verified in the browser: an insert that does not touch the hole and an
    insert that moves it from node/0/1 to node/0/0/1 both leave it a hole,
    and dropping a source into it clears the mark on the frame the module lands.
  • A hole survives a reload, in holeStore/ui.holes, the same shape and
    the same argument as lockStore/ui.locks — persisting it is only honest
    because it names a node. It also survives ⌘Z/⇧⌘Z, because benchStep carries
    it: pruning gets undo right for free and could never have got redo right.
  • case "committed" files the child's locks — and its holes — under the
    child.
    One line and its twin (m1). The commit reply carries no m.subject
    so it never reaches case "bench", and IDB ended with an entry for the parent
    and none for the patch the player had actually authored: pins evaporating on
    reload for the one patch that mattered most, with the next ⚡ then breeding
    away the routing they meant to hold. Verified end to end through a commit, a
    full page reload, and re-benching the child.
  • Canvas, bank and accessibility tree agree about absence (p4). The IN THIS
    PATCH list printed "vco" and the plate's aria-label said "vco module" about
    a socket the canvas was drawing as empty. All three route through one
    predicate now; the chip is dashed, reads "empty", and carries no θ, because a
    belief about vcos is not a belief about a hole.
  • The EMPTY plate stops shouting (p5). It was inheriting the plate of
    whatever it replaced — up to 240×164 with a recessed control well — giving the
    most visual weight on the panel to the thing that is not there. It renders at
    the narrow 96-unit width, one row tall, title and hint only, no well.
  • Freeform can no longer strand the view, and now says so if it has.
    contentBox() returns the modules' bounding box instead of the layout
    canvas's extent, so a fit is a fit of what is drawn — a persisted layout that
    put every plate at y ≈ 3400 had Home dutifully framing 3744 units of which
    3400 were empty. The minimap reads the same box. applyGrid re-seeds from the
    chain when what is drawn is degenerate, instead of pinning the stranding —
    the one command that looked like a rescue was the one that made the damage
    permanent. A stored layout that places under two thirds of the rack's nodes is
    dropped wholesale rather than applied, and the inheritance test rose from
    "some uid in common" (1 in 18) to the same floor. A reset verb sits in
    the freeform controls, and below 0.30× with a measurably worse-than-chain
    arrangement the frame itself offers it. Measured on a reproduced stranding:
    0.049× → 0.249× at 1280×900, 0.080× → 0.403× at 1700×1000.
  • The patcher fits on a laptop (M4). The docked spec card collapses to a
    single line when it has nothing to describe (and stays one line while armed,
    so a placement in progress never resizes the canvas underneath itself); the
    short-laptop media query's breakpoint moves from 860px to 940px, which is
    where it was always meant to apply — 1280×900 is the plan's own second test
    size; a draggable divider above the strip gives the player the final say,
    the node bank's rail pattern on the other axis, persisted and keyboard-
    operable; and the auto-LOD threshold scales with the frame's height, because
    what makes a knob small in a 364px band is the band, not the patch. Result at
    1280×900: rack frame 295 → 364px, and 5 of 5 stock presets open in
    full detail with knobs (First Bass 0.67, Sub & Sparkle 0.61, Acid Line 0.67,
    Reese 0.44, Anvil 0.67 against a 0.40 threshold) where 5 of 5 opened as
    knob-less block diagrams. At 1700×1000 the frame is 489px, the threshold 0.54,
    and all five are in full detail.
  • The freeform verbs hold their slots (m6, taken because M3 would otherwise
    have made it worse). apply grid used to be display: none outside freeform,
    so entering the mode slid the layout toggle ~100px under the pointer that had
    just pressed it and a second press fired apply grid — a command that
    rewrites every position. Both verbs are now reserved and disabled, and both
    are one word (snap, reset), because two long labels wrapped the group onto
    a second row at 1280 and cost 35px of the very budget M4 is fighting for.

Fixed — the sentinel: a knob outside its range, and everything downstream that believed it

The closing panel's one non-negotiable item, found independently by three
reviewers from three unrelated surfaces: a faceplate reading "SUSTAIN 1200.0
dB", a HELD fragment printing 1e+30 for every parameter, and six cells of
exactly 1e30 inside the raw φ of the persisted observation log.

  • Every continuous site in the grammar has a declared range, and it is now
    written down
    PARAM_DOMAIN, one constant, next to the u01() the prior
    actually samples from. PatchTree::domain_violations reports the sites that
    leave it and PatchTree::clamp_domains pulls them back, both by walking the
    trace rather than matching 26 productions: the trace enumerates exactly
    the continuous sites, by construction, so there is no second table of "which
    fields are knobs" for the next module to be left out of.
  • validate_tree — the WS-1 rider — now speaks about values. It has always
    gated size, depth and modulation depth; it had nothing to say about a knob,
    which is why a value could walk through it into edit_set_tree, into
    finish(), into φ, into the exported PNG's tEXt chunk and into the log.
  • Domains are repaired, ceilings are refused, and the asymmetry is the
    point: a 40-node patch cannot be clamped without deciding what to delete, and
    a knob can be fixed exactly. Refusing would have meant a saved session that
    already contains one becomes an app the player cannot edit their way out of.
    finish() (so every ReplaceTree/InsertTree/SetModTree fragment the
    panel hands in), edit_set_tree_apply, import_patch and the refinement
    boundary all repair; identities survive, so locks and hand-placed positions
    ride through the repair.
  • The featurizer's quarantine caught only audio pathology. sustain = 1e30
    renders fine — the limiter bounds the voice — so it passed the vet and its φ
    became evidence. featurize now refuses an out-of-domain term before the
    render, and refuses a non-finite coordinate after it.
  • Standardizer::fit gained a runaway-column detector — and it is a detector,
    not a trim, because the trim was measured and thrown out.
    One escaped row
    gave amp_sustain a mean of ~1.2e29 and a σ of ~5.5e29, which standardizes
    every real patch to the same place: a dead coordinate the model can never
    learn from while the belief line still prints a contribution for it. The first
    fix was routine winsorization at 2% per tail; the 16-seed paired run took it
    straight back out (+1.877 ± 0.362+0.204 ± 1.347 mean gain, 15/16 → 11/16
    seeds climbing, one seed at −18.2). Trimming a real tail is not free. So the
    shipped rule uses the plain moments unless a column's plain σ exceeds its
    winsorized σ by more than RUNAWAY_RATIO, which makes it a bit-identical no-op
    on clean data by construction rather than by luck. The threshold was measured
    too — a new winsor_ratio example fits 150 clean 48-patch ...
Read more

Ricercar v0.1.0

Choose a tag to compare

@github-actions github-actions released this 30 Jul 16:40
9f1d4ed

What's Changed

  • release: v0.1.0 machinery — tag-triggered web-bundle releases by @alexnodeland in #1

New Contributors

Full Changelog: https://github.com/alexnodeland/ricercar/commits/v0.1.0