Front: Partition: Prevent skip of first note

This commit is contained in:
Arthur Jamet
2023-05-06 14:18:18 +01:00
parent 8a3d4f9c25
commit ae4d1f00d9
3 changed files with 41 additions and 22 deletions
+1 -1
View File
@@ -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') } },
+27 -16
View File
@@ -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)
}
+13 -5
View File
@@ -109,7 +109,7 @@ const PlayView = ({ songId, type, route }: RouteProps<PlayViewProps>) => {
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<PlayViewProps>) => {
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<PlayViewProps>) => {
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<PlayViewProps>) => {
<View style={{ flexGrow: 1, justifyContent: 'center' }}>
<PartitionView file={musixml.data}
onPartitionReady={() => 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<PlayViewProps>) => {
} onPress={() => {
setVirtualPianoVisible(!isVirtualPianoVisible);
}}/>
<Text>{Math.floor(time / 60000)}:{Math.floor((time % 60000) / 1000).toFixed(0).toString().padStart(2, '0')}</Text>
<IconButton size='sm' colorScheme='coolGray' variant='solid' opacity={time ?? 1} disabled={time == 0} icon={
<Text>
{ 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')}`
}
</Text>
<IconButton size='sm' colorScheme='coolGray' variant='solid' icon={
<Icon as={Ionicons} name="stop"/>
} onPress={() => {
onEnd();