feat(sorting): sound — per-lane tones and a finish chime, with mute and volume - #22
Merged
Merged
Conversation
…alue Lane::last_touch() returns the kind of the most recent op (compare, or write for writes and swaps) and the value it landed on — the larger of a compared/swapped pair, or the value written. The rule summary carries it as last_kind/last_value (null before the first tick) plus the array size, so the lab can voice each lane without the op traces.
…h mute and volume lib/sorting/audio.ts: planAudio() diffs consecutive summaries into per-lane tone/chime/rest events (pure, tested); SortingAudio voices them on Web Audio with one persistent oscillator per lane (sine for compares, triangle for writes, pitch log-mapped over three octaves from the value touched), a throwaway two-note chime when a lane finishes, and a master gain into a compressor so 28 voices stay listenable. Starts muted; the speaker button's click is the gesture that brings the context up. The controls bar gains a speaker toggle and a volume slider (disabled while muted). readSummary() now requires the engine's size/last_kind/ last_value per lane. The shell's bar wraps instead of widening the page.
wasm-bindgen hands the engine's None across as undefined, not null, so the strict null check rejected every lane that had not ticked yet and the whole summary read as null — a single running lane never showed as running and no voices were built until every lane had moved. Accept either and normalize to null. README: describe the sound controls.
- pitchOf maps the engine's 1..=size value range (value 1 is the base
note, value size the top) instead of 0..size-1, which had pinned the
two largest values to the same note and never played the base
- planAudio no longer rests a running lane between ops, so a slow lane's
blip rings out on its own envelope instead of being cut every frame;
rests fire when a lane stops, is rewound, or the summary goes away
- the speaker button keeps a fixed accessible name ("Sound") with
aria-pressed for state, rather than a changing label plus aria-pressed
- the chime's throwaway nodes disconnect themselves once they end
- tests for the no-advance, pause, and rewind cases; docs counts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds sonification to the sorting lab.
Engine (Rust)
Lane::last_touch(): the kind of the most recent op (compare, or write for writes and swaps) and the value it landed onsize,last_kind,last_valueper lane (null before the first tick)Web
lib/sorting/audio.ts:planAudio()diffs consecutive summaries into per-lane tone/chime/rest events (pure);SortingAudiovoices them on Web Audio with one persistent oscillator per lane (sine for compares, triangle for writes, pitch log-mapped over three octaves from the value touched), a two-note chime when a lane finishes, and a master gain into a compressor so 28 voices stay listenablereadSummary()accepts the new fields, treating wasm-bindgen'sundefinedfor a RustNoneas nullTests: 178 Rust, 127 web (17 new for the planner and wrapper against a stub AudioContext, 2 for the controls). Browser-verified: 28 voices build on unmute, a single lane runs with live counters, pitch updates flow, chime fires on finish, no horizontal overflow at 800px.