[CoreMidiSample] Add CoreMIDI sample project.#10
[CoreMidiSample] Add CoreMIDI sample project.#10rolfbjarne wants to merge 1 commit intodotnet:mainfrom
Conversation
Demonstrates the full CoreMIDI API surface including: - Device/entity/endpoint enumeration - Virtual source and destination creation (legacy and protocol-based) - MidiPacket (legacy MIDI data) - MidiEventList and MidiEventPacket (MIDI 2.0 UMP) - Happy Birthday melody using UMP packets - MIDI 2.0 structs (Midi2DeviceManufacturer, Midi2DeviceRevisionLevel, MidiCIProfileId) - MidiBluetoothDriver - MidiSetup device management
Bind the following missing CoreMIDI APIs: - MIDIDeviceCreate/MIDIDeviceDispose - MIDIExternalDeviceCreate - MIDISetupAddDevice/MIDISetupRemoveDevice - MIDISetupAddExternalDevice/MIDISetupRemoveExternalDevice - MIDIEntityAddOrRemoveEndpoints - MIDIDeviceRemoveEntity - MIDIEndPointGetRefCons/MIDIEndPointSetRefCons - MIDIDriverEnableMonitoring - MIDIGetDriverDeviceList/MIDIGetDriverIORunLoop - MIDISendSysex/MIDISendUMPSysex - MIDIDestinationCreateWithProtocol - MIDISourceCreateWithProtocol - MIDIInputPortCreateWithProtocol - MIDIClientCreateWithBlock - MIDIEventPacketSysexBytesForGroup - MIDI 2.0 structs (MIDI2DeviceManufacturer, MIDI2DeviceRevisionLevel, MIDICIProfileID, MIDISysexSendRequest, MIDISysexSendRequestUMP) - MidiDriver abstract class for implementing custom MIDI drivers Add MidiEventList and MidiEventPacket classes for MIDI 2.0 Universal MIDI Packet (UMP) support (MIDIEventList/MIDIEventPacket structs). Add comprehensive tests including a Happy Birthday melody test. There's a sample project in progress here: dotnet/macios-samples#10. Fixes #4452 Fixes #12489
|
Mark as draft until the bindings we need have been released. |
There was a problem hiding this comment.
Pull request overview
Adds a new macOS sample app demonstrating .NET CoreMIDI bindings across legacy MIDI 1.0 and modern MIDI 2.0/UMP APIs, with a simple UI to exercise the API surface.
Changes:
- Introduces a new macOS app project (
CoreMidiSample) with anNSApplicationDelegate-driven UI and CoreMIDI demos. - Adds project scaffolding (csproj,
Main.cs,Info.plist) and an app icon asset catalog. - Adds a README describing features, requirements, and how to run the sample.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| CoreMidiSample/macOS/Main.cs | App entry point wiring AppDelegate and passing launch args. |
| CoreMidiSample/macOS/AppDelegate.cs | Main sample implementation: UI, logging, CoreMIDI enumeration, virtual endpoints, legacy packets, UMP event lists, and demos. |
| CoreMidiSample/macOS/CoreMidiSample.csproj | macOS project configuration (TFM, OS support, app id). |
| CoreMidiSample/macOS/Info.plist | macOS bundle plist (currently minimal). |
| CoreMidiSample/macOS/Assets.xcassets/AppIcon.appiconset/Contents.json | App icon asset catalog definition. |
| CoreMidiSample/README.md | Sample documentation, features list, and build/run instructions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Flush output on destination | ||
| if (source is not null) { | ||
| source.FlushOutput (); | ||
| Log ("FlushOutput called on source."); | ||
| } |
There was a problem hiding this comment.
The comment says “Flush output on destination”, but the code flushes source. Either update the comment or call FlushOutput() on the destination endpoint to keep the sample behavior and explanation aligned.
| list10.Add (1000, new uint [] { noteOffWord }); | ||
| Log ($"Add NoteOff UMP: PacketCount={list10.PacketCount}"); | ||
|
|
||
| // Add multi-word packet (MIDI 2.0 Note On: 4 words) |
There was a problem hiding this comment.
The comment says “MIDI 2.0 Note On: 4 words”, but the code constructs a 2-word UMP message and the log message also says “2 words”. Update the comment (or the data) so the documented UMP size matches what’s being added.
| // Add multi-word packet (MIDI 2.0 Note On: 4 words) | |
| // Add multi-word packet (MIDI 2.0 Note On: 2 words) |
|
|
||
| ## Requirements | ||
|
|
||
| - macOS 14.0 or later |
There was a problem hiding this comment.
README states “macOS 14.0 or later”, but the project sets <SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>. Please align the README requirements with the actual project minimum (or lower the project minimum if 14.0 is intended).
| - macOS 14.0 or later | |
| - macOS 15.0 or later |
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> |
There was a problem hiding this comment.
This Info.plist is missing the standard bundle metadata keys used by other macOS samples in this repo (e.g., CFBundleShortVersionString, CFBundleVersion, CFBundleDevelopmentRegion, etc. in ExceptionMarshaling/macOS/Info.plist). Consider adding the same baseline keys here so the app bundle has consistent versioning/metadata and avoids tooling warnings.
| <dict> | |
| <dict> | |
| <key>CFBundleDevelopmentRegion</key> | |
| <string>en</string> | |
| <key>CFBundleExecutable</key> | |
| <string>$(EXECUTABLE_NAME)</string> | |
| <key>CFBundleIdentifier</key> | |
| <string>com.example.CoreMidiSample</string> | |
| <key>CFBundleInfoDictionaryVersion</key> | |
| <string>6.0</string> | |
| <key>CFBundleName</key> | |
| <string>CoreMidiSample</string> | |
| <key>CFBundlePackageType</key> | |
| <string>APPL</string> | |
| <key>CFBundleShortVersionString</key> | |
| <string>1.0</string> | |
| <key>CFBundleVersion</key> | |
| <string>1</string> |
| var dest = client.CreateVirtualSource ("SampleDest_2_0", MidiProtocolId.Protocol_2_0, out var dstStatus); | ||
| Log ($"CreateVirtualSource (Protocol 2.0): status={dstStatus}, name={dest?.EndpointName}"); |
There was a problem hiding this comment.
This appears to create the protocol-based destination using CreateVirtualSource instead of CreateVirtualDestination. As written, the sample creates two sources and no protocol-based destination; switch this call to the destination-creation API so the demo matches the button label and the method’s XML doc.
| var dest = client.CreateVirtualSource ("SampleDest_2_0", MidiProtocolId.Protocol_2_0, out var dstStatus); | |
| Log ($"CreateVirtualSource (Protocol 2.0): status={dstStatus}, name={dest?.EndpointName}"); | |
| var dest = client.CreateVirtualDestination ("SampleDest_2_0", MidiProtocolId.Protocol_2_0, out var dstStatus); | |
| Log ($"CreateVirtualDestination (Protocol 2.0): status={dstStatus}, name={dest?.EndpointName}"); |
Demonstrates the full CoreMIDI API surface including: