feat/sample editor - #21
Open
DavidMenting wants to merge 24 commits into
Open
Conversation
DavidMenting
commented
Jul 8, 2026
Member
- Rework sample recorder trim and controls
- Dim tracks that do not hold the selected note
- feat(midi): implement SDS download protocol and transfer locking
- refactor(ui): clean up redundant controls and mount SettingsModal
- i18n: add translations for settings modal and SDS downloads
- feat(recorder): auto-download device sample on pad selection
- ci: configure GitHub Actinos deployment to GitHub Pages
- Make the yellow trim bars in the waveform draggable (with center handle circles), replacing the horizontal start/end sliders - Merge record and record-again into one round button left of the waveform; first press opens the microphone and records immediately, removing the separate turn-on-microphone button - Keep play and save buttons always visible (disabled when unusable), play/save now sit right of the gain slider - Add browse and factory-reset buttons next to the record button; both load audio into the capture buffer for trim/gain adjustment before saving to the device - Extract FACTORY_SAMPLES map to shared config - SampleCapture: add load() for external buffers, playback without an open mic stream, reset() falls back to idle - Move mic selector below the buttons; drop unused locale keys
DavidMenting
force-pushed
the
feat/sample-editor
branch
from
July 8, 2026 09:24
de7bf5b to
b2542b3
Compare
DavidMenting
had a problem deploying
to
github-pages
July 8, 2026 09:24 — with
GitHub Actions
Failure
DavidMenting
had a problem deploying
to
github-pages
July 8, 2026 09:25 — with
GitHub Actions
Failure
…ith velocity >= 120
Pad selection now loads instantly from an in-memory cache (device downloads, uploads, and preloaded factory samples). The ~1s SDS device download on selection is gated behind a new 'downloadOnSelect' feature flag (default off) so we can evaluate whether factory preload alone is good enough.
Gives the device time to finish playing back the sample before the transfer freezes the sequencer. The wait is abortable, so switching pads during the delay cancels it immediately.
Timer handle in the browser isn't a number under this env's DOM lib config, causing a type-check error.
…napshots prevSelectedSampleIndex/prevContainerWidthPx intentionally snapshot the initial value and are updated inside the effect below, which is the pattern Svelte's warning otherwise flags as a mistake.
Deduplicate the decode -> stereo-to-mono -> resample logic that lived in both SampleRecorder.loadIntoBuffer and sampleCache.doPreload into a single decodeToMono() in audioAnalysis. Factory samples now cache at their native rate (rate is stored and consumers resample on load).
Remove the hidden mode switch in load() (adopt rate when no context, throw on mismatch otherwise). load() now resamples any incoming rate to capture.sampleRate itself, so callers no longer pre-resample by convention.
Collapse the two near-identical load paths into one loadIntoEditor with
an explicit trim policy ('auto' | 'full'); file decoding and the
MAX_LOAD_S cap live in loadFileIntoEditor, the file-input wrapper.
downloadState no longer duplicates the sample data (nobody read it); results flow through the downloadSample promise only. Caching a completed download moves into the store, where download knowledge belongs, instead of the recorder's effect.
…ader Move the cache -> maybe-download -> maybe-load policy out of the SampleRecorder $effect into a plain component-free function that can be reasoned about and tested without mounting the component. The effect now only detects slot changes and delegates.
…ckets Two receive-path bugs: - Messages arriving between waitForIncoming() calls were dropped (only a single one-shot resolver existed), causing spurious 2s timeouts when the device sends packets back-to-back. Incoming download messages are now queued when no waiter is armed and drained in order. - expectedPacketNum was computed but never checked, so an out-of-order packet (other than an exact duplicate of the last) was silently written at the wrong buffer offset, corrupting the sample. Out-of-order packets are now NAKed with the expected packet number. waitForIncoming is also abort-aware now: an AbortSignal resolves the wait immediately with 'aborted' instead of blocking until the timeout.
downloadSample aborted the previous download and then immediately checked isTransferActive() — but the aborted transfer only releases the lock in its finally, which hadn't run yet, so rapid pad-switching made the new download silently bail. The in-flight promise is now tracked and awaited after abort (fast, since waits are abort-aware) before the lock check.
lastLoadedSlot was set before the recording/isSaving guard, so a pad selected mid-recording was permanently marked as loaded and never got its sample loaded afterwards. The slot is now only marked once the load actually proceeds.
- i18n the hardcoded Browse/Reset button labels in SampleRecorder (new recorder_browse/recorder_reset keys in en/de/nl) - SettingsModal closes on Escape and backdrop click - remove unused download_empty_slot/download_timeout locale keys - remove dead downloadState import from Voice
…play triangle for play button
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.