Implement MIDI Input
This commit is contained in:
parent
a43472f7f2
commit
b9ea16d2c6
@ -1,23 +1,65 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { onMount } from "svelte";
|
||||
import NoteDisplay from "./NoteDisplay.svelte";
|
||||
|
||||
const notes = [
|
||||
"c/4", "d/4", "e/4", "f/4", "g/4", "a/4", "b/4",
|
||||
"c/5", "d/5", "e/5", "f/5", "g/5", "a/5", "b/5",
|
||||
"c/6"
|
||||
type Note = {name: string, target: number}
|
||||
|
||||
const notes: Note[] = [
|
||||
{name: "c/4", target: 60},
|
||||
{name: "d/4", target: 62},
|
||||
{name: "e/4", target: 64},
|
||||
{name: "f/4", target: 65},
|
||||
{name: "g/4", target: 67},
|
||||
{name: "a/4", target: 69},
|
||||
{name: "b/4", target: 71},
|
||||
{name: "c/5", target: 72},
|
||||
{name: "d/5", target: 74},
|
||||
{name: "e/5", target: 76},
|
||||
{name: "f/5", target: 77},
|
||||
{name: "g/5", target: 79},
|
||||
{name: "a/5", target: 81},
|
||||
{name: "b/5", target: 83},
|
||||
{name: "c/5", target: 84},
|
||||
];
|
||||
|
||||
|
||||
let note: string;
|
||||
let target: number;
|
||||
|
||||
const randomize = () => {
|
||||
let newNote: string;
|
||||
let newNote: Note;
|
||||
do {
|
||||
newNote = notes[Math.floor(Math.random() * notes.length)];
|
||||
} while (newNote === note);
|
||||
} while (newNote.target === target);
|
||||
|
||||
note = newNote;
|
||||
}
|
||||
note = newNote.name;
|
||||
target = newNote.target;
|
||||
};
|
||||
|
||||
// MIDI
|
||||
|
||||
let midi: MIDIAccess | null = null;
|
||||
|
||||
const onMIDIMessage = (event: MIDIMessageEvent) => {
|
||||
// console.debug(event.data);
|
||||
if (!event.data || event.data.length !== 3) return;
|
||||
const [status, pitch, _velocity] = event.data;
|
||||
|
||||
// filter for "NOTE ON"
|
||||
if (status >> 4 !== 0b1001) return;
|
||||
|
||||
// console.debug(pitch);
|
||||
|
||||
if (pitch === target) {
|
||||
randomize();
|
||||
};
|
||||
};
|
||||
|
||||
const connectMidi = async () => {
|
||||
midi = await navigator.requestMIDIAccess();
|
||||
midi.inputs.forEach((entry) => {
|
||||
entry.onmidimessage = onMIDIMessage;
|
||||
});
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
randomize();
|
||||
@ -27,20 +69,28 @@
|
||||
<div id="root">
|
||||
<header class="container">
|
||||
<hgroup>
|
||||
<h1>Foobar</h1>
|
||||
<p>The fooest of bars</p>
|
||||
<h1>Sheet Music Trainer</h1>
|
||||
<p>
|
||||
<button class="connect" on:click={connectMidi}>Connect</button> a MIDI device
|
||||
and start playing
|
||||
</p>
|
||||
</hgroup>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<article>
|
||||
<NoteDisplay note={note} />
|
||||
<button on:click={randomize}>Randomize</button>
|
||||
<NoteDisplay {note} />
|
||||
<!--<footer><small>Target: {note} ({target})</small></footer>-->
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer class="container">
|
||||
<small>Hallo i bims 1 footer</small>
|
||||
<small
|
||||
>Made with <a class="secondary" href="https://svelte.dev/">Svelte</a>,
|
||||
<a class="secondary" href="https://picocss.com">PicoCSS</a>
|
||||
and
|
||||
<a class="secondary" href="https://www.vexflow.com/">VexFlow</a></small
|
||||
>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@ -55,4 +105,8 @@
|
||||
main {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.connect {
|
||||
padding: 0.2em 0.4em 0.2em 0.4em;
|
||||
}
|
||||
</style>
|
||||
|
@ -10,7 +10,7 @@
|
||||
if (!note) return;
|
||||
if (!container) return;
|
||||
|
||||
console.log(`call draw("${note}");`);
|
||||
// console.log(`call draw("${note}");`);
|
||||
|
||||
for (let child of container.children) {
|
||||
container.removeChild(child);
|
||||
|
Loading…
Reference in New Issue
Block a user