Merge branch 'main' into feature/adc/#71-create-search-route
This commit is contained in:
+17
-2
@@ -17,13 +17,15 @@ export type AccessToken = string;
|
||||
type FetchParams = {
|
||||
route: string;
|
||||
body?: Object;
|
||||
method?: 'GET' | 'POST' | 'DELETE'
|
||||
method?: 'GET' | 'POST' | 'DELETE',
|
||||
// If true, No JSON parsing is done, the raw response's content is returned
|
||||
raw?: true;
|
||||
}
|
||||
|
||||
const dummyIllustration = "https://i.discogs.com/syRCX8NaLwK2SMk8X6TVU_DWc8RRqE4b-tebAQ6kVH4/rs:fit/g:sm/q:90/h:600/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTgyNTQz/OC0xNjE3ODE0NDI2/LTU1MjUuanBlZw.jpeg";
|
||||
|
||||
// we will need the same thing for the scorometer API url
|
||||
const baseAPIUrl = Platform.OS === 'web' ? '/api' : Constants.manifest?.extra?.apiUrl;
|
||||
const baseAPIUrl = process.env.NODE_ENV != 'development' && Platform.OS === 'web' ? '/api' : Constants.manifest?.extra?.apiUrl;
|
||||
|
||||
export default class API {
|
||||
|
||||
@@ -37,6 +39,9 @@ export default class API {
|
||||
body: JSON.stringify(params.body),
|
||||
method: params.method ?? 'GET'
|
||||
});
|
||||
if (params.raw) {
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
const body = await response.text();
|
||||
|
||||
try {
|
||||
@@ -110,6 +115,16 @@ export default class API {
|
||||
route: `/song/${songId}`
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Retrive a song's midi partition
|
||||
* @param songId the id to find the song
|
||||
*/
|
||||
public static async getSongMidi(songId: number): Promise<any> {
|
||||
return API.fetch({
|
||||
route: `/song/${songId}/midi`,
|
||||
raw: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive an artist
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ WORKDIR /app
|
||||
COPY package.json yarn.lock ./
|
||||
RUN yarn install
|
||||
# install expo cli
|
||||
RUN yarn global add expo-cli
|
||||
RUN yarn global add expo-cli@6.0.5
|
||||
# add sharp-cli (^2.1.0) for faster image processing
|
||||
RUN yarn global add sharp-cli@^2.1.0
|
||||
COPY . .
|
||||
|
||||
@@ -11,4 +11,12 @@ server {
|
||||
location /api/ {
|
||||
proxy_pass http://back:3000/;
|
||||
}
|
||||
|
||||
location /ws/ {
|
||||
proxy_pass http://scorometer:6543/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
"install": "^0.13.0",
|
||||
"jest": "^26.6.3",
|
||||
"jest-expo": "^45.0.1",
|
||||
"midi-player-js": "^2.0.16",
|
||||
"moti": "^0.22.0",
|
||||
"native-base": "^3.4.17",
|
||||
"react": "18.1.0",
|
||||
@@ -56,6 +57,7 @@
|
||||
"react-redux": "^8.0.2",
|
||||
"react-timer-hook": "^3.0.5",
|
||||
"redux-persist": "^6.0.0",
|
||||
"soundfont-player": "^0.12.0",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+46
-18
@@ -1,34 +1,51 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { SafeAreaView, Text } from 'react-native';
|
||||
import { SafeAreaView, Text, Platform } from 'react-native';
|
||||
import * as ScreenOrientation from 'expo-screen-orientation';
|
||||
import { Box, Center, Column, IconButton, Progress, Row, View, useToast } from 'native-base';
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
import API from '../API';
|
||||
import LoadingComponent from '../components/Loading';
|
||||
import Constants from 'expo-constants';
|
||||
import { useStopwatch } from 'react-timer-hook';
|
||||
import PartitionVisualizer from '../components/PartitionVisualizer/PartitionVisualizer';
|
||||
import SlideView from '../components/PartitionVisualizer/SlideView';
|
||||
import MidiPlayer from 'midi-player-js';
|
||||
import SoundFont from 'soundfont-player';
|
||||
|
||||
type PlayViewProps = {
|
||||
songId: number
|
||||
}
|
||||
|
||||
|
||||
// this a hot fix this should be reverted soon
|
||||
let scoroBaseApiUrl = Constants.manifest?.extra?.scoroUrl;
|
||||
|
||||
if (process.env.NODE_ENV != 'development' && Platform.OS === 'web') {
|
||||
if (location.protocol === 'https:') {
|
||||
scoroBaseApiUrl = "wss://" + location.host + "/ws";
|
||||
} else {
|
||||
scoroBaseApiUrl = "ws://" + location.host + "/ws";
|
||||
}
|
||||
}
|
||||
|
||||
const PlayView = ({ songId }: PlayViewProps) => {
|
||||
const navigation = useNavigation();
|
||||
const song = useQuery(['song'], () => API.getSong(songId));
|
||||
const queryClient = useQueryClient();
|
||||
const song = useQuery(['song', songId], () => API.getSong(songId));
|
||||
const toast = useToast();
|
||||
const webSocket = useRef<WebSocket>();
|
||||
const timer = useStopwatch({ autoStart: false });
|
||||
const [paused, setPause] = useState<boolean>();
|
||||
const partitionRessources = useQuery(["partition"], () =>
|
||||
const [paused, setPause] = useState<boolean>(true);
|
||||
const [midiPlayer, setMidiPlayer] = useState<MidiPlayer.Player>();
|
||||
|
||||
const partitionRessources = useQuery(["partition", songId], () =>
|
||||
API.getPartitionRessources(songId)
|
||||
);
|
||||
|
||||
const onPause = () => {
|
||||
timer.pause();
|
||||
midiPlayer?.pause();
|
||||
setPause(true);
|
||||
webSocket.current?.send(JSON.stringify({
|
||||
type: "pause",
|
||||
@@ -38,6 +55,7 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
}
|
||||
const onResume = () => {
|
||||
setPause(false);
|
||||
midiPlayer?.play();
|
||||
timer.start();
|
||||
webSocket.current?.send(JSON.stringify({
|
||||
type: "pause",
|
||||
@@ -47,15 +65,11 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
}
|
||||
const onEnd = () => {
|
||||
webSocket.current?.close();
|
||||
midiPlayer?.pause();
|
||||
}
|
||||
|
||||
const onMIDISuccess = (access) => {
|
||||
const inputs = access.inputs;
|
||||
webSocket.current?.send(JSON.stringify({
|
||||
type: "start",
|
||||
paused: false,
|
||||
time: Date.now()
|
||||
}));
|
||||
|
||||
if (inputs.size < 2) {
|
||||
toast.show({ description: 'No MIDI Keyboard found' });
|
||||
@@ -63,13 +77,12 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
}
|
||||
toast.show({ description: `MIDI ready!`, placement: 'top' });
|
||||
let inputIndex = 0;
|
||||
webSocket.current = new WebSocket(Constants.manifest?.extra?.scoroUrl);
|
||||
webSocket.current = new WebSocket(scoroBaseApiUrl);
|
||||
webSocket.current.onopen = () => {
|
||||
webSocket.current!.send(JSON.stringify({
|
||||
type: "start",
|
||||
name: "clair-de-lune" /*song.data.id*/,
|
||||
}));
|
||||
timer.start();
|
||||
};
|
||||
webSocket.current.onmessage = (message) => {
|
||||
try {
|
||||
@@ -83,7 +96,6 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
|
||||
}
|
||||
}
|
||||
setPause(false);
|
||||
inputs.forEach((input) => {
|
||||
if (inputIndex != 0) {
|
||||
return;
|
||||
@@ -100,6 +112,19 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
}
|
||||
inputIndex++;
|
||||
});
|
||||
Promise.all([
|
||||
queryClient.fetchQuery(['song', songId, 'midi'], () => API.getSongMidi(songId)),
|
||||
SoundFont.instrument(new AudioContext(), 'electric_piano_1'),
|
||||
]).then(([midiFile, audioController]) => {
|
||||
const player = new MidiPlayer.Player((event) => {
|
||||
if (event['noteName']) {
|
||||
console.log(event);
|
||||
audioController.play(event['noteName']);
|
||||
}
|
||||
});
|
||||
player.loadArrayBuffer(midiFile);
|
||||
setMidiPlayer(player);
|
||||
});
|
||||
}
|
||||
const onMIDIFailure = () => {
|
||||
toast.show({ description: `Failed to get MIDI access` });
|
||||
@@ -142,11 +167,11 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
}}/>
|
||||
<IconButton size='sm' variant='solid' _icon={{
|
||||
as: Ionicons,
|
||||
name: paused === false ? "pause" : "play"
|
||||
name: paused ? "play" : "pause"
|
||||
}} onPress={() => {
|
||||
if (paused == true) {
|
||||
if (paused) {
|
||||
onResume();
|
||||
} else if (paused === false) {
|
||||
} else {
|
||||
onPause();
|
||||
}
|
||||
}}/>
|
||||
@@ -154,7 +179,10 @@ const PlayView = ({ songId }: PlayViewProps) => {
|
||||
<IconButton size='sm' colorScheme='coolGray' variant='solid' _icon={{
|
||||
as: Ionicons,
|
||||
name: "stop"
|
||||
}} onPress={() => navigation.navigate('Score')}/>
|
||||
}} onPress={() => {
|
||||
onEnd();
|
||||
navigation.navigate('Score')
|
||||
}}/>
|
||||
</Row>
|
||||
</Row>
|
||||
</Box>
|
||||
|
||||
@@ -5242,6 +5242,11 @@ address@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e"
|
||||
integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==
|
||||
|
||||
adsr@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/adsr/-/adsr-1.0.1.tgz#a7bc08e5ef8a71e6364abc96fce7df1c44881cc3"
|
||||
integrity sha512-thr9LK4jxApOzBA33IWOA83bXJFbyfbeozpHXyrMQOIhUni198uRxXqDhobW0S/51iokqty2Yz2WbLZbE6tntQ==
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
@@ -5659,6 +5664,11 @@ atob@^2.1.2:
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
audio-loader@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/audio-loader/-/audio-loader-0.5.0.tgz#9c125d1b25c33cd9626084054d9f6b7f31ddc908"
|
||||
integrity sha512-mEoYRjZhqkBSen/X9i2PNosqvafEsur8bI5MNoPr0wsJu9Nzlul3Yv1elYeMPsXxTxYhXLY8AZlScBvaK4mydg==
|
||||
|
||||
autoprefixer@^9.8.6:
|
||||
version "9.8.8"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a"
|
||||
@@ -12556,6 +12566,16 @@ microseconds@0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39"
|
||||
integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==
|
||||
|
||||
midi-player-js@^2.0.16:
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/midi-player-js/-/midi-player-js-2.0.16.tgz#41167859e3f430e55eeb962887cb498726d6c570"
|
||||
integrity sha512-Y1yCRvvSjJjT5J4U8T4XTCDF1FLXtw8Otvq5BAmIob/2cj10aQUDrPDFByTWeuMRPu6/nLhusROc1DuTLCzRnw==
|
||||
|
||||
midimessage@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/midimessage/-/midimessage-1.0.5.tgz#ad99f04d863a053a2563d553c5bf35070b48802c"
|
||||
integrity sha512-MPJ2tDupFOfZB5/PLp8fri1IS4fd9hPj0Bio//FBhWRQ+TsJA7/49CF1aJyraDxa0Jq8zMHAwrwXl2GINvLvgw==
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
||||
@@ -13088,6 +13108,16 @@ normalize-url@^6.0.1:
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||
|
||||
note-parser@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/note-parser/-/note-parser-1.1.0.tgz#12e9f17e51450ec994f1364a01982c22667b8e6b"
|
||||
integrity sha512-YTqWQBsRp40EFrEznnkGtmx68gcgOQ8CdoBspqGBA3G1/4mJwIYbDe/vuNpX3oGX2DhP7b1dBgTmj7p3Zr0P1Q==
|
||||
|
||||
note-parser@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/note-parser/-/note-parser-2.0.1.tgz#2438fd57a46894b402b3a2071798660129c8fbc1"
|
||||
integrity sha512-w9o6Fv46y3NsFxeezTZSmftBtUM/ypme6iZWVrTJvvsD5RN+w0XNDePWtfreNrZFL3jSjBFhadPoXb+pJO4UdA==
|
||||
|
||||
npm-package-arg@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-7.0.0.tgz#52cdf08b491c0c59df687c4c925a89102ef794a5"
|
||||
@@ -15481,6 +15511,15 @@ safe-regex@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sample-player@^0.5.5:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/sample-player/-/sample-player-0.5.5.tgz#bc35bea3449c6fa972528f022a9bbc2872195637"
|
||||
integrity sha512-VQ9pXPJ1m/eTH8QK6OQ8Dn/HSVToNyY9w9vnv+y/yjkJeRm87tJ/gBEm66jItfSLhKe6VG1DfX8+oT+Mg7QUpg==
|
||||
dependencies:
|
||||
adsr "^1.0.0"
|
||||
midimessage "^1.0.5"
|
||||
note-parser "^1.1.0"
|
||||
|
||||
sane@^4.0.3:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded"
|
||||
@@ -15903,6 +15942,15 @@ sockjs@0.3.20:
|
||||
uuid "^3.4.0"
|
||||
websocket-driver "0.6.5"
|
||||
|
||||
soundfont-player@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/soundfont-player/-/soundfont-player-0.12.0.tgz#2b26149f28aba471d2285d3df9a2e1e5793ceaf1"
|
||||
integrity sha512-8BJIsAt7h1PK3thSZDgF6zecgGhYkK74JnZO8WRZi3h34qG6H/DYlnv7cpRvL7Q9C8N6qld4Qwj7nJsX1gYjEA==
|
||||
dependencies:
|
||||
audio-loader "^0.5.0"
|
||||
note-parser "^2.0.0"
|
||||
sample-player "^0.5.5"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
[Metadata]
|
||||
Name=Chopin - Nocturne Op 9 No 2 (E Flat Major)
|
||||
Artist=Frédéric Chopin
|
||||
Genre=Classical
|
||||
Album=e
|
||||
|
||||
[Difficulties]
|
||||
TwoHands=0
|
||||
Rhythm=0
|
||||
NoteCombo=0
|
||||
Arpeggio=0
|
||||
Distance=0
|
||||
LeftHand=0
|
||||
RightHand=0
|
||||
LeadHandChange=0
|
||||
ChordComplexity=0
|
||||
ChordTiming=0
|
||||
Length=0
|
||||
PedalPoint=0
|
||||
Precision=0
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
[Metadata]
|
||||
Name=Prelude I in C major, BWV 846 - Well Tempered Clavier [First Book]
|
||||
Artist=Johann Sebastian Bach
|
||||
Genre=Classical
|
||||
Album=e
|
||||
|
||||
[Difficulties]
|
||||
TwoHands=0
|
||||
Rhythm=0
|
||||
NoteCombo=0
|
||||
Arpeggio=0
|
||||
Distance=0
|
||||
LeftHand=0
|
||||
RightHand=0
|
||||
LeadHandChange=0
|
||||
ChordComplexity=0
|
||||
ChordTiming=0
|
||||
Length=0
|
||||
PedalPoint=0
|
||||
Precision=0
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
[Metadata]
|
||||
Name=Rachmaninoff - Rhapsody on a theme of Paganini, Variation 18, Solo Piano
|
||||
Artist=Sergei Rachmaninoff
|
||||
Genre=Classical
|
||||
Album=e
|
||||
|
||||
[Difficulties]
|
||||
TwoHands=0
|
||||
Rhythm=0
|
||||
NoteCombo=0
|
||||
Arpeggio=0
|
||||
Distance=0
|
||||
LeftHand=0
|
||||
RightHand=0
|
||||
LeadHandChange=0
|
||||
ChordComplexity=0
|
||||
ChordTiming=0
|
||||
Length=0
|
||||
PedalPoint=0
|
||||
Precision=0
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
[Metadata]
|
||||
Name=Vivaldi's Spring from the Four Seasons, Piano Transcription
|
||||
Artist=Antonio Vivaldi
|
||||
Genre=Classical
|
||||
Album=e
|
||||
|
||||
[Difficulties]
|
||||
TwoHands=0
|
||||
Rhythm=0
|
||||
NoteCombo=0
|
||||
Arpeggio=0
|
||||
Distance=0
|
||||
LeftHand=0
|
||||
RightHand=0
|
||||
LeadHandChange=0
|
||||
ChordComplexity=0
|
||||
ChordTiming=0
|
||||
Length=0
|
||||
PedalPoint=0
|
||||
Precision=0
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container>
|
||||
<rootfiles>
|
||||
<rootfile full-path="score.xml">
|
||||
</rootfile>
|
||||
</rootfiles>
|
||||
</container>
|
||||
+29657
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user