piano samples + home polish
Created by: jedmund
Summary
-
Piano voice replaced with real samples. Bundles the Salamander Grand Piano V3 44.1kHz/16-bit pack (CC-BY Alexander Holm) and a new
PianoSamplerthat parses its SFZ, handles<group>release triggers +pitch_keycenterdefaults, and falls back to the nearest region so any key plays. Voice pool usesAVAudioPlayerNode+Varispeed+ per-voice mixer with a PCM-buffer cache. Fixes the "only plays if you slam the key" behavior (previously a voice-allocation race where a finishing fade task would clobber the next note's volume). -
Velocity support.
AudioEngine.playNote(_:velocity:)+ velocity-awareKeyboardContainersugar that maps normalized Y within the key plusUITouch.majorRadius(captured globally via a passiveUIGestureRecognizeron the key window) to MIDI velocity in [40, 120]. Playground, Scale Explorer, Playable Keyboard, and the shared lesson keyboard are migrated. -
Glissando improvements. 48-voice pool, equal-power crossfade between rapid notes (sin/cos ramps over 18ms), ~22ms sample offset on rapid notes to skip the hammer transient, shorter release envelope for rapid voices. Audibly smoother than raw sample retriggers but doesn't fully match GarageBand's glissando — see memory note
project_piano_sampler_glissando.mdfor the full exploration log. - Home polish. Hero card's resume button aligns with the progress ring bottom. Page padding halved (horizontal 40→20) across bento home, track detail, playground gallery; top padding unified to 40. Chip-to-card gap tightened.
-
Side panel dismiss fixes. Background sidebar's X button has a larger tappable frame (36x36, was ~15pt icon-only). Swipe-to-dismiss when
showHandle: false. Opening the Background sidebar fades the home screen to 0 opacity and blocks hit-testing so the user can focus on the wallpaper.
Test plan
-
Play keys in the playground — soft taps should produce sound, held notes should sustain, rapid retriggers shouldn't drop volume -
Velocity: tap a key near its bottom edge (firmer press, more contact) vs the top edge (gentle, less contact) and hear the loudness differ -
Glissando: drag a finger across the keyboard, verify it's perceptibly smoother than a direct sample retrigger; acceptable but not GB-quality -
Change the playground's octave range to the extremes (low=1, high=6) and verify every key plays -
Open the Background sidebar on home, tap X → sidebar dismisses and home fades back in -
Open the Background sidebar, swipe right on the header → dismisses via drag -
Hero card: resume button bottom should line up with the activity ring bottom