feat(midi): add native MIDI input and output - #151
Open
iplanwebsites wants to merge 11 commits into
Open
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
… kinds, C-emission mapping Adds declare module midi/node:midi, midiInput/midiOutput IR handle kinds, moduleUsesMidi predicate, type mapping, module registry entries, and the C-representation/retain/release mapping in the emission layer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
Refcounted midi Input/Output handles over the event-loop poller seam, off-thread callback bridging via self-pipe, number[] message delivery with deltaTime, virtual-port loopback on POSIX, header decls and scr_async.c loop hook. Falls back to a stub backend where no MIDI stack is present. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
…arshalers, install hook) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
lower-midi.ts lowers new Input()/Output() constructors and the port method surface (getPortCount/getPortName/openPort/openVirtualPort/closePort/ isPortOpen/ignoreTypes/sendMessage/on-once message) to the midi.* lib calls, wired into lowerNew and the method-call dispatch; surfaces.ts fence hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
Adds the midi.* ids to IrLibFn, the emitter dispatch mapping each to its scr_midi_* symbol (with per-arity onMessage thunk selection and input-only loop liveness), the may-throw set, and the lib-fn signature table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
…I fence Threads moduleUsesMidi into the backend opts, compiles scr_midi.c and links the platform MIDI stack (ALSA where present / CoreMIDI / WinMM) conditionally, emits scr_midi_install() into generated main, and refuses the MIDI surface on the WASI target (SC3002). End-to-end: an enumerate program builds and runs natively via the C backend (LLVM defers node surfaces, as dgram does). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
…ne dev-dep - diagnostics snapshot (SC2020 bad sendMessage shape; SC1090 void-result rules) - coverage fixture pinning the enumerate program at 100% static - capability-gated harness: WASI SC3002 refusal + virtual-port loopback differential (skipped where no ALSA/CoreMIDI backend / @julusian/midi) - platforms / limitations / introduction / how-it-works docs + CHANGELOG - regenerated surface-manifest (node-builtin.midi) and @julusian/midi dev-dep Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYLKF6JBn2Fozts9CGr9W6
|
@iplanwebsites is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| if (kind == SCR_MIDI_IN) { | ||
| ScrMidiInput *s = (ScrMidiInput *)handle; | ||
| if (s->open) scr_midi_plat_in_close(s); /* node-midi re-opens */ | ||
| const char *err = scr_midi_plat_in_open(s, (int)idx, NULL); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds native MIDI input and output for compiled ScriptC programs.
The main use case is audio and real-time tools that need to talk to MIDI keyboards, controllers, hardware, or virtual MIDI ports without falling back to a JavaScript engine. The API follows node-midi / @julusian/midi, so programs can list ports, open an input or output, send raw MIDI messages, and receive message events.
The implementation uses the platform MIDI system on macOS, Linux, and Windows. MIDI code is linked only when a program uses it. WASI gives a clear compile-time error because WASI does not provide a MIDI device API. Windows supports physical WinMM ports, but not virtual ports because WinMM does not offer them.
I tested this on macOS with CoreMIDI. The test creates a virtual MIDI connection, sends Note On, Control Change, and Note Off messages, and compares the Node and native ScriptC results byte for byte. This caught a packet-boundary issue during development; host timestamps now keep separate sends separate, matching node-midi behavior.
Validation completed on the repository pinned Node 24.15.0:
The Sandbox image was not configured on this machine, so I used the documented full local fallback. The separate hybrid audio-engine application and our internal implementation notes are not part of this PR.