Skip to content

Commit

Permalink
Merge pull request #265 from microsoft/pete-dev
Browse files Browse the repository at this point in the history
More API docs, and the new mididmp command-line utlity
  • Loading branch information
Psychlist1972 authored Feb 9, 2024
2 parents 26aeb75 + d5d2ca2 commit f24f7f1
Show file tree
Hide file tree
Showing 174 changed files with 3,131 additions and 1,639 deletions.
4 changes: 4 additions & 0 deletions build/build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ Task("SetupEnvironment")
// copy the C++ header for the API
CopyFiles(System.IO.Path.Combine(generatedFilesDir, "Windows.Devices.Midi2.h"), copyToDir);
CopyFiles(System.IO.Path.Combine(outputDir, "mididmp.exe"), copyToDir);
// copy the API Header and the .winmd to the "API bare" folder
var apiBareCopyToDir = System.IO.Path.Combine(releaseRootDir, "api");
Expand Down
7 changes: 7 additions & 0 deletions build/replace_running_service.bat
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ sc stop midisrv

set servicepath="%ProgramFiles%\Windows MIDI Services\Service"
set apipath="%ProgramFiles%\Windows MIDI Services\API"
set dmppath="%ProgramFiles%\Windows MIDI Services\"
set buildoutput="%midi_repo_root%src\api\VSFiles\x64\Release"

echo mididmp.exe
copy /Y %buildoutput%\mididmp.exe %dmppath%

echo MidiSrv.exe
copy /Y %buildoutput%\MidiSrv.exe %servicepath%
copy /Y %buildoutput%\Midi2.*Abstraction.dll %servicepath%
copy /Y %buildoutput%\Midi2.*Transform.dll %servicepath%

echo Windows.Devices.Midi2.dll
copy /Y %buildoutput%\Windows.Devices.Midi2.dll %apipath%
echo Windows.Devices.Midi2.pri
copy /Y %buildoutput%\Windows.Devices.Midi2.pri %apipath%


Expand Down
3 changes: 0 additions & 3 deletions build/staging/reg/WinRTActivationEntries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,10 @@ class RegistryEntries
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiChannelEndpointListener", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiGroupEndpointListener", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiMessageTypeEndpointListener", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiVirtualEndpointDevice", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiVirtualEndpointDeviceDefinition", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiMessageReceivedEventArgs", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiEndpointConnection", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.IMidiEndpointConnectionStatics", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiEndpointConnectionOptions", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiStreamConfigurationSettings", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiService", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.IMidiServiceStatics", ActivationType=0, Threading=0, TrustLevel=0 },
new RegEntry{ ClassName="Windows.Devices.Midi2.MidiClock", ActivationType=0, Threading=0, TrustLevel=0 },
Expand Down
15 changes: 0 additions & 15 deletions build/staging/reg/WinRTActivationEntries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,6 @@
threading="Both"
trustLevel="Base"
/>
<class
activatableClassId="Windows.Devices.Midi2.MidiVirtualEndpointDevice"
threading="Both"
trustLevel="Base"
/>
<class
activatableClassId="Windows.Devices.Midi2.MidiVirtualEndpointDeviceDefinition"
threading="Both"
Expand All @@ -158,16 +153,6 @@
threading="Both"
trustLevel="Base"
/>
<class
activatableClassId="Windows.Devices.Midi2.MidiEndpointConnectionOptions"
threading="Both"
trustLevel="Base"
/>
<class
activatableClassId="Windows.Devices.Midi2.MidiStreamConfigurationSettings"
threading="Both"
trustLevel="Base"
/>
<class
activatableClassId="Windows.Devices.Midi2.MidiService"
threading="Both"
Expand Down
2 changes: 1 addition & 1 deletion build/staging/version/BundleInfo.wxi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Include>
<?define SetupVersionName="Developer Preview 5" ?>
<?define SetupVersionNumber="1.0.24038.0149" ?>
<?define SetupVersionNumber="1.0.24039.2143" ?>
</Include>
2 changes: 1 addition & 1 deletion docs/_site/api-back-compat.html

Large diffs are not rendered by default.

494 changes: 261 additions & 233 deletions docs/_site/assets/js/search-data.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/config-json.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/developer-docs/best-practices.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/developer-docs/consuming-midi-api.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/developer-docs/diagnostic-endpoints.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/developer-docs/endpoint-ids.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/developer-docs/faq-programming-languages.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_site/midi-console.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You can learn more about high-resolution timestamps in Windows at [https://aka.m
| --------------- | ----------- |
| `Now` | Returns the current timestamp |
| `TimestampFrequency` | Returns the number of timestamp ticks per second. This is calculated the first time it is called, and then cached for future calls. |
| `TimestampConstantSendImmediately` | Returns the constant to use when you want to send messages immediately and bypass outgoing message scheduling. Developers may use this value or simply provide `0` in place of the timestamp when sending messages. |

## Static Functions

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
layout: api_page
title: IMidiEndpointConnectionSettings
parent: Connections
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# IMidiEndpointConnectionSettings

Settings which are optionally provided when connecting to an endpoint. Typically, the implementation of the endpoint will come with a concrete settings class which implements this interface, and translates the settings into JSON which is sent up to the service and read by the abstraction.

## Properties

| Property | Description |
| -------- | ----------- |
| `SettingsJson` | The JSON representation of the settings. |

## IDL

[IMidiEndpointConnectionSettings IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/IMidiEndpointConnectionSettings.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
layout: api_page
title: IMidiEndpointConnectionSource
parent: Connections
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# IMidiEndpointConnectionSource

Marker interface which is used to prevent circular references in the API, specifically with message processing plugins. This interface is only supported when used by the `MidiEndpointConnection` class.

## IDL

[IMidiEndpointConnectionSource IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/IMidiEndpointConnectionSource.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
layout: api_page
title: IMidiMessageReceivedEventSource
parent: Connections
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# IMidiMessageReceivedEventSource

Interface which contains the event definition used by any class which raises the `MessageReceived` event. This is defined in an interface so that message processing plugins and the `MidiEndpointConnection` type can be used interchangeably in an event handler.

## Events

| Event | Description |
| -------- | ----------- |
| `MessageReceived(source, args)` | The main message received event definition. |

## IDL

[IMidiMessageReceivedEventSource IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/IMidiMessageReceivedEventSource.idl)

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Connections allocate resources including send/receive buffers, and processing th

To ensure an application is able to wire up processing plugins and event handlers before the connection is active, the connection returned by the `MidiSession` is not yet open. Once the connection is acquired, the application should assign event handlers, and optionally assign any message processing plugins. Once complete, the application calls the `Open()` function to connect to the service, create the queues, and begin sending and receiving messages.

## A note on sending messages

All `SendMessageXX` functions send a single Universal MIDI Packet message at a time. The pluralized versions `SendMessagesXX` will send multiple packets, in order, with the same timestamp.

Currently, in the implementation behind the scenes, the service receives each timestamped message one at a time. We have the functions for sending more than one message as a developer convenience for similarity with other platforms, and also to allow for possible future optimization in the service communication code.

## Properties

| Property | Description |
Expand All @@ -22,7 +28,7 @@ To ensure an application is able to wire up processing plugins and event handler
| `EndpointDeviceId` | The system-wide identifier for the device connection. This is returned through enumeration calls. |
| `Tag` | You may use this `Tag` property to hold any additional information you wish to have associated with the connection. |
| `IsOpen` | True if this connection is currently open. When first created, the connection is not open until the consuming code calls the `Open` method |
| `Settings` | Settings used to create this connection. |
| `Settings` | Settings used to create this connection. Treat this as read-only. |
| `MessageProcessingPlugins` | Collection of all message processing plugins which will optionally handle incoming messages. |

## Static Member Functions
Expand All @@ -46,8 +52,10 @@ To ensure an application is able to wire up processing plugins and event handler
| `SendMessageWords(timestamp, word0, word1, word2)` | Send a single 96-bit Universal MIDI Packet as 32-bit words. This is often the most efficient way to send this type of message |
| `SendMessageWords(timestamp, word0, word1, word2, word3)` | Send a single 128-bit Universal MIDI Packet as 32-bit words. This is often the most efficient way to send this type of message |
| `SendMessageBuffer(timestamp, buffer, byteOffset, byteLength)` | Send a single Universal MIDI Packet as bytes from a buffer. The number of bytes sent must match the size read from the first 4 bits of the data starting at the specified offset, and must be laid out correctly with the first byte corresponding to the MSB of the first word of the UMP (the word which contains hte message type). If you want to manage a chunk of buffer memory, the `IMemoryBuffer` type is the acceptable WinRT approach, and is as close as you get to sending a pointer into a buffer. |
| `SendMessagesWordList(timestamp,words)` | This sends more than one message with the same timestamp. Message words must be ordered contiguously from word-0 to word-n for each message, and the message types must be valid for the number of words for each message. If an error is encountered when sending messages, the function stops processing the list at that point and returns a failure code, even if some messages were sent successfully. |
| `SendMessagesWordArray(timestamp,words)` | This sends more than one message with the same timestamp. Message words must be ordered contiguously from word-0 to word-n for each message, and the message types must be valid for the number of words for each message. If an error is encountered when sending messages, the function stops processing the list at that point and returns a failure code, even if some messages were sent successfully.|
| `AddEndpointProcessingPlugin(plugin)` | Add an endpoint processing plugin to this connection |
| `RemoveEndpointProcessingPlugin(id)` | Remove an endpoint processing plugin |
| `RemoveEndpointProcessingPlugin(id)` | Remove an endpoint processing plugin from this connection |

> Tip: In all the functions which accept a timestamp to schedule the message, **you can send a timestamp of 0 (zero) to bypass the scheduler and send the message immediately**. Otherwise, the provided timestamp is treated as an absolute time for when the message should be sent from the service. Note that the service-based scheduler (currently based on a `std::priority_queue`) gets less efficient when there are thousands of messages in it, so it's recommended that you not schedule too many messages at a time or too far out into the future.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
layout: api_page
title: MidiSendMessageResult
parent: Connections
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# MidiSendMessageResult

When an application sends a message, it should check the result of sending to ensure that the message was transmitted. Each of the message sending functions returns a `MidiSendMessageResult` flags enum. Values in this enum are OR'd together to indicate success or failure, and in the case of failure, the reason.

The `MidiEndpointConnection` type includes static helper functions to process the `MidiSendMessageResult` and determine success or failure. The application may then optionally look at the remaining data to see which failure reason(s) apply.

```cpp
auto sendResult = myConnection.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), 0x28675309);

if (MidiEndpointConnection::SendMessageSucceeded(sendResult))
{
// do something in the case of success
}
else
{
// one or more failure reasons in the result. Use bitwise AND `&` operator to decipher.
}

```

## Properties

| Property | Value | Description |
| -------- | ----- | ----------- |
| `Succeeded` | `0x80000000` | Indicates success. |
| `Failed` | `0x10000000` | Indicates failure. The actual failure reason will be combined with the result. |
| `BufferFull` | `0x00010000` | The message could not be sent because the outgoing buffer to the service was full |
| `EndpointConnectionClosedOrInvalid` | `0x00040000` | The endpoint connection was closed or invalidated before the message could be sent. |
| `InvalidMessageTypeForWordCount` | `0x00100000` | The number of words sent does not match the message type of the first word. |
| `InvalidMessageOther` | `0x00200000` | The message sent was invalid for another reason. |
| `DataIndexOutOfRange` | `0x00400000` | Reading a full message would result in overrunning the provided array, collection, or buffer. |
| `TimestampOutOfRange` | `0x00800000` | The provided timestamp is too far in the future to be scheduled. |
| `MessageListPartiallyProcessed` | `0x00A00000` | The message list was only partially processed. Not all messages were sent. |
| `Other` | `0x01000000` | Other reason that cannot be determined. |

## IDL

[MidiSendMessageResult IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/MidiSendMessageResult.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
layout: api_page
title: MidiEndpointDeviceInformationFilter
parent: Endpoint Enumeration
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# MidiEndpointDeviceInformationFilter Enumeration

When enumerating devices, it is helpful to be able to filter for different types of devices. For example, an application providing diagnostic or development services may want to enumerate the diagnostic loopback endpoints. A Digital Audio Workstation, on the other hand, would only want to enumerate the normal UMP and Byte Stream native endpoints.

## Properties

| Property | Value | Description |
| --------------- | ---------- | ----------- |
| `IncludeClientUmpNative` | `0x00000001` | Include endpoints which are MIDI UMP endpoints natively. These are typically considered MIDI 2.0 devices even if they only send MIDI 1.0 messages in UMP. |
| `IncludeClientByteStreamNative` | `0x00000002` | Include endpoints which are MIDI 1.0 byte stream endpoints natively. These are converted to UMP internally in Windows MIDI Services. |
| `IncludeVirtualDeviceResponder` | `0x00000100` | Include endpoints which are virtual devices. Note that this is the device side of the endpoint, not the side available to other applications. Typically, you would not use this. |
| `IncludeDiagnosticLoopback` | `0x00010000` | Use this value only when providing development, test, or diagnostic services for MIDI. |
| `IncludeDiagnosticPing` | `0x00020000` | You would not normally include this in an enumeration. This endpoint is internal. |
| `AllTypicalEndpoints` | `IncludeClientUmpNative | IncludeClientByteStreamNative` | This is the value most applications should use, and is the default. |

## IDL

[MidiEndpointDeviceInformationFilterEnum IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/MidiEndpointDeviceInformationFilterEnum.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: api_page
title: MidiEndpointDeviceInformationSortOrder
parent: Endpoint Enumeration
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# MidiEndpointDeviceInformationSortOrder Enumeration

Specifies the sort order to use when enumerating a static list of devices.

## Properties

| Property | Value | Description |
| --------------- | ---------- | ----------- |
| `None` | `0` | No sort. Return in default order |
| `Name` | `1` | Sort by the name of the endpoint |
| `EndpointDeviceId` | `2` | Sort by the id of the endpoint (the SWD id) |
| `DeviceInstanceId` | `3` | Sort by the device instance id |
| `ContainerThenName` | `11` | Sort by the container and then by name. This is helpful when you want endpoints grouped by parent. |
| `ContainerThenEndpointDeviceId` | `12` | Sort by the container and then by the endpoint id |
| `ContainerThenDeviceInstanceId` | `13` | Sort by the container and then by the device instance id |
| `TransportMnemonicThenName` | `21` | Sort by the transport mnemonic (example: "DIAG") and then by the device instance id |
| `TransportMnemonicThenEndpointDeviceId` | `22` | Sort by the transport mnemonic and then by the endpoint id |
| `TransportMnemonicThenDeviceInstanceId` | `23` | Sort by the transport mnemonic and then by the device instance id |

## IDL

[MidiEndpointDeviceInformationSortOrderEnum IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/MidiEndpointDeviceInformationSortOrderEnum.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
layout: api_page
title: MidiEndpointDevicePurpose
parent: Endpoint Enumeration
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# MidiEndpointDevicePurpose Enumeration

Indicates the intended purpose of the endpoint. Use this to help classify endpoints you show to users in your application. This value is also used internally when filtering endpoints per the `MidiEndpointDeviceInformationFilter` enumeration.

## Properties

| Property | Value | Description |
| --------------- | ---------- | ----------- |
| `NormalMessageEndpoint` | `0` | The endpoint is any number of normal messaging endpoint types. |
| `VirtualDeviceResponder` | `100` | The endpoint is the device-side of an app-to-app MIDI connection. Only the device app should use this endpoint. |
| `InBoxGeneralMidiSynth` | `400` | The endpoint represents the internal General MIDI Synthesizer |
| `DiagnosticLoopback` | `500` | The endpoint is one of the static system-wide diagnostics loopback endpoints. These are not normally used in applications |
| `DiagnosticPing` | `510` | The endpoint is the internal diagnostics ping endpoint. This endpoint should never be used by applications as it is reserved for the `MidiService` ping feature. |

## IDL

[MidiEndpointDevicePurposeEnum IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/MidiEndpointDevicePurposeEnum.idl)

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
layout: api_page
title: Midi1ChannelVoiceMessageStatus
parent: Messages
grand_parent: Windows.Devices.Midi2 API
has_children: false
---

# Midi1ChannelVoiceMessageStatus Enumeration

Status to use for MIDI 1.0 Channel Voice messages. Note that not all MIDI 1.0 messages are channel voice messages, so this is not an exhaustive list of MIDI 1.0 messages. However, this is the total set of MIDI 1.0 messages which can be used in a MIDI Universal MIDI Packet Message type 2.

## Properties

| Property | Value | Description |
| -------- | ------- | ------ |
| `NoteOff` | `0x8` | MIDI 1.0 Note Off message |
| `NoteOn` | `0x9` | MIDI 1.0 Note On message |
| `PolyPressure` | `0xA` | MIDI 1.0 polyphonic pressure message |
| `ControlChange` | `0xB` | MIDI 1.0 control change message |
| `ProgramChange` | `0xC` | MIDI 1.0 program change message |
| `ChannelPressure` | `0xD` | MIDI 1.0 channel pressure message |
| `PitchBend` | `0xE` | MIDI 1.0 pitch bend message |

## IDL

[Midi1ChannelVoiceMessageStatusEnum IDL](https://github.com/microsoft/MIDI/blob/main/src/api/Client/Midi2Client/Midi1ChannelVoiceMessageStatusEnum.idl)
Loading

0 comments on commit f24f7f1

Please sign in to comment.