Skip to content

Commit

Permalink
Merge pull request #95 from microsoft/pete-dev
Browse files Browse the repository at this point in the history
Prep for dev sdk preview release 2
  • Loading branch information
Psychlist1972 authored Jul 2, 2023
2 parents 8fbc586 + 76c3ec7 commit e29b263
Show file tree
Hide file tree
Showing 85 changed files with 777 additions and 1,001 deletions.
48 changes: 5 additions & 43 deletions get-started/midi-developers/app-developers/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,8 @@

API and other documentation which will eventually be used in either the Microsoft.com docs portal, or in a github site. Format is markdown. Work on the docs has not really started. We will lean heavily on the samples to help wth explanations.

## Some basics

The API, SDK, tools, service, drivers, and more are being developed with some guidelines about how apps could/should interact with MIDI on Windows. In no specific order or organization, here's a high-level look at what we plan to do here. In most cases, the MIDI API provides raw, and not easily used information, but the MIDI SDK provides everything an application needs to use the API in a way compatible with the MIDI Association MIDI 2.0 Implementation Guide.

Both the MIDI API and the SDK are Windows Runtime (WinRT) components.

* [Using WinRT Components from Desktop Applications](https://blogs.windows.com/windowsdeveloper/2019/04/30/enhancing-non-packaged-desktop-apps-using-windows-runtime-components/)

### Enumeration

MIDI 2.0 enumeration involves both physically connected devices discoverable through PnP, as well as in-protocol information.

#### Enumerate UMP Endpoints

Windows.Devices.Enumeration provides the classes required to enumerate MIDI devices, and to watch for add/removal of devices, as it. We're building upon that and use the SDK to interpret the enumerated information as well as provide additional information about the devices.

#### Get Group Block or Function Block information for a UMP Endpoint

Function blocks could be requested through in-protocol UMP messages. Our intent is that applications not do this themselves, but that they use an SDK call to request this information. That gives us flexibility in how we can provide this information for older devices, and also reduce the number of Function Block information request calls.

Group Block information is provided by the USB driver, and passed through the API to the SDK.

### Names and Formatting

MIDI 2.0 naming of entities is more complex than it was with MIDI 1.0. Names can be sourced from different places through both enumeration and in-protocol messages. We would like to keep names consistent across applications and Windows. To that end, the SDK includes code to provide formatted, and when appropriate, localized names for entities.

#### Format Function Block, Group Block, UMP Endpoint names

The SDK will provide properties with this information formatted per the implementation guide.

#### Format Group and Channel names

The SDK has calls to enumerate Groups and Channels using data provided by MIDI 2.0 and MIDI CI. The results are formatted as per the MIDI 2.0 implementation guide and with the correct number transition (0-15 indexes changed to 1-16 for display, Channel names listed when available, Function Block names included with the group, etc.)

### USB MIDI 2.0 UMP Endpoints

#### Support more than one UMP Endpoint on a MIDI 2.0 USB device

We recommend you use a separate MIDI interface for each UMP Endpoint exposed by a USB device. This makes it easier to correctly association group blocks and with the resulting UMP Endpoints. Our driver does not support multiple UMP Endpoints on a single interface.

#### Use both Function Blocks and Group Blocks

The MIDI Association implementation guide has information on using both function blocks and group blocks together. These need to be logically consistent and not overlap in incompatible ways. This is especially important for how macOS uses these entities, so we don't want to have them represented differently on the operating systems.
| Page | Description |
| ------------- | --------------------- |
| [consuming-midi-sdk.md](consuming-midi-sdk.md) | Information on how to use the SDK in your own apps |
| [building-midi-sdk.md](building-midi-sdk.md) | Basics on what's needed in case you want to build the SDK yourself |
| [general-info.md](general-info.md) | Some early general information about the SDK |
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Building the MIDI SDK for yourself

The Windows MIDI Services SDK is built using C++/WinRT. WinRT, a requirement for modern APIs on Windows, enables desktop applications, regardless of language, to be able to use APIs, SDKs, etc. that we create. The older tools, C++/CX, are arguably simpler to implement in, but because they include proprietary extensions to C++, we decided to go with standards-based C++/WinRT instead.

Normally, you'll just one of the SDK packages. However, if you wish to build it for yourself, this document explains how.

## Prerequisites

To build the SDK you need to use Visual Studio 2022 and C++/WinRT

* Visual Studio 2022 if you are using Visual Studio
* Windows SDK 10.0.20348 (Install with Visual Studio)
* Windows 10 22H2, or preferably, the latest version of Windows 11. Our development machines are all running Windows 11.
* C++ 17 (C++ 20 may work, C++ 14 will not)
* Boost 1.82 or higher installed in %BOOST_ROOT% (and that environment variable set, of course)
* The same environment variable as $(BOOST_ROOT) needs to be in your VC++ include location for all build configurations.
* C++/WinRT will be installed via NuGet

## Folder Structure

Here's the structure on my developer PC.

`github\microsoft\midi` is the root of the repo. Inside that, the src, get-started, etc. folders from GitHub.

`github\microsoft\midi\publish` is a folder that doesn't appear in the repo, but is referenced by the NuGet build. This is where the NuGet packages end up

`github\microsoft\midi\src\app-dev-sdk\_build` is the build target location for SDK projects. This is where the NuGet packaging steps expect to find the binaries for packaging.

## Building

The midi-sdk solution is the main solution for building, well, the MIDI SDK. It includes the correct `runsettings` for tests, and the `Directory.Build.props` files for the build layout.

For the native projects, note that 32 Bit Arm and x86 (32 bit) architectures are not supported by this project. You may build for x64, Arm64, (and in the future, Arm64EC). We are intentionally not building for 32 bit architectures here.

NuGet packages are set to pick up only Release output, not Debug. To get it all going, do a batch build of the supported architectures.

## Tests

To run the Catch2 unit tests, you'll need the Catch2 Test Adapter VSIX installed. It's called `Test Adapter for Catch2` and is available in the Visual Studio Marketplace.

Open the Test Explorer and then build the full solution if tests do not appear in it. You can then execute tests.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ To use the SDK (or underlying API) your application language and tools must be a
* Windows SDK 10.0.20348 (Install with Visual Studio)
* Windows 10 22H2, or preferably, the latest version of Windows 11. Our development machines are all running Windows 11.
* C++ 17 (C++ 20 may work, C++ 14 will not)
* The NuGet package(s) from the release

Note that there are somewhat hacky ways to get traditional C to work with the COM interfaces, but it is a ton of work for you, and is not a scenario we support. If you find yourself in that situation, I recommend factoring out the MIDI code into its own lib and encapsulating all the C++ calls in there.

Expand Down Expand Up @@ -47,6 +48,8 @@ When run outside the tools, you'll need to be prepared to either use a packaged

### Problem locating header files

**First, REBuild your project (not just Build) after adding or updating the SDK NuGet package.** I'm working on the correct targets file to enable normal incremental build to generate the header file based on the winmd, but it's not functioning at the moment. Of course, I'm assuming you have the C++/WinRT NuGet package already installed in your project.

If your project cannot resolve the header files, you may be running into [this bug](https://github.com/microsoft/cppwinrt/issues/593). That bug should be fixed, but there are instances, it seems, where it still crops up. If that happens, and you've verified that it's not a problem with the WinMD missing from your project (it's more typically an issue with a reference), you can add `$(GeneratedFilesDir)` to the include path for your project.

CPPWinRT.exe creates the winrt/namespace-name.h files in the Generated Files/winrt folder based upon the referenced winmd.
Expand All @@ -57,23 +60,18 @@ Add the C++/WinRT Nuget package to your C++ project in Visual Studio. This insta

Download the NuGet package for the Core SDK

* Until this is published on NuGet.org, you'll need to set up a local package repository. This is easy to do inside the NuGet Package Manager in Visual Studio. You simply point to a folder. The structure I use in the local clone of the repo is /publish for all NuGet packages

The next step will become unnecessary once the package structure is sorted. It's a silly step, and restricts you to a single architecture at the moment, but needed right now.

* Right-click the project in Visual Studio, and add a reference
* Browse to the packages folder for your project, and into the folder for the NuGet package you installed
* Navigate to the runtimes\win10-x64\native folder
* Add the reference to the .winmd from there. Both the .winmd and the .dll are located in that same folder, which is important. If the files are not side by side, type activation will fail.
* Until this is published on NuGet.org, you'll need to set up a local package repository. This is easy to do inside the NuGet Package Manager in Visual Studio. You simply point to a folder. The structure I use in the local clone of the repo is /publish for all NuGet packages. Specifically `D:\peteb\Documents\GitHub\microsoft\midi\publish\`

If needed, modify the project file as required (info in the C++/WinRT docs, and you can also look at the sample application code). If you are not using Visual Studio as your toolchain for your project, you may want to pull out the MIDI code into a library in your project which does. It's not strictly required, but it's much easier. (If you do not want to do this, you'll need to manually set up the cppwinrt tools as part of your build process).

> Tip: you can look at the SDK tests for up-to-date project files which target the SDKs in the same solution
[Read through this page](https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/consume-apis), specifically the "If the API is implemented in a Windows Runtime component". For the SDK, the calls are NOT in a Windows namespace, although that section can be useful to read.
[Read through this page](https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/consume-apis), specifically the "If the API is implemented in a Windows Runtime component". **For the MIDI SDK, the calls are NOT in a Windows namespace, although that section can be useful to read.**

After that, you reference the types as you would anything else in C++. Only the toolchain is an extra step. What it produces is standard C++. We're considering what we can do here to possibly eliminate even that step in the future, but it's required for now.

> When in doubt, REbuild your project. C++/WinRT does a lot of code generation for the projections.
* [C++ Windows MIDI Services Example Code](https://github.com/microsoft/midi/get-started/midi-developers/app-developers/samples/cpp-winrt/)
* [Introduction to C++/WinRT](https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/)
* [C++/WinRT on GitHub](https://github.com/microsoft/cppwinrt)
Expand All @@ -82,6 +80,8 @@ After that, you reference the types as you would anything else in C++. Only the

## Consuming from C# Desktop App

**NOTE: In the current SDK builds, .NET Consumption is not working**

Please note any .NET-specifics called out in the package release. Some early packages do not support C#/ .NET.

Your project will currently need to target .NET 7 or above. We are considering support for .NET Framework and lower versions of .NET like .NET 6. However, that is neither confirmed nor promised.
Expand All @@ -99,7 +99,7 @@ The package contains the .NET (C#) projection for .NET 7 and above. You will sti

Support for this is not yet in place. We are evaluating.

## Consuming from RS
## Consuming from Rust / RS

We will provide more information in the future. However, you will follow a similar approach to C++ using RS/WinRT instead of C++/WinRT. Note that teh Rust WinRT tools are newer and are still in active development. Supporting non-Windows SDK winmd files is or will be supported, but is not intuitive at the moment. **There is no existing crate for Windows MIDI Services right now.**

Expand Down
47 changes: 47 additions & 0 deletions get-started/midi-developers/app-developers/docs/general-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Documentation

API and other documentation which will eventually be used in either the Microsoft.com docs portal, or in a github site. Format is markdown. Work on the docs has not really started. We will lean heavily on the samples to help wth explanations.

## Some basics

The API, SDK, tools, service, drivers, and more are being developed with some guidelines about how apps could/should interact with MIDI on Windows. In no specific order or organization, here's a high-level look at what we plan to do here. In most cases, the MIDI API provides raw, and not easily used information, but the MIDI SDK provides everything an application needs to use the API in a way compatible with the MIDI Association MIDI 2.0 Implementation Guide.

Both the MIDI API and the SDK are Windows Runtime (WinRT) components.

* [Using WinRT Components from Desktop Applications](https://blogs.windows.com/windowsdeveloper/2019/04/30/enhancing-non-packaged-desktop-apps-using-windows-runtime-components/)

### Enumeration

MIDI 2.0 enumeration involves both physically connected devices discoverable through PnP, as well as in-protocol information.

#### Enumerate UMP Endpoints

Windows.Devices.Enumeration provides the classes required to enumerate MIDI devices, and to watch for add/removal of devices, as it. We're building upon that and use the SDK to interpret the enumerated information as well as provide additional information about the devices.

#### Get Group Block or Function Block information for a UMP Endpoint

Function blocks could be requested through in-protocol UMP messages. Our intent is that applications not do this themselves, but that they use an SDK call to request this information. That gives us flexibility in how we can provide this information for older devices, and also reduce the number of Function Block information request calls.

Group Block information is provided by the USB driver, and passed through the API to the SDK.

### Names and Formatting

MIDI 2.0 naming of entities is more complex than it was with MIDI 1.0. Names can be sourced from different places through both enumeration and in-protocol messages. We would like to keep names consistent across applications and Windows. To that end, the SDK includes code to provide formatted, and when appropriate, localized names for entities.

#### Format Function Block, Group Block, UMP Endpoint names

The SDK will provide properties with this information formatted per the implementation guide.

#### Format Group and Channel names

The SDK has calls to enumerate Groups and Channels using data provided by MIDI 2.0 and MIDI CI. The results are formatted as per the MIDI 2.0 implementation guide and with the correct number transition (0-15 indexes changed to 1-16 for display, Channel names listed when available, Function Block names included with the group, etc.)

### USB MIDI 2.0 UMP Endpoints

#### Support more than one UMP Endpoint on a MIDI 2.0 USB device

We recommend you use a separate MIDI interface for each UMP Endpoint exposed by a USB device. This makes it easier to correctly association group blocks and with the resulting UMP Endpoints. Our driver does not support multiple UMP Endpoints on a single interface.

#### Use both Function Blocks and Group Blocks

The MIDI Association implementation guide has information on using both function blocks and group blocks together. These need to be logically consistent and not overlap in incompatible ways. This is especially important for how macOS uses these entities, so we don't want to have them represented differently on the operating systems.
Loading

0 comments on commit e29b263

Please sign in to comment.