Skip to content

[CoreMidiSample] Add CoreMIDI sample project.#10

Draft
rolfbjarne wants to merge 1 commit intodotnet:mainfrom
rolfbjarne:coremidi-sample
Draft

[CoreMidiSample] Add CoreMIDI sample project.#10
rolfbjarne wants to merge 1 commit intodotnet:mainfrom
rolfbjarne:coremidi-sample

Conversation

@rolfbjarne
Copy link
Copy Markdown
Member

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

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
@rolfbjarne rolfbjarne requested a review from Copilot February 18, 2026 19:26
rolfbjarne added a commit to dotnet/macios that referenced this pull request Feb 18, 2026
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
@rolfbjarne
Copy link
Copy Markdown
Member Author

Mark as draft until the bindings we need have been released.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 an NSApplicationDelegate-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.

Comment on lines +282 to +286
// Flush output on destination
if (source is not null) {
source.FlushOutput ();
Log ("FlushOutput called on source.");
}
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
list10.Add (1000, new uint [] { noteOffWord });
Log ($"Add NoteOff UMP: PacketCount={list10.PacketCount}");

// Add multi-word packet (MIDI 2.0 Note On: 4 words)
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
// Add multi-word packet (MIDI 2.0 Note On: 4 words)
// Add multi-word packet (MIDI 2.0 Note On: 2 words)

Copilot uses AI. Check for mistakes.
Comment thread CoreMidiSample/README.md

## Requirements

- macOS 14.0 or later
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

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).

Suggested change
- macOS 14.0 or later
- macOS 15.0 or later

Copilot uses AI. Check for mistakes.
<?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>
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
<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>

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +266
var dest = client.CreateVirtualSource ("SampleDest_2_0", MidiProtocolId.Protocol_2_0, out var dstStatus);
Log ($"CreateVirtualSource (Protocol 2.0): status={dstStatus}, name={dest?.EndpointName}");
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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}");

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants