Skip to content

Commit

Permalink
Merge pull request #313 from microsoft/pete-dev
Browse files Browse the repository at this point in the history
Docs updates and clean up error logging in scheduler
  • Loading branch information
Psychlist1972 authored Apr 17, 2024
2 parents a6272ba + 9838b04 commit 20164ae
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 224 deletions.
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 6 arm64" ?>
<?define SetupVersionNumber="1.0.24107.1653" ?>
<?define SetupVersionNumber="1.0.24107.2219" ?>
</Include>
176 changes: 13 additions & 163 deletions docs/midi-console.md → docs/console/endpoints.md
Original file line number Diff line number Diff line change
@@ -1,152 +1,10 @@
---
layout: page
title: MIDI Console
parent: Windows Midi Services
title: Endpoints and Messages
parent: MIDI Console
---

# Windows MIDI Services Console

If you have the midi console installed, you can invoke it from any command prompt using `midi`. We recommend using [Windows Terminal](https://aka.ms/terminal) for the best experience.

## General Information

### Commands vs Options

MIDI Console commands are words with no symbol prefix. For example `endpoint` or `send-message-file`. Options are prefixed with two dashes if you use the full word, or a single dash if you use the single-letter abbreviation. For example `--help` or `-h`. There is no statement completion built in to the console, but there are some supported abbreviations for commands. These are not yet fully documented but are present in the Program.cs in the console source code.

### "Ports" vs "Streams"

In MIDI 1.0, specifically USB MIDI 1.0, a connected device would have a single input and single output stream. Inside that stream are packets of data with virtual cable numbers. Those numbers (16 total at most) identify the "port" the data is going to. Operating systems would then translate those into input and output ports. Those cable numbers were hidden from users.

MIDI 2.0 does not have a concept of a port. Instead, you always work with the stream itself. The group number, which is in the MIDI message now, is the moral equivalent of that cable number.

So where you may have seen a device with 5 input and 5 output ports in the past, you will now see a **single bidirectional UMP Endpoint stream** with 5 input groups and 5 output groups. We know this can take some getting used to, but it enables us to use MIDI 1.0 devices as though they are MIDI 2.0 devices, and provide a unified API.

### Help

Add the option `--help` or its short version `-h` to any command to get information and examples for that command.

```
midi --help
midi service --help
midi enumerate --help
midi enumerate endpoints --help
```

The `--help` option will always provide the most up-to-date list of commands and options supported by the MIDI Services Console.

## Check the MIDI Service Health

The heart of Windows MIDI Services is the Windows Service which processes and routes messages, creates endpoints, and more. The MIDI Services Console app includes a few commands to check the status and health of the service.

### Check MIDI Service Status

If you want to verify that the MIDI Service is running, you can check its status using the Service Control Manager, or through the MIDI Console.

```
midi service status
midi svc status
```

If you uset the `--verbose` or `-v` option, the console will display more information about the service.

```
midi service status
midi svc status
```

### Ping the Service

If you want to verify that the service is transmitting and receiving messages, you can use the ping command, much like you would

```
midi service ping
midi svc ping
```

This command also supports the `--verbose` or `-v` option to display the full results of the ping. It also supports a `--count` or `-c` parameter for the number of messages you want to send. Finally, the call supports a `--timeout` or `-t` parameter to set the timeout in milliseconds before the ping is considered to have failed.

Here are examples of the command with various parameters.

```
midi service ping --verbose
midi service ping --verbose --count 20 --timeout 20000
```

### Stop / Start / Restart the Service

The MIDI console has three commands for managing the Windows service. These can be useful when developing or debugging service-side plugins. Note that these must be run from an Administrator console session.

```
midi service stop
midi service start
midi service restart
```

## See the Current Timestamp and Frequency

If you want to see the MIDI clock we're using for timestamps and message scheduling, you can use the `time` command. It will display the current timestamp in ticks, and the number of ticks per second (the resolution)

```
midi time
midi clock
```

## Enumerate (List) MIDI Entities

A basic operation you may do with the tool is list the major entities (Endpoints and Plugins) in the system.

The enumerate command has the aliases `enum` and `list` which may be used instead of the full `enumerate` command.

### Enumerate MIDI UMP Endpoints

The `ump-endpoints` parameter has the alias `endpoints` and the alias `ump` so either may be used with the same results. These commands are all equivalent:

```
midi enumerate ump-endpoints
midi enumerate endpoints
midi enum endpoints
midi list endpoints
midi list ump
```

All of the above statements will return a list of all the user-focused UMP endpoints on the system.

> **Note:** There are loopback endpoints A and B that are always available and are built into the service. They are crosswired to each other so that any message sent to A is received on B, and vice versa. They cannot be removed or disabled. Because these are more for support, testing, and developer scenarios, they are not returned from enumeration calls by default. Instead, you would supply the `--include-loopback` option for the enumeration commands.
### Enumerate Classic Byte-stream (MIDI 1.0) Endpoints

This uses the old WinRT API. Its primary reason for existance is so you can see what's shown to older APIs vs what is shown for the new Windows MIDI Services API. As with the UMP endpoints, the commands have aliases, so the following are all equivalent

```
midi enumerate bytestream-endpoints
midi enumerate legacy-endpoints
midi enum legacy-endpoints
midi list legacy
```

### Enumerate Transport Plugins

TODO: This feature is actively in development.

### Enumerate Message Processing Plugins

TODO: This feature is actively in development.

## Watch UMP Endpoints for Changes

Enumerating endpoints gives you a snapshot of the list at a moment in time. Watching the endpoints will give you a constantly updating list, which reflects device add/remove as well as property updates. This is useful more for developers, or those who are using tools to modify endpoints and want to verify that the changes were reported.

The `watch-endpoints` command has the alias `watch`, so these are equivalent:

```
midi watch-endpoints
midi watch
```

Note that only UMP endpoints (or bytestream endpoints converted to UMP by the new USB driver and service) are watched for changes. The older MIDI API is not used here. When you want to stop watching the endpoints for changes, hit the `escape` key.

## Single-Endpoint Commands
# Single-Endpoint Commands

There are a number of commands, including those for monitoring and sending messages, which operate on a single endpoint.

Expand All @@ -158,7 +16,7 @@ If you want to script the commands without requiring any user interaction, provi
midi endpoint \\?\SWD#MIDISRV#MIDIU_DIAG_LOOPBACK_B#{e7cce071-3c03-423f-88d3-f1045d02552b} properties --verbose
```

### Get Detailed Endpoint Properties
## Get Detailed Endpoint Properties

In the Device Manager in Windows, you can only see a subset of properties for a device. The same goes with the `pnputil` utility. It can be useful to see all of the key properties of a MIDI Endpoint. Therefore, we've baked property reporting right into the MIDI Services Console.

Expand All @@ -174,7 +32,7 @@ midi endpoint properties --verbose

As with other endpoint commands, if you provide the endpoint device Id, it will be used. Otherwise, you will be prompted to select an endpoint.

### Monitor an Endpoint for Incoming Messages
## Monitor an Endpoint for Incoming Messages

By default, every UMP Endpoint in Windows MIDI Services is multi-client. That means that more than one application can open a connection to the endpoint and send and/or receive messages. This also makes it possible to monitor all the incoming messages on an endpoint, even when that endpoint is in use by another application.

Expand All @@ -194,7 +52,7 @@ Verbose mode:
midi endpoint monitor --verbose
```

#### Saving messages to a file
### Saving messages to a file

When monitoring, you also have the option to save the messages to a file. This can be used to capture test data which you will send using the `send-message-file` command, or for storing something like a System Exclusive dump.

Expand All @@ -211,7 +69,7 @@ If no file extension is specified, the extension `.midi2` will be automatically

When you have completed monitoring an endpoint, hit the `escape` key to close the connection and the app.

### Send a Message from the Command Line
## Send a Message from the Command Line

Sending a message to an endpoint is very helpful for testing, but can also be used in automation to, for example, change the current program, or set a MIDI CC value. It would be very easy for a person to build a batch file or PowerShell script which used midi.exe to synchronize different devices, or reset devices to a known state in preparation for a performance.

Expand All @@ -237,7 +95,7 @@ midi endpoint send-message 0x41234567 0xDEADBEEF --count 15 --pause 2000

In general, we recommend sending messages in hexadecimal format (prefix `0x` followed by 8 hexadecimal digits)as it is easier to visually inspect the information being sent. The 1-4 MIDI words are in order from left to right, from 1 to 4.

#### Special debug messages
### Special debug messages

One thing that can be useful is to send otherwise valid UMP messages where the last word is incremented by 1 for each sent message. This helps to validate that all messages were received by your application, and in the correct order. Note that this requires a message type of at least two words. We don't recommend sending Type F stream messages as those have the potential to corrupt data. Instead, a Type 4 MIDI 2.0 channel voice message is usually safer.

Expand All @@ -247,9 +105,7 @@ midi endpoint send-message 0x41234567 0x00000000 --count 10000 --pause 2 --debug

When sent, you should see messages where the second word is updated from `0x00000000` through `0x00002710` (decimal 10000). We recommend the pause when sending large numbers of messages because a pause of 0 ("send as fast as possible") can flood the buffers with more data than the client may be able to retrieve in time and may result in dropped messages. A warning is displayed when that possibility seems likely.

#### Scheduling messages

> NOTE: In current Developer Preview builds, message scheduling is turned off so the timestamp is ignored. Refer to the release notes.
### Scheduling messages

When sending messages, you have two options for timestamps:

Expand All @@ -271,7 +127,7 @@ Of course, you can also use the `midi time` command to see the current timestamp

Finally, if you do not specify a timestamp, the current time is used.

### Send a File full of Messages
## Send a File full of Messages

If you want to send a file full of messages, for SysEx or testing, for example, the console has provision for this.

Expand Down Expand Up @@ -334,7 +190,7 @@ F3345678h 12345678h 86754321h 86753099h
# bunch of empty lines above. And the file ends with a comment
```

### Sending Endpoint Metadata Requests
## Sending Endpoint Metadata Requests

The MIDI Services Console also makes it possible to send some common stream request messages without having to remember their exact format.

Expand All @@ -344,7 +200,7 @@ These are primarily a convenience for developers.

Note that in all the request commands, you may abbreviate `request` as `req`

#### Send a Function Block Request Message
### Send a Function Block Request Message

In the command, you may abbreviate `function-blocks` as `fb`, `functions`, `function` or `function-block`. The singular versions are available to make the command make more sense when requesting a single block's data.

Expand All @@ -369,7 +225,7 @@ midi endpoint request function-blocks --all --request-name false
midi endpoint request function-blocks --all --request-info false
```

#### Send an Endpoint Information Request Message
### Send an Endpoint Information Request Message

In the command, you may abbreviate `endpoint-metadata` as `em` or `metadata`.

Expand Down Expand Up @@ -402,9 +258,3 @@ midi endpoint request endpoint-metadata --stream-configuration
```

Finally, note that you can provide a UMP version to send with the request. By default, the version is Major 1, Minor 1. The `--ump-version-major` and `--ump-version-minor` options are what you want to use here.

## Technical Information

The Windows MIDI Services Console app has been developed using C#, .NET 8, the MIT-licensed open source [Spectre.Console](https://spectreconsole.net/) library, and the Microsoft-developed open source [C#/WinRT](https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/) toolkit.

The console uses the same Windows MIDI Services WinRT APIs available to other desktop applications. Its full source code is available [on our Github repo](https://aka.ms/midirepo). Pull-requests, feature requests, and bug reports welcome. The project is open source, but we request that instead of forking it to create your own version, you consider contributing to the project.
48 changes: 48 additions & 0 deletions docs/console/enum-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
layout: page
title: Enumerate Endpoints
parent: MIDI Console
---

# Enumerate (List) Endpoints

## Enumerate MIDI UMP Endpoints

The `ump-endpoints` parameter has the alias `endpoints` and the alias `ump` so either may be used with the same results. These commands are all equivalent:

```
midi enumerate ump-endpoints
midi enumerate endpoints
midi enum endpoints
midi list endpoints
midi list ump
```

All of the above statements will return a list of all the user-focused UMP endpoints on the system.

> **Note:** There are loopback endpoints A and B that are always available and are built into the service. They are crosswired to each other so that any message sent to A is received on B, and vice versa. They cannot be removed or disabled. Because these are more for support, testing, and developer scenarios, they are not returned from enumeration calls by default. Instead, you would supply the `--include-loopback` option for the enumeration commands.
## Enumerate Classic Byte-format (MIDI 1.0) Endpoints

This uses the old WinRT API. Its primary reason for existance is so you can see what's shown to older APIs vs what is shown for the new Windows MIDI Services API. As with the UMP endpoints, the commands have aliases, so the following are all equivalent

```
midi enumerate bytestream-endpoints
midi enumerate legacy-endpoints
midi enum legacy-endpoints
midi list legacy
```

## Watch UMP Endpoints for Changes

Enumerating endpoints gives you a snapshot of the list at a moment in time. Watching the endpoints will give you a constantly updating list, which reflects device add/remove as well as property updates. This is useful more for developers, or those who are using tools to modify endpoints and want to verify that the changes were reported.

The `watch-endpoints` command has the alias `watch`, so these are equivalent:

```
midi watch-endpoints
midi watch
```

Note that only UMP endpoints (or bytestream endpoints converted to UMP by the new USB driver and service) are watched for changes. The older MIDI API is not used here. When you want to stop watching the endpoints for changes, hit the `escape` key.

25 changes: 25 additions & 0 deletions docs/console/enum-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: page
title: Enumerate Plugins
parent: MIDI Console
---

# Enumerate (List) MIDI Service Plugins

The enumerate command has the aliases `enum` and `list` which may be used instead of the full `enumerate` command.

## Enumerate Transport Plugins

This command makes it easy to see which transports are currently enabled in Windows MIDI Services.

```
midi enumerate transport-plugins
```

![Enumerate Transport Plugins](./enum-transports.png)


## Enumerate Message Processing Plugins

TODO: This feature is actively in development.

Binary file added docs/console/enum-transports.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 20164ae

Please sign in to comment.