diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi
index 78121137..a567b0f3 100644
--- a/build/staging/version/BundleInfo.wxi
+++ b/build/staging/version/BundleInfo.wxi
@@ -1,4 +1,4 @@
-
+
diff --git a/build/staging/version/WindowsMidiServicesVersion.cs b/build/staging/version/WindowsMidiServicesVersion.cs
index e7115934..6554d0bf 100644
--- a/build/staging/version/WindowsMidiServicesVersion.cs
+++ b/build/staging/version/WindowsMidiServicesVersion.cs
@@ -6,12 +6,12 @@ public static class MidiBuildInformation
{
public const string Source = "GitHub Preview";
public const string Name = "Customer Preview 2";
- public const string BuildFullVersion = "1.0.3-preview-11.250209-429";
+ public const string BuildFullVersion = "1.0.3-preview-11.250211-2313";
public const string VersionMajor = "1";
public const string VersionMinor = "0";
public const string VersionRevision = "3";
- public const string VersionDateNumber = "250209";
- public const string VersionTimeNumber = "429";
+ public const string VersionDateNumber = "250211";
+ public const string VersionTimeNumber = "2313";
}
}
diff --git a/build/staging/version/WindowsMidiServicesVersion.h b/build/staging/version/WindowsMidiServicesVersion.h
index cf1a4154..5774f5ca 100644
--- a/build/staging/version/WindowsMidiServicesVersion.h
+++ b/build/staging/version/WindowsMidiServicesVersion.h
@@ -5,12 +5,12 @@
#define WINDOWS_MIDI_SERVICES_BUILD_SOURCE L"GitHub Preview"
#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_NAME L"Customer Preview 2"
-#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.3-preview-11.250209-429"
+#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.3-preview-11.250211-2313"
#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MAJOR L"1"
#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MINOR L"0"
#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_REVISION L"3"
-#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_DATE_NUMBER L"250209"
-#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"429"
+#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_DATE_NUMBER L"250211"
+#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"2313"
#endif
diff --git a/docs/sdk-winrt-core/common/MidiGroup.md b/docs/sdk-winrt-core/common/MidiGroup.md
index 399b3e1c..b12ceee9 100644
--- a/docs/sdk-winrt-core/common/MidiGroup.md
+++ b/docs/sdk-winrt-core/common/MidiGroup.md
@@ -22,7 +22,8 @@ The `MidiGroup` class is used to provide formatting and data validation for MIDI
## Constructors
-| `MidiGroup(UInt8)` | Create a MidiGroup with the specified group Index (0-15) |
+| `MidiGroup()` | Create a MidiGroup initialized with group Index 0 |
+| `MidiGroup(UInt8)` | Create a MidiGroup with the specified group Index (0-15). C++ note: C++/WinRT creates a constructor which takes nullptr, as a result `MidiGroup(0)` will fail to compile if you have the compiler option set to equate 0 and nullptr. To avoid this, use `MidiGroup(static_cast(0))` or simply `MidiGroup()` |
## Properties
diff --git a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
index 5521a969..9e17f3b6 100644
--- a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
+++ b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
false
diff --git a/samples/cpp-winrt/basics/packages.config b/samples/cpp-winrt/basics/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/basics/packages.config
+++ b/samples/cpp-winrt/basics/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj
index f453ff5f..cd091688 100644
--- a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj
+++ b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/samples/cpp-winrt/loopback-endpoints/packages.config b/samples/cpp-winrt/loopback-endpoints/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/loopback-endpoints/packages.config
+++ b/samples/cpp-winrt/loopback-endpoints/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/send-speed/packages.config b/samples/cpp-winrt/send-speed/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/send-speed/packages.config
+++ b/samples/cpp-winrt/send-speed/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj
index 8fa76522..e3945717 100644
--- a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj
+++ b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/samples/cpp-winrt/simple-app-to-app-midi/packages.config b/samples/cpp-winrt/simple-app-to-app-midi/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/simple-app-to-app-midi/packages.config
+++ b/samples/cpp-winrt/simple-app-to-app-midi/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj
index 8176f9b6..cc4b41c7 100644
--- a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj
+++ b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/samples/cpp-winrt/static-enum-endpoints/packages.config b/samples/cpp-winrt/static-enum-endpoints/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/static-enum-endpoints/packages.config
+++ b/samples/cpp-winrt/static-enum-endpoints/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj
index 7e36d41c..4e9d5e15 100644
--- a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj
+++ b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/samples/cpp-winrt/watch-endpoints/packages.config b/samples/cpp-winrt/watch-endpoints/packages.config
index 8cd2fd68..acb430cb 100644
--- a/samples/cpp-winrt/watch-endpoints/packages.config
+++ b/samples/cpp-winrt/watch-endpoints/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj
index b35d1956..332164df 100644
--- a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj
+++ b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/src/api/Inc/MidiDefs.h b/src/api/Inc/MidiDefs.h
index 33089295..c359b57b 100644
--- a/src/api/Inc/MidiDefs.h
+++ b/src/api/Inc/MidiDefs.h
@@ -86,6 +86,11 @@ static_assert( MAXIMUM_LOOPED_BUFFER_SIZE < ULONG_MAX/2, "The maximum looped
#define MIDI_USE_MMCSS_REG_VALUE L"UseMMCSS"
#define MIDI_USE_MMCSS_REG_DEFAULT_VALUE 0x00000000
+// this is used as the default approach for how we name MIDI 1 ports
+// individual ports can override this via a property in the list below.
+#define MIDI_USE_OLD_MIDI1PORT_NAMING_DEFAULT_REG_VALUE L"DefaultToOldMidi1PortNaming"
+#define MIDI_USE_OLD_MIDI1PORT_NAMING_DEFAULT_VALUE 0x00000001
+
#define MIDI_CONFIG_FILE_REG_VALUE L"CurrentConfig"
// if value > 0, then endpoint discovery and protocol negotiation are enabled
@@ -93,9 +98,10 @@ static_assert( MAXIMUM_LOOPED_BUFFER_SIZE < ULONG_MAX/2, "The maximum looped
#define MIDI_DISCOVERY_ENABLED_REG_VALUE L"Midi2DiscoveryEnabled"
#define MIDI_DISCOVERY_ENABLED_REG_DEFAULT_VALUE 0x00000001
+// this is the amount of time we allocate to discovery across all native UMP format MIDI 2 devices
#define MIDI_DISCOVERY_TIMEOUT_REG_VALUE L"Midi2DiscoveryTimeoutMS"
#define MIDI_DISCOVERY_TIMEOUT_DEFAULT_VALUE 10000
-#define MIDI_DISCOVERY_TIMEOUT_MINIMUM_VALUE 1000
+#define MIDI_DISCOVERY_TIMEOUT_MINIMUM_VALUE 500
#define MIDI_DISCOVERY_TIMEOUT_MAXIMUM_VALUE 50000
@@ -639,7 +645,18 @@ DEFINE_MIDIDEVPROPKEY(PKEY_MIDI_VirtualMidiEndpointAssociator, 900); // DEVP
-// Structures for properties ================================================================
+// MIDI 1.0 Port Naming Properties ==========================================================
+// Starts at 1000
+
+// this property is used on the parent UMP interface to control all generated MIDI 1 ports
+#define STRING_PKEY_MIDI_UseOldMidi1PortNamingScheme MIDI_STRING_PKEY_GUID MIDI_STRING_PKEY_PID_SEPARATOR L"1000"
+DEFINE_MIDIDEVPROPKEY(PKEY_MIDI_UseOldMidi1PortNamingScheme, 1000); // DEVPROP_TYPE_BOOL
+
+
+
+
+
+// Structures for properties =================================================================
diff --git a/src/api/Inc/midi_naming.h b/src/api/Inc/midi_naming.h
new file mode 100644
index 00000000..c422afd0
--- /dev/null
+++ b/src/api/Inc/midi_naming.h
@@ -0,0 +1,153 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License
+// ============================================================================
+// This is part of the Windows MIDI Services App API and should be used
+// in your Windows application via an official binary distribution.
+// Further information: https://aka.ms/midi
+// ============================================================================
+
+#pragma once
+
+#ifndef MIDI_NAMING_H
+#define MIDI_NAMING_H
+
+#include
+#include
+
+namespace WindowsMidiServicesInternal::Midi1PortNaming
+{
+ inline std::wstring CleanupKSPinName(
+ _In_ std::wstring const& pinName,
+ _In_ std::wstring parentDeviceName,
+ _In_ std::wstring filterName
+ )
+ {
+ std::wstring cleanedPinName{};
+
+ // Used by ESI, MOTU, and others. We don't want to mess up other names, so check only
+ // for whole word. We do other removal in the next step
+ if (pinName == L"MIDI" ||
+ pinName == L"Out" || pinName == L"OUT" || pinName == L"out" ||
+ pinName == L"In" || pinName == L"IN" || pinName == L"in"
+ )
+ {
+ cleanedPinName = L"";
+ }
+ else
+ {
+ cleanedPinName = pinName;
+ }
+
+ // the double and triple space entries need to be last
+ // there are other ways to do this with pattern matching,
+ // but just banging this through for this version
+ const std::wstring wordsToRemove[] =
+ {
+ // many of these are added by our USB and KS stack, not by the device, which is why they are here
+ parentDeviceName, filterName,
+ L"[0]", L"[1]", L"[2]", L"[3]", L"[4]", L"[5]", L"[6]", L"[7]", L"[8]", L"[9]", L"[10]", L"[11]", L"[12]", L"[13]", L"[14]", L"[15]", L"[16]",
+ L" ", L" ", L" "
+ };
+
+ for (auto const& word : wordsToRemove)
+ {
+ if (cleanedPinName.length() >= word.length())
+ {
+ auto idx = cleanedPinName.find(word);
+
+ if (idx != std::wstring::npos)
+ {
+ cleanedPinName = cleanedPinName.erase(idx, word.length());
+ }
+ }
+ }
+
+ internal::InPlaceTrim(cleanedPinName);
+
+ return cleanedPinName;
+ }
+
+
+ // This is used for generating the GTB names on KSA endpoints, for MIDI 1.0 devices. Those
+ // GTB names are used directly when creating WinMM endpoints
+ inline std::wstring GenerateMidi1PortName(
+ _In_ bool const useOldStyleNaming, // this comes from the property on the device, and if not specified, from the registry. Controls using old WinMM-style naming
+ _In_ std::wstring const& userSuppliedPortName, // if the user has supplied a name for the generated port, and we're not using old-style naming, this wins
+ _In_ std::wstring const& deviceContainerName, // oddly some old WinMM code picks up the deviceContainerName somehow
+ _In_ std::wstring const& parentDeviceName, // the name of the actual connected device from which the UMP interface is generated
+ _In_ std::wstring const& parentDeviceManufacturerName, // the name of the parent device
+ _In_ std::wstring const& filterName, // the name of the filter. This is sometimes the same as the parent device
+ _In_ std::wstring const& pinName, // the name of the KS Filter pin. This can be the same as the USB iJack
+ _In_ uint8_t const groupIndex,
+ _In_ MidiFlow const flowFromUserPerspective,
+ _In_ bool const isUmpDevice,
+ _In_ bool const isUsingVendorDriver,
+ _In_ bool const truncateToWinMMLimit,
+ _In_ std::vector const& otherExistingMidi1PortNamesForThisDeviceAndFlow
+ )
+ {
+ UNREFERENCED_PARAMETER(deviceContainerName);
+ UNREFERENCED_PARAMETER(parentDeviceName);
+ UNREFERENCED_PARAMETER(parentDeviceManufacturerName);
+ UNREFERENCED_PARAMETER(groupIndex);
+ UNREFERENCED_PARAMETER(flowFromUserPerspective);
+ UNREFERENCED_PARAMETER(isUmpDevice);
+ UNREFERENCED_PARAMETER(isUsingVendorDriver);
+ UNREFERENCED_PARAMETER(otherExistingMidi1PortNamesForThisDeviceAndFlow);
+
+ // user supplied a port name, so it is what we use
+ // if we're using old-style naming, we do not use
+ // any user-supplied information for the name
+ if (!userSuppliedPortName.empty() && !useOldStyleNaming)
+ {
+ return userSuppliedPortName;
+ }
+
+
+ if (useOldStyleNaming)
+ {
+ std::wstring name{};
+
+ // TODO: Find the old naming code in the source tree, and reimplement
+
+
+
+ return name;
+ }
+ else
+ {
+ std::wstring name{};
+
+ auto cleanedPinName = CleanupKSPinName(pinName, parentDeviceName, filterName);
+
+ name = internal::TrimmedWStringCopy(filterName + L" " + internal::TrimmedWStringCopy(cleanedPinName));
+
+ if (truncateToWinMMLimit)
+ {
+ if (name.length() + 1 > MAXPNAMELEN)
+ {
+ if (!cleanedPinName.empty())
+ {
+ // we're over length, so just use the pin name
+ name = cleanedPinName.substr(0, MAXPNAMELEN - 1);
+ }
+ else
+ {
+ // we're over length, and there's no pin name
+ // so we use the filter name
+ name = filterName.substr(0, MAXPNAMELEN - 1);
+ }
+ }
+ }
+
+ // TODO: do we need to do any port differentiators here? Look at the collection and see
+ // if there are already ports starting with the same name, and if so, increment a counter and append
+
+ return name;
+ }
+
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/api/Midi2.sln b/src/api/Midi2.sln
index 72775e07..560bc0f6 100644
--- a/src/api/Midi2.sln
+++ b/src/api/Midi2.sln
@@ -42,6 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{A4512D
Inc\loopback_ids.h = Inc\loopback_ids.h
Inc\MidiDefs.h = Inc\MidiDefs.h
Inc\midi_group_terminal_blocks.h = Inc\midi_group_terminal_blocks.h
+ Inc\midi_naming.h = Inc\midi_naming.h
Inc\midi_timestamp.h = Inc\midi_timestamp.h
Inc\midi_ump.h = Inc\midi_ump.h
Inc\midi_ump_message_defs.h = Inc\midi_ump_message_defs.h
diff --git a/src/api/Transport/KSAggregateTransport/Midi2.KSAggregateMidiEndpointManager.cpp b/src/api/Transport/KSAggregateTransport/Midi2.KSAggregateMidiEndpointManager.cpp
index 1d116347..32fa6cb8 100644
--- a/src/api/Transport/KSAggregateTransport/Midi2.KSAggregateMidiEndpointManager.cpp
+++ b/src/api/Transport/KSAggregateTransport/Midi2.KSAggregateMidiEndpointManager.cpp
@@ -91,53 +91,53 @@ CMidi2KSAggregateMidiEndpointManager::Initialize(
-// this will be used for the group terminal block name but also for the WinMM port name
-HRESULT
-CreateGroupTerminalBlockName(
- _In_ std::wstring parentDeviceName,
- _In_ std::wstring filterName,
- _In_ std::wstring currentPinName,
- _Inout_ std::wstring& newGroupTerminalBlockName)
-{
- std::wstring cleanedPinName{};
-
- // MOTU-specific. We don't want to mess up other names, so check only for whole word
- if (currentPinName == L"MIDI")
- {
- cleanedPinName = L"";
- }
- else
- {
- cleanedPinName = currentPinName;
- }
-
- // the double and triple space entries need to be last
- // there are other ways to do this with pattern matching,
- // but just banging this through for this version
- std::wstring wordsToRemove[] =
- {
- parentDeviceName, filterName,
- L"[0]", L"[1]", L"[2]", L"[3]", L"[4]", L"[5]", L"[6]", L"[7]", L"[8]", L"[9]", L"[10]", L"[11]", L"[12]", L"[13]", L"[14]", L"[15]", L"[16]",
- L" ", L" ", L" "
- };
-
- for (auto const& word : wordsToRemove)
- {
- if (cleanedPinName.length() >= word.length())
- {
- auto idx = cleanedPinName.find(word);
-
- if (idx != std::wstring::npos)
- {
- cleanedPinName = cleanedPinName.erase(idx, word.length());
- }
- }
- }
-
- newGroupTerminalBlockName = internal::TrimmedWStringCopy(filterName + L" " + internal::TrimmedWStringCopy(cleanedPinName));
-
- return S_OK;
-}
+//// this will be used for the group terminal block name but also for the WinMM port name
+//HRESULT
+//CreateGroupTerminalBlockName(
+// _In_ std::wstring parentDeviceName,
+// _In_ std::wstring filterName,
+// _In_ std::wstring currentPinName,
+// _Inout_ std::wstring& newGroupTerminalBlockName)
+//{
+// std::wstring cleanedPinName{};
+//
+// // Used by ESI, MOTU, and others. We don't want to mess up other names, so check only for whole word
+// if (currentPinName == L"MIDI")
+// {
+// cleanedPinName = L"";
+// }
+// else
+// {
+// cleanedPinName = currentPinName;
+// }
+//
+// // the double and triple space entries need to be last
+// // there are other ways to do this with pattern matching,
+// // but just banging this through for this version
+// std::wstring wordsToRemove[] =
+// {
+// parentDeviceName, filterName,
+// L"[0]", L"[1]", L"[2]", L"[3]", L"[4]", L"[5]", L"[6]", L"[7]", L"[8]", L"[9]", L"[10]", L"[11]", L"[12]", L"[13]", L"[14]", L"[15]", L"[16]",
+// L" ", L" ", L" "
+// };
+//
+// for (auto const& word : wordsToRemove)
+// {
+// if (cleanedPinName.length() >= word.length())
+// {
+// auto idx = cleanedPinName.find(word);
+//
+// if (idx != std::wstring::npos)
+// {
+// cleanedPinName = cleanedPinName.erase(idx, word.length());
+// }
+// }
+// }
+//
+// newGroupTerminalBlockName = internal::TrimmedWStringCopy(filterName + L" " + internal::TrimmedWStringCopy(cleanedPinName));
+//
+// return S_OK;
+//}
typedef struct {
@@ -218,6 +218,9 @@ CMidi2KSAggregateMidiEndpointManager::CreateMidiUmpEndpoint(
std::vector blocks{ };
std::vector pinMapEntries{ };
+ std::vector portNamesUserFlowOut{ };
+ std::vector portNamesUserFlowIn{ };
+
for (auto const& pin : masterEndpointDefinition.MidiPins)
{
RETURN_HR_IF(E_INVALIDARG, pin.FilterDeviceId.empty());
@@ -233,26 +236,78 @@ CMidi2KSAggregateMidiEndpointManager::CreateMidiUmpEndpoint(
pinMapEntry.FilterId = pin.FilterDeviceId;
pinMapEntry.PinDataFlow = pin.PinDataFlow;
+ MidiFlow flowFromUserPerspective;
+
+
+ std::wstring userSuppliedPortName{}; // TODO: This should come from config file
+ bool useOldStyleNaming{ false }; // TODO: This should come from registry and property
+ std::wstring deviceContainerName{}; // TODO: Need to get this from the device info
+ std::wstring parentDeviceManufacturerName{}; // TODO: Need to get this from the parent device
+ bool isUsingVendorDriver{ false }; // TODO: Need to get this from the device information
+
+
if (pin.PinDataFlow == MidiFlow::MidiFlowIn)
{
+ flowFromUserPerspective = MidiFlow::MidiFlowOut;
+
pinMapEntry.GroupIndex = currentGtbInputGroupIndex;
gtb.Direction = MIDI_GROUP_TERMINAL_BLOCK_INPUT; // from the pin/gtb's perspective
gtb.FirstGroupIndex = currentGtbInputGroupIndex;
currentGtbInputGroupIndex++;
+
+ gtb.Name = internal::Midi1PortNaming::GenerateMidi1PortName(
+ useOldStyleNaming, // this comes from the property on the device, and if not specified, from the registry. Controls using old WinMM-style naming
+ userSuppliedPortName, // if the user has supplied a name for the generated port, and we're not using old-style naming, this wins
+ deviceContainerName, // oddly some old WinMM code picks up the deviceContainerName somehow
+ masterEndpointDefinition.ParentDeviceName, // the name of the actual connected device from which the UMP interface is generated
+ parentDeviceManufacturerName, // the name of the parent device
+ pin.FilterName, // the name of the filter. This is sometimes the same as the parent device
+ pin.PinName, // the name of the KS Filter pin. This can be the same as the USB iJack
+ gtb.FirstGroupIndex,
+ flowFromUserPerspective,
+ false, // this is not a native UMP device, it is a native byte stream device
+ isUsingVendorDriver,
+ true, // we truncate to the WinMM max name limit (32 chars including nul)
+ portNamesUserFlowOut
+ );
+
+ // this is kept just so we can add ordinal differentiators if we need to
+ portNamesUserFlowOut.push_back(gtb.Name);
}
else if (pin.PinDataFlow == MidiFlow::MidiFlowOut)
{
+ flowFromUserPerspective = MidiFlow::MidiFlowIn;
+
pinMapEntry.GroupIndex = currentGtbOutputGroupIndex;
gtb.Direction = MIDI_GROUP_TERMINAL_BLOCK_OUTPUT; // from the pin/gtb's perspective
gtb.FirstGroupIndex = currentGtbOutputGroupIndex;
currentGtbOutputGroupIndex++;
+
+ gtb.Name = internal::Midi1PortNaming::GenerateMidi1PortName(
+ useOldStyleNaming, // this comes from the property on the device, and if not specified, from the registry. Controls using old WinMM-style naming
+ userSuppliedPortName, // if the user has supplied a name for the generated port, and we're not using old-style naming, this wins
+ deviceContainerName, // oddly some old WinMM code picks up the deviceContainerName somehow
+ masterEndpointDefinition.ParentDeviceName, // the name of the actual connected device from which the UMP interface is generated
+ parentDeviceManufacturerName, // the name of the parent device
+ pin.FilterName, // the name of the filter. This is sometimes the same as the parent device
+ pin.PinName, // the name of the KS Filter pin. This can be the same as the USB iJack
+ gtb.FirstGroupIndex,
+ flowFromUserPerspective,
+ false, // this is not a native UMP device, it is a native byte stream device
+ isUsingVendorDriver,
+ true, // we truncate to the WinMM max name limit (32 chars including nul)
+ portNamesUserFlowIn
+ );
+
+ // this is kept just so we can add ordinal differentiators if we need to
+ portNamesUserFlowIn.push_back(gtb.Name);
}
else
{
RETURN_IF_FAILED(E_INVALIDARG);
}
- LOG_IF_FAILED(CreateGroupTerminalBlockName(masterEndpointDefinition.ParentDeviceName, pin.FilterName, pin.PinName, gtb.Name));
+ //LOG_IF_FAILED(CreateGroupTerminalBlockName(masterEndpointDefinition.ParentDeviceName, pin.FilterName, pin.PinName, gtb.Name));
// default values as defined in the MIDI 2.0 USB spec
gtb.Protocol = 0x01; // midi 1.0
@@ -810,9 +865,19 @@ HRESULT CMidi2KSAggregateMidiEndpointManager::OnDeviceRemoved(DeviceWatcher, Dev
}
_Use_decl_annotations_
-HRESULT CMidi2KSAggregateMidiEndpointManager::OnDeviceUpdated(DeviceWatcher, DeviceInformationUpdate)
+HRESULT CMidi2KSAggregateMidiEndpointManager::OnDeviceUpdated(DeviceWatcher, DeviceInformationUpdate update)
{
//see this function for info on the IDeviceInformationUpdate object: https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/enumerate-devices#enumerate-and-watch-devices
+
+ // NOTE: When you change the assigned driver for the device, instead of sending
+ // separate remove/add events, this gets a couple of OnDeviceUpdate notifications.
+
+ for (auto const& prop : update.Properties())
+ {
+ OutputDebugString((std::wstring(L"KSA: ") + std::wstring(prop.Key().c_str())).c_str());
+ }
+
+
return S_OK;
}
diff --git a/src/api/Transport/KSAggregateTransport/pch.h b/src/api/Transport/KSAggregateTransport/pch.h
index 7057ebf5..cf747d0b 100644
--- a/src/api/Transport/KSAggregateTransport/pch.h
+++ b/src/api/Transport/KSAggregateTransport/pch.h
@@ -77,9 +77,8 @@ namespace json = ::winrt::Windows::Data::Json;
#include "swd_helpers.h"
#include "resource_util.h"
#include "ump_helpers.h"
-
#include "MidiXProc.h"
-
+#include "midi_naming.h"
#include "strsafe.h"
@@ -108,7 +107,6 @@ namespace json = ::winrt::Windows::Data::Json;
#include "Midi2UMP2BSTransform_i.c"
-
class CMidi2KSAggregateMidiEndpointManager;
class CMidi2KSAggregateMidiInProxy;
class CMidi2KSAggregateMidiOutProxy;
diff --git a/src/api/Transport/KSTransport/Midi2.KSMidiEndpointManager.cpp b/src/api/Transport/KSTransport/Midi2.KSMidiEndpointManager.cpp
index c553385c..81b8e04c 100644
--- a/src/api/Transport/KSTransport/Midi2.KSMidiEndpointManager.cpp
+++ b/src/api/Transport/KSTransport/Midi2.KSMidiEndpointManager.cpp
@@ -847,9 +847,15 @@ HRESULT CMidi2KSMidiEndpointManager::OnDeviceRemoved(DeviceWatcher, DeviceInform
}
_Use_decl_annotations_
-HRESULT CMidi2KSMidiEndpointManager::OnDeviceUpdated(DeviceWatcher, DeviceInformationUpdate)
+HRESULT CMidi2KSMidiEndpointManager::OnDeviceUpdated(DeviceWatcher, DeviceInformationUpdate update)
{
//see this function for info on the IDeviceInformationUpdate object: https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/enumerate-devices#enumerate-and-watch-devices
+
+ for (auto const& prop : update.Properties())
+ {
+ OutputDebugString((std::wstring(L"KS: ") + std::wstring(prop.Key().c_str())).c_str() );
+ }
+
return S_OK;
}
diff --git a/src/app-sdk/app-sdk-tools-and-tests.sln b/src/app-sdk/app-sdk-tools-and-tests.sln
index 167a6809..5d0e37be 100644
--- a/src/app-sdk/app-sdk-tools-and-tests.sln
+++ b/src/app-sdk/app-sdk-tools-and-tests.sln
@@ -23,6 +23,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midimdnsinfo", "midimdnsinf
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midi1monitor", "midi1monitor\midi1monitor.vcxproj", "{357A35F3-D207-43C5-8F56-B3A374F9EBF9}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midiupdatedriver", "midiupdatedriver\midiupdatedriver.vcxproj", "{631E4512-699C-4BC8-AE31-942498CB55FA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -163,6 +165,22 @@ Global
{357A35F3-D207-43C5-8F56-B3A374F9EBF9}.Release|ARM64EC.Build.0 = Release|ARM64
{357A35F3-D207-43C5-8F56-B3A374F9EBF9}.Release|x64.ActiveCfg = Release|x64
{357A35F3-D207-43C5-8F56-B3A374F9EBF9}.Release|x64.Build.0 = Release|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|Any CPU.Build.0 = Debug|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|ARM64.Build.0 = Debug|ARM64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|ARM64EC.ActiveCfg = Debug|ARM64EC
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|ARM64EC.Build.0 = Debug|ARM64EC
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|x64.ActiveCfg = Debug|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Debug|x64.Build.0 = Debug|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|Any CPU.ActiveCfg = Release|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|Any CPU.Build.0 = Release|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|ARM64.Build.0 = Release|ARM64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|ARM64EC.ActiveCfg = Release|ARM64EC
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|ARM64EC.Build.0 = Release|ARM64EC
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|x64.ActiveCfg = Release|x64
+ {631E4512-699C-4BC8-AE31-942498CB55FA}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -176,6 +194,7 @@ Global
{9803D8E6-5CA5-420C-A02B-5E3327355041} = {900D72D2-91F0-4E6C-B694-192FD48393D2}
{C787073C-50F0-5CA0-D53C-12107196F2F0} = {C8B31D71-0226-4D2D-AC78-53D5C84F472F}
{357A35F3-D207-43C5-8F56-B3A374F9EBF9} = {C8B31D71-0226-4D2D-AC78-53D5C84F472F}
+ {631E4512-699C-4BC8-AE31-942498CB55FA} = {C8B31D71-0226-4D2D-AC78-53D5C84F472F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AE1DF8B9-9FAB-4E20-8AC6-FF316882222F}
diff --git a/src/app-sdk/mididiag/mididiag.vcxproj b/src/app-sdk/mididiag/mididiag.vcxproj
index 0d43feeb..5e1c8514 100644
--- a/src/app-sdk/mididiag/mididiag.vcxproj
+++ b/src/app-sdk/mididiag/mididiag.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/src/app-sdk/mididiag/packages.config b/src/app-sdk/mididiag/packages.config
index 9596ff16..b98787f6 100644
--- a/src/app-sdk/mididiag/packages.config
+++ b/src/app-sdk/mididiag/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj
index ea4fd8f4..ed6225d9 100644
--- a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj
+++ b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj
@@ -2,7 +2,7 @@
- Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250209-429
+ Microsoft.Windows.Devices.Midi2.1.0.3-preview-11.250211-2313
true
true
true
diff --git a/src/app-sdk/midimdnsinfo/packages.config b/src/app-sdk/midimdnsinfo/packages.config
index 9596ff16..b98787f6 100644
--- a/src/app-sdk/midimdnsinfo/packages.config
+++ b/src/app-sdk/midimdnsinfo/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/app-sdk/midiupdatedriver/color.hpp b/src/app-sdk/midiupdatedriver/color.hpp
new file mode 100644
index 00000000..cb080b6e
--- /dev/null
+++ b/src/app-sdk/midiupdatedriver/color.hpp
@@ -0,0 +1,881 @@
+// source: https://github.com/aafulei/color-console/blob/master/include/color.hpp
+
+
+#ifndef COLOR_HPP
+#define COLOR_HPP
+
+#include
+#include
+#include
+#include