Urgent.News

What's breaking now, across thousands of outlets.

Tech

Grading piano timing in the browser with Web MIDI

I picked up piano again this year and wanted to connect my digital piano to my laptop, read real sheet music, and figure out which notes or beats I missed. But none of the apps I tested could do that. So I created Keystair , a browser-based piano course that listens to a USB MIDI keyboard. Most of it is standard React code. A few browser details took me longer than they should have, so here they…

Grading piano timing in the browser with Web MIDI involves using a simple API to read the input from a USB MIDI keyboard. The key challenge is handling the note-off signal, as many keyboards send a note-on with a velocity of 0 instead of a note-off. The code initializes access to the MIDI inputs, attaches a handler to each input, and reads three bytes per message.

When a note is pressed, the code checks if the note is a note-on or note-off, and if it's a note-on, it calls a function with the pitch, on/off status, and timestamp. If the note-off has a velocity of 64, it's considered as the sustain pedal being pressed. The event's timeStamp is synchronized with performance.now(), which is important for timing.

Output works by sending MIDIOutput.send() with a timestamp, allowing the app to play an example at a precise moment on the student's own piano. Permissions are handled by checking if the site already has access, and reconnecting on the next visit if it doesn't. Different browsers have different levels of support for Web MIDI, so if a browser doesn't support it, the app falls back to using the microphone.

The metronome click is generated from the Web Audio API, with a clock maintained by an AudioContext. All times are kept in performance.now() milliseconds, and only converted to the audio clock time when scheduling sounds. This ensures that a click meant for beat 3 is heard right then, not slightly later. The timing windows for notes are determined by the tempo, with notes counted as being on time within half a beat, up to 400 milliseconds.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Sample Article_User Stories in Agile: How to Write Effective User Stories

Agile teams need a clear way to understand what users actually need without turning every requirement into a lengthy specification. This is where user stories in Agile come in.

  • User stories describe user value without implementation details.
  • Effective user stories follow As a [user], I want [goal] so that [benefit] format.
  • The 3 Cs framework (Card, Conversation, Confirmation) guides user story creation.

Postgres Multi-Tenancy: Row-Level Security, tenant_id Filters, or a Schema per Tenant?

For most B2B SaaS apps, a tenant_id column plus row-level security (RLS) on every table is the right default: you keep one schema and one migration path, and the database enforces isolation even when…

  • Row-level security (RLS) with tenantid column is common starting point for PostgreSQL multi-tenancy.
  • RLS can lead to data leaks if not implemented carefully, failing silently in both directions.

More from Friday 2 October →