Skip to content

WebMIDI In/Out extension#2022

Open
lselden wants to merge 63 commits into
TurboWarp:masterfrom
lselden:ext_midi
Open

WebMIDI In/Out extension#2022
lselden wants to merge 63 commits into
TurboWarp:masterfrom
lselden:ext_midi

Conversation

@lselden

@lselden lselden commented Mar 10, 2025

Copy link
Copy Markdown

This is an extension that adds MIDI support using the WebMIDI API. It tries to cover most use cases - it supports notes, CC, Pitch Bend, Program Change messages, etc.

Features

  • Device detection/enumeration
  • MIDI Input (When Note On/Off, When any midi event)
  • MIDI Output (similar syntax to the "Music" extension) - uses music "tempo" if set
  • Event reporter for thread context's current event
  • human-readable (and forgiving) string formatting of events for parsing/formatting

Todo

  • Translations
  • Add blocks documentation
  • Add string format documentation
  • Add "Getting Started" / browser compatibility documentation
  • Test on target devices (in particular mac / android)
  • Feedback on blocks - are any missing? should some be pruned? Better naming convention?
  • Image
  • (OPTIONAL) Separate icons for input vs output?

lselden added 3 commits March 5, 2025 12:12
Added midi extension for input/output of midi using the WebMidi API. Still pending documentation and peer-review
use "t=<time>" instead of "@<time>". Allow using "type=note pitch=60" instead of "note 60" if need to be verbose. Some bugfixes
@github-actions github-actions Bot added the pr: new extension Pull requests that add a new extension label Mar 10, 2025
@lselden lselden mentioned this pull request Mar 10, 2025
@Brackets-Coder

Brackets-Coder commented Mar 11, 2025

Copy link
Copy Markdown
Contributor

At a glance, this looks much better than mine. You'll definitely need to add it to the list in extensions.json and probably make a gallery thumbnail too for it to be accepted though. You probably spent a lot more than four hours on it like I did. I might give it a full review (just for my opinion) when I have more time but I'm a bit busy right now. If you'd like, I can submit a PR or so to your fork that adds translations so you have one less thing to worry about (but again, I'm a bit busy right now, I'll have to get around to it when I can).

Comment thread extensions/extensions.json
Comment thread extensions/midi/midi.js
Comment thread extensions/midi/midi.js
Comment thread extensions/midi/midi.js
*/
function noteNameToMidiPitch(note, defaultOctave = 4) {
const parts =
/(?<pitch>[A-G])(?<flat>[b♭]+)?(?<sharp>[#♯]+)?_?(?<octave>-?\d+)?/i.exec(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more human-readable if possible

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a regex with named groups to describe what's matched. added method comments to help describe what's valid. If anyone's interested in other implementations I used these for reference: strudel and tonaljs

Comment thread extensions/midi/midi.js
Comment thread extensions/midi/midi.js Outdated
function stringToMidi(text, opts = {}) {
if (typeof text !== "string") text = Cast.toString(text);
const fullRe =
/^\s*(?<type>[a-zA-Z]{2,})?\s*((?<pitch>[A-G][#b♯♭_]*-?\d?)|(?<data1>\b-?[0-9a-f]{1,5}\b))?\s*(?<data2>\b[0-9a-f]{1,3}\b)?\s*(?<keyvals>.+)\s*$/;

@Brackets-Coder Brackets-Coder Mar 11, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't fun to try to understand... Also you should use Scratch.Cast instead of Cast

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast here is a local const of Scratch.Cast. Switched to the verbose Scratch.Cast to avoid confusion in the future

This comment was marked as abuse.

Comment thread extensions/midi/midi.js Outdated
Comment thread extensions/midi/midi.js Outdated
Comment on lines +2104 to +2105
// sanity check - don't let a note be more than 1 minute
// if anyone ever needs a longer note then they should manually write event string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?
I know it's a rare occurrence but as a musician (pianist), developer, and Scratch user you shouldn't generally limit the user's capabilities unless necessary. Notes technically can be a minute long and a user shouldn't have that length unexpectedly cut off...
Keep in mind this is just a quick look-over and I haven't fully analyzed it in depth yet

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hear ya. I checked and the Scratch Music extension clamps to 100 beats max (100 seconds at 60bpm) - updated code accordingly

This comment was marked as abuse.

Comment thread extensions/midi/midi.js Outdated
Comment thread extensions/midi/midi.js Outdated
Comment thread extensions/midi/midi.js Outdated
Comment thread extensions/midi/midi.js
}

//#endregion
Scratch.extensions.register(new MidiExtension());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class name is a bit overgeneralized?
Also your code style is not exactly like mine but I guess it's just a matter of preference. seems a bit cluttered to me but I guess it's just a personal problem.

Other than that it looks fine

This comment was marked as abuse.

@Brackets-Coder

Copy link
Copy Markdown
Contributor

Just a quick review, nothing in depth. Going over best practices for TW extensions in particular, not necessarily anything related to the functionality of the code.

lselden added 7 commits March 17, 2025 23:40
Existing code uses "dur" for "duration", and "pitch" for "noteName"
midi precision doesn't go under 2-5 milliseconds, so forcing numbers to be readable 1ms precision
Added midi extension for input/output of midi using the WebMidi API. Still pending documentation and peer-review
@Brackets-Coder

Copy link
Copy Markdown
Contributor

@SharkPool-SP mind doing a quick review?
@lselden is there anything you know you want done prior to merging?

@SharkPool-SP

Copy link
Copy Markdown
Collaborator

I don't have a midi to test with

@Brackets-Coder

Copy link
Copy Markdown
Contributor

I don't have a midi to test with

That's right, I forgot you told me
I don't suppose any of the others do either...
Could you just do a quick code skim and see if I missed anything? You don't have to approve if you feel like you can't test

@SharkPool-SP

Copy link
Copy Markdown
Collaborator

I don't have a midi to test with

That's right, I forgot you told me I don't suppose any of the others do either... Could you just do a quick code skim and see if I missed anything? You don't have to approve if you feel like you can't test

okay

@SharkPool-SP

Copy link
Copy Markdown
Collaborator

ill do it when they fix the other requested changes

lselden added 2 commits March 7, 2026 15:09
added extra block for outputting devices as json, allow outputting active notes as json
@lselden

lselden commented Mar 7, 2026

Copy link
Copy Markdown
Author

@SharkPool-SP I addressed comments and added some JSON output blocks. I also plan on adding some documentation.

@SharkPool-SP

Copy link
Copy Markdown
Collaborator

Then I'll wait until documentation is made before merging

@Brackets-Coder

Copy link
Copy Markdown
Contributor

Hi @lselden,

I'd like to get this extension merged as soon as possible. Is there anything I can do to help you with that?

@samuellouf

samuellouf commented May 12, 2026

Copy link
Copy Markdown
Contributor

Hello! I've taken a look at your WebMIDI I/O extension and it looks very good!
I do have a few suggestions though :

  • I think it would be nice if you could choose the input device in the "when note" / "when event" hat blocks.
  • Maybe the "Input Event" reporter could have a dropdown in which you can choose the part of the event you want.

But other than that, it's really good.

@samuellouf

Copy link
Copy Markdown
Contributor

Btw I think I'm going to do a MIDI Player extension, if anybody here wants to contribute just dm me on discord @ samuelloufcoder.

@AliceC-W

Copy link
Copy Markdown

Btw I think I'm going to do a MIDI Player extension, if anybody here wants to contribute just dm me on discord @ samuelloufcoder.

Will that extension record/write files too?

@lselden lselden requested a review from a team as a code owner May 22, 2026 06:54
@lselden

lselden commented May 22, 2026

Copy link
Copy Markdown
Author

Hello! I've taken a look at your WebMIDI I/O extension and it looks very good! I do have a few suggestions though :

  • I think it would be nice if you could choose the input device in the "when note" / "when event" hat blocks.
  • Maybe the "Input Event" reporter could have a dropdown in which you can choose the part of the event you want.

But other than that, it's really good.

@samuellouf I added the input device selection to the when hats - good idea! I didn't get a chance to add the type filter to the input event hat. Sounds like a good idea though, and I'd welcome the contribution

@lselden

lselden commented May 22, 2026

Copy link
Copy Markdown
Author

Hi @lselden,

I'd like to get this extension merged as soon as possible. Is there anything I can do to help you with that?

Hi @Brackets-Coder - thanks for the nudge. I've added some help docs and a sample project, and made a couple of bugfixes.

@SharkPool-SP I've added the documentation - hopefully it makes sense and is useful

@Brackets-Coder

Copy link
Copy Markdown
Contributor

Okay, I'll probably take a look sometime tomorrow or after

@samuellouf samuellouf mentioned this pull request Jun 3, 2026
@Brackets-Coder

Copy link
Copy Markdown
Contributor

@lselden sorry for the delay, I'll review this weekend if I remember

@Brackets-Coder Brackets-Coder left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a code review, I'm just looking over the documentation with two quick suggestions. Let me know if you have any questions or need anything.

I haven't tested the sample project or code yet after my previous review, but everything else looks okay

Comment thread docs/midi/MIDI.md Outdated
Comment thread samples/Midi.sb3 Outdated
@Brackets-Coder

Copy link
Copy Markdown
Contributor

p.s. sorry for my tardiness

@lselden lselden requested a review from Brackets-Coder June 23, 2026 21:40
@lselden

lselden commented Jun 23, 2026

Copy link
Copy Markdown
Author

@Brackets-Coder sorry for my tardiness in seeing your comments. I updated as per your comments.

@Brackets-Coder

Copy link
Copy Markdown
Contributor

@lselden Apologies for the delays in getting this merged. I'm currently out of town so things are moving a bit slower but I'll try to help you and review where I can. Thanks for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: new extension Pull requests that add a new extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants