Implement MIDI Input

This commit is contained in:
Kai Vogelgesang 2024-07-18 14:47:51 +02:00
parent a43472f7f2
commit b9ea16d2c6
Signed by: kai
GPG Key ID: 3FC8578CC818A9EB
2 changed files with 70 additions and 16 deletions

View File

@ -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>

View File

@ -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);