diff --git a/build/nuke_build/Build.cs b/build/nuke_build/Build.cs
index 9584600c4..eebb2a5e7 100644
--- a/build/nuke_build/Build.cs
+++ b/build/nuke_build/Build.cs
@@ -264,6 +264,7 @@ class Build : NukeBuild
"Microsoft.Windows.Devices.Midi2.Endpoints.Loopback",
"Microsoft.Windows.Devices.Midi2.Endpoints.Virtual",
"Microsoft.Windows.Devices.Midi2.Utilities.SysEx",
+ "Microsoft.Windows.Devices.Midi2.VirtualPatchBay",
"Microsoft.Windows.Devices.Midi2.Initialization" // this last one gets packed 100% in the nuget, including the impl
})
{
@@ -540,6 +541,7 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Endpoints.Loopback.dll", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.dll", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Utilities.SysEx.dll", stagingFolder, FileExistsPolicy.Overwrite, true);
+ FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.VirtualPatchBay.dll", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Initialization.dll", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
@@ -550,6 +552,7 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Messages.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Endpoints.Loopback.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
+ FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.VirtualPatchBay.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Utilities.SysEx.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
FileSystemTasks.CopyFileToDirectory(runtimesFolder / "Microsoft.Windows.Devices.Midi2.Initialization.pri", stagingFolder, FileExistsPolicy.Overwrite, true);
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.dll b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.dll
index e7de8f5b1..dc0e87a21 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.dll and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.dll differ
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.winmd b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.winmd
index dc67d4a73..30f62852d 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.winmd and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.winmd differ
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.dll b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.dll
index f964e9f1c..7e4464224 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.dll and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.dll differ
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.winmd b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.winmd
index 382966a53..ac8c563bc 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.winmd and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Messages.winmd differ
diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi
index e2ab1d9ca..83cc8bfb7 100644
--- a/build/staging/version/BundleInfo.wxi
+++ b/build/staging/version/BundleInfo.wxi
@@ -1,4 +1,4 @@
-
+
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
index 5b4d4180a..23cef22d9 100644
--- a/docs/Gemfile.lock
+++ b/docs/Gemfile.lock
@@ -70,7 +70,7 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
- rexml (3.3.2)
+ rexml (3.3.3)
strscan
rouge (4.2.0)
rubyzip (2.3.2)
diff --git a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.cpp b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.cpp
index 6dc6633cf..0c4fdb894 100644
--- a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.cpp
+++ b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.cpp
@@ -18,6 +18,11 @@ CMidi2VirtualPatchBayRoutingDestination::Initialize(
m_matchJson = endpointMatchJson;
m_router = router;
+ for (uint8_t i = 0; i < 16; i++)
+ {
+ m_groupTransformMap[i] = i;
+ }
+
return S_OK;
}
@@ -68,7 +73,20 @@ CMidi2VirtualPatchBayRoutingDestination::SetGroupTransforms(
std::map groupTransformMap
)
{
- UNREFERENCED_PARAMETER(groupTransformMap);
+ // reset all groups before applying any transform
+ for (uint8_t i = 0; i < 16; i++)
+ {
+ m_groupTransformMap[i] = i;
+ }
+
+ // apply only the transforms presented
+ for (auto transform : groupTransformMap)
+ {
+ if (transform.first < 16)
+ {
+ m_groupTransformMap[transform.first] = transform.second;
+ }
+ }
return S_OK;
}
diff --git a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.h b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.h
index 507f49133..e95e7946a 100644
--- a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.h
+++ b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingDestination.h
@@ -32,6 +32,7 @@ class CMidi2VirtualPatchBayRoutingDestination :
CMidi2VirtualPatchBayRoutingEntry* m_router;
std::wstring m_matchJson{ };
+ GUID m_endpointAbstractionId{ };
std::wstring m_resolvedEndpointDeviceInterfaceId{ };
wil::com_ptr_nothrow m_endpointBiDi{ nullptr };
@@ -39,6 +40,6 @@ class CMidi2VirtualPatchBayRoutingDestination :
// each entry in this array is the destination group. Index is the source group
// all values in this array must be valid. Multiple source groups can map to the
// same destination group, but not the other way around.
- uint8_t m_groupTransformMap[16]{ };
+ std::array m_groupTransformMap{ };
};
diff --git a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.cpp b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.cpp
index b2096c00f..e05b5cfa4 100644
--- a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.cpp
+++ b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.cpp
@@ -38,49 +38,83 @@ CMidi2VirtualPatchBayRoutingSource::Callback(
// Verify message meets criteria.
auto word0 = internal::MidiWord0FromVoidMessageDataPointer(data);
+ auto mt = internal::GetUmpMessageTypeFromFirstWord(word0);
- // if this is a groupless message
- if (internal::MessageHasGroupField(word0))
+ // check to see if we support this message type
+ if (m_includedMessageTypes[mt])
{
- // if group is not in our list, return
- auto groupIndex = internal::GetGroupIndexFromFirstWord(word0);
-
- if (!m_includedGroupIndexes[groupIndex])
+ if (internal::MessageHasGroupField(word0))
{
- return S_OK;
+ // if group is not in our list, return
+ auto groupIndex = internal::GetGroupIndexFromFirstWord(word0);
+
+ if (!m_includedGroupIndexes[groupIndex])
+ {
+ return S_OK;
+ }
}
+
+ RETURN_IF_FAILED(m_router->Callback(data, length, position, context));
}
- else
+
+ return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT
+CMidi2VirtualPatchBayRoutingSource::SetIncludedGroups(
+ std::vector groupIndexes
+)
+{
+ if (groupIndexes.size() > 0)
{
- // message has no group field
- if (!m_includeGrouplessMessages)
+ m_includedGroupIndexes = { false };
+
+ for (auto const messageType : groupIndexes)
{
- return S_OK;
+ if (messageType < 16)
+ {
+ m_includedGroupIndexes[messageType] = true;
+ }
}
}
-
- RETURN_IF_FAILED(m_router->Callback(data, length, position, context));
+ else
+ {
+ // if an empty set is provided, all groups are included
+ m_includedGroupIndexes = { true };
+ }
return S_OK;
}
_Use_decl_annotations_
HRESULT
-CMidi2VirtualPatchBayRoutingSource::AddIncludedGroups(
- std::vector groupIndexes
+CMidi2VirtualPatchBayRoutingSource::SetIncludedMessageTypes(
+ std::vector messageTypes
)
{
- for (auto const index : groupIndexes)
+ if (messageTypes.size() > 0)
{
- if (index < 16)
+ m_includedMessageTypes = { false };
+
+ for (auto const messageType : messageTypes)
{
- m_includedGroupIndexes[index] = true;
+ if (messageType < 16)
+ {
+ m_includedMessageTypes[messageType] = true;
+ }
}
}
+ else
+ {
+ // if an empty set is provided, all message types are included
+ m_includedMessageTypes = { true };
+ }
return S_OK;
}
+
_Use_decl_annotations_
HRESULT
CMidi2VirtualPatchBayRoutingSource::SetEndpointCallback(
diff --git a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.h b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.h
index c51380de0..397a18d3b 100644
--- a/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.h
+++ b/src/api/Abstraction/VirtualPatchbayAbstraction/Midi2.VirtualPatchBayRoutingSource.h
@@ -20,7 +20,8 @@ class CMidi2VirtualPatchBayRoutingSource :
STDMETHOD(Callback)(_In_ PVOID data, _In_ UINT length, _In_ LONGLONG position, _In_ LONGLONG context);
- STDMETHOD(AddIncludedGroups)(_In_ std::vector groupIndexes);
+ STDMETHOD(SetIncludedGroups)(_In_ std::vector groupIndexes);
+ STDMETHOD(SetIncludedMessageTypes)(_In_ std::vector messageTypes);
STDMETHOD(SetEndpointCallback)(_In_ LPCWSTR resolvedEndpointDeviceInterfaceId, _In_ IMidiCallback* sourceEndpointCallback);
STDMETHOD(Cleanup)();
@@ -29,13 +30,15 @@ class CMidi2VirtualPatchBayRoutingSource :
CMidi2VirtualPatchBayRoutingEntry* m_router;
std::wstring m_matchJson{ };
- std::wstring m_resolvedEndpointDeviceInterfaceId{ };
+ GUID m_endpointAbstractionId{ };
+ std::wstring m_resolvedEndpointDeviceInterfaceId{ };
- bool m_includeGrouplessMessages{ false };
+ // array of booleans indexed by message type. If true, the type is included
+ std::array m_includedMessageTypes{ true };
// array of booleans. If an index is true, it is included
- bool m_includedGroupIndexes[16]{ false };
+ std::array m_includedGroupIndexes{ true };
wil::com_ptr m_sourceEndpointBiDi{ nullptr };
diff --git a/src/app-sdk/MyMidiApp.exe.manifest b/src/app-sdk/MyMidiApp.exe.manifest
index fad0c63bd..d0f8abd83 100644
--- a/src/app-sdk/MyMidiApp.exe.manifest
+++ b/src/app-sdk/MyMidiApp.exe.manifest
@@ -158,8 +158,43 @@
name="Microsoft.Windows.Devices.Midi2.Utilities.SysEx.MidiSystemExclusiveSender"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app-sdk/app-sdk.sln b/src/app-sdk/app-sdk.sln
index 73b4c1ebd..e17de24a6 100644
--- a/src/app-sdk/app-sdk.sln
+++ b/src/app-sdk/app-sdk.sln
@@ -12,6 +12,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.Devices.Midi2.Messages", "winrt-messages\Microsoft.Windows.Devices.Midi2.Messages.vcxproj", "{001601DE-B7AB-41D1-81B7-40286B139841}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.Devices.Midi2.Endpoints.Loopback", "winrt-endpoint-loopback\Microsoft.Windows.Devices.Midi2.Endpoints.Loopback.vcxproj", "{D3B84D5D-8BED-4CB7-B430-B0BF1E46F3A1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {001601DE-B7AB-41D1-81B7-40286B139841} = {001601DE-B7AB-41D1-81B7-40286B139841}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.Devices.Midi2.Endpoints.Virtual", "winrt-endpoint-virtual\Microsoft.Windows.Devices.Midi2.Endpoints.Virtual.vcxproj", "{9B93146C-4D9D-4915-BECB-5227DF2667E2}"
EndProject
@@ -64,6 +67,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midiusbinfo", "midiusbinfo\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.Devices.Midi2.Utilities.SysEx", "winrt-utilities-sysex\Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj", "{0D4739EF-C0D3-441C-AC25-20A55909E1DC}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Windows.Devices.Midi2.VirtualPatchBay", "winrt-virtual-patchbay\Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj", "{7BCB819F-CA97-4312-BF7B-1919A5CCDE69}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -348,6 +353,22 @@ Global
{0D4739EF-C0D3-441C-AC25-20A55909E1DC}.Release|ARM64EC.Build.0 = Release|ARM64EC
{0D4739EF-C0D3-441C-AC25-20A55909E1DC}.Release|x64.ActiveCfg = Release|x64
{0D4739EF-C0D3-441C-AC25-20A55909E1DC}.Release|x64.Build.0 = Release|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|Any CPU.Build.0 = Debug|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|ARM64.Build.0 = Debug|ARM64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|ARM64EC.ActiveCfg = Debug|ARM64EC
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|ARM64EC.Build.0 = Debug|ARM64EC
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|x64.ActiveCfg = Debug|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Debug|x64.Build.0 = Debug|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|Any CPU.ActiveCfg = Release|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|Any CPU.Build.0 = Release|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|ARM64.ActiveCfg = Release|ARM64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|ARM64.Build.0 = Release|ARM64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|ARM64EC.ActiveCfg = Release|ARM64EC
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|ARM64EC.Build.0 = Release|ARM64EC
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|x64.ActiveCfg = Release|x64
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -375,6 +396,7 @@ Global
{4DABE157-7DD5-422A-8C77-B83EAC9987D0} = {900D72D2-91F0-4E6C-B694-192FD48393D2}
{0F688DE9-BE99-4A86-BE79-C5BE32BC471D} = {C8B31D71-0226-4D2D-AC78-53D5C84F472F}
{0D4739EF-C0D3-441C-AC25-20A55909E1DC} = {F5AE94B4-47A7-4D35-A9EE-65FD4CF58C4B}
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69} = {F5AE94B4-47A7-4D35-A9EE-65FD4CF58C4B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AE1DF8B9-9FAB-4E20-8AC6-FF316882222F}
diff --git a/src/app-sdk/coalesce/coalesce.vcxproj b/src/app-sdk/coalesce/coalesce.vcxproj
index f5f0ca627..a13cdda01 100644
--- a/src/app-sdk/coalesce/coalesce.vcxproj
+++ b/src/app-sdk/coalesce/coalesce.vcxproj
@@ -211,6 +211,9 @@
{0d4739ef-c0d3-441c-ac25-20a55909e1dc}
+
+ {7bcb819f-ca97-4312-bf7b-1919a5ccde69}
+
diff --git a/src/app-sdk/mididiag/main.cpp b/src/app-sdk/mididiag/main.cpp
index 474334b01..4f50876f3 100644
--- a/src/app-sdk/mididiag/main.cpp
+++ b/src/app-sdk/mididiag/main.cpp
@@ -129,6 +129,34 @@ void OutputNumericField(_In_ std::wstring const& fieldName, _In_ uint32_t const
<< std::endl;
}
+void OutputDoubleField(_In_ std::wstring const& fieldName, _In_ double const value, _In_ uint32_t precision)
+{
+ OutputFieldLabel(fieldName);
+
+ std::wcout
+ << fieldSeparator
+ << std::dec
+ << std::setprecision(precision)
+ << value
+ << std::endl;
+}
+
+void OutputDecimalMillisecondsField(_In_ std::wstring const& fieldName, _In_ double const value, _In_ uint32_t precision)
+{
+ OutputFieldLabel(fieldName);
+
+ std::wcout
+ << fieldSeparator
+ << std::dec
+ << std::setprecision(precision)
+ << std::fixed
+ << value
+ << " ms"
+ << std::endl;
+}
+
+
+
void OutputHexNumericField(_In_ std::wstring const& fieldName, _In_ uint32_t const value)
{
OutputFieldLabel(fieldName);
@@ -519,6 +547,40 @@ bool DoSectionSystemInfo(_In_ bool verbose)
::GetNativeSystemInfo(&sysinfoNative);
OutputSystemInfo(sysinfoNative);
+ TIMECAPS timecaps;
+ auto tcresult = ::timeGetDevCaps(&timecaps, sizeof(timecaps));
+
+ OutputBlankLine();
+
+ if (tcresult == MMSYSERR_NOERROR)
+ {
+ OutputNumericField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_MIN_PERIOD, timecaps.wPeriodMin);
+ OutputNumericField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_MAX_PERIOD, timecaps.wPeriodMax);
+ }
+ else
+ {
+ OutputStringField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_ERROR, std::wstring{ L"Could not get timecaps" });
+ }
+
+ ULONG minResolution;
+ ULONG maxResolution;
+ ULONG actualResolution;
+
+ auto resresult = NtQueryTimerResolution(&maxResolution, &minResolution, &actualResolution);
+
+ if (resresult == STATUS_SUCCESS)
+ {
+ double minResolutionMilliseconds = (double)minResolution / 10000.0; // minResolution is in 100 nanosecond units
+ double maxResolutionMilliseconds = (double)maxResolution / 10000.0; // maxResolution is in 100 nanosecond units
+ double actualResolutionMilliseconds = (double)actualResolution / 10000.0; // actualResolution is in 100 nanosecond units
+
+ // results here are in 100ns units
+ OutputBlankLine();
+ OutputDecimalMillisecondsField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_MIN_MS, minResolutionMilliseconds, 3);
+ OutputDecimalMillisecondsField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_MAX_MS, maxResolutionMilliseconds, 3);
+ OutputDecimalMillisecondsField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_CURRENT_MS, actualResolutionMilliseconds, 3);
+ }
+
return true;
}
diff --git a/src/app-sdk/mididiag/mididiag.vcxproj b/src/app-sdk/mididiag/mididiag.vcxproj
index d1056c544..fffd30e84 100644
--- a/src/app-sdk/mididiag/mididiag.vcxproj
+++ b/src/app-sdk/mididiag/mididiag.vcxproj
@@ -127,9 +127,9 @@
Console
false
- %(AdditionalDependencies)
- %(AdditionalDependencies)
- %(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
@@ -159,9 +159,9 @@
true
true
false
- %(AdditionalDependencies)
- %(AdditionalDependencies)
- %(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
+ ntdll.lib;%(AdditionalDependencies)
diff --git a/src/app-sdk/mididiag/mididiag_field_defs.h b/src/app-sdk/mididiag/mididiag_field_defs.h
index 79efc6beb..79eb4055d 100644
--- a/src/app-sdk/mididiag/mididiag_field_defs.h
+++ b/src/app-sdk/mididiag/mididiag_field_defs.h
@@ -70,6 +70,15 @@
#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_PROCESSOR_LEVEL L"processor_level"
#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_PROCESSOR_REVISION L"processor_revision"
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_ERROR L"timecaps_error"
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_MIN_PERIOD L"timecaps_min_period"
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMECAPS_MAX_PERIOD L"timecaps_max_period"
+
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_MIN_MS L"timer_resolution_min"
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_MAX_MS L"timer_resolution_max"
+#define MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_TIMER_RESOLUTION_CURRENT_MS L"timer_resolution_current"
+
+
#define MIDIDIAG_SECTION_LABEL_HEADER L"header"
#define MIDIDIAG_FIELD_LABEL_CURRENT_TIME L"current_time"
diff --git a/src/app-sdk/mididiag/pch.h b/src/app-sdk/mididiag/pch.h
index eb542e265..47a667ca9 100644
--- a/src/app-sdk/mididiag/pch.h
+++ b/src/app-sdk/mididiag/pch.h
@@ -12,6 +12,8 @@
#include
#include
+#include
+
//#pragma warning (disable: 4005)
//#include
//#pragma warning (pop)
@@ -42,6 +44,9 @@ namespace diag = winrt::Microsoft::Windows::Devices::Midi2::Diagnostics;
namespace svc = winrt::Microsoft::Windows::Devices::Midi2::ServiceConfig;
#include "combaseapi.h"
+#include
+#include
+
#include "wstring_util.h"
namespace internal = ::WindowsMidiServicesInternal;
diff --git a/src/app-sdk/midiusbinfo/main.cpp b/src/app-sdk/midiusbinfo/main.cpp
index 448a2ae43..e1d36389f 100644
--- a/src/app-sdk/midiusbinfo/main.cpp
+++ b/src/app-sdk/midiusbinfo/main.cpp
@@ -30,10 +30,12 @@ int __cdecl main()
winrt::init_apartment();
std::cout << dye::grey("===================================================================") << std::endl;
- std::cout << "Enumerating kernel streaming devices to discover MIDI pins" << std::endl;
- std::cout << "-------------------------------------------------------------------" << std::endl;
- std::cout << dye::aqua("If the MIDI service is running when you run this utility, some") << std::endl;
- std::cout << dye::aqua("devices may not report all pin properties.") << std::endl;
+ std::cout << dye::aqua(" Enumerating kernel streaming devices to discover MIDI pins") << std::endl;
+ std::cout << dye::aqua(" Typically, these are USB, but other KS drivers will be included") << std::endl;
+ std::cout << dye::grey("-------------------------------------------------------------------") << std::endl;
+ std::cout << dye::aqua(" If the MIDI service is running when you run this utility, some") << std::endl;
+ std::cout << dye::aqua(" devices may not report all pin properties. It is recommended") << std::endl;
+ std::cout << dye::aqua(" that you stop the midisrv service before running this tool.") << std::endl;
std::cout << dye::grey("===================================================================") << std::endl;
// enumerate all in-scope devices
diff --git a/src/app-sdk/midiusbinfo/pch.h b/src/app-sdk/midiusbinfo/pch.h
index aa3768a9a..2889949fd 100644
--- a/src/app-sdk/midiusbinfo/pch.h
+++ b/src/app-sdk/midiusbinfo/pch.h
@@ -64,6 +64,7 @@ namespace collections = winrt::Windows::Foundation::Collections;
//#include "Devpkey.h"
#include
+
#include "wstring_util.h"
diff --git a/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props b/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
index a1a1ef898..5847802d7 100644
--- a/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
+++ b/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
@@ -41,6 +41,9 @@
$(NugetRoot)\ref\native\Microsoft.Windows.Devices.Midi2.Utilities.SysEx.winmd
+
+ $(NugetRoot)\ref\native\Microsoft.Windows.Devices.Midi2.VirtualPatchBay.winmd
+
$(NugetRoot)\ref\native\Microsoft.Windows.Devices.Midi2.Initialization.winmd
diff --git a/src/app-sdk/winrt-messages/MidiMessageHelper.cpp b/src/app-sdk/winrt-messages/MidiMessageHelper.cpp
index 8b96c75b5..93f469025 100644
--- a/src/app-sdk/winrt-messages/MidiMessageHelper.cpp
+++ b/src/app-sdk/winrt-messages/MidiMessageHelper.cpp
@@ -114,100 +114,6 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
-
- _Use_decl_annotations_
- uint8_t MidiMessageHelper::GetDataByteCountFromSystemExclusive7MessageFirstWord(uint32_t word0) noexcept
- {
- return MIDIWORDNIBBLE4(word0);
- }
-
- _Use_decl_annotations_
- uint8_t MidiMessageHelper::AppendDataBytesFromSingleSystemExclusive7Message(
- uint32_t const word0,
- uint32_t const word1,
- collections::IVector dataBytesToAppendTo) noexcept
- {
- uint8_t messageByteCount = GetDataByteCountFromSystemExclusive7MessageFirstWord(word0);
- uint32_t currentWord = word0;
- uint8_t shift = 8;
-
- for (uint8_t i = 0; i < messageByteCount; i++)
- {
- dataBytesToAppendTo.Append((uint8_t)(currentWord >> shift & 0xFF)); // we don't & 0x7F in case the data is actually bad
-
- if (shift == 0)
- {
- currentWord = word1;
- shift = 24;
- }
- else
- {
- shift -= 8;
- }
- }
-
- return messageByteCount;
- }
-
- _Use_decl_annotations_
- uint8_t MidiMessageHelper::AppendDataBytesFromSingleSystemExclusive7Message(
- midi2::MidiMessage64 const& message,
- collections::IVector dataBytesToAppendTo) noexcept
- {
- return AppendDataBytesFromSingleSystemExclusive7Message(message.Word0(), message.Word1(), dataBytesToAppendTo);
- }
-
-
- _Use_decl_annotations_
- collections::IVector MidiMessageHelper::GetDataBytesFromMultipleSystemExclusive7Messages(
- collections::IIterable const& messages) noexcept
- {
- auto result = winrt::single_threaded_vector();
-
- for (auto const& message : messages)
- {
- AppendDataBytesFromSingleSystemExclusive7Message(message, result);
- }
-
- return result;
- }
-
- _Use_decl_annotations_
- collections::IVector MidiMessageHelper::GetDataBytesFromSingleSystemExclusive7Message(
- uint32_t const word0,
- uint32_t const word1
- ) noexcept
- {
- auto result = winrt::single_threaded_vector();
-
- AppendDataBytesFromSingleSystemExclusive7Message(word0, word1, result);
-
- return result;
- }
-
- _Use_decl_annotations_
- collections::IVector MidiMessageHelper::GetDataBytesFromSingleSystemExclusive7Message(
- midi2::MidiMessage64 const& message) noexcept
- {
- auto result = winrt::single_threaded_vector();
-
- AppendDataBytesFromSingleSystemExclusive7Message(message.Word0(), message.Word1(), result);
-
- return result;
- }
-
-
-
-
-
- _Use_decl_annotations_
- bool MidiMessageHelper::MessageIsSystemExclusive7Message(uint32_t word0) noexcept
- {
- return internal::GetUmpMessageTypeFromFirstWord(word0) == MIDI_UMP_MESSAGE_TYPE_DATA_MESSAGE_64 &&
- internal::GetStatusFromDataMessage64FirstWord(word0) <= 0x03; // 0x0, 0x1, 0x2, 0x3 are SysEx7
- }
-
-
_Use_decl_annotations_
bool MidiMessageHelper::ValidateMessage32MessageType(uint32_t const word0) noexcept
{
@@ -363,6 +269,35 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
}
+ // this works for classic note indexes 0-127
+ _Use_decl_annotations_
+ winrt::hstring MidiMessageHelper::GetNoteDisplayNameFromNoteIndex(uint8_t const noteIndex) noexcept
+ {
+ static const winrt::hstring noteNames[]{ L"C", L"C#/Db", L"D", L"D#/Eb", L"E", L"F", L"F#/Gb", L"G", L"G#/Ab", L"A", L"A#/Bb", L"B" };
+
+ if (noteIndex > 0x7F) return internal::ResourceGetHString(IDS_NOTE_INVALID);
+
+ return noteNames[noteIndex % _countof(noteNames)];
+ }
+
+ // this works for classic note indexes 0-127
+ _Use_decl_annotations_
+ int16_t MidiMessageHelper::GetNoteOctaveFromNoteIndex(uint8_t const noteIndex) noexcept
+ {
+ // default octave range is -2 to 8 with Middle C as C3. Note 0 is C -2, C0 is index 24
+
+ return GetNoteOctaveFromNoteIndex(noteIndex, 3);
+ }
+
+ // this works for classic note indexes 0-127
+ _Use_decl_annotations_
+ int16_t MidiMessageHelper::GetNoteOctaveFromNoteIndex(uint8_t const noteIndex, uint8_t middleCOctave) noexcept
+ {
+ if (noteIndex > 0x7F) return 0;
+ if ((middleCOctave < 1) || (middleCOctave > 7)) return 0; // Middle C is typically 3, 4, or even 5. We allow a bit more.
+
+ return static_cast((noteIndex / 12) - (middleCOctave - 1));
+ }
// Names used in this function are those used in the MIDI 2.0 Specification
@@ -442,7 +377,19 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
case msgs::Midi1ChannelVoiceMessageStatus::PolyPressure:
return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT2_A_POLY_PRESSURE); //L"MIDI 1.0 Poly Pressure";
case msgs::Midi1ChannelVoiceMessageStatus::ControlChange:
- return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT2_B_CONTROL_CHANGE); //L"MIDI 1.0 Control Change";
+ {
+ uint8_t ccNumber = static_cast((word0 & 0x00007F00) >> 8);
+
+ if (ccNumber >= 120)
+ {
+ return internal::ResourceGetHString(IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + ccNumber);
+ }
+ else
+ {
+ return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT2_B_CONTROL_CHANGE); //L"MIDI 1.0 Control Change";
+ }
+ }
+
case msgs::Midi1ChannelVoiceMessageStatus::ProgramChange:
return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT2_C_PROGRAM_CHANGE); //L"MIDI 1.0 Program Change";
case msgs::Midi1ChannelVoiceMessageStatus::ChannelPressure:
@@ -496,7 +443,20 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
case msgs::Midi2ChannelVoiceMessageStatus::PolyPressure:
return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT4_A_POLY_PRESSURE); //L"MIDI 2.0 Poly Pressure";
case msgs::Midi2ChannelVoiceMessageStatus::ControlChange:
- return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT4_B_CONTROL_CHANGE); //L"MIDI 2.0 Control Change";
+ {
+ uint8_t ccNumber = static_cast((word0 & 0x00007F00) >> 8);
+
+ if (ccNumber >= 120)
+ {
+ return internal::ResourceGetHString(IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + ccNumber);
+ }
+ else
+ {
+ return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT4_B_CONTROL_CHANGE); //L"MIDI 2.0 Control Change";
+ }
+ }
+
+
case msgs::Midi2ChannelVoiceMessageStatus::ProgramChange:
return internal::ResourceGetHString(IDS_MESSAGE_DESC_MT4_C_PROGRAM_CHANGE); //L"MIDI 2.0 Program Change";
case msgs::Midi2ChannelVoiceMessageStatus::ChannelPressure:
diff --git a/src/app-sdk/winrt-messages/MidiMessageHelper.h b/src/app-sdk/winrt-messages/MidiMessageHelper.h
index 4ac696763..efeecfee6 100644
--- a/src/app-sdk/winrt-messages/MidiMessageHelper.h
+++ b/src/app-sdk/winrt-messages/MidiMessageHelper.h
@@ -48,7 +48,11 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
static winrt::hstring GetMessageDisplayNameFromFirstWord(_In_ uint32_t const word0) noexcept;
-
+ static winrt::hstring GetNoteDisplayNameFromNoteIndex(_In_ uint8_t const noteIndex) noexcept;
+
+ // these are int16_t becuase IDL doesn't support int8_t
+ static int16_t GetNoteOctaveFromNoteIndex(_In_ uint8_t const noteIndex) noexcept;
+ static int16_t GetNoteOctaveFromNoteIndex(_In_ uint8_t const noteIndex, _In_ uint8_t middleCOctave) noexcept;
static uint8_t GetStatusFromUtilityMessage(_In_ uint32_t const word0) noexcept;
@@ -68,29 +72,6 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation
- static collections::IVector GetDataBytesFromMultipleSystemExclusive7Messages(
- _In_ collections::IIterable const& messages) noexcept;
-
- static collections::IVector GetDataBytesFromSingleSystemExclusive7Message(
- _In_ midi2::MidiMessage64 const& message) noexcept;
-
- static collections::IVector GetDataBytesFromSingleSystemExclusive7Message(
- _In_ uint32_t const word0,
- _In_ uint32_t const word1
- ) noexcept;
-
- static uint8_t AppendDataBytesFromSingleSystemExclusive7Message(
- _In_ midi2::MidiMessage64 const& message,
- _In_ collections::IVector dataBytesToAppendTo) noexcept;
-
- static uint8_t AppendDataBytesFromSingleSystemExclusive7Message(
- _In_ uint32_t const word0,
- _In_ uint32_t const word1,
- _In_ collections::IVector dataBytesToAppendTo) noexcept;
-
- static uint8_t GetDataByteCountFromSystemExclusive7MessageFirstWord(_In_ uint32_t word0) noexcept;
- static bool MessageIsSystemExclusive7Message(_In_ uint32_t word0) noexcept;
-
};
}
namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::factory_implementation
diff --git a/src/app-sdk/winrt-messages/MidiMessageHelper.idl b/src/app-sdk/winrt-messages/MidiMessageHelper.idl
index 5a836fa41..8bbf64b94 100644
--- a/src/app-sdk/winrt-messages/MidiMessageHelper.idl
+++ b/src/app-sdk/winrt-messages/MidiMessageHelper.idl
@@ -53,24 +53,13 @@ namespace Microsoft.Windows.Devices.Midi2.Messages
static String GetMessageDisplayNameFromFirstWord(UInt32 word0);
+ static String GetNoteDisplayNameFromNoteIndex(UInt8 noteIndex);
+
+ static Int16 GetNoteOctaveFromNoteIndex(UInt8 noteIndex);
+ static Int16 GetNoteOctaveFromNoteIndex(UInt8 noteIndex, UInt8 middleCOctave);
static IVector GetPacketListFromWordList(UInt64 timestamp, IIterable words);
static IVector GetWordListFromPacketList(IIterable words);
-
-
- // System Exclusive 7 handling
- static IVector GetDataBytesFromMultipleSystemExclusive7Messages(IIterable messages);
-
- static IVector GetDataBytesFromSingleSystemExclusive7Message(Microsoft.Windows.Devices.Midi2.MidiMessage64 message);
- static IVector GetDataBytesFromSingleSystemExclusive7Message(UInt32 word0, UInt32 word1);
-
- static UInt8 AppendDataBytesFromSingleSystemExclusive7Message(Microsoft.Windows.Devices.Midi2.MidiMessage64 message, IVector dataBytesToAppendTo);
- static UInt8 AppendDataBytesFromSingleSystemExclusive7Message(UInt32 word0, UInt32 word1, IVector dataBytesToAppendTo);
-
- static UInt8 GetDataByteCountFromSystemExclusive7MessageFirstWord(UInt32 word0);
- static Boolean MessageIsSystemExclusive7Message(UInt32 word0);
-
-
};
}
diff --git a/src/app-sdk/winrt-messages/Resources.rc b/src/app-sdk/winrt-messages/Resources.rc
index 94bb12530..102813ae3 100644
Binary files a/src/app-sdk/winrt-messages/Resources.rc and b/src/app-sdk/winrt-messages/Resources.rc differ
diff --git a/src/app-sdk/winrt-messages/resource.h b/src/app-sdk/winrt-messages/resource.h
index 2b23725d1..481e63449 100644
--- a/src/app-sdk/winrt-messages/resource.h
+++ b/src/app-sdk/winrt-messages/resource.h
@@ -40,6 +40,12 @@
#define IDS_MIDI_COMMON_LABEL_MUID_SHORT 50109
+// Note index info
+
+#define IDS_NOTE_INVALID 50199
+
+
+
// Message type descriptions. These are optionally displayed by apps using the API
@@ -197,5 +203,17 @@
#define IDS_MESSAGE_DESC_MTF_UNKNOWN 51999
+// CC Mode messages
+// these are the base index + the CC number
+
+#define IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX 60000
+#define IDS_MESSAGE_DESC_CC_MODE_ALL_SOUNDS_OFF IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 120
+#define IDS_MESSAGE_DESC_CC_MODE_RESET_CONTROLLERS IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 121
+#define IDS_MESSAGE_DESC_CC_MODE_LOCAL_CONTROL IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 122
+#define IDS_MESSAGE_DESC_CC_MODE_ALL_NOTES_OFF IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 123
+#define IDS_MESSAGE_DESC_CC_MODE_OMNI_OFF IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 124
+#define IDS_MESSAGE_DESC_CC_MODE_OMNI_ON IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 125
+#define IDS_MESSAGE_DESC_CC_MODE_MONO_ON IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 126
+#define IDS_MESSAGE_DESC_CC_MODE_POLY_ON IDS_MESSAGE_DESC_CC_MODE_BASE_INDEX + 127
// Errors
diff --git a/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj b/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj
index d185b287d..e5340dd2d 100644
--- a/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj
+++ b/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj
@@ -273,7 +273,12 @@
-
+
+ MidiSystemExclusiveMessageHelper.idl
+
+
+ MidiSystemExclusiveSender.idl
+
@@ -351,7 +356,12 @@
NotUsing
NotUsing
-
+
+ MidiSystemExclusiveMessageHelper.idl
+
+
+ MidiSystemExclusiveSender.idl
+
Create
@@ -359,6 +369,7 @@
+
diff --git a/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj.filters b/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj.filters
index 1c3dabcfa..7a8e2da08 100644
--- a/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj.filters
+++ b/src/app-sdk/winrt-utilities-sysex/Microsoft.Windows.Devices.Midi2.Utilities.SysEx.vcxproj.filters
@@ -36,6 +36,9 @@
libmidi2\src
+
+ SDK\Messages
+
@@ -72,6 +75,9 @@
libmidi2\include
+
+ SDK\Messages
+
@@ -86,6 +92,9 @@
SDK\SysEx Sending
+
+ SDK\Messages
+
@@ -111,6 +120,9 @@
{bbdd01b4-c1f5-4b22-9f6e-060d872329f5}
+
+ {2268b5d2-008c-4671-85d2-496e318b0c03}
+
diff --git a/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.cpp b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.cpp
new file mode 100644
index 000000000..245133fa7
--- /dev/null
+++ b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.cpp
@@ -0,0 +1,110 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiSystemExclusiveMessageHelper.h"
+#include "MidiSystemExclusiveMessageHelper.g.cpp"
+
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::Utilities::SysEx::implementation
+{
+
+
+
+ _Use_decl_annotations_
+ uint8_t MidiSystemExclusiveMessageHelper::GetDataByteCountFromSystemExclusive7MessageFirstWord(uint32_t word0) noexcept
+ {
+ return MIDIWORDNIBBLE4(word0);
+ }
+
+ _Use_decl_annotations_
+ uint8_t MidiSystemExclusiveMessageHelper::AppendDataBytesFromSingleSystemExclusive7Message(
+ uint32_t const word0,
+ uint32_t const word1,
+ collections::IVector dataBytesToAppendTo) noexcept
+ {
+ uint8_t messageByteCount = GetDataByteCountFromSystemExclusive7MessageFirstWord(word0);
+ uint32_t currentWord = word0;
+ uint8_t shift = 8;
+
+ for (uint8_t i = 0; i < messageByteCount; i++)
+ {
+ dataBytesToAppendTo.Append((uint8_t)(currentWord >> shift & 0xFF)); // we don't & 0x7F in case the data is actually bad
+
+ if (shift == 0)
+ {
+ currentWord = word1;
+ shift = 24;
+ }
+ else
+ {
+ shift -= 8;
+ }
+ }
+
+ return messageByteCount;
+ }
+
+ _Use_decl_annotations_
+ uint8_t MidiSystemExclusiveMessageHelper::AppendDataBytesFromSingleSystemExclusive7Message(
+ midi2::MidiMessage64 const& message,
+ collections::IVector dataBytesToAppendTo) noexcept
+ {
+ return AppendDataBytesFromSingleSystemExclusive7Message(message.Word0(), message.Word1(), dataBytesToAppendTo);
+ }
+
+
+ _Use_decl_annotations_
+ collections::IVector MidiSystemExclusiveMessageHelper::GetDataBytesFromMultipleSystemExclusive7Messages(
+ collections::IIterable const& messages) noexcept
+ {
+ auto result = winrt::single_threaded_vector();
+
+ for (auto const& message : messages)
+ {
+ AppendDataBytesFromSingleSystemExclusive7Message(message, result);
+ }
+
+ return result;
+ }
+
+ _Use_decl_annotations_
+ collections::IVector MidiSystemExclusiveMessageHelper::GetDataBytesFromSingleSystemExclusive7Message(
+ uint32_t const word0,
+ uint32_t const word1
+ ) noexcept
+ {
+ auto result = winrt::single_threaded_vector();
+
+ AppendDataBytesFromSingleSystemExclusive7Message(word0, word1, result);
+
+ return result;
+ }
+
+ _Use_decl_annotations_
+ collections::IVector MidiSystemExclusiveMessageHelper::GetDataBytesFromSingleSystemExclusive7Message(
+ midi2::MidiMessage64 const& message) noexcept
+ {
+ auto result = winrt::single_threaded_vector();
+
+ AppendDataBytesFromSingleSystemExclusive7Message(message.Word0(), message.Word1(), result);
+
+ return result;
+ }
+
+
+
+
+
+ _Use_decl_annotations_
+ bool MidiSystemExclusiveMessageHelper::MessageIsSystemExclusive7Message(uint32_t word0) noexcept
+ {
+ return internal::GetUmpMessageTypeFromFirstWord(word0) == MIDI_UMP_MESSAGE_TYPE_DATA_MESSAGE_64 &&
+ internal::GetStatusFromDataMessage64FirstWord(word0) <= 0x03; // 0x0, 0x1, 0x2, 0x3 are SysEx7
+ }
+}
diff --git a/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.h b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.h
new file mode 100644
index 000000000..ee70856e7
--- /dev/null
+++ b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.h
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiSystemExclusiveMessageHelper.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::Utilities::SysEx::implementation
+{
+ struct MidiSystemExclusiveMessageHelper
+ {
+ MidiSystemExclusiveMessageHelper() = default;
+
+ static collections::IVector GetDataBytesFromMultipleSystemExclusive7Messages(
+ _In_ collections::IIterable const& messages) noexcept;
+
+ static collections::IVector GetDataBytesFromSingleSystemExclusive7Message(
+ _In_ midi2::MidiMessage64 const& message) noexcept;
+
+ static collections::IVector GetDataBytesFromSingleSystemExclusive7Message(
+ _In_ uint32_t const word0,
+ _In_ uint32_t const word1
+ ) noexcept;
+
+ static uint8_t AppendDataBytesFromSingleSystemExclusive7Message(
+ _In_ midi2::MidiMessage64 const& message,
+ _In_ collections::IVector dataBytesToAppendTo) noexcept;
+
+ static uint8_t AppendDataBytesFromSingleSystemExclusive7Message(
+ _In_ uint32_t const word0,
+ _In_ uint32_t const word1,
+ _In_ collections::IVector dataBytesToAppendTo) noexcept;
+
+ static uint8_t GetDataByteCountFromSystemExclusive7MessageFirstWord(_In_ uint32_t word0) noexcept;
+ static bool MessageIsSystemExclusive7Message(_In_ uint32_t word0) noexcept;
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::Utilities::SysEx::factory_implementation
+{
+ struct MidiSystemExclusiveMessageHelper : MidiSystemExclusiveMessageHelperT
+ {
+ };
+
+}
diff --git a/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.idl b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.idl
new file mode 100644
index 000000000..70e71d0ae
--- /dev/null
+++ b/src/app-sdk/winrt-utilities-sysex/MidiSystemExclusiveMessageHelper.idl
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+namespace Microsoft.Windows.Devices.Midi2.Utilities.SysEx
+{
+ static runtimeclass MidiSystemExclusiveMessageHelper
+ {
+ // System Exclusive 7 handling
+ static IVector GetDataBytesFromMultipleSystemExclusive7Messages(IIterable messages);
+
+ static IVector GetDataBytesFromSingleSystemExclusive7Message(Microsoft.Windows.Devices.Midi2.MidiMessage64 message);
+ static IVector GetDataBytesFromSingleSystemExclusive7Message(UInt32 word0, UInt32 word1);
+
+ static UInt8 AppendDataBytesFromSingleSystemExclusive7Message(Microsoft.Windows.Devices.Midi2.MidiMessage64 message, IVector dataBytesToAppendTo);
+ static UInt8 AppendDataBytesFromSingleSystemExclusive7Message(UInt32 word0, UInt32 word1, IVector dataBytesToAppendTo);
+
+ static UInt8 GetDataByteCountFromSystemExclusive7MessageFirstWord(UInt32 word0);
+ static Boolean MessageIsSystemExclusive7Message(UInt32 word0);
+
+ // System Exclusive 8 handling
+
+
+ };
+}
diff --git a/src/app-sdk/winrt-utilities-sysex/pch.h b/src/app-sdk/winrt-utilities-sysex/pch.h
index 649f36120..4c02800cb 100644
--- a/src/app-sdk/winrt-utilities-sysex/pch.h
+++ b/src/app-sdk/winrt-utilities-sysex/pch.h
@@ -58,6 +58,7 @@ namespace midi2 = ::winrt::Microsoft::Windows::Devices::Midi2;
#include
#include
#include
+#include
// SDK shared
#include
@@ -73,4 +74,5 @@ namespace implementation = ::winrt::Microsoft::Windows::Devices::Midi2::Utilitie
#include "MidiSystemExclusiveSender.h"
+#include "MidiSystemExclusiveMessageHelper.h"
diff --git a/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj b/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj
new file mode 100644
index 000000000..3344ca42d
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj
@@ -0,0 +1,352 @@
+
+
+
+
+ Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+ $(ProjectName)
+ {7BCB819F-CA97-4312-BF7B-1919A5CCDE69}
+ true
+ true
+ true
+ true
+ C++/WinRT
+ true
+ 10.0
+ 10.0.20348.0
+ true
+ en-US
+ 14.0
+ true
+ Windows Store
+ 10.0
+ None
+
+
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ ARM64EC
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ ARM64EC
+
+
+ Release
+ x64
+
+
+
+ DynamicLibrary
+ v143
+ v142
+ v141
+ v140
+ Unicode
+ false
+
+
+ true
+
+
+ false
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(IncludePath)
+ $(ProjectName)
+ true
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+ $(IncludePath)
+ $(ProjectName)
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+ $(IncludePath)
+ $(ProjectName)
+ true
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+ $(IncludePath)
+ $(ProjectName)
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+ $(IncludePath)
+ $(ProjectName)
+ true
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+ $(IncludePath)
+ $(ProjectName)
+ $(SolutionDir)vsfiles\out\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)vsfiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
+ $(SolutionDir)VSFiles\intermediate\$(MSBuildProjectName)\$(Platform)\$(Configuration)\GeneratedFiles\
+ $(LibraryPath)
+
+
+
+ Use
+ pch.h
+ $(IntDir)pch.pch
+ Level4
+ %(AdditionalOptions) /bigobj
+ _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)
+ $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)
+
+
+ Console
+ false
+ midi-app-sdk.def
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions);WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
+ stdcpp20
+ false
+ true
+ true
+ true
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ stdcpp20
+ stdcpp20
+
+
+ false
+ false
+ %(AdditionalDependencies)
+
+
+ false
+ false
+ %(AdditionalDependencies)
+
+
+ false
+ false
+ %(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Yes
+
+
+ Yes
+
+
+ Yes
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions);WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ $(SolutionDir)..\api\inc;$(SolutionDir)..\shared\api-ref\$(Platform);$(SolutionDir)sdk-shared;%(AdditionalIncludeDirectories)
+ true
+ true
+ true
+ stdcpp20
+ stdcpp20
+ stdcpp20
+
+
+ true
+ true
+ false
+ false
+ false
+ %(AdditionalDependencies)
+ %(AdditionalDependencies)
+ %(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Yes
+
+
+ Yes
+
+
+ Yes
+
+
+
+
+ MidiVirtualPatchBayDestinationDefinition.idl
+
+
+ MidiVirtualPatchBayManager.idl
+
+
+ MidiVirtualPatchBayRouteCreationConfig.idl
+
+
+ MidiVirtualPatchBayRouteDefinition.idl
+
+
+ MidiVirtualPatchBayRouteRemovalConfig.idl
+
+
+ MidiVirtualPatchBayRouteUpdateConfig.idl
+
+
+ MidiVirtualPatchBaySourceDefinition.idl
+
+
+
+
+
+
+ MidiVirtualPatchBayDestinationDefinition.idl
+
+
+ MidiVirtualPatchBayManager.idl
+
+
+ MidiVirtualPatchBayRouteCreationConfig.idl
+
+
+ MidiVirtualPatchBayRouteDefinition.idl
+
+
+ MidiVirtualPatchBayRouteRemovalConfig.idl
+
+
+ MidiVirtualPatchBayRouteUpdateConfig.idl
+
+
+ MidiVirtualPatchBaySourceDefinition.idl
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {9eaa3af3-7328-4f67-a011-e2dd8fbaa4c4}
+
+
+ {72d1a831-0492-41cc-aa58-bdd05c1099f7}
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj.filters b/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj.filters
new file mode 100644
index 000000000..4fcdb3cb2
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/Microsoft.Windows.Devices.Midi2.VirtualPatchBay.vcxproj.filters
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+ SDK
+
+
+ SDK
+
+
+ SDK
+
+
+
+
+
+ SDK
+
+
+ SDK
+
+
+ SDK
+
+
+
+
+ SDK\Configuration
+
+
+ SDK\Configuration
+
+
+ SDK\Management
+
+
+ SDK\Management
+
+
+ SDK\Definitions
+
+
+ SDK\Definitions
+
+
+ SDK\Configuration
+
+
+ SDK\Definitions
+
+
+ SDK\Management
+
+
+
+
+
+
+
+
+
+ {be86096a-366a-491b-825e-1722b96c678d}
+
+
+ {7bedd7f9-3966-4a85-b089-916e72f4211d}
+
+
+ {656ea1ee-7afd-4546-89aa-1e2ed9d80f83}
+
+
+ {1d805a69-c470-459d-be7d-59011bb9d8d9}
+
+
+
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.cpp
new file mode 100644
index 000000000..d054348cc
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.cpp
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayDestinationDefinition.h"
+#include "MidiVirtualPatchBayDestinationDefinition.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+
+
+ collections::IMap MidiVirtualPatchBayDestinationDefinition::GroupTransformMap()
+ {
+ throw hresult_not_implemented();
+ }
+
+ void MidiVirtualPatchBayDestinationDefinition::GroupTransformMap(collections::IMap const& value)
+ {
+ UNREFERENCED_PARAMETER(value);
+
+ throw hresult_not_implemented();
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.h
new file mode 100644
index 000000000..57c20729d
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.h
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBayDestinationDefinition.g.h"
+
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayDestinationDefinition : MidiVirtualPatchBayDestinationDefinitionT
+ {
+ MidiVirtualPatchBayDestinationDefinition() = default;
+
+ bool IsEnabled() { return m_isEnabled; }
+ void IsEnabled(_In_ bool value) { m_isEnabled = value; }
+
+ winrt::hstring EndpointDeviceId() { return m_endpointDeviceId; }
+ void EndpointDeviceId (_In_ winrt::hstring const& value) { m_endpointDeviceId = value; }
+
+ collections::IMap GroupTransformMap();
+ void GroupTransformMap(_In_ collections::IMap const& value);
+
+ private:
+ bool m_isEnabled{ true };
+ winrt::hstring m_endpointDeviceId{};
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayDestinationDefinition : MidiVirtualPatchBayDestinationDefinitionT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.idl
new file mode 100644
index 000000000..f1aab3352
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayDestinationDefinition.idl
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBayDestinationDefinition
+ {
+ MidiVirtualPatchBayDestinationDefinition();
+
+ Boolean IsEnabled;
+
+ String EndpointDeviceId; // TODO: May want to have fuzzy match here
+
+ // first group is incoming group. Second group is the group to transform it into in the destination
+ // If this map is empty, we map 1:1
+ // source group must be unique (0-15), but destination group can be duplicated to allow mapping multiple
+ // source groups to a single destination group. The opposite is not true, however - one source group
+ // cannot be mapped to multiple destination groups, as that would require duplicating messages
+ // This group map is also how we handle MIDI 1.0 devices and mapping to the correct port/cable.
+ IMap GroupTransformMap;
+ }
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.cpp
new file mode 100644
index 000000000..b04679f0c
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.cpp
@@ -0,0 +1,66 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayManager.h"
+#include "MidiVirtualPatchBayManager.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ bool MidiVirtualPatchBayManager::IsTransportAvailable()
+ {
+ throw hresult_not_implemented();
+ }
+ winrt::guid MidiVirtualPatchBayManager::AbstractionId()
+ {
+ throw hresult_not_implemented();
+ }
+
+ _Use_decl_annotations_
+ local::MidiVirtualPatchBayRouteCreationResult MidiVirtualPatchBayManager::CreateRoute(
+ local::MidiVirtualPatchBayRouteCreationConfig const& creationConfig)
+ {
+ UNREFERENCED_PARAMETER(creationConfig);
+
+ return {};
+ }
+
+ _Use_decl_annotations_
+ bool MidiVirtualPatchBayManager::RemoveRoute(
+ local::MidiVirtualPatchBayRouteRemovalConfig const& removalConfig)
+ {
+ UNREFERENCED_PARAMETER(removalConfig);
+
+ return false;
+ }
+
+ _Use_decl_annotations_
+ local::MidiVirtualPatchBayRouteUpdateResult MidiVirtualPatchBayManager::UpdateRoute(
+ local::MidiVirtualPatchBayRouteUpdateConfig const& updateConfig)
+ {
+ UNREFERENCED_PARAMETER(updateConfig);
+
+ return {};
+ }
+
+ collections::IVector MidiVirtualPatchBayManager::GetRoutes()
+ {
+ throw hresult_not_implemented();
+ }
+
+ _Use_decl_annotations_
+ local::MidiVirtualPatchBayRouteDefinition MidiVirtualPatchBayManager::GetRoute(
+ winrt::guid routeId)
+ {
+ UNREFERENCED_PARAMETER(routeId);
+
+ throw hresult_not_implemented();
+ }
+
+
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.h
new file mode 100644
index 000000000..d2315eaae
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.h
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBayManager.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayManager : MidiVirtualPatchBayManagerT
+ {
+ MidiVirtualPatchBayManager() = default;
+
+ static bool IsTransportAvailable();
+ static winrt::guid AbstractionId();
+
+
+ static local::MidiVirtualPatchBayRouteCreationResult CreateRoute(
+ _In_ local::MidiVirtualPatchBayRouteCreationConfig const& creationConfig);
+
+ static local::MidiVirtualPatchBayRouteUpdateResult UpdateRoute(
+ _In_ local::MidiVirtualPatchBayRouteUpdateConfig const& updateConfig);
+
+ static bool RemoveRoute(
+ _In_ local::MidiVirtualPatchBayRouteRemovalConfig const& removalConfig);
+
+ static collections::IVector GetRoutes();
+
+ static local::MidiVirtualPatchBayRouteDefinition GetRoute(
+ _In_ winrt::guid routeId);
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayManager : MidiVirtualPatchBayManagerT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.idl
new file mode 100644
index 000000000..ff779e548
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayManager.idl
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+import "MidiVirtualPatchBayRouteCreationResult.idl";
+import "MidiVirtualPatchBayRouteUpdateResult.idl";
+
+import "MidiVirtualPatchBayRouteCreationConfig.idl";
+import "MidiVirtualPatchBayRouteRemovalConfig.idl";
+import "MidiVirtualPatchBayRouteUpdateConfig.idl";
+
+import "MidiVirtualPatchBayRouteDefinition.idl";
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ static runtimeclass MidiVirtualPatchBayManager
+ {
+ static Boolean IsTransportAvailable{ get; };
+ static Guid AbstractionId{ get; };
+
+ static IVector GetRoutes();
+ static MidiVirtualPatchBayRouteDefinition GetRoute(Guid routeId);
+
+
+ static MidiVirtualPatchBayRouteCreationResult CreateRoute(
+ MidiVirtualPatchBayRouteCreationConfig creationConfig);
+
+ static MidiVirtualPatchBayRouteUpdateResult UpdateRoute(
+ MidiVirtualPatchBayRouteUpdateConfig updateConfig);
+
+ static Boolean RemoveRoute(
+ MidiVirtualPatchBayRouteRemovalConfig removalConfig);
+
+ }
+}
+
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.cpp
new file mode 100644
index 000000000..babfd057e
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayRouteCreationConfig.h"
+#include "MidiVirtualPatchBayRouteCreationConfig.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ _Use_decl_annotations_
+ MidiVirtualPatchBayRouteCreationConfig::MidiVirtualPatchBayRouteCreationConfig(
+ winrt::guid const& routeId)
+ {
+ m_routeId = routeId;
+ }
+
+ winrt::hstring MidiVirtualPatchBayRouteCreationConfig::GetConfigJson()
+ {
+ throw hresult_not_implemented();
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.h
new file mode 100644
index 000000000..291169295
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.h
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBayRouteCreationConfig.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayRouteCreationConfig : MidiVirtualPatchBayRouteCreationConfigT
+ {
+ MidiVirtualPatchBayRouteCreationConfig() = default;
+ MidiVirtualPatchBayRouteCreationConfig(_In_ winrt::guid const& routeId);
+
+ winrt::guid RouteId() { return m_routeId; }
+ void RouteId(_In_ winrt::guid const& value) { m_routeId = value; }
+
+ winrt::guid TransportId() { return m_transportId; }
+ bool IsFromCurrentConfigFile() { return m_isFromCurrentConfigFile; }
+ winrt::hstring GetConfigJson();
+
+ private:
+ winrt::guid m_routeId{};
+ winrt::guid m_transportId{};
+ bool m_isFromCurrentConfigFile{ false };
+
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayRouteCreationConfig : MidiVirtualPatchBayRouteCreationConfigT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.idl
new file mode 100644
index 000000000..9b88b042d
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationConfig.idl
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+import "MidiVirtualPatchBayRouteDefinition.idl";
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBayRouteCreationConfig : Microsoft.Windows.Devices.Midi2.ServiceConfig.IMidiServiceTransportPluginConfig
+ {
+ MidiVirtualPatchBayRouteCreationConfig();
+
+ MidiVirtualPatchBayRouteCreationConfig(
+ Guid routeId
+ );
+
+ Guid RouteId;
+
+ }
+}
+
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationResult.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationResult.idl
new file mode 100644
index 000000000..f58205234
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteCreationResult.idl
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ struct MidiVirtualPatchBayRouteCreationResult
+ {
+ Boolean Success;
+
+ Guid RouteId;
+
+
+ };
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.cpp
new file mode 100644
index 000000000..de03478fe
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.cpp
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayRouteDefinition.h"
+#include "MidiVirtualPatchBayRouteDefinition.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ local::MidiVirtualPatchBayRouteDefinition MidiVirtualPatchBayRouteDefinition::CreateFromConfigJson(winrt::hstring const& jsonSection)
+ {
+ UNREFERENCED_PARAMETER(jsonSection);
+
+ throw hresult_not_implemented();
+ }
+
+ collections::IVector MidiVirtualPatchBayRouteDefinition::Sources()
+ {
+ throw hresult_not_implemented();
+ }
+ void MidiVirtualPatchBayRouteDefinition::Sources(collections::IVector const& value)
+ {
+ UNREFERENCED_PARAMETER(value);
+
+ throw hresult_not_implemented();
+ }
+
+ collections::IVector MidiVirtualPatchBayRouteDefinition::Destinations()
+ {
+ throw hresult_not_implemented();
+ }
+
+ void MidiVirtualPatchBayRouteDefinition::Destinations(collections::IVector const& value)
+ {
+ UNREFERENCED_PARAMETER(value);
+
+ throw hresult_not_implemented();
+ }
+
+ winrt::hstring MidiVirtualPatchBayRouteDefinition::GetConfigJson()
+ {
+ throw hresult_not_implemented();
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.h
new file mode 100644
index 000000000..94dda33c0
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.h
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+#pragma once
+#include "MidiVirtualPatchBayRouteDefinition.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayRouteDefinition : MidiVirtualPatchBayRouteDefinitionT
+ {
+ MidiVirtualPatchBayRouteDefinition() = default;
+
+ static local::MidiVirtualPatchBayRouteDefinition CreateFromConfigJson(_In_ winrt::hstring const& jsonSection);
+
+ bool IsEnabled() { return m_isEnabled; }
+ void IsEnabled(bool value) { m_isEnabled = value; }
+
+ collections::IVector Sources();
+ void Sources(_In_ collections::IVector const& value);
+
+ collections::IVector Destinations();
+ void Destinations(_In_ collections::IVector const& value);
+
+ hstring GetConfigJson();
+
+ private:
+ bool m_isEnabled{ true };
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayRouteDefinition : MidiVirtualPatchBayRouteDefinitionT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.idl
new file mode 100644
index 000000000..9065f77ce
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteDefinition.idl
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+import "MidiVirtualPatchBaySourceDefinition.idl";
+import "MidiVirtualPatchBayDestinationDefinition.idl";
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBayRouteDefinition
+ {
+ MidiVirtualPatchBayRouteDefinition();
+
+ Boolean IsEnabled;
+
+ IVector Sources;
+ IVector Destinations;
+
+ static MidiVirtualPatchBayRouteDefinition CreateFromConfigJson(String jsonSection);
+
+ String GetConfigJson();
+ }
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.cpp
new file mode 100644
index 000000000..0519694ab
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.cpp
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayRouteRemovalConfig.h"
+#include "MidiVirtualPatchBayRouteRemovalConfig.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ _Use_decl_annotations_
+ MidiVirtualPatchBayRouteRemovalConfig::MidiVirtualPatchBayRouteRemovalConfig(
+ winrt::guid const& routeId)
+ {
+ m_routeId = routeId;
+
+ }
+
+ winrt::hstring MidiVirtualPatchBayRouteRemovalConfig::GetConfigJson()
+ {
+ throw hresult_not_implemented();
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.h
new file mode 100644
index 000000000..0ac579039
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.h
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBayRouteRemovalConfig.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayRouteRemovalConfig : MidiVirtualPatchBayRouteRemovalConfigT
+ {
+ MidiVirtualPatchBayRouteRemovalConfig() = default;
+ MidiVirtualPatchBayRouteRemovalConfig(_In_ winrt::guid const& routeId);
+
+ winrt::guid RouteId() { return m_routeId; }
+ void RouteId(_In_ winrt::guid const& value) { m_routeId = value; }
+
+ winrt::guid TransportId() { return m_transportId; }
+ bool IsFromCurrentConfigFile() { return m_isFromCurrentConfigFile; }
+ winrt::hstring GetConfigJson();
+
+ private:
+ winrt::guid m_routeId{};
+ winrt::guid m_transportId{};
+ bool m_isFromCurrentConfigFile{ false };
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayRouteRemovalConfig : MidiVirtualPatchBayRouteRemovalConfigT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.idl
new file mode 100644
index 000000000..79b3e9a70
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteRemovalConfig.idl
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+import "MidiVirtualPatchBayRouteDefinition.idl";
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBayRouteRemovalConfig : Microsoft.Windows.Devices.Midi2.ServiceConfig.IMidiServiceTransportPluginConfig
+ {
+ MidiVirtualPatchBayRouteRemovalConfig(Guid routeId);
+
+ Guid RouteId;
+ }
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.cpp
new file mode 100644
index 000000000..3a25b2e67
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.cpp
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBayRouteUpdateConfig.h"
+#include "MidiVirtualPatchBayRouteUpdateConfig.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ _Use_decl_annotations_
+ MidiVirtualPatchBayRouteUpdateConfig::MidiVirtualPatchBayRouteUpdateConfig(
+ winrt::guid const& routeId)
+ {
+ m_routeId = routeId;
+
+ }
+
+ winrt::hstring MidiVirtualPatchBayRouteUpdateConfig::GetConfigJson()
+ {
+ throw hresult_not_implemented();
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.h
new file mode 100644
index 000000000..b64df3707
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.h
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBayRouteUpdateConfig.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBayRouteUpdateConfig : MidiVirtualPatchBayRouteUpdateConfigT
+ {
+ MidiVirtualPatchBayRouteUpdateConfig() = default;
+ MidiVirtualPatchBayRouteUpdateConfig(_In_ winrt::guid const& routeId);
+
+ winrt::guid RouteId() { return m_routeId; }
+ void RouteId(_In_ winrt::guid const& value) { m_routeId = value; }
+
+ winrt::guid TransportId() { return m_transportId; }
+ bool IsFromCurrentConfigFile() { return m_isFromCurrentConfigFile; }
+ winrt::hstring GetConfigJson();
+
+ private:
+ winrt::guid m_routeId{};
+ winrt::guid m_transportId{};
+ bool m_isFromCurrentConfigFile{ false };
+
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBayRouteUpdateConfig : MidiVirtualPatchBayRouteUpdateConfigT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.idl
new file mode 100644
index 000000000..e0aea16d9
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateConfig.idl
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+import "MidiVirtualPatchBayRouteDefinition.idl";
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBayRouteUpdateConfig : Microsoft.Windows.Devices.Midi2.ServiceConfig.IMidiServiceTransportPluginConfig
+ {
+ MidiVirtualPatchBayRouteUpdateConfig();
+
+ MidiVirtualPatchBayRouteUpdateConfig(
+ Guid routeId
+ );
+
+ Guid RouteId;
+ }
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateResult.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateResult.idl
new file mode 100644
index 000000000..15425e004
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBayRouteUpdateResult.idl
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ struct MidiVirtualPatchBayRouteUpdateResult
+ {
+ Boolean Success;
+
+ Guid RouteId;
+
+
+ };
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.cpp b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.cpp
new file mode 100644
index 000000000..c84ca2c98
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.cpp
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#include "pch.h"
+#include "MidiVirtualPatchBaySourceDefinition.h"
+#include "MidiVirtualPatchBaySourceDefinition.g.cpp"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+
+ collections::IVector MidiVirtualPatchBaySourceDefinition::IncludedMessageTypes()
+ {
+ throw hresult_not_implemented();
+ }
+
+ _Use_decl_annotations_
+ void MidiVirtualPatchBaySourceDefinition::IncludedMessageTypes(
+ collections::IVector const& value)
+ {
+ UNREFERENCED_PARAMETER(value);
+
+ }
+
+ collections::IVector MidiVirtualPatchBaySourceDefinition::IncludedGroups()
+ {
+ throw hresult_not_implemented();
+ }
+
+ _Use_decl_annotations_
+ void MidiVirtualPatchBaySourceDefinition::IncludedGroups(
+ collections::IVector const& value)
+ {
+ UNREFERENCED_PARAMETER(value);
+
+ }
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.h b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.h
new file mode 100644
index 000000000..772668d1a
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.h
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+#include "MidiVirtualPatchBaySourceDefinition.g.h"
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation
+{
+ struct MidiVirtualPatchBaySourceDefinition : MidiVirtualPatchBaySourceDefinitionT
+ {
+ MidiVirtualPatchBaySourceDefinition() = default;
+
+ bool IsEnabled() { return m_isEnabled; }
+ void IsEnabled(_In_ bool value) { m_isEnabled = value; }
+
+ winrt::hstring EndpointDeviceId() { return m_endpointDeviceId; }
+ void EndpointDeviceId(_In_ winrt::hstring const& value) { m_endpointDeviceId = value; }
+
+
+ collections::IVector IncludedMessageTypes();
+ void IncludedMessageTypes(_In_ collections::IVector const& value);
+
+ collections::IVector IncludedGroups();
+ void IncludedGroups(_In_ collections::IVector const& value);
+
+ private:
+ bool m_isEnabled{ true };
+ winrt::hstring m_endpointDeviceId{};
+ };
+}
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::factory_implementation
+{
+ struct MidiVirtualPatchBaySourceDefinition : MidiVirtualPatchBaySourceDefinitionT
+ {
+ };
+}
diff --git a/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.idl b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.idl
new file mode 100644
index 000000000..745b5aabb
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/MidiVirtualPatchBaySourceDefinition.idl
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+namespace Microsoft.Windows.Devices.Midi2.VirtualPatchBay
+{
+ [default_interface]
+ runtimeclass MidiVirtualPatchBaySourceDefinition
+ {
+ MidiVirtualPatchBaySourceDefinition();
+
+ Boolean IsEnabled;
+
+ String EndpointDeviceId; // TODO: May want to have fuzzy match here
+
+ // message types to include. If empty, all types are included.
+ IVector IncludedMessageTypes;
+
+ // only for messages with groups. If this is empty, all groups are included.
+ IVector IncludedGroups;
+ }
+}
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/PropertySheet.props b/src/app-sdk/winrt-virtual-patchbay/PropertySheet.props
new file mode 100644
index 000000000..e34141b01
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/PropertySheet.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/makefile.inc b/src/app-sdk/winrt-virtual-patchbay/makefile.inc
new file mode 100644
index 000000000..bad71dcc9
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/makefile.inc
@@ -0,0 +1,3 @@
+$(OBJ_PATH)\$(O)\merged\Windows.Devices.Midi2.winmd :
+ -$(MKDIR) $(OBJ_PATH)\$(O)\merged
+ $(MDMERGE) -i $(OBJ_PATH)\$(O) -o $(OBJ_PATH)\$(O)\merged -metadata_dir $(PROJECT_SDK_METADATA_PATH) -partial
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/midi-app-sdk.def b/src/app-sdk/winrt-virtual-patchbay/midi-app-sdk.def
new file mode 100644
index 000000000..24e7c1235
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/midi-app-sdk.def
@@ -0,0 +1,3 @@
+EXPORTS
+DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
+DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
diff --git a/src/app-sdk/winrt-virtual-patchbay/packages.config b/src/app-sdk/winrt-virtual-patchbay/packages.config
new file mode 100644
index 000000000..7b7f4f96c
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app-sdk/winrt-virtual-patchbay/pch.cpp b/src/app-sdk/winrt-virtual-patchbay/pch.cpp
new file mode 100644
index 000000000..b437ca7e5
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/pch.cpp
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+#include "pch.h"
diff --git a/src/app-sdk/winrt-virtual-patchbay/pch.h b/src/app-sdk/winrt-virtual-patchbay/pch.h
new file mode 100644
index 000000000..02a6186b4
--- /dev/null
+++ b/src/app-sdk/winrt-virtual-patchbay/pch.h
@@ -0,0 +1,114 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App SDK and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+
+
+#pragma once
+
+//#define _VSDESIGNER_DONT_LOAD_AS_DLL
+
+
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace json = ::winrt::Windows::Data::Json;
+namespace enumeration = ::winrt::Windows::Devices::Enumeration;
+namespace midi1 = ::winrt::Windows::Devices::Midi;
+namespace foundation = ::winrt::Windows::Foundation;
+namespace collections = ::winrt::Windows::Foundation::Collections;
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+// pre-declare namespaces
+
+namespace WindowsMidiServicesInternal {};
+namespace winrt::Microsoft::Windows::Devices::Midi2 {};
+
+namespace internal = ::WindowsMidiServicesInternal;
+namespace midi2 = ::winrt::Microsoft::Windows::Devices::Midi2;
+
+
+#include
+#include
+#include
+
+// shared
+#include // general shared
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+// service interface
+#include
+#include
+#include
+
+// SDK shared
+#include
+
+// References to other midi2 SDKs -------------------------------------
+
+#include
+namespace midi2 = ::winrt::Microsoft::Windows::Devices::Midi2;
+
+#include
+namespace svc = ::winrt::Microsoft::Windows::Devices::Midi2::ServiceConfig;
+
+//#include
+//namespace msgs = ::winrt::Microsoft::Windows::Devices::Midi2::Messages;
+
+// Project-local ------------------------------------------------
+
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay {};
+namespace winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation {};
+namespace local = ::winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay;
+namespace implementation = ::winrt::Microsoft::Windows::Devices::Midi2::VirtualPatchBay::implementation;
+
+//#include "resource.h"
+
+#include "MidiVirtualPatchBaySourceDefinition.h"
+#include "MidiVirtualPatchBayDestinationDefinition.h"
+
+#include "MidiVirtualPatchBayRouteCreationConfig.h"
+#include "MidiVirtualPatchBayRouteRemovalConfig.h"
+#include "MidiVirtualPatchBayRouteUpdateConfig.h"
+
+#include "MidiVirtualPatchBayManager.h"
diff --git a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointMonitorCommand.cs b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointMonitorCommand.cs
index 33855ac79..c4e96b4bf 100644
--- a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointMonitorCommand.cs
+++ b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointMonitorCommand.cs
@@ -10,6 +10,7 @@
using Microsoft.Windows.Devices.Midi2.Initialization;
using Microsoft.Windows.Devices.Midi2.Messages;
+using Microsoft.Windows.Devices.Midi2.Utilities.SysEx;
namespace Microsoft.Midi.ConsoleApp
{
@@ -325,9 +326,9 @@ public override int Execute(CommandContext context, Settings settings)
index++;
- if (MidiMessageHelper.MessageIsSystemExclusive7Message(e.PeekFirstWord()))
+ if (MidiSystemExclusiveMessageHelper.MessageIsSystemExclusive7Message(e.PeekFirstWord()))
{
- countSysEx7BytesReceived += MidiMessageHelper.GetDataByteCountFromSystemExclusive7MessageFirstWord(e.PeekFirstWord());
+ countSysEx7BytesReceived += MidiSystemExclusiveMessageHelper.GetDataByteCountFromSystemExclusive7MessageFirstWord(e.PeekFirstWord());
}
var receivedMessage = new ReceivedMidiMessage()
diff --git a/src/user-tools/midi-console/Midi/CustomTable/MidiMessageTable.cs b/src/user-tools/midi-console/Midi/CustomTable/MidiMessageTable.cs
index 20be3c35f..491cd8a3e 100644
--- a/src/user-tools/midi-console/Midi/CustomTable/MidiMessageTable.cs
+++ b/src/user-tools/midi-console/Midi/CustomTable/MidiMessageTable.cs
@@ -9,6 +9,7 @@
using Microsoft.Windows.Devices.Midi2.Messages;
+using Microsoft.Windows.Devices.Midi2.Utilities.SysEx;
namespace Microsoft.Midi.ConsoleApp
{
@@ -128,6 +129,8 @@ private void BuildStringFormats()
private string m_deltaValueDefaultColor = "lightskyblue3_1";
private string m_deltaValueErrorColor = "red";
+ private const int m_detailedMessageTypeTextWidth = 35;
+
public MidiMessageTable(bool verbose)
{
m_verbose = verbose;
@@ -148,10 +151,10 @@ public MidiMessageTable(bool verbose)
if (verbose)
{
- Columns.Add(new MidiMessageTableColumn(11, "Gr", 2, false, "indianred", ""));
- Columns.Add(new MidiMessageTableColumn(12, "Ch", 2, true, "mediumorchid3", ""));
- Columns.Add(new MidiMessageTableColumn(13, "Decoded Data", -35, false, "deepskyblue1", ""));
- Columns.Add(new MidiMessageTableColumn(14, "Message Type", -35, false, "steelblue1_1", ""));
+ Columns.Add(new MidiMessageTableColumn(11, "Message Type", m_detailedMessageTypeTextWidth * -1, false, "steelblue1_1", ""));
+ Columns.Add(new MidiMessageTableColumn(12, "Gr", 2, false, "indianred", ""));
+ Columns.Add(new MidiMessageTableColumn(13, "Ch", 2, true, "mediumorchid3", ""));
+ Columns.Add(new MidiMessageTableColumn(14, "Decoded Data", -35, false, "grey", ""));
}
BuildStringFormats();
@@ -180,44 +183,7 @@ public void OutputRow(ReceivedMidiMessage message)
{
detailedMessageType = MidiMessageHelper.GetMessageDisplayNameFromFirstWord(message.Word0);
- // For SysEx, we display the bytes here. We may want to offer decoding for other message
- // types as well, in the future, and just have a dedicated column for the decoding.
-
- const uint maxSysEx7BytesPerMessage = 6;
- if (MidiMessageHelper.MessageIsSystemExclusive7Message(message.Word0))
- {
- // show the bytes
- var byteCount = MidiMessageHelper.GetDataByteCountFromSystemExclusive7MessageFirstWord(message.Word0);
-
- foreach (var b in MidiMessageHelper.GetDataBytesFromSingleSystemExclusive7Message(message.Word0, message.Word1))
- {
- decodedData += b.ToString("X2") + " ";
- }
-
- if (byteCount < maxSysEx7BytesPerMessage)
- {
- decodedData += "[grey]";
-
- for (int i = 0; i < maxSysEx7BytesPerMessage - byteCount; i++)
- {
- decodedData += "-- ";
- }
-
- decodedData += "[/]";
- }
-
- decodedData = $"[darkseagreen2]{decodedData}[/]";
- }
-
- //if (messageType == MidiMessageType.DataMessage64)
- //{
- //}
- //else if (MessageIsSysEx8(message))
- //{
- //}
- //else
- //{
- //}
+ decodedData = GetDecodedOutput(message);
}
string word0 = string.Empty;
@@ -309,7 +275,7 @@ public void OutputRow(ReceivedMidiMessage message)
if (deltaValueText.Length > timestampOffsetValueColumnWidth)
{
- deltaValueText = "######";
+ deltaValueText = "000000";
deltaUnitLabel = "";
Columns[m_deltaColumnNumber].DataColor = m_deltaValueErrorColor;
}
@@ -320,7 +286,7 @@ public void OutputRow(ReceivedMidiMessage message)
if (offsetValueText.Length > timestampOffsetValueColumnWidth)
{
- offsetValueText = "######";
+ offsetValueText = "000000";
offsetUnitLabel = "";
Columns[m_offsetColumnNumber].DataColor = m_offsetValueErrorColor;
}
@@ -341,10 +307,10 @@ public void OutputRow(ReceivedMidiMessage message)
deltaValueText,
deltaUnitLabel,
word0, word1, word2, word3,
+ detailedMessageType.PadRight(m_detailedMessageTypeTextWidth, ' ').Substring(0, m_detailedMessageTypeTextWidth),
groupText,
channelText,
- decodedData,
- detailedMessageType
+ decodedData
);
}
else
@@ -359,15 +325,220 @@ public void OutputRow(ReceivedMidiMessage message)
deltaValueText,
deltaUnitLabel,
word0, word1, word2, word3,
+ detailedMessageType.PadRight(m_detailedMessageTypeTextWidth, ' ').Substring(0, m_detailedMessageTypeTextWidth),
groupText,
channelText,
- decodedData,
- detailedMessageType
+ decodedData
);
UInt64 outputEnd = MidiClock.Now;
}
}
+
+
+
+ public string GetDecodedOutput(ReceivedMidiMessage message)
+ {
+ // For SysEx, we display the bytes here. We may want to offer decoding for other message
+ // types as well, in the future, like note on/off (easier with M1 protocol)
+
+ var messageType = MidiMessageHelper.GetMessageTypeFromMessageFirstWord(message.Word0);
+
+ switch(messageType)
+ {
+ case MidiMessageType.Midi1ChannelVoice32:
+ return GetDecodedMidi1ChannelVoiceData(message);
+
+ case MidiMessageType.DataMessage64:
+ return GetDecodedSysEx7MessageData(message);
+
+ default:
+ return string.Empty;
+
+ }
+ }
+
+ private string FormatByteDecimal(byte value)
+ {
+ return value.ToString().PadLeft(3, ' ');
+ }
+
+ private string GetDecodedMidi1ChannelVoiceData(ReceivedMidiMessage message)
+ {
+ string decodedData = string.Empty;
+
+ var status = MidiMessageHelper.GetStatusFromMidi1ChannelVoiceMessage(message.Word0);
+
+ byte dataByte1 = (byte)((message.Word0 >> 8) & 0xFF);
+ byte dataByte2 = (byte)((message.Word0) & 0xFF);
+
+ switch (status)
+ {
+ case Midi1ChannelVoiceMessageStatus.NoteOn:
+ case Midi1ChannelVoiceMessageStatus.NoteOff:
+ decodedData = $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1]({MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}{MidiMessageHelper.GetNoteOctaveFromNoteIndex(dataByte1)})[/], "+
+ $"Velocity: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/]";
+ break;
+
+ case Midi1ChannelVoiceMessageStatus.ControlChange:
+ decodedData = $"Controller: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], Value: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/]";
+ break;
+
+ case Midi1ChannelVoiceMessageStatus.PitchBend:
+ decodedData = $"Fine: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], Coarse: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/]";
+ break;
+
+ case Midi1ChannelVoiceMessageStatus.ChannelPressure:
+ decodedData = $"Value: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/]";
+ break;
+
+ case Midi1ChannelVoiceMessageStatus.PolyPressure:
+ decodedData = $"Key: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], Value: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/]";
+ break;
+
+ case Midi1ChannelVoiceMessageStatus.ProgramChange:
+ decodedData = $"Value: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/]";
+ break;
+
+ default:
+ break;
+ }
+
+ return decodedData;
+ }
+
+ private string GetDecodedMidi2ChannelVoiceData(ReceivedMidiMessage message)
+ {
+ string decodedData = string.Empty;
+
+ var status = MidiMessageHelper.GetStatusFromMidi2ChannelVoiceMessageFirstWord(message.Word0);
+
+ byte dataByte1 = (byte)((message.Word0 >> 8) & 0xFF);
+ byte dataByte2 = (byte)((message.Word0) & 0xFF);
+
+ switch (status)
+ {
+ case Midi2ChannelVoiceMessageStatus.NoteOn:
+ case Midi2ChannelVoiceMessageStatus.NoteOff:
+ {
+ UInt16 velocity = (UInt16)((message.Word1 >> 16) & 0xFFFF);
+ UInt16 attribute = (UInt16)(message.Word1 & 0xFFFF);
+
+ decodedData =
+ $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1](May be: {MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}[/], " +
+ $"Type: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/], " +
+ $"Vel: [darkseagreen2]{velocity}[/], " +
+ $"Attr: [darkseagreen2]{attribute}[/]";
+ }
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.PolyPressure:
+ decodedData =
+ $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1](May be: {MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.RegisteredPerNoteController:
+ case Midi2ChannelVoiceMessageStatus.AssignablePerNoteController:
+ decodedData =
+ $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1](May be: {MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}[/], " +
+ $"Index: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.PerNoteManagement:
+ decodedData =
+ $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1](May be: {MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}[/], " +
+ $"Detach: [darkseagreen2]{(bool)((dataByte1 & 0x2) == 0x2)}[/], " +
+ $"Set: [darkseagreen2]{(bool)((dataByte1 & 0x1) == 0x1)}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.ControlChange:
+ decodedData =
+ $"Controller: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.RegisteredController:
+ case Midi2ChannelVoiceMessageStatus.AssignableController:
+ decodedData =
+ $"Bank: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], " +
+ $"Index: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.RelativeRegisteredController:
+ case Midi2ChannelVoiceMessageStatus.RelativeAssignableController:
+ decodedData =
+ $"Bank: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/], " +
+ $"Index: [darkseagreen2]{FormatByteDecimal(dataByte2)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.ProgramChange:
+ decodedData =
+ $"Program: [darkseagreen2]{FormatByteDecimal((byte)(message.Word1 & 0xFF000000 >> 24))}[/], " +
+ $"Bank Valid: [darkseagreen2]{(bool)((dataByte1 & 0x1) == 0x1)}[/], " +
+ $"MSB: [darkseagreen2]{FormatByteDecimal((byte)(message.Word1 & 0x0000FF00 >> 8))}[/], " +
+ $"LSB: [darkseagreen2]{FormatByteDecimal((byte)(message.Word1 & 0x000000FF))}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.ChannelPressure:
+ decodedData = $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.PitchBend:
+ decodedData = $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ case Midi2ChannelVoiceMessageStatus.PerNotePitchBend:
+ decodedData =
+ $"Note: [darkseagreen2]{FormatByteDecimal(dataByte1)}[/] [deepskyblue1](May be: {MidiMessageHelper.GetNoteDisplayNameFromNoteIndex(dataByte1)}[/], " +
+ $"Data: [darkseagreen2]{message.Word1}[/]";
+ break;
+
+ default:
+ break;
+ }
+
+ return decodedData;
+ }
+
+
+
+ private string GetDecodedSysEx7MessageData(ReceivedMidiMessage message)
+ {
+ string decodedData = string.Empty;
+
+ const uint maxSysEx7BytesPerMessage = 6;
+ if (MidiSystemExclusiveMessageHelper.MessageIsSystemExclusive7Message(message.Word0))
+ {
+ // show the bytes
+ var byteCount = MidiSystemExclusiveMessageHelper.GetDataByteCountFromSystemExclusive7MessageFirstWord(message.Word0);
+
+ foreach (var b in MidiSystemExclusiveMessageHelper.GetDataBytesFromSingleSystemExclusive7Message(message.Word0, message.Word1))
+ {
+ decodedData += b.ToString("X2") + " ";
+ }
+
+ if (byteCount < maxSysEx7BytesPerMessage)
+ {
+ decodedData += "[grey]";
+
+ for (int i = 0; i < maxSysEx7BytesPerMessage - byteCount; i++)
+ {
+ decodedData += "-- ";
+ }
+
+ decodedData += "[/]";
+ }
+
+ decodedData = $"[darkseagreen2]{decodedData}[/]";
+ }
+
+ return decodedData;
+ }
+
}
diff --git a/src/user-tools/midi-console/Midi/Midi.csproj b/src/user-tools/midi-console/Midi/Midi.csproj
index 3bcc1edcb..a3be80c10 100644
--- a/src/user-tools/midi-console/Midi/Midi.csproj
+++ b/src/user-tools/midi-console/Midi/Midi.csproj
@@ -35,7 +35,7 @@
-
+
diff --git a/src/user-tools/midi-console/Midi/midi.exe.manifest b/src/user-tools/midi-console/Midi/midi.exe.manifest
index c496106bc..d495317c5 100644
--- a/src/user-tools/midi-console/Midi/midi.exe.manifest
+++ b/src/user-tools/midi-console/Midi/midi.exe.manifest
@@ -150,5 +150,17 @@
xmlns="urn:schemas-microsoft-com:winrt.v1" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Config/EndpointConfigMetadataPayload.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Config/EndpointConfigMetadataPayload.cs
index 027fe001c..93c7314d6 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Config/EndpointConfigMetadataPayload.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Config/EndpointConfigMetadataPayload.cs
@@ -5,14 +5,14 @@
using System.Threading.Tasks;
using Windows.Data.Json;
+using Microsoft.Windows.Devices.Midi2.ServiceConfig;
namespace Microsoft.Midi.Settings.Config
{
- internal class EndpointConfigMetadataPayload : IMidiServiceTransportPluginConfiguration
+ internal class EndpointConfigMetadataPayload : IMidiServiceTransportPluginConfig
{
- public bool IsFromConfigurationFile => true;
+ public bool IsFromCurrentConfigFile => true;
- public JsonObject? SettingsJson { get; private set; }
public Guid TransportId { get; private set; }
@@ -51,9 +51,20 @@ public EndpointConfigMetadataPayload(Guid transportId, string newName, string ne
// }
// }
- public void BuildJson()
+
+ public string GetConfigJson()
{
+ // TODO
+
+
+
+
+
+
+
+ return string.Empty;
}
+
}
}
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiEndpointNativeDataFormatConverter.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiEndpointNativeDataFormatConverter.cs
index f366dd212..c2c880d3d 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiEndpointNativeDataFormatConverter.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiEndpointNativeDataFormatConverter.cs
@@ -24,11 +24,11 @@ public object Convert(object value, Type targetType, object parameter, string la
switch (val)
{
- case MidiEndpointNativeDataFormat.UniversalMidiPacket:
+ case MidiEndpointNativeDataFormat.UniversalMidiPacketFormat:
return "MIDI 2.0 Universal MIDI Packet (UMP) format";
- case MidiEndpointNativeDataFormat.ByteStream:
- return "MIDI 1.0 byte stream format";
+ case MidiEndpointNativeDataFormat.Midi1ByteFormat:
+ return "MIDI 1.0 byte format";
default:
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiFunctionBlockMidi10Converter.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiFunctionBlockMidi10Converter.cs
index 7840bd561..dafff9d68 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiFunctionBlockMidi10Converter.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiFunctionBlockMidi10Converter.cs
@@ -16,21 +16,21 @@ public object Convert(object value, Type targetType, object parameter, string la
return string.Empty;
}
- if (value is MidiFunctionBlockMidi10)
+ if (value is MidiFunctionBlockRepresentsMidi10Connection)
{
- var val = (MidiFunctionBlockMidi10)value;
+ var val = (MidiFunctionBlockRepresentsMidi10Connection)value;
// TODO: Localize
switch (val)
{
- case MidiFunctionBlockMidi10.Not10:
+ case MidiFunctionBlockRepresentsMidi10Connection.Not10:
return "Not MIDI 1.0";
- case MidiFunctionBlockMidi10.YesBandwidthUnrestricted:
+ case MidiFunctionBlockRepresentsMidi10Connection.YesBandwidthUnrestricted:
return "MIDI 1.0 unrestricted bandwidth";
- case MidiFunctionBlockMidi10.YesBandwidthRestricted:
+ case MidiFunctionBlockRepresentsMidi10Connection.YesBandwidthRestricted:
return "MIDI 1.0 restricted bandwidth";
default:
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiGroupIndexConverter.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiGroupIndexConverter.cs
index 9a15c9a81..7fcf0799e 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiGroupIndexConverter.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Helpers/MidiGroupIndexConverter.cs
@@ -21,7 +21,7 @@ public object Convert(object value, Type targetType, object parameter, string la
var val = (byte)value;
// todo: localize
- return $"{MidiGroup.LabelFull} {(val + 1)} (Index {val})";
+ return $"{MidiGroup.LongLabel} {(val + 1)} (Index {val})";
}
else
{
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj
index e5e612086..4b77f5702 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj
@@ -15,7 +15,7 @@
true
true
-
+ true
Properties\PublishProfiles\win10-$(Platform).pubxml
@@ -63,6 +63,7 @@
+
@@ -82,7 +83,7 @@
-
+
@@ -127,6 +128,9 @@
Never
+
+ MSBuild:Compile
+
MSBuild:Compile
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs
index 40147639f..6e3b1af9c 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Services/PageService.cs
@@ -15,6 +15,7 @@ public PageService()
{
Configure();
Configure();
+ Configure();
Configure();
//Configure();
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Strings/en-us/Resources.resw b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Strings/en-us/Resources.resw
index 09c39d3d1..9ad19a74f 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Strings/en-us/Resources.resw
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Strings/en-us/Resources.resw
@@ -297,4 +297,7 @@
Home
+
+ Routing
+
\ No newline at end of file
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DeviceDetailViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DeviceDetailViewModel.cs
index 4105502b0..4497222f6 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DeviceDetailViewModel.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DeviceDetailViewModel.cs
@@ -17,15 +17,23 @@ public class DeviceDetailViewModel : ObservableRecipient, INavigationAware
{
public EndpointUserMetadata UserMetadata { get; private set; } = new EndpointUserMetadata();
- public MidiEndpointDeviceInformation? DeviceInformation
+ public MidiEndpointDeviceInformation DeviceInformation
{
get; private set;
}
+ public IReadOnlyList FunctionBlocks => DeviceInformation.GetDeclaredFunctionBlocks();
- public DeviceInformation? ParentDeviceInformation
- {
- get; private set;
- }
+ public MidiEndpointTransportSuppliedInfo TransportSuppliedInfo => DeviceInformation.GetTransportSuppliedInfo();
+
+ public MidiEndpointUserSuppliedInfo UserSuppliedInfo => DeviceInformation.GetUserSuppliedInfo();
+
+ public MidiDeclaredDeviceIdentity DeviceIdentity => DeviceInformation.GetDeclaredDeviceIdentity();
+
+ public MidiDeclaredStreamConfiguration StreamConfiguration => DeviceInformation.GetDeclaredStreamConfiguration();
+
+ public MidiDeclaredEndpointInfo EndpointInfo => DeviceInformation.GetDeclaredEndpointInfo();
+
+ public DeviceInformation ParentDeviceInformation => DeviceInformation.GetParentDeviceInformation();
public void OnNavigatedFrom()
@@ -36,8 +44,6 @@ public void OnNavigatedFrom()
public void OnNavigatedTo(object parameter)
{
DeviceInformation = (MidiEndpointDeviceInformation)parameter;
-
- ParentDeviceInformation = DeviceInformation.GetParentDeviceInformation();
}
}
}
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DevicesViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DevicesViewModel.cs
index a0118507d..b974f11af 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DevicesViewModel.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/DevicesViewModel.cs
@@ -103,7 +103,7 @@ public void RefreshDeviceCollection(bool showDiagnosticsEndpoints = false)
{
// TODO: this is a hack. Probably shouldn't be using the mnemonic directly
// Instead, need a transport properly for purpose like we have with endpoints
- if (item.Transport.Abbreviation == "DIAG")
+ if (item.Transport.TransportCode == "DIAG")
{
if (showDiagnosticsEndpoints)
{
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/ManagementSessionsViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/ManagementSessionsViewModel.cs
index 85f8d4f3b..01be37bb4 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/ManagementSessionsViewModel.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/ManagementSessionsViewModel.cs
@@ -6,6 +6,9 @@
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
+using Microsoft.Windows.Devices.Midi2.Diagnostics;
+
+
namespace Microsoft.Midi.Settings.ViewModels
{
public class ManagementSessionsViewModel : ObservableRecipient
@@ -23,7 +26,7 @@ public void RefreshSessions()
{
Sessions.Clear();
- var sessions = MidiService.GetActiveSessions();
+ var sessions = MidiReporting.GetActiveSessions();
foreach (var session in sessions)
{
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/PluginsTransportViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/PluginsTransportViewModel.cs
index 40975d12c..79dea7a89 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/PluginsTransportViewModel.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/PluginsTransportViewModel.cs
@@ -17,7 +17,7 @@ public PluginsTransportViewModel()
{
Plugins.Clear();
- var plugins = MidiService.GetInstalledTransportPlugins();
+ var plugins = MidiReporting.GetInstalledTransportPlugins();
foreach (var plugin in plugins.OrderBy(x => x.Name))
{
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/RoutesViewModel.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/RoutesViewModel.cs
new file mode 100644
index 000000000..b48c0ecb6
--- /dev/null
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/ViewModels/RoutesViewModel.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Microsoft.Midi.Settings.Contracts.ViewModels;
+using Microsoft.Midi.Settings.Models;
+using Microsoft.Midi.Settings.ViewModels.Data;
+using Microsoft.UI.Dispatching;
+using Windows.Devices.Enumeration;
+
+namespace Microsoft.Midi.Settings.ViewModels
+{
+ public class RoutesViewModel : ObservableRecipient, INavigationAware
+ {
+
+
+ public void OnNavigatedFrom()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnNavigatedTo(object parameter)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml
index 1c937b7b3..f44e37462 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml
@@ -4,7 +4,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Midi.Settings.Views"
- xmlns:midi2="using:Windows.Devices.Midi2"
+ xmlns:midi2="using:Microsoft.Windows.Devices.Midi2"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:helpers="using:Microsoft.Midi.Settings.Helpers"
@@ -60,23 +60,23 @@
-
-
-
-
-
@@ -108,10 +108,10 @@
-
-
-
-
+
+
+
+
@@ -142,20 +142,20 @@
-
+
-
+
-
+
-
+
-
+
@@ -184,19 +184,19 @@
-
+
-
+
-
+
-
+
-
+
@@ -211,7 +211,7 @@
@@ -308,7 +308,7 @@
Text="MIDI 1.0"
Style="{StaticResource SmallPropertyLabel}" />
-
-
-
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml.cs
index 2ed74aad2..663ae900d 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml.cs
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DeviceDetailPage.xaml.cs
@@ -53,10 +53,17 @@ public DeviceDetailPage()
private async void Button_Click(object sender, RoutedEventArgs e)
{
- ViewModel.UserMetadata.Name = ViewModel.DeviceInformation!.UserSuppliedName;
- ViewModel.UserMetadata.Description = ViewModel.DeviceInformation.UserSuppliedDescription;
- ViewModel.UserMetadata.LargeImagePath = ViewModel.DeviceInformation.UserSuppliedLargeImagePath;
- ViewModel.UserMetadata.SmallImagePath = ViewModel.DeviceInformation.UserSuppliedSmallImagePath;
+ if (ViewModel.DeviceInformation == null)
+ {
+ return;
+ }
+
+ var userSuppliedInfo = ViewModel.DeviceInformation.GetUserSuppliedInfo();
+
+ ViewModel.UserMetadata.Name = userSuppliedInfo.Name;
+ ViewModel.UserMetadata.Description = userSuppliedInfo.Description;
+ ViewModel.UserMetadata.LargeImagePath = userSuppliedInfo.LargeImagePath;
+ ViewModel.UserMetadata.SmallImagePath = userSuppliedInfo.SmallImagePath;
editUserDefinedPropertiesDialog.Width = this.Width / 3;
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DevicesPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DevicesPage.xaml
index ae5d6c84d..d3f6d5210 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DevicesPage.xaml
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/DevicesPage.xaml
@@ -8,7 +8,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="using:Microsoft.Midi.Settings.Views"
xmlns:local="using:Microsoft.Midi.Settings.ViewModels"
- xmlns:midi2="using:Windows.Devices.Midi2"
+ xmlns:midi2="using:Microsoft.Windows.Devices.Midi2"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:helpers="using:Microsoft.Midi.Settings.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -55,8 +55,8 @@
-
-
+
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ManagementSessionsPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ManagementSessionsPage.xaml
index a3c517faf..ac1f597d0 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ManagementSessionsPage.xaml
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ManagementSessionsPage.xaml
@@ -7,7 +7,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="using:Microsoft.Midi.Settings.Views"
xmlns:local="using:Microsoft.Midi.Settings.ViewModels"
- xmlns:midi2="using:Windows.Devices.Midi2"
+ xmlns:midi2="using:Microsoft.Windows.Devices.Midi2"
+ xmlns:mididiag="using:Microsoft.Windows.Devices.Midi2.Diagnostics"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:helpers="using:Microsoft.Midi.Settings.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -44,7 +45,7 @@
-
+
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/PluginsTransportPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/PluginsTransportPage.xaml
index 10a76c883..4660f5ff7 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/PluginsTransportPage.xaml
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/PluginsTransportPage.xaml
@@ -7,7 +7,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="using:Microsoft.Midi.Settings.Views"
xmlns:local="using:Microsoft.Midi.Settings.ViewModels"
- xmlns:midi2="using:Windows.Devices.Midi2"
+ xmlns:midi2="using:Microsoft.Windows.Devices.Midi2"
+ xmlns:mididiag="using:Microsoft.Windows.Devices.Midi2.Diagnostics"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:helpers="using:Microsoft.Midi.Settings.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -35,7 +36,7 @@
-
+
@@ -78,7 +79,7 @@
-
+
@@ -103,7 +104,7 @@
-
+
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml
new file mode 100644
index 000000000..adaa4a640
--- /dev/null
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml.cs b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml.cs
new file mode 100644
index 000000000..347e1e315
--- /dev/null
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/RoutesPage.xaml.cs
@@ -0,0 +1,31 @@
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Controls.Primitives;
+using Microsoft.UI.Xaml.Data;
+using Microsoft.UI.Xaml.Input;
+using Microsoft.UI.Xaml.Media;
+using Microsoft.UI.Xaml.Navigation;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace Microsoft.Midi.Settings.Views
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class RoutesPage : Page
+ {
+ public RoutesPage()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ShellPage.xaml b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ShellPage.xaml
index 14afda169..82d0e1562 100644
--- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ShellPage.xaml
+++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Views/ShellPage.xaml
@@ -96,8 +96,7 @@
-
+
@@ -106,9 +105,14 @@
-
-
-
+
+
+
+
+
+
+
+