diff --git a/front/Navigation.tsx b/front/Navigation.tsx index ac8d024..5255564 100644 --- a/front/Navigation.tsx +++ b/front/Navigation.tsx @@ -25,8 +25,8 @@ import TextButton from './components/TextButton'; const protectedRoutes = () => ({ Home: { component: HomeView, options: { title: translate('welcome'), headerLeft: null } }, - Settings: { component: SetttingsNavigator, options: { title: 'Settings' } }, Play: { component: PlayView, options: { title: translate('play') } }, + Settings: { component: SetttingsNavigator, options: { title: 'Settings' } }, Song: { component: SongLobbyView, options: { title: translate('play') } }, Score: { component: ScoreView, options: { title: translate('score'), headerLeft: null } }, Search: { component: SearchView, options: { title: translate('search') } }, diff --git a/front/components/PartitionView.tsx b/front/components/PartitionView.tsx index dd022b8..3d5c593 100644 --- a/front/components/PartitionView.tsx +++ b/front/components/PartitionView.tsx @@ -52,6 +52,21 @@ const PartitionView = (props: PartitionViewProps) => { return duration; } + const playNotesUnderCursor = () => { + osmd!.cursor.NotesUnderCursor() + .filter((note) => note.isRest() == false) + .filter((note) => note.Pitch) // Pitch Can be null, avoiding them + .forEach((note) => { + // Put your hands together for https://github.com/jimutt/osmd-audio-player/blob/master/src/internals/noteHelpers.ts + const fixedKey = note.ParentVoiceEntry.ParentVoice.Parent.SubInstruments.at(0)?.fixedKey ?? 0; + const midiNumber = note.halfTone - fixedKey * 12; + let duration = getActualNoteLength(note); + const gain = note.ParentVoiceEntry.ParentVoice.Volume; + console.log('Expecting ' + midiNumber); + soundPlayer!.play(midiNumber, audioContext.currentTime, { duration, gain }) + }); + } + useEffect(() => { const _osmd = new OSMD(OSMD_DIV_ID, options); Promise.all([ @@ -60,11 +75,12 @@ const PartitionView = (props: PartitionViewProps) => { ]).then(([player, __]) => { setSoundPlayer(player); _osmd.render(); + _osmd.cursor.hide(); // Ty https://github.com/jimutt/osmd-audio-player/blob/ec205a6e46ee50002c1fa8f5999389447bba7bbf/src/PlaybackEngine.ts#LL77C12-L77C63 const bpm = _osmd.Sheet.HasBPMInfo ? _osmd.Sheet.getExpressionsStartTempoInBPM() : 60; setWholeNoteLength(Math.round((60 / bpm) * 4000)) props.onPartitionReady(); - _osmd.cursor.show(); + // Do not show cursor before actuall start }); setOsmd(_osmd); }, []); @@ -73,7 +89,9 @@ const PartitionView = (props: PartitionViewProps) => { useEffect(() => { if (osmd && osmd.IsReadyToRender()) { osmd.render(); - osmd.cursor.show(); + if (!osmd.cursor.hidden) { + osmd.cursor.show(); + } } }, [dimensions]) @@ -81,6 +99,11 @@ const PartitionView = (props: PartitionViewProps) => { if (!osmd || !soundPlayer) { return; } + if (props.timestamp > 0 && osmd.cursor.hidden && !osmd.cursor.iterator.EndReached) { + osmd.cursor.show(); + playNotesUnderCursor(); + return; + } let previousCursorPosition = -1; let currentCursorPosition = osmd.cursor.cursorElement.offsetLeft; while(!osmd.cursor.iterator.EndReached && @@ -89,25 +112,13 @@ const PartitionView = (props: PartitionViewProps) => { ) { previousCursorPosition = currentCursorPosition; osmd.cursor.next(); - osmd.cursor.show(); if (osmd.cursor.iterator.EndReached) { osmd.cursor.hide(); // Lousy fix for https://github.com/opensheetmusicdisplay/opensheetmusicdisplay/issues/1338 + soundPlayer.stop(); props.onEndReached(); } else { // Shamelessly stolen from https://github.com/jimutt/osmd-audio-player/blob/ec205a6e46ee50002c1fa8f5999389447bba7bbf/src/PlaybackEngine.ts#LL223C7-L224C1 - osmd.cursor.NotesUnderCursor() - .filter((note) => note.isRest() == false) - .filter((note) => note.Pitch) // Pitch Can be null, avoiding them - .forEach((note) => { - // Put your hands together for https://github.com/jimutt/osmd-audio-player/blob/master/src/internals/noteHelpers.ts - const fixedKey = note.ParentVoiceEntry.ParentVoice.Parent.SubInstruments.at(0)?.fixedKey ?? 0; - const midiNumber = note.halfTone - fixedKey * 12; - let duration = getActualNoteLength(note); - const gain = note.ParentVoiceEntry.ParentVoice.Volume; - // console.log(midiNumber, duration, gain); - soundPlayer.play(midiNumber, audioContext.currentTime, { duration, gain }) - - }); + playNotesUnderCursor(); currentCursorPosition = osmd.cursor.cursorElement.offsetLeft; document.getElementById(OSMD_DIV_ID).scrollBy(currentCursorPosition - previousCursorPosition, 0) } diff --git a/front/views/PlayView.tsx b/front/views/PlayView.tsx index 2549eb1..118cbec 100644 --- a/front/views/PlayView.tsx +++ b/front/views/PlayView.tsx @@ -109,7 +109,7 @@ const PlayView = ({ songId, type, route }: RouteProps) => { return; } const points = data.info.score; - const maxPoints = data.info.maxScore; + const maxPoints = data.info.maxScore || 1; setScore(Math.floor(Math.max(points, 0) / maxPoints) * 100); @@ -154,6 +154,7 @@ const PlayView = ({ songId, type, route }: RouteProps) => { input.onmidimessage = (message) => { const keyIsPressed = message.data[2] == 100; const keyCode = message.data[1]; + console.log(`${keyIsPressed ? 'Pressing' : 'Releasing'} ` + keyCode); webSocket.current?.send(JSON.stringify({ type: keyIsPressed ? "note_on" : "note_off", note: keyCode, @@ -171,7 +172,7 @@ const PlayView = ({ songId, type, route }: RouteProps) => { useEffect(() => { ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE).catch(() => {}); let interval = setInterval(() => { - setTime(() => stopwatch.getElapsedRunningTime()) + setTime(() => stopwatch.getElapsedRunningTime() - 3000) // Countdown }, 1); return () => { @@ -199,7 +200,7 @@ const PlayView = ({ songId, type, route }: RouteProps) => { setPartitionRendered(true)} - timestamp={time} + timestamp={Math.max(0, time)} onEndReached={() => { onEnd(); navigation.navigate('Score', { songId: song.data.id }); @@ -268,8 +269,15 @@ const PlayView = ({ songId, type, route }: RouteProps) => { } onPress={() => { setVirtualPianoVisible(!isVirtualPianoVisible); }}/> - {Math.floor(time / 60000)}:{Math.floor((time % 60000) / 1000).toFixed(0).toString().padStart(2, '0')} - + { time < 0 + ? paused + ? '0:00' + : Math.floor((time % 60000) / 1000).toFixed(0).toString() + : `${Math.floor(time / 60000)}:${Math.floor((time % 60000) / 1000).toFixed(0).toString().padStart(2, '0')}` + } + + } onPress={() => { onEnd();