Add piano fingering generation and display via pianoplayer, fix silent audio on first load
This commit is contained in:
@@ -44,7 +44,9 @@ export function PracticeView() {
|
||||
isLoadingDocument,
|
||||
} = useAppStore();
|
||||
|
||||
// Pre-warm audio so piano keys respond with minimal latency.
|
||||
// Pre-warm sample loading so piano keys respond with minimal latency.
|
||||
// Sample fetch (CDN) does NOT need a user gesture - just creates an
|
||||
// AudioContext (suspended) and downloads samples in the background.
|
||||
useEffect(() => {
|
||||
syncEngine.audio.load().catch(() => {});
|
||||
const preWarm = () => syncEngine.audio.load().catch(() => {});
|
||||
@@ -52,6 +54,24 @@ export function PracticeView() {
|
||||
return () => document.removeEventListener("pointermove", preWarm);
|
||||
}, []);
|
||||
|
||||
// Wake both audio contexts (Tone.js + smplr) on the FIRST real user gesture.
|
||||
// The pre-warm above creates contexts before any gesture, so browser autoplay
|
||||
// policy keeps them suspended. Without this, no sound ever plays.
|
||||
useEffect(() => {
|
||||
let woken = false;
|
||||
const wake = () => {
|
||||
if (woken) return;
|
||||
woken = true;
|
||||
syncEngine.wakeAudio();
|
||||
};
|
||||
window.addEventListener("pointerdown", wake);
|
||||
window.addEventListener("keydown", wake);
|
||||
return () => {
|
||||
window.removeEventListener("pointerdown", wake);
|
||||
window.removeEventListener("keydown", wake);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Apply theme to <html> element
|
||||
useEffect(() => {
|
||||
document.documentElement.dataset.theme = settings.theme;
|
||||
|
||||
Reference in New Issue
Block a user