Skip to content

Commit

Permalink
refact: rewrite scheduling on practice page
Browse files Browse the repository at this point in the history
  • Loading branch information
threedalpeng committed Feb 26, 2024
1 parent 87a70b8 commit 90aed68
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 67 deletions.
3 changes: 2 additions & 1 deletion src/lib/guitar/finger-board/FingerBoard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
end: 12,
visibility: 'start'
};
let range = Object.assign(
$: range = Object.assign(
{
start: 0,
end: 12,
Expand Down
1 change: 0 additions & 1 deletion src/lib/practice/RandomBox/RandomBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export class RandomBox<T> {
return this.#items;
}
set items(value: T[]) {
console.log(value);
this.#items = value;
this.init();
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/practice/RandomBox/RandomBoxProvider.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
const randomBox = setRandomBoxContext(new RandomBox<T>(items));
$: randomBox.items = items;
console.log(randomBox);
onDestroy(() => {
randomBox.destroy();
});
Expand Down
15 changes: 10 additions & 5 deletions src/routes/practice/(practice)/[category]/[slug]/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
<script lang="ts">
import MetronomeProvider from '$/lib/device/metronome/MetronomeProvider.svelte';
import RandomBoxProvider from '$/lib/practice/RandomBox/RandomBoxProvider.svelte';
import { TempoTimer } from '$/lib/timer/tick';
import type { LayoutData } from './$types';
export let data: LayoutData;
$: practice = data.pages.current.practice;
let timer = new TempoTimer();
$: {
timer.bpm = practice.tempo.bpm;
timer.beatPerBar = practice.tempo.beatPerBar;
timer.signatureUnit = practice.tempo.signatureUnit;
}
console.log(timer);
</script>

<MetronomeProvider
bpm={practice.tempo.bpm}
beatPerBar={practice.tempo.beatPerBar}
signatureUnit={practice.tempo.signatureUnit}
>
<MetronomeProvider {timer}>
<RandomBoxProvider items={practice.scores}>
<slot />
</RandomBoxProvider>
Expand Down
103 changes: 43 additions & 60 deletions src/routes/practice/(practice)/[category]/[slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<script lang="ts">
import MetronomeBeats from '$/lib/device/metronome/MetronomeBeats.svelte';
import MetronomeOptions from '$/lib/device/metronome/MetronomeOptions.svelte';
import MetronomePlayButton from '$/lib/device/metronome/MetronomePlayButton.svelte';
import { getMetronomeContext } from '$/lib/device/metronome/context';
import type { OnBarCallback, OnOptionChangeCallback } from '$/lib/device/metronome/metronome';
import FingerBoard, {
type FingerInfo,
type FingerPosition
Expand All @@ -12,8 +10,8 @@
import { getRandomBoxContext } from '$/lib/practice/RandomBox/context';
import type { PracticeScore } from '$/lib/practice/types';
import { getPitchFromFingerPosition, numberingPitch } from '$/utils/music/pitch';
import MetronomePlayButton from '$lib/device/metronome/MetronomePlayButton.svelte';
import { CacheStorage, Soundfont } from 'smplr';
import { onDestroy, onMount } from 'svelte';
import type { PageData } from './$types';
export let data: PageData;
Expand All @@ -23,15 +21,31 @@
const randomBox = getRandomBoxContext<PracticeScore>();
const timer = metronome.timer;
$: score = replaceScore();
$: fretRange = score.fretRange;
$: practice, (score = replaceScore());
$: console.log(score);
let isRunning: boolean = metronome.isRunning;
$: currentScore = practice.scores[0];
$: fretRange = currentScore.fretRange;
$: currentBoard = currentScore.boards[0];
let currentActiveFingers = new Set<number>();
let nextNotes: number[] = [];
$: fingers = (currentBoard?.fingers ?? []).map((finger) => {
const order = nextNotes.findIndex((f) => f === finger);
return {
position: currentScore.positions[finger],
style: {
color: currentActiveFingers.has(finger) ? 'red' : undefined
// scale: currentActiveFingers.has(finger) ? 1 : order >= 0 ? (4 - order) / 4 : 0.5
}
};
}) as FingerInfo[];
let guitarSoundfont: Soundfont | null = null;
$: practice,
(() => {
currentScore = replaceScore();
})();
function replaceScore() {
let score = randomBox.open();
const schedule = () => {
const cancel = timer.beforeStart(async () => {
if (!guitarSoundfont) {
guitarSoundfont = new Soundfont(timer.audioCtx!!, {
instrument: 'acoustic_guitar_steel',
Expand All @@ -40,48 +54,32 @@
}
// preload soundfont
guitarSoundfont.load.then(() => {
metronome.clearSchedule();
metronome.schedule();
console.count('afterload');
currentScheduleIdList.forEach((id) => {
timer.cancelSchedule(id);
});
scheduleScore(score);
cancel();
});
};
timer.onStart(schedule);
});
return score;
}
$: currentBoard = score.boards[0];
let currentActiveFingers = new Set<number>();
let nextNotes: number[] = [];
$: fingers = (currentBoard?.fingers ?? []).map((finger) => {
const order = nextNotes.findIndex((f) => f === finger);
return {
position: score.positions[finger],
style: {
color: currentActiveFingers.has(finger) ? 'red' : undefined
// scale: currentActiveFingers.has(finger) ? 1 : order >= 0 ? (4 - order) / 4 : 0.5
}
};
}) as FingerInfo[];
let guitarSoundfont: Soundfont | null = null;
let currentScheduleIdList: number[] = [];
function scheduleScore(score: PracticeScore) {
/** Now scheduling */
// 1. board replacement
score.boards.map((board) => {
timer.onTimeAfter(
board.time,
() => {
const boardScheduleId = timer.scheduleOnTempo({
time: board.time,
animation: () => {
console.log('replace board');
currentActiveFingers.clear();
currentBoard = board;
},
({ audioCtx }) => {
// guitarSoundfont!!.start({
// note: 50 + 12
// });
}
);
});
currentScheduleIdList.push(boardScheduleId);
});
// 2. notes
Expand All @@ -96,18 +94,19 @@
for (let i = 0; i < notes.length; i++) {
const note = notes[i];
const nextThreeFingers = notes.slice(i + 1, i + 4).map((n) => n.position);
timer.onTimeAfter(
note.time,
() => {
const noteScheduleId = timer.scheduleOnTempo({
time: note.time,
animation: () => {
currentActiveFingers.add(note.position);
currentActiveFingers = currentActiveFingers;
nextNotes = nextThreeFingers;
return () => {
console.log('?');
currentActiveFingers.delete(note.position);
currentActiveFingers = currentActiveFingers;
};
},
({ audioCtx, time }) => {
audio: ({ audioCtx, time }) => {
// play audio with pitch
if (note.pitch) {
guitarSoundfont!!.start({
Expand All @@ -119,26 +118,10 @@
});
}
}
);
});
currentScheduleIdList.push(noteScheduleId);
}
}
onMount(() => {
metronome.onBar(onMetronomeBar);
metronome.onOptionChange(onMetronomeOptionChange);
});
onDestroy(() => {
metronome.removeBar(onMetronomeBar);
metronome.removeOptionChange(onMetronomeOptionChange);
});
const onMetronomeBar: OnBarCallback = () => {
// score = replaceScore();
};
const onMetronomeOptionChange: OnOptionChangeCallback = ({ bpm }) => {
// timer.tickIntervalMs = calcTickIntervalMs(bpm);
};
</script>

<div class="h-full w-screen">
Expand Down

0 comments on commit 90aed68

Please sign in to comment.