diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll index 8c3bf23ec..8472ea0d6 100644 Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll differ diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi index 125208214..afd13689c 100644 --- a/build/staging/version/BundleInfo.wxi +++ b/build/staging/version/BundleInfo.wxi @@ -1,4 +1,4 @@ - + diff --git a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj index 808551e4a..72dc6421e 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.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true false diff --git a/samples/cpp-winrt/basics/packages.config b/samples/cpp-winrt/basics/packages.config index c54983cf3..96c621c1b 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 9ead06ad2..e147a0912 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.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true true diff --git a/samples/cpp-winrt/loopback-endpoints/packages.config b/samples/cpp-winrt/loopback-endpoints/packages.config index c54983cf3..96c621c1b 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 c54983cf3..96c621c1b 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 002c73650..96282bba6 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.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true true diff --git a/samples/cpp-winrt/static-enum-endpoints/packages.config b/samples/cpp-winrt/static-enum-endpoints/packages.config index c54983cf3..96c621c1b 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 e77e1816f..cf12ed0cf 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.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true true diff --git a/samples/cpp-winrt/virtual-device-app-winui/packages.config b/samples/cpp-winrt/virtual-device-app-winui/packages.config index 312ee9661..ff2e2207f 100644 --- a/samples/cpp-winrt/virtual-device-app-winui/packages.config +++ b/samples/cpp-winrt/virtual-device-app-winui/packages.config @@ -1,7 +1,7 @@  - + diff --git a/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj b/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj index c91577feb..434a7cc8a 100644 --- a/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj +++ b/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj @@ -4,7 +4,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true true diff --git a/samples/cpp-winrt/watch-endpoints/packages.config b/samples/cpp-winrt/watch-endpoints/packages.config index c54983cf3..96c621c1b 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 58264a2f6..69faa8e2d 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.1-preview.7.24301.1830 + Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24305.1347 true true true diff --git a/samples/csharp-net/virtual-device-app-winui/MainWindow.xaml.cs b/samples/csharp-net/virtual-device-app-winui/MainWindow.xaml.cs index 4ed591235..9a07ebd12 100644 --- a/samples/csharp-net/virtual-device-app-winui/MainWindow.xaml.cs +++ b/samples/csharp-net/virtual-device-app-winui/MainWindow.xaml.cs @@ -112,6 +112,7 @@ private bool StartVirtualDevice() System.Diagnostics.Debug.WriteLine("StartVirtualDevice Creating virtual device"); _virtualDevice = MidiVirtualDeviceManager.CreateVirtualDevice(creationConfig); + // return if unable to create virtual device if (_virtualDevice == null) { @@ -119,6 +120,12 @@ private bool StartVirtualDevice() return false; } + // this is for debugging in the sample. Normally you'd have this set to true + // you want to set this before you open the "device" side connection or else you may + // miss the initial discovery messages + _virtualDevice.SuppressHandledMessages = false; + + // create our device-side connection System.Diagnostics.Debug.WriteLine("StartVirtualDevice Creating endpoint connection"); _connection = _session.CreateEndpointConnection(_virtualDevice.DeviceEndpointDeviceId); @@ -164,8 +171,7 @@ private bool StartVirtualDevice() private void OnMidiMessageReceived(IMidiMessageReceivedEventSource sender, MidiMessageReceivedEventArgs args) { - System.Diagnostics.Debug.WriteLine("Message Received " + MidiMessageHelper.GetMessageDisplayNameFromFirstWord( - args.PeekFirstWord())); + System.Diagnostics.Debug.WriteLine($"- Received: {MidiMessageHelper.GetMessageDisplayNameFromFirstWord(args.PeekFirstWord())} / {args.GetMessagePacket().ToString()}"); } private void OnStreamConfigurationRequestReceived(MidiVirtualDevice sender, MidiStreamConfigRequestReceivedEventArgs args) @@ -200,15 +206,30 @@ MidiVirtualDeviceCreationConfig DefineDevice() declaredEndpointInfo.ProductInstanceId = "PMB_APP2_3263827"; declaredEndpointInfo.SpecificationVersionMajor = 1; // see latest MIDI 2 UMP spec declaredEndpointInfo.SpecificationVersionMinor = 1; // see latest MIDI 2 UMP spec - declaredEndpointInfo.SupportsMidi10Protocol = true; + declaredEndpointInfo.SupportsMidi10Protocol = false; declaredEndpointInfo.SupportsMidi20Protocol = true; declaredEndpointInfo.SupportsReceivingJitterReductionTimestamps = false; declaredEndpointInfo.SupportsSendingJitterReductionTimestamps = false; + declaredEndpointInfo.HasStaticFunctionBlocks = true; - + declaredEndpointInfo.DeclaredFunctionBlockCount = 3; // needs to match the number of function blocks in the collection + - var declaredDeviceIdentity = new MidiDeclaredDeviceIdentity() ; // todo: set any device identity values if you want. This is optional + // The SysEx id, if used, needs to be a valid one + var declaredDeviceIdentity = new MidiDeclaredDeviceIdentity() ; + declaredDeviceIdentity.DeviceFamilyMsb = 0x01; + declaredDeviceIdentity.DeviceFamilyLsb = 0x02; + declaredDeviceIdentity.DeviceFamilyModelNumberMsb = 0x03; + declaredDeviceIdentity.DeviceFamilyModelNumberLsb = 0x04; + declaredDeviceIdentity.SoftwareRevisionLevelByte1 = 0x05; + declaredDeviceIdentity.SoftwareRevisionLevelByte2 = 0x06; + declaredDeviceIdentity.SoftwareRevisionLevelByte3 = 0x07; + declaredDeviceIdentity.SoftwareRevisionLevelByte4 = 0x08; + declaredDeviceIdentity.SystemExclusiveIdByte1 = 0x09; + declaredDeviceIdentity.SystemExclusiveIdByte2 = 0x0A; + declaredDeviceIdentity.SystemExclusiveIdByte3 = 0x0B; + var userSuppliedInfo = new MidiEndpointUserSuppliedInfo() ; userSuppliedInfo.Name = userSuppliedName; // for names, this will bubble to the top in priority @@ -221,15 +242,19 @@ MidiVirtualDeviceCreationConfig DefineDevice() transportSuppliedManufacturerName, // transport-supplied company name declaredEndpointInfo, // for endpoint discovery declaredDeviceIdentity, // for endpoint discovery - userSuppliedInfo - + userSuppliedInfo ); // if set to true, WinMM / WinRT MIDI 1.0 backwards-compat endpoints won't be created + // when that feature is available in the service config.CreateOnlyUmpEndpoints = false; // Function blocks. The MIDI 2 UMP specification covers the meanings // of these values + + // Note: the number of blocks needs to match the number declared for the endpoint + // and function blocks must start at 0 and go up from there, without any gaps + var block1 = new MidiFunctionBlock(); block1.Number = 0; block1.Name = "Pads Output"; @@ -246,11 +271,11 @@ MidiVirtualDeviceCreationConfig DefineDevice() var block2 = new MidiFunctionBlock(); block2.Number = 1; - block2.Name = "A Function Block"; + block2.Name = "Second Function Block"; block2.IsActive = true; block2.UIHint = MidiFunctionBlockUIHint.Sender; block2.FirstGroupIndex = 1; - block2.GroupCount = 2; + block2.GroupCount = 4; block2.Direction = MidiFunctionBlockDirection.Bidirectional; block2.RepresentsMidi10Connection = MidiFunctionBlockRepresentsMidi10Connection.Not10; block2.MaxSystemExclusive8Streams = 0; @@ -258,6 +283,20 @@ MidiVirtualDeviceCreationConfig DefineDevice() config.FunctionBlocks.Add(block2); + var block3 = new MidiFunctionBlock(); + block3.Number = 2; + block3.Name = "Third Function Block"; + block3.IsActive = false; // function blocks can be marked as inactive. + block3.UIHint = MidiFunctionBlockUIHint.Receiver; + block3.FirstGroupIndex = 5; + block3.GroupCount = 1; + block3.Direction = MidiFunctionBlockDirection.BlockInput; + block3.RepresentsMidi10Connection = MidiFunctionBlockRepresentsMidi10Connection.Not10; + block3.MaxSystemExclusive8Streams = 0; + block3.MidiCIMessageVersionFormat = 0; + + config.FunctionBlocks.Add(block3); + return config; } diff --git a/src/api/Abstraction/KSAbstraction/Midi2.KSMidi.cpp b/src/api/Abstraction/KSAbstraction/Midi2.KSMidi.cpp index 2e2dd6c67..40124f6df 100644 --- a/src/api/Abstraction/KSAbstraction/Midi2.KSMidi.cpp +++ b/src/api/Abstraction/KSAbstraction/Midi2.KSMidi.cpp @@ -35,10 +35,10 @@ CMidi2KSMidi::Initialize( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), TraceLoggingHexUInt32(creationParams->DataFormat, "MidiDataFormats"), TraceLoggingHexUInt32(flow, "MidiFlow"), - TraceLoggingHexUInt32(*mmcssTaskId, "mmcssTaskId"), TraceLoggingPointer(callback, "callback") ); @@ -184,7 +184,8 @@ CMidi2KSMidi::Shutdown() MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); if (m_MidiOutDevice) diff --git a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiBidi.cpp b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiBidi.cpp index e5b2c28fe..f29343aaf 100644 --- a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiBidi.cpp +++ b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiBidi.cpp @@ -18,7 +18,7 @@ CMidi2KSMidiBiDi::Initialize( DWORD * mmcssTaskId, IMidiCallback * callback, LONGLONG context, - GUID /* SessionId */ + GUID SessionId ) { RETURN_HR_IF(E_INVALIDARG, nullptr == callback); @@ -32,9 +32,12 @@ CMidi2KSMidiBiDi::Initialize( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(device, "device"), - TraceLoggingHexUInt32(*mmcssTaskId, "mmcssTaskId") - ); + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), + TraceLoggingGuid(SessionId, "Session Id"), + TraceLoggingPointer(callback, "callback") + ); + std::unique_ptr midiDevice(new (std::nothrow) CMidi2KSMidi()); RETURN_IF_NULL_ALLOC(midiDevice); @@ -53,7 +56,8 @@ CMidi2KSMidiBiDi::Shutdown() MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); if (m_MidiDevice) diff --git a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiIn.cpp b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiIn.cpp index d24fb2688..cb710dc65 100644 --- a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiIn.cpp +++ b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiIn.cpp @@ -18,7 +18,7 @@ CMidi2KSMidiIn::Initialize( DWORD * mmcssTaskId, IMidiCallback * callback, LONGLONG context, - GUID /* SessionId */ + GUID SessionId ) { RETURN_HR_IF(E_INVALIDARG, nullptr == callback); @@ -32,10 +32,12 @@ CMidi2KSMidiIn::Initialize( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(device, "device"), - TraceLoggingHexUInt32(*mmcssTaskId, "MmCss Id"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), + TraceLoggingGuid(SessionId, "Session Id"), TraceLoggingPointer(callback, "callback") - ); + ); + std::unique_ptr midiDevice(new (std::nothrow) CMidi2KSMidi()); RETURN_IF_NULL_ALLOC(midiDevice); diff --git a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiOut.cpp b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiOut.cpp index 993e4c1a2..461f4a3fa 100644 --- a/src/api/Abstraction/KSAbstraction/Midi2.KSMidiOut.cpp +++ b/src/api/Abstraction/KSAbstraction/Midi2.KSMidiOut.cpp @@ -18,7 +18,7 @@ CMidi2KSMidiOut::Initialize( LPCWSTR device, PTRANSPORTCREATIONPARAMS creationParams, DWORD * mmcssTaskId, - GUID /* SessionId */ + GUID SessionId ) { RETURN_HR_IF(E_INVALIDARG, nullptr == device); @@ -31,9 +31,10 @@ CMidi2KSMidiOut::Initialize( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), - TraceLoggingHexUInt32(*mmcssTaskId, "MmCss Id") - ); + TraceLoggingGuid(SessionId, "Session Id") + ); std::unique_ptr midiDevice(new (std::nothrow) CMidi2KSMidi()); RETURN_IF_NULL_ALLOC(midiDevice); diff --git a/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiBidi.cpp b/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiBidi.cpp index 96d1572f9..74c3df36e 100644 --- a/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiBidi.cpp +++ b/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiBidi.cpp @@ -175,26 +175,26 @@ CMidi2VirtualMidiBiDi::SendMidiMessage( } else { - TraceLoggingWrite( - MidiVirtualMidiAbstractionTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_VERBOSE, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), - TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"No linked connections", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(m_endpointId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), - TraceLoggingBool(m_isDeviceSide, "is device side"), - TraceLoggingUInt32(Size, "bytes"), - TraceLoggingUInt64(Position, "timestamp"), - TraceLoggingGuid(m_sessionId, "session id") - ); - if (m_isDeviceSide) { return S_OK; // ok for device side to send when nothing is listening } else { + TraceLoggingWrite( + MidiVirtualMidiAbstractionTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_VERBOSE, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"No linked connections", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(m_endpointId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), + TraceLoggingBool(m_isDeviceSide, "is device side"), + TraceLoggingUInt32(Size, "bytes"), + TraceLoggingUInt64(Position, "timestamp"), + TraceLoggingGuid(m_sessionId, "session id") + ); + RETURN_IF_FAILED(E_POINTER); // but if the client-side is not connected to a device, something is really wrong. } } @@ -209,19 +209,19 @@ CMidi2VirtualMidiBiDi::Callback( LONGLONG context ) { - TraceLoggingWrite( - MidiVirtualMidiAbstractionTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_VERBOSE, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), - TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(m_endpointId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), - TraceLoggingBool(m_isDeviceSide, "is device side"), - TraceLoggingUInt32(Size, "bytes"), - TraceLoggingUInt64(Position, "timestamp"), - TraceLoggingGuid(m_sessionId, "session id") - ); + //TraceLoggingWrite( + // MidiVirtualMidiAbstractionTelemetryProvider::Provider(), + // MIDI_TRACE_EVENT_VERBOSE, + // TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + // TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + // TraceLoggingPointer(this, "this"), + // TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + // TraceLoggingWideString(m_endpointId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), + // TraceLoggingBool(m_isDeviceSide, "is device side"), + // TraceLoggingUInt32(Size, "bytes"), + // TraceLoggingUInt64(Position, "timestamp"), + // TraceLoggingGuid(m_sessionId, "session id") + //); // message received from the client diff --git a/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiEndpointManager.cpp b/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiEndpointManager.cpp index 2ca19d2fb..ca1b46607 100644 --- a/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiEndpointManager.cpp +++ b/src/api/Abstraction/VirtualMidiAbstraction/Midi2.VirtualMidiEndpointManager.cpp @@ -270,7 +270,7 @@ CMidi2VirtualMidiEndpointManager::CreateClientVisibleEndpoint( wil::unique_cotaskmem_string newDeviceInterfaceId; - MIDIENDPOINTCOMMONPROPERTIES commonProperties; + MIDIENDPOINTCOMMONPROPERTIES commonProperties{}; commonProperties.TransportId = ABSTRACTION_LAYER_GUID; commonProperties.EndpointDeviceType = MidiEndpointDeviceType_Normal; commonProperties.FriendlyName = friendlyName.c_str(); @@ -280,6 +280,7 @@ CMidi2VirtualMidiEndpointManager::CreateClientVisibleEndpoint( commonProperties.CustomEndpointName = nullptr; commonProperties.CustomEndpointDescription = nullptr; commonProperties.UniqueIdentifier = entry.ShortUniqueId.c_str(); + commonProperties.ManufacturerName = nullptr; commonProperties.SupportedDataFormats = MidiDataFormats::MidiDataFormats_UMP; commonProperties.NativeDataFormat = MidiDataFormats::MidiDataFormats_UMP; diff --git a/src/api/Abstraction/VirtualMidiAbstraction/MidiEndpointTable.cpp b/src/api/Abstraction/VirtualMidiAbstraction/MidiEndpointTable.cpp index f9256531d..09d1d353d 100644 --- a/src/api/Abstraction/VirtualMidiAbstraction/MidiEndpointTable.cpp +++ b/src/api/Abstraction/VirtualMidiAbstraction/MidiEndpointTable.cpp @@ -105,8 +105,8 @@ MidiEndpointTable::OnClientConnected( // add the client //entry.MidiClientConnections.push_back(clientBiDi); entry.MidiClientBiDi = clientBiDi; - entry.MidiDeviceBiDi->LinkAssociatedCallback(entry.MidiClientBiDi); - entry.MidiClientBiDi->LinkAssociatedCallback(entry.MidiDeviceBiDi); + LOG_IF_FAILED(entry.MidiDeviceBiDi->LinkAssociatedCallback(entry.MidiClientBiDi)); + LOG_IF_FAILED(entry.MidiClientBiDi->LinkAssociatedCallback(entry.MidiDeviceBiDi)); m_endpoints[associationId] = entry; } @@ -155,7 +155,7 @@ MidiEndpointTable::OnClientDisconnected( { std::wstring associationId = internal::GetSwdPropertyVirtualEndpointAssociationId(clientEndpointInterfaceId); - if (associationId != L"") + if (!associationId.empty()) { auto lock = m_entriesLock.lock(); @@ -165,9 +165,16 @@ MidiEndpointTable::OnClientDisconnected( auto entry = m_endpoints[associationId]; // we unlink the two, but only remove the client - entry.MidiDeviceBiDi->UnlinkAssociatedCallback(); - entry.MidiClientBiDi->UnlinkAssociatedCallback(); - entry.MidiClientBiDi.reset(); + if (entry.MidiDeviceBiDi != nullptr) + { + LOG_IF_FAILED(entry.MidiDeviceBiDi->UnlinkAssociatedCallback()); + } + + if (entry.MidiClientBiDi != nullptr) + { + LOG_IF_FAILED(entry.MidiClientBiDi->UnlinkAssociatedCallback()); + entry.MidiClientBiDi.reset(); + } m_endpoints[associationId] = entry; @@ -246,7 +253,7 @@ HRESULT MidiEndpointTable::OnDeviceConnected( if (entry.MidiDeviceBiDi == nullptr) { entry.MidiDeviceBiDi = deviceBiDi; - // m_endpoints[associationId] = entry; + m_endpoints[associationId] = entry; } else { @@ -376,20 +383,18 @@ HRESULT MidiEndpointTable::OnDeviceDisconnected( TraceLoggingWideString(deviceEndpointInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); - // unlink the bidi devices - //entry.MidiDeviceBiDi->UnlinkAssociatedBiDi(); - entry.MidiDeviceBiDi->UnlinkAssociatedCallback(); - entry.MidiDeviceBiDi.reset(); - entry.MidiClientBiDi->UnlinkAssociatedCallback(); - entry.MidiClientBiDi.reset(); + if (entry.MidiClientBiDi != nullptr) + { + LOG_IF_FAILED(entry.MidiClientBiDi->UnlinkAssociatedCallback()); + entry.MidiClientBiDi.reset(); + } - RETURN_IF_FAILED(AbstractionState::Current().GetEndpointManager()->DeleteClientEndpoint(entry.CreatedShortClientInstanceId)); + LOG_IF_FAILED(entry.MidiDeviceBiDi->UnlinkAssociatedCallback()); + entry.MidiDeviceBiDi.reset(); - //entry.CreatedClientEndpointId = L""; - //entry.CreatedShortClientInstanceId = L""; - //m_endpoints[entry.VirtualEndpointAssociationId] = entry; + RETURN_IF_FAILED(AbstractionState::Current().GetEndpointManager()->DeleteClientEndpoint(entry.CreatedShortClientInstanceId)); // deactivate the device // TODO: Should this really be done on device disconnect vs an explicit delete command? diff --git a/src/api/Inc/ump_helpers.h b/src/api/Inc/ump_helpers.h index 90978a610..d8092d232 100644 --- a/src/api/Inc/ump_helpers.h +++ b/src/api/Inc/ump_helpers.h @@ -358,7 +358,7 @@ namespace WindowsMidiServicesInternal inline void SetGroupIndexInFirstWord(_Inout_ std::uint32_t firstWord, _In_ std::uint8_t groupIndex) noexcept { firstWord &= MIDI_MESSAGE_GROUP_WORD_CLEARING_MASK; - firstWord |= CleanupNibble(groupIndex) << MIDI_MESSAGE_GROUP_BITSHIFT; + firstWord |= static_cast(CleanupNibble(groupIndex)) << MIDI_MESSAGE_GROUP_BITSHIFT; } // in order from msb to lsb. Avoids endian issues @@ -369,7 +369,11 @@ namespace WindowsMidiServicesInternal _In_ uint8_t const byte3 ) noexcept { - return (uint32_t)(byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3); + return (uint32_t)( + static_cast(byte0) << 24 | + static_cast(byte1) << 16 | + static_cast(byte2) << 8 | + static_cast(byte3)); } // this function assumes you've already done the required range checking @@ -410,22 +414,22 @@ namespace WindowsMidiServicesInternal inline void SetMidiWordMostSignificantByte1(_Inout_ uint32_t& word, _In_ uint8_t value) { - word = (word & 0x00FFFFFF) | (value << 24); + word = (word & 0x00FFFFFF) | (static_cast(value) << 24); } inline void SetMidiWordMostSignificantByte2(_Inout_ uint32_t& word, _In_ uint8_t value) { - word = (word & 0xFF00FFFF) | (value << 16); + word = (word & 0xFF00FFFF) | (static_cast(value) << 16); } inline void SetMidiWordMostSignificantByte3(_Inout_ uint32_t& word, _In_ uint8_t value) { - word = (word & 0xFFFF00FF) | (value << 8); + word = (word & 0xFFFF00FF) | (static_cast(value) << 8); } inline void SetMidiWordMostSignificantByte4(_Inout_ uint32_t& word, _In_ uint8_t value) { - word = (word & 0xFFFFFF00) | (value); + word = (word & 0xFFFFFF00) | (static_cast(value)); } diff --git a/src/api/Service/Exe/MidiClientManager.cpp b/src/api/Service/Exe/MidiClientManager.cpp index 060b46f65..7b474dd17 100644 --- a/src/api/Service/Exe/MidiClientManager.cpp +++ b/src/api/Service/Exe/MidiClientManager.cpp @@ -130,10 +130,9 @@ GetEndpointRequiresOutboundProtocolDownscaling( auto prop = deviceInfo.Properties().Lookup(winrt::to_hstring(STRING_PKEY_MIDI_NativeDataFormat)); if (prop) { - // this interface is pointing to a UMP interface, so use that instance id. auto nativeFormat = winrt::unbox_value(prop); - if (nativeFormat == MidiDataFormats_UMP) + if (nativeFormat == MidiDataFormats_ByteStream) { // Native bytestream behind a UMP driver, so yes, we need to downscale because the driver will just discard MT4 @@ -156,51 +155,6 @@ GetEndpointRequiresOutboundProtocolDownscaling( return S_OK; } -//HRESULT -//GetEndpointShouldHaveMetadataHandler(_In_ std::wstring midiDevice, _Inout_ bool& addMetadataListener, _In_ MidiFlow flow) -//{ -// TraceLoggingWrite( -// MidiSrvTelemetryProvider::Provider(), -// __FUNCTION__, -// TraceLoggingLevel(WINEVENT_LEVEL_INFO), -// TraceLoggingWideString(midiDevice.c_str(), "Device Id") -// ); -// -// if (flow == MidiFlow::MidiFlowBidirectional || flow == MidiFlow::MidiFlowIn) -// { -// auto additionalProperties = winrt::single_threaded_vector(); -// additionalProperties.Append(winrt::to_hstring(STRING_PKEY_MIDI_EndpointRequiresMetadataHandler)); -// auto deviceInfo = DeviceInformation::CreateFromIdAsync(midiDevice, additionalProperties, winrt::Windows::Devices::Enumeration::DeviceInformationKind::DeviceInterface).get(); -// -// auto prop = deviceInfo.Properties().Lookup(winrt::to_hstring(STRING_PKEY_MIDI_EndpointRequiresMetadataHandler)); -// if (prop) -// { -// // this interface is pointing to a UMP interface, so use that instance id. -// addMetadataListener = winrt::unbox_value(prop); -// } -// else -// { -// // default to true -// addMetadataListener = true; -// } -// } -// else -// { -// // output-only flow -// addMetadataListener = false; -// } -// -// TraceLoggingWrite( -// MidiSrvTelemetryProvider::Provider(), -// __FUNCTION__, -// TraceLoggingLevel(WINEVENT_LEVEL_INFO), -// TraceLoggingWideString(midiDevice.c_str(), "Device Id"), -// TraceLoggingBool(addMetadataListener, "Add Metadata Listener") -// ); -// -// return S_OK; -//} - HRESULT GetDeviceSupportedDataFormat(_In_ std::wstring midiDevice, _Inout_ MidiDataFormats& dataFormat) @@ -365,52 +319,52 @@ GetEndpointAlias(_In_ LPCWSTR midiDevice, _In_ std::wstring& alias, _In_ MidiFlo return S_OK; } -HRESULT -GetEndpointGroupIndex(_In_ std::wstring midiDevice, _Inout_ BYTE& groupIndex) -{ - TraceLoggingWrite( - MidiSrvTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(nullptr, "this"), - TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(midiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) - ); +HRESULT +GetEndpointGroupIndex(_In_ std::wstring midiDevice, _Inout_ BYTE& groupIndex) +{ + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(midiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); // Default to the invalid group index, to indicate that no group index is available for // this midiDevice. groupIndex = INVALID_GROUP_INDEX; - - auto additionalProperties = winrt::single_threaded_vector(); - additionalProperties.Append(winrt::to_hstring(STRING_PKEY_MIDI_PortAssignedGroupIndex)); - auto deviceInfo = DeviceInformation::CreateFromIdAsync(midiDevice, additionalProperties, winrt::Windows::Devices::Enumeration::DeviceInformationKind::DeviceInterface).get(); - - auto prop = deviceInfo.Properties().Lookup(winrt::to_hstring(STRING_PKEY_MIDI_PortAssignedGroupIndex)); - if (prop) - { - try - { + + auto additionalProperties = winrt::single_threaded_vector(); + additionalProperties.Append(winrt::to_hstring(STRING_PKEY_MIDI_PortAssignedGroupIndex)); + auto deviceInfo = DeviceInformation::CreateFromIdAsync(midiDevice, additionalProperties, winrt::Windows::Devices::Enumeration::DeviceInformationKind::DeviceInterface).get(); + + auto prop = deviceInfo.Properties().Lookup(winrt::to_hstring(STRING_PKEY_MIDI_PortAssignedGroupIndex)); + if (prop) + { + try + { // If a group index is provided by this device, it must be valid. - groupIndex = (BYTE) winrt::unbox_value(prop); + groupIndex = (BYTE) winrt::unbox_value(prop); RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INDEX_OUT_OF_BOUNDS), !IS_VALID_GROUP_INDEX(groupIndex)); - } - CATCH_LOG(); - } - - TraceLoggingWrite( - MidiSrvTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(nullptr, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(midiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), - TraceLoggingBool(groupIndex, "Port group index") - ); - - return S_OK; -} + } + CATCH_LOG(); + } + + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(midiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), + TraceLoggingBool(groupIndex, "Port group index") + ); + + return S_OK; +} _Use_decl_annotations_ @@ -470,7 +424,7 @@ CMidiClientManager::GetMidiClient( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(cleanMidiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), TraceLoggingGuid(sessionId, "Session Id") ); @@ -536,7 +490,7 @@ CMidiClientManager::GetMidiDevice( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(cleanMidiDevice.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); @@ -619,7 +573,7 @@ CMidiClientManager::GetMidiProtocolDownscalerTransform( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(devicePipe->MidiDevice().c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); @@ -951,84 +905,6 @@ CMidiClientManager::GetMidiScheduler( return S_OK; } -//_Use_decl_annotations_ -//HRESULT -//CMidiClientManager::GetMidiEndpointMetadataHandler( -// MidiFlow flow, -// wil::com_ptr_nothrow& devicePipe, -// wil::com_ptr_nothrow& nextDeviceSidePipe, -// wil::com_ptr_nothrow& clientConnectionPipe -//) -//{ -// RETURN_HR_IF_NULL(E_INVALIDARG, devicePipe); -// -// TraceLoggingWrite( -// MidiSrvTelemetryProvider::Provider(), -// MIDI_TRACE_EVENT_INFO, -// TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), -// TraceLoggingLevel(WINEVENT_LEVEL_INFO), -// TraceLoggingPointer(this, "this"), -// TraceLoggingWideString(devicePipe->MidiDevice().c_str(), "Device Id") -// ); -// -// wil::com_ptr_nothrow transformPipe{ nullptr }; -// -// // we only handle metadata on incoming messages -// RETURN_HR_IF(E_UNEXPECTED, flow != MidiFlow::MidiFlowIn); -// -// -// auto transforms = m_TransformPipes.equal_range(devicePipe->MidiDevice()); -// for (auto& transform = transforms.first; transform != transforms.second; ++transform) -// { -// //wil::com_ptr_nothrow pipe = transform->second.get(); -// -// if (transform->second->TransformGuid() == __uuidof(Midi2EndpointMetadataListenerTransform)) -// { -// transformPipe = transform->second; -// break; -// } -// } -// -// // not found, instantiate the transform that is needed. -// if (!transformPipe) -// { -// MIDISRV_TRANSFORMCREATION_PARAMS creationParams{ 0 }; -// -// creationParams.Flow = flow; -// creationParams.DataFormatIn = MidiDataFormats::MidiDataFormats_UMP; -// creationParams.DataFormatOut = MidiDataFormats::MidiDataFormats_UMP; -// -// creationParams.TransformGuid = __uuidof(Midi2EndpointMetadataListenerTransform); -// creationParams.UmpGroupIndex = INVALID_GROUP_INDEX; -// -// // create the transform -// wil::com_ptr_nothrow transform; -// RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&transform)); -// -// RETURN_IF_FAILED(transform->Initialize(devicePipe->MidiDevice().c_str(), &creationParams, &m_MmcssTaskId, m_DeviceManager.get())); -// -// transformPipe = transform.get(); -// -// // connect the transform to the device -// -// if (flow == MidiFlowIn) -// { -// RETURN_IF_FAILED(nextDeviceSidePipe->AddConnectedPipe(transformPipe)); -// } -// else -// { -// RETURN_IF_FAILED(transformPipe->AddConnectedPipe(nextDeviceSidePipe)); -// } -// -// m_TransformPipes.emplace(devicePipe->MidiDevice(), transform); -// } -// -// clientConnectionPipe = transformPipe; -// -// return S_OK; -//} - - _Use_decl_annotations_ HRESULT @@ -1318,7 +1194,8 @@ CMidiClientManager::DestroyMidiClient( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(clientHandle, "client handle") ); auto lock = m_ClientManagerLock.lock(); @@ -1334,10 +1211,10 @@ CMidiClientManager::DestroyMidiClient( wil::com_ptr_nothrow midiClientPipe = (CMidiClientPipe*)(client->second.get()); wil::com_ptr_nothrow clientAsMidiPipe = midiClientPipe.get(); - midiClientPipe->Shutdown(); - m_SessionTracker->RemoveClientEndpointConnection(midiClientPipe->SessionId(), midiClientPipe->ClientProcessId(), client->second->MidiDevice().c_str(), clientHandle); + midiClientPipe->Shutdown(); + // remove this client from all of the transforms and disconnect it and any transforms no longer in use for (auto transform = m_TransformPipes.begin(); transform != m_TransformPipes.end();) { @@ -1404,5 +1281,16 @@ CMidiClientManager::DestroyMidiClient( RETURN_IF_FAILED(E_INVALIDARG); } + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(clientHandle, "client handle") + ); + + return S_OK; } diff --git a/src/api/Service/Exe/MidiDeviceManager.cpp b/src/api/Service/Exe/MidiDeviceManager.cpp index cd8b8da81..779b6e624 100644 --- a/src/api/Service/Exe/MidiDeviceManager.cpp +++ b/src/api/Service/Exe/MidiDeviceManager.cpp @@ -1060,10 +1060,16 @@ CMidiDeviceManager::ActivateEndpoint friendlyName += commonProperties->EndpointName; } - if (friendlyName.size() > 32 - 6) +#define MAX_WINMM_ENDPOINT_NAME_SIZE_WITHOUT_GROUP_SUFFIX (32-6) + + if (friendlyName.size() > MAX_WINMM_ENDPOINT_NAME_SIZE_WITHOUT_GROUP_SUFFIX) { - // if the size of name + " O-12\0" > 32, we need to lose the manufacturer name for WinMM compat - friendlyName = commonProperties->EndpointName; + // if the size of name + " O-nn\0" > 32, we need to lose the manufacturer name for WinMM compat + + std::wstring shortName{ commonProperties->EndpointName }; + shortName.resize(MAX_WINMM_ENDPOINT_NAME_SIZE_WITHOUT_GROUP_SUFFIX); + + friendlyName = shortName.c_str(); } } @@ -1707,9 +1713,12 @@ CMidiDeviceManager::DeactivateEndpoint TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(instanceId, MIDI_TRACE_EVENT_DEVICE_INSTANCE_ID_FIELD) ); + RETURN_HR_IF_NULL(E_INVALIDARG, instanceId); + auto cleanId = internal::NormalizeDeviceInstanceIdWStringCopy(instanceId); // there may be more than one SWD associated with this instance id, as we reuse @@ -1741,8 +1750,9 @@ CMidiDeviceManager::DeactivateEndpoint TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Found instance id in ports list.", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(instanceId, MIDI_TRACE_EVENT_DEVICE_INSTANCE_ID_FIELD) + TraceLoggingWideString(L"Found instance id in ports list. Erasing", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(cleanId.c_str(), MIDI_TRACE_EVENT_DEVICE_INSTANCE_ID_FIELD), + TraceLoggingWideString(item->get()->DeviceInterfaceId.get(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); // Erasing this item from the list will free the unique_ptr and also trigger a SwDeviceClose on the item->SwDevice, @@ -1751,6 +1761,17 @@ CMidiDeviceManager::DeactivateEndpoint } } while (TRUE); + + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(cleanId.c_str(), MIDI_TRACE_EVENT_DEVICE_INSTANCE_ID_FIELD) + ); + return S_OK; } diff --git a/src/api/Service/Exe/MidiDevicePipe.cpp b/src/api/Service/Exe/MidiDevicePipe.cpp index 28e8454c1..50073e2a4 100644 --- a/src/api/Service/Exe/MidiDevicePipe.cpp +++ b/src/api/Service/Exe/MidiDevicePipe.cpp @@ -172,7 +172,8 @@ CMidiDevicePipe::Shutdown() MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); { @@ -198,6 +199,15 @@ CMidiDevicePipe::Shutdown() RETURN_IF_FAILED(CMidiPipe::Shutdown()); + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) + ); + return S_OK; } diff --git a/src/api/Service/Exe/MidiEndpointProtocolManager.cpp b/src/api/Service/Exe/MidiEndpointProtocolManager.cpp index da9891755..0d149d9cc 100644 --- a/src/api/Service/Exe/MidiEndpointProtocolManager.cpp +++ b/src/api/Service/Exe/MidiEndpointProtocolManager.cpp @@ -51,7 +51,6 @@ CMidiEndpointProtocolManager::Initialize( // we only spin this all up if negotiation is enabled if (m_discoveryAndProtocolNegotiationEnabled) { - // use our clsid as the session id. m_sessionId = __uuidof(IMidiEndpointProtocolManagerInterface); @@ -93,6 +92,18 @@ CMidiEndpointProtocolManager::Initialize( m_watcher.Start(); } + else + { + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_WARNING, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_WARNING), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Discovery and protocol negotiation (and metadata capture) are disabled", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingGuid(m_sessionId, "session id") + ); + } return S_OK; } @@ -159,7 +170,7 @@ CMidiEndpointProtocolManager::DiscoverAndNegotiate( TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD), - TraceLoggingBool(m_discoveryAndProtocolNegotiationEnabled, "IsEnabled") + TraceLoggingBool(m_discoveryAndProtocolNegotiationEnabled, "DiscoveryEnabled") ); // clients should check for IsEnabled before calling this function @@ -168,6 +179,7 @@ CMidiEndpointProtocolManager::DiscoverAndNegotiate( return E_ABORT; } + std::scoped_lock lock(m_endpointWorkersMapMutex); auto cleanEndpointDeviceInterfaceId = internal::NormalizeEndpointInterfaceIdWStringCopy(endpointDeviceInterfaceId); @@ -200,22 +212,19 @@ CMidiEndpointProtocolManager::DiscoverAndNegotiate( RETURN_IF_FAILED(initializeHR); - { - std::scoped_lock lock(m_endpointWorkersMapMutex); - // create the thread + // create the thread - ProtocolNegotiationWorkerThreadEntry newEntry{}; + ProtocolNegotiationWorkerThreadEntry newEntry{}; - newEntry.Worker = worker; + newEntry.Worker = worker; - newEntry.Thread = std::make_shared(&CMidiEndpointProtocolWorker::Start, newEntry.Worker, - negotiationParams, - negotiationCompleteCallback); + newEntry.Thread = std::make_shared(&CMidiEndpointProtocolWorker::Start, newEntry.Worker, + negotiationParams, + negotiationCompleteCallback); - m_endpointWorkers[cleanEndpointDeviceInterfaceId] = newEntry; - m_endpointWorkers[cleanEndpointDeviceInterfaceId].Thread->detach(); - } + m_endpointWorkers[cleanEndpointDeviceInterfaceId] = newEntry; + m_endpointWorkers[cleanEndpointDeviceInterfaceId].Thread->detach(); TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), @@ -247,12 +256,12 @@ CMidiEndpointProtocolManager::RemoveWorkerIfPresent(std::wstring endpointInterfa auto cleanEndpointId = internal::NormalizeEndpointInterfaceIdWStringCopy(endpointInterfaceId); + std::scoped_lock lock(m_endpointWorkersMapMutex); + auto val = m_endpointWorkers.find(cleanEndpointId); if (val != m_endpointWorkers.end()) { - std::scoped_lock lock(m_endpointWorkersMapMutex); - val->second.Worker->EndProcessing(); // this sets an event that tells the thread to quit if (val->second.Thread->joinable()) diff --git a/src/api/Service/Exe/MidiEndpointProtocolWorker.cpp b/src/api/Service/Exe/MidiEndpointProtocolWorker.cpp index af2102de2..06c608ae1 100644 --- a/src/api/Service/Exe/MidiEndpointProtocolWorker.cpp +++ b/src/api/Service/Exe/MidiEndpointProtocolWorker.cpp @@ -32,7 +32,7 @@ CMidiEndpointProtocolWorker::Initialize( m_abstractionId = transportId; m_sessionId = sessionId; - m_deviceInterfaceId = endpointDeviceInterfaceId; + m_deviceInterfaceId = internal::NormalizeEndpointInterfaceIdWStringCopy(endpointDeviceInterfaceId); m_clientManager = clientManager; m_deviceManager = deviceManager; @@ -169,7 +169,6 @@ CMidiEndpointProtocolWorker::Start( try { - // we do this here instead of in initialize so this is created on the worker thread if (!m_midiBiDiDevice) { @@ -182,8 +181,7 @@ CMidiEndpointProtocolWorker::Start( DWORD mmcssTaskId{ 0 }; LONGLONG context{ 0 }; - - // this is not a good idea, but we don't have a reference to the lib here + // this is not a good idea, but we don't have a reference to the COM lib here GUID midi2MidiSrvAbstractionIID = internal::StringToGuid(L"{2BA15E4E-5417-4A66-85B8-2B2260EFBC84}"); RETURN_IF_FAILED(CoCreateInstance((IID)midi2MidiSrvAbstractionIID, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&serviceAbstraction))); RETURN_IF_NULL_ALLOC(serviceAbstraction); @@ -200,6 +198,16 @@ CMidiEndpointProtocolWorker::Start( context, m_sessionId )); + + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Protocol negotiation connection created", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); } // add this connection to the session tracker. The manager already logged the overall session @@ -208,7 +216,7 @@ CMidiEndpointProtocolWorker::Start( // m_deviceInterfaceId.c_str(), // (MidiClientHandle)nullptr)); - if (m_initialNegotiation && !m_allNegotiationMessagesReceived) + if (m_initialNegotiation && !m_allNegotiationMessagesReceived.is_valid()) { RETURN_IF_FAILED(m_allNegotiationMessagesReceived.create(wil::EventOptions::ManualReset)); } @@ -235,16 +243,6 @@ CMidiEndpointProtocolWorker::Start( m_taskEndpointProductInstanceIdReceived = false; m_taskFinalStreamNegotiationResponseReceived = false; - TraceLoggingWrite( - MidiSrvTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_VERBOSE, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), - TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Requesting discovery information", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) - ); - // Partner device-compatibility requirement. May be able to remove this in the future // but needed for now for their USB device to work properly. Given when this is called, @@ -260,21 +258,23 @@ CMidiEndpointProtocolWorker::Start( // End partner compatibility mitigation added 2024-10-08 - // start initial negotiation. Return when timed out or when we have all the requested info. - LOG_IF_FAILED(RequestAllEndpointDiscoveryInformation()); - - m_allNegotiationMessagesReceived.wait(negotiationParams.TimeoutMilliseconds); - TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_VERBOSE, + MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Returned from manual reset event wait", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Requesting discovery information", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); + // start initial negotiation. Return when timed out or when we have all the requested info. + LOG_IF_FAILED(RequestAllEndpointDiscoveryInformation()); + + // TODO: This should likely also wait on the endprocessing in case device is + // disconnected during this wait + m_allNegotiationMessagesReceived.wait(negotiationParams.TimeoutMilliseconds); + if (m_allNegotiationMessagesReceived.is_signaled()) { TraceLoggingWrite( @@ -283,12 +283,11 @@ CMidiEndpointProtocolWorker::Start( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"All discovery/negotiation messages received", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"All discovery/negotiation messages received within timeout period", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); // provide all the negotiation results - m_mostRecentResults.AllEndpointInformationReceived = true; } else @@ -299,7 +298,7 @@ CMidiEndpointProtocolWorker::Start( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_WARNING), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Discovery/negotiation messages partially received", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Incomplete or no discovery/negotiation messages received (event timed out)", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); @@ -503,15 +502,19 @@ CMidiEndpointProtocolWorker::Callback( LONGLONG position, LONGLONG context) { + //TraceLoggingWrite( // MidiSrvTelemetryProvider::Provider(), // MIDI_TRACE_EVENT_WARNING, // TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), // TraceLoggingLevel(WINEVENT_LEVEL_WARNING), // TraceLoggingPointer(this, "this"), + // TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), // TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) //); + if (m_endProcessing.is_signaled()) return S_OK; + UNREFERENCED_PARAMETER(position); UNREFERENCED_PARAMETER(context); @@ -529,6 +532,16 @@ CMidiEndpointProtocolWorker::Callback( if (internal::GetUmpMessageTypeFromFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_UMP_MESSAGE_TYPE) { + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Stream message received.", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); + LOG_IF_FAILED(ProcessStreamMessage(ump)); // check flags. If we've received everything, signal @@ -605,7 +618,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) { case MIDI_STREAM_MESSAGE_STATUS_ENDPOINT_INFO_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -614,7 +626,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Endpoint Info Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif LOG_IF_FAILED(UpdateEndpointInfoProperties(ump)); @@ -667,7 +678,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_DEVICE_IDENTITY_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -676,7 +686,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Device Identity Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif LOG_IF_FAILED(UpdateDeviceIdentityProperty(ump)); @@ -686,7 +695,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_STREAM_CONFIGURATION_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -695,7 +703,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Stream Configuration Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif LOG_IF_FAILED(UpdateStreamConfigurationProperties(ump)); LOG_IF_FAILED(ProcessStreamConfigurationRequest(ump)); @@ -704,7 +711,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_FUNCTION_BLOCK_INFO_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -713,7 +719,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Function Block Info Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif m_countFunctionBlocksReceived += 1; @@ -746,7 +751,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_FUNCTION_BLOCK_NAME_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -755,7 +759,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Function Block Name Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif if (internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_COMPLETE || internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_END) @@ -769,7 +772,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_ENDPOINT_PRODUCT_INSTANCE_ID_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -778,7 +780,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Product Instance Id Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif if (internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_COMPLETE || internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_END) @@ -792,7 +793,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) case MIDI_STREAM_MESSAGE_STATUS_ENDPOINT_NAME_NOTIFICATION: { -#ifdef _DEBUG TraceLoggingWrite( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, @@ -801,7 +801,6 @@ CMidiEndpointProtocolWorker::ProcessStreamMessage(internal::PackedUmp128 ump) TraceLoggingPointer(this, "this"), TraceLoggingWideString(L"Received Endpoint Name Notification", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); -#endif if (internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_COMPLETE || internal::GetFormFromStreamMessageFirstWord(ump.word0) == MIDI_STREAM_MESSAGE_MULTI_FORM_END) @@ -889,6 +888,16 @@ CMidiEndpointProtocolWorker::RequestAllEndpointDiscoveryInformation() // send it immediately RETURN_IF_FAILED(m_midiBiDiDevice->SendMidiMessage((byte*)&ump, (UINT)sizeof(ump), 0)); + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); + return S_OK; } @@ -969,16 +978,11 @@ CMidiEndpointProtocolWorker::Shutdown() TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); - - // stop worker thread - + // signal to stop worker thread EndProcessing(); - //if (m_.joinable()) - // m_queueWorkerThread.join(); m_allNegotiationMessagesReceived.reset(); - m_negotiationCompleteCallback = nullptr; if (m_midiBiDiDevice) @@ -987,10 +991,10 @@ CMidiEndpointProtocolWorker::Shutdown() m_midiBiDiDevice.reset(); } - if (m_sessionTracker) - { - LOG_IF_FAILED(m_sessionTracker->RemoveClientEndpointConnection(m_sessionId, m_clientProcessId, m_deviceInterfaceId.c_str(), (MidiClientHandle)nullptr)); - } + //if (m_sessionTracker) + //{ + // LOG_IF_FAILED(m_sessionTracker->RemoveClientEndpointConnection(m_sessionId, m_clientProcessId, m_deviceInterfaceId.c_str(), (MidiClientHandle)nullptr)); + //} return S_OK; } @@ -1240,7 +1244,7 @@ CMidiEndpointProtocolWorker::UpdateDeviceIdentityProperty(internal::PackedUmp128 DEVPROPERTY props[] = { {{ PKEY_MIDI_DeviceIdentity, DEVPROP_STORE_SYSTEM, nullptr }, - DEVPROP_TYPE_BINARY, static_cast(sizeof(prop)), &prop }, + DEVPROP_TYPE_BINARY, static_cast(sizeof(prop)), (PVOID)(&prop) }, {{ PKEY_MIDI_DeviceIdentityLastUpdateTime, DEVPROP_STORE_SYSTEM, nullptr}, DEVPROP_TYPE_FILETIME, static_cast(sizeof(FILETIME)), (PVOID)(¤tTime) }, @@ -1267,17 +1271,18 @@ CMidiEndpointProtocolWorker::UpdateEndpointInfoProperties(internal::PackedUmp128 TraceLoggingWideString(m_deviceInterfaceId.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); - BYTE umpVersionMajor = MIDIWORDBYTE3(endpointInfoNotificationMessage.word0); - BYTE umpVersionMinor = MIDIWORDBYTE4(endpointInfoNotificationMessage.word0); - BYTE functionBlockCount = internal::CleanupByte7(MIDIWORDBYTE1(endpointInfoNotificationMessage.word1)); + BYTE umpVersionMajor = internal::GetEndpointInfoNotificationUmpVersionMajorFirstWord(endpointInfoNotificationMessage.word0); + BYTE umpVersionMinor = internal::GetEndpointInfoNotificationUmpVersionMinorFirstWord(endpointInfoNotificationMessage.word0); + BYTE functionBlockCount = internal::GetEndpointInfoNotificationNumberOfFunctionBlocksFromSecondWord(endpointInfoNotificationMessage.word1); + - DEVPROP_BOOLEAN functionBlocksAreStatic = MIDIWORDHIGHBIT(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; + DEVPROP_BOOLEAN functionBlocksAreStatic = internal::GetEndpointInfoNotificationStaticFunctionBlocksFlagFromSecondWord(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; - DEVPROP_BOOLEAN supportsMidi1Protocol = MIDIWORDBYTE3LOWBIT1(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; - DEVPROP_BOOLEAN supportsMidi2Protocol = MIDIWORDBYTE3LOWBIT2(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; + DEVPROP_BOOLEAN supportsMidi1Protocol = internal::GetEndpointInfoNotificationMidi1ProtocolCapabilityFromSecondWord(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; + DEVPROP_BOOLEAN supportsMidi2Protocol = internal::GetEndpointInfoNotificationMidi2ProtocolCapabilityFromSecondWord(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; - DEVPROP_BOOLEAN supportsSendingJR = MIDIWORDBYTE4LOWBIT1(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; - DEVPROP_BOOLEAN supportsReceivingJR = MIDIWORDBYTE4LOWBIT2(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; + DEVPROP_BOOLEAN supportsSendingJR = internal::GetEndpointInfoNotificationTransmitJRTimestampCapabilityFromSecondWord(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; + DEVPROP_BOOLEAN supportsReceivingJR = internal::GetEndpointInfoNotificationReceiveJRTimestampCapabilityFromSecondWord(endpointInfoNotificationMessage.word1) ? DEVPROP_TRUE : DEVPROP_FALSE; FILETIME currentTime; GetSystemTimePreciseAsFileTime(¤tTime); @@ -1301,7 +1306,7 @@ CMidiEndpointProtocolWorker::UpdateEndpointInfoProperties(internal::PackedUmp128 DEVPROP_TYPE_BYTE, static_cast(sizeof(umpVersionMajor)), &umpVersionMajor }, {{ PKEY_MIDI_EndpointUmpVersionMinor, DEVPROP_STORE_SYSTEM, nullptr }, - DEVPROP_TYPE_BYTE, static_cast(sizeof(umpVersionMajor)), &umpVersionMinor }, + DEVPROP_TYPE_BYTE, static_cast(sizeof(umpVersionMinor)), &umpVersionMinor }, {{ PKEY_MIDI_FunctionBlockCount, DEVPROP_STORE_SYSTEM, nullptr }, DEVPROP_TYPE_BYTE, static_cast(sizeof(functionBlockCount)), &functionBlockCount }, @@ -1336,17 +1341,17 @@ CMidiEndpointProtocolWorker::UpdateFunctionBlockProperty(internal::PackedUmp128& MidiFunctionBlockProperty prop; - prop.IsActive = MIDIWORDBYTE3HIGHBIT(functionBlockInfoNotificationMessage.word0); - prop.BlockNumber = internal::CleanupByte7(MIDIWORDBYTE3(functionBlockInfoNotificationMessage.word0)); - prop.Direction = MIDIWORDBYTE4LOWCRUMB1(functionBlockInfoNotificationMessage.word0); - prop.Midi1 = MIDIWORDBYTE4LOWCRUMB2(functionBlockInfoNotificationMessage.word0); - prop.UIHint = MIDIWORDBYTE4LOWCRUMB3(functionBlockInfoNotificationMessage.word0); + prop.IsActive = internal::GetFunctionBlockActiveFlagFromInfoNotificationFirstWord(functionBlockInfoNotificationMessage.word0); + prop.BlockNumber = internal::GetFunctionBlockNumberFromInfoNotificationFirstWord(functionBlockInfoNotificationMessage.word0); + prop.Direction = internal::GetFunctionBlockDirectionFromInfoNotificationFirstWord(functionBlockInfoNotificationMessage.word0); + prop.Midi1 = internal::GetFunctionBlockMidi10FromInfoNotificationFirstWord(functionBlockInfoNotificationMessage.word0); + prop.UIHint = internal::GetFunctionBlockUIHintFromInfoNotificationFirstWord(functionBlockInfoNotificationMessage.word0); prop.Reserved0 = MIDIWORDBYTE4LOWCRUMB4(functionBlockInfoNotificationMessage.word0); - prop.FirstGroup = MIDIWORDBYTE1(functionBlockInfoNotificationMessage.word1); - prop.NumberOfGroupsSpanned = MIDIWORDBYTE2(functionBlockInfoNotificationMessage.word1); - prop.MidiCIMessageVersionFormat = MIDIWORDBYTE3(functionBlockInfoNotificationMessage.word1); - prop.MaxSysEx8Streams = MIDIWORDBYTE4(functionBlockInfoNotificationMessage.word1); + prop.FirstGroup = internal::GetFunctionBlockFirstGroupFromInfoNotificationSecondWord(functionBlockInfoNotificationMessage.word1); + prop.NumberOfGroupsSpanned = internal::GetFunctionBlockNumberOfGroupsFromInfoNotificationSecondWord(functionBlockInfoNotificationMessage.word1); + prop.MidiCIMessageVersionFormat = internal::GetFunctionBlockMidiCIVersionFromInfoNotificationSecondWord(functionBlockInfoNotificationMessage.word1); + prop.MaxSysEx8Streams = internal::GetFunctionBlockMaxSysex8StreamsFromInfoNotificationSecondWord(functionBlockInfoNotificationMessage.word1); prop.Reserved1 = functionBlockInfoNotificationMessage.word2; prop.Reserved2 = functionBlockInfoNotificationMessage.word3; @@ -1359,7 +1364,7 @@ CMidiEndpointProtocolWorker::UpdateFunctionBlockProperty(internal::PackedUmp128& DEVPROPERTY props[] = { {{ propKey, DEVPROP_STORE_SYSTEM, nullptr}, - DEVPROP_TYPE_BINARY, static_cast(sizeof(prop)), &prop }, + DEVPROP_TYPE_BINARY, static_cast(sizeof(prop)), (PVOID)(&prop)}, {{ PKEY_MIDI_FunctionBlocksLastUpdateTime, DEVPROP_STORE_SYSTEM, nullptr}, DEVPROP_TYPE_FILETIME, static_cast(sizeof(FILETIME)), (PVOID)(¤tTime) }, diff --git a/src/api/Service/Exe/MidiEndpointProtocolWorker.h b/src/api/Service/Exe/MidiEndpointProtocolWorker.h index 0bd779633..e90dc4491 100644 --- a/src/api/Service/Exe/MidiEndpointProtocolWorker.h +++ b/src/api/Service/Exe/MidiEndpointProtocolWorker.h @@ -37,7 +37,7 @@ class CMidiEndpointProtocolWorker : public Microsoft::WRL::RuntimeClass< STDMETHOD(Shutdown)(); - void EndProcessing() { if (m_endProcessing.is_valid()) m_endProcessing.SetEvent(); } + void EndProcessing() { if (m_endProcessing.is_valid() && !m_endProcessing.is_signaled()) m_endProcessing.SetEvent(); } private: std::wstring m_deviceInterfaceId; diff --git a/src/api/Service/Exe/MidiSessionTracker.cpp b/src/api/Service/Exe/MidiSessionTracker.cpp index 032dd83d7..8ae930e92 100644 --- a/src/api/Service/Exe/MidiSessionTracker.cpp +++ b/src/api/Service/Exe/MidiSessionTracker.cpp @@ -20,8 +20,9 @@ CMidiSessionTracker::FindSession(GUID sessionId, DWORD clientProcessId) TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingGuid(sessionId), - TraceLoggingUInt32(clientProcessId), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingGuid(sessionId, "session id"), + TraceLoggingUInt32(clientProcessId, "client process"), TraceLoggingUInt32((UINT32)m_sessions.size(), "Total session count") ); @@ -48,8 +49,9 @@ CMidiSessionTracker::FindSessionForContextHandle(PVOID contextHandle) MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) + ); if (contextHandle == nullptr) return m_sessions.end(); @@ -74,7 +76,8 @@ CMidiSessionTracker::Initialize(std::shared_ptr& clientManag MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); m_clientManager = clientManager; @@ -90,8 +93,9 @@ CMidiSessionTracker::VerifyConnectivity() MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) + ); // if this gets called, we have connectivity return TRUE; @@ -345,7 +349,8 @@ CMidiSessionTracker::RemoveClientSessionInternal( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingPointer(contextHandle) + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingPointer(contextHandle, "context handle") ); RETURN_HR_IF_NULL(E_INVALIDARG, contextHandle); @@ -371,6 +376,16 @@ CMidiSessionTracker::RemoveClientSessionInternal( m_sessions.erase(sessionEntry); } + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingPointer(contextHandle, "context handle") + ); + return S_OK; } diff --git a/src/api/Service/Exe/MidiSrvRpc.cpp b/src/api/Service/Exe/MidiSrvRpc.cpp index 5d8f5929d..38cd0a5f7 100644 --- a/src/api/Service/Exe/MidiSrvRpc.cpp +++ b/src/api/Service/Exe/MidiSrvRpc.cpp @@ -37,7 +37,9 @@ MidiSrvVerifyConnectivity( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO) + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -64,7 +66,9 @@ HRESULT MidiSrvCreateClient( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO) + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr clientManager; @@ -117,7 +121,9 @@ HRESULT MidiSrvDestroyClient( MidiSrvTelemetryProvider::Provider(), MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO) + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr clientManager; @@ -143,14 +149,6 @@ MidiSrvUpdateConfiguration( // in case of any HRESULT error, the response is supposed to be nullptr *responseJson = nullptr; - TraceLoggingWrite( - MidiSrvTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") - ); - RETURN_HR_IF_NULL(E_INVALIDARG, configurationJson); //RETURN_HR_IF_NULL(E_INVALIDARG, responseJson); @@ -159,6 +157,8 @@ MidiSrvUpdateConfiguration( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(configurationJson, "JSON") ); @@ -181,7 +181,8 @@ MidiSrvUpdateConfiguration( MIDI_TRACE_EVENT_ERROR, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), - TraceLoggingWideString(L"Only one config entry allowed per call") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Only one config entry allowed per call", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return E_FAIL; @@ -206,7 +207,8 @@ MidiSrvUpdateConfiguration( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -226,7 +228,8 @@ MidiSrvRegisterSession( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -251,7 +254,8 @@ MidiSrvRegisterSession( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -272,7 +276,8 @@ MidiSrvUpdateSessionName( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -291,7 +296,8 @@ MidiSrvUpdateSessionName( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -311,7 +317,8 @@ MidiSrvDeregisterSession( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -330,7 +337,8 @@ MidiSrvDeregisterSession( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -350,7 +358,8 @@ __RPC_USER PMIDISRV_CONTEXT_HANDLE_rundown( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter context handle rundown") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter context handle rundown", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -380,7 +389,8 @@ MidiSrvGetSessionList( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr sessionTracker; @@ -396,7 +406,8 @@ MidiSrvGetSessionList( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -416,7 +427,8 @@ MidiSrvGetTransportList( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); std::shared_ptr configManager; @@ -472,7 +484,8 @@ MidiSrvGetTransportList( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Exit success") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); return S_OK; @@ -572,7 +585,8 @@ MidiSrvGetTransformList( MIDI_TRACE_EVENT_INFO, TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingWideString(L"Enter") + TraceLoggingPointer(nullptr, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); json::JsonObject rootObject{}; diff --git a/src/api/Service/Exe/MidiTransformPipe.cpp b/src/api/Service/Exe/MidiTransformPipe.cpp index 69510adb2..eed9e0af2 100644 --- a/src/api/Service/Exe/MidiTransformPipe.cpp +++ b/src/api/Service/Exe/MidiTransformPipe.cpp @@ -56,7 +56,7 @@ CMidiTransformPipe::Initialize( TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD), TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) ); @@ -93,7 +93,7 @@ CMidiTransformPipe::Shutdown() TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Exit", MIDI_TRACE_EVENT_MESSAGE_FIELD) + TraceLoggingWideString(L"Exit success", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); diff --git a/src/api/Service/Inc/MidiPipe.h b/src/api/Service/Inc/MidiPipe.h index a43a3cef0..357a79688 100644 --- a/src/api/Service/Inc/MidiPipe.h +++ b/src/api/Service/Inc/MidiPipe.h @@ -162,16 +162,51 @@ class CMidiPipe : virtual void AddClient(MidiClientHandle handle) { + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(handle, "MIDI Client Handle"), + TraceLoggingWideString(m_Device.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); + auto lock = m_Lock.lock(); auto client = std::find(m_Clients.begin(), m_Clients.end(), handle); if (client == m_Clients.end()) { m_Clients.push_back(handle); } + else + { + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_WARNING, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_WARNING), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Client already exists", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(handle, "MIDI Client Handle"), + TraceLoggingWideString(m_Device.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); + } } virtual void RemoveClient(MidiClientHandle handle) { + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(handle, "MIDI Client Handle"), + TraceLoggingWideString(m_Device.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); + auto lock = m_Lock.lock(); auto client = std::find(m_Clients.begin(), m_Clients.end(), handle); if (client != m_Clients.end()) @@ -181,6 +216,17 @@ class CMidiPipe : else { LOG_IF_FAILED(E_NOTFOUND); + + TraceLoggingWrite( + MidiSrvTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_WARNING, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_WARNING), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Client not found", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingUInt64(handle, "MIDI Client Handle"), + TraceLoggingWideString(m_Device.c_str(), MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD) + ); } } diff --git a/src/api/Transform/UmpProtocolDownscaler/Midi2.UmpProtocolDownscalerMidiTransform.cpp b/src/api/Transform/UmpProtocolDownscaler/Midi2.UmpProtocolDownscalerMidiTransform.cpp index 6362f7d6f..f49403de5 100644 --- a/src/api/Transform/UmpProtocolDownscaler/Midi2.UmpProtocolDownscalerMidiTransform.cpp +++ b/src/api/Transform/UmpProtocolDownscaler/Midi2.UmpProtocolDownscalerMidiTransform.cpp @@ -153,7 +153,7 @@ CMidi2UmpProtocolDownscalerMidiTransform::OnDeviceUpdated(DeviceWatcher, DeviceI { m_downscalingRequiredForEndpoint = false; - if (m_endpointSupportsMidi1Protocol && m_endpointSupportsMidi2Protocol) + if (m_endpointSupportsMidi1Protocol /* && m_endpointSupportsMidi2Protocol*/) { TraceLoggingWrite( MidiUmpProtocolDownscalerTransformTelemetryProvider::Provider(), @@ -242,6 +242,14 @@ CMidi2UmpProtocolDownscalerMidiTransform::SendMidiMessage( { if (length >= sizeof(uint32_t)) { + // downscale only MIDI 2.0 channel voice messages : message type 4. Everything else passes through + if (internal::GetUmpMessageTypeFromFirstWord(internal::MidiWord0FromVoidMessageDataPointer(inputData)) != 4) + { + RETURN_IF_FAILED(m_Callback->Callback(inputData, length, timestamp, m_Context)); + + return S_OK; + } + // Send the UMP(s) to the parser uint32_t* data = (uint32_t*)inputData; for (UINT i = 0; i < (length / sizeof(uint32_t)); i++) diff --git a/src/app-sdk/winrt/Microsoft.Windows.Devices.Midi2.vcxproj.filters b/src/app-sdk/winrt/Microsoft.Windows.Devices.Midi2.vcxproj.filters index 6285976c6..ed8df60bc 100644 --- a/src/app-sdk/winrt/Microsoft.Windows.Devices.Midi2.vcxproj.filters +++ b/src/app-sdk/winrt/Microsoft.Windows.Devices.Midi2.vcxproj.filters @@ -262,9 +262,6 @@ SDK\Endpoints\Loopback - - SDK\Core\Messages - SDK\ServiceConfig @@ -373,6 +370,9 @@ SDK\CapabilityInquiry + + SDK\Utilities\Messages + diff --git a/src/app-sdk/winrt/MidiEndpointConnection.cpp b/src/app-sdk/winrt/MidiEndpointConnection.cpp index 4b996bbad..434297cda 100644 --- a/src/app-sdk/winrt/MidiEndpointConnection.cpp +++ b/src/app-sdk/winrt/MidiEndpointConnection.cpp @@ -372,6 +372,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation // todo: some error / hresult handling here auto hr = m_endpointAbstraction->Shutdown(); + m_endpointAbstraction == nullptr; if (FAILED(hr)) { @@ -396,8 +397,6 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation return false; } } - - m_endpointAbstraction == nullptr; } return true; diff --git a/src/app-sdk/winrt/MidiEndpointConnection.h b/src/app-sdk/winrt/MidiEndpointConnection.h index 45a272814..3d07f06c8 100644 --- a/src/app-sdk/winrt/MidiEndpointConnection.h +++ b/src/app-sdk/winrt/MidiEndpointConnection.h @@ -211,6 +211,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation bool m_isOpen{ false }; bool m_wasAlreadyOpened { false }; // true if this was initially opened. This is to avoid reopen events when first opened + bool m_hasHadDisconnect{ false }; bool m_closeHasBeenCalled{ false }; winrt::com_ptr m_serviceAbstraction{ nullptr }; diff --git a/src/app-sdk/winrt/MidiEndpointConnection_AutoReconnect.cpp b/src/app-sdk/winrt/MidiEndpointConnection_AutoReconnect.cpp index cd800f561..682ee1786 100644 --- a/src/app-sdk/winrt/MidiEndpointConnection_AutoReconnect.cpp +++ b/src/app-sdk/winrt/MidiEndpointConnection_AutoReconnect.cpp @@ -28,13 +28,13 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation // Deactivate MIDI stream DeactivateMidiStream(true); - //m_endpointAbstraction = nullptr; // Let plugins know we're not connected // TODO // set IsOpen to false m_isOpen = false; + m_hasHadDisconnect = true; if (m_endpointDeviceDisconnectedEvent) { @@ -67,22 +67,9 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation TraceLoggingGuid(m_connectionId, MIDI_SDK_TRACE_CONNECTION_ID_FIELD) ); - if (m_endpointAbstraction != nullptr && m_isOpen) - { - // never disconnected - - TraceLoggingWrite( - Midi2SdkTelemetryProvider::Provider(), - MIDI_SDK_TRACE_EVENT_WARNING, - TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_WARNING), - TraceLoggingPointer(this, MIDI_SDK_TRACE_THIS_FIELD), - TraceLoggingWideString(L"InternalOnDeviceReconnect called, but endpoint was still open.", MIDI_SDK_TRACE_MESSAGE_FIELD), - TraceLoggingWideString(m_endpointDeviceId.c_str(), MIDI_SDK_TRACE_ENDPOINT_DEVICE_ID_FIELD) - ); + // we only care about this if we've actually had a disconnect incident already + if (!m_hasHadDisconnect) return; - return; - } if (!ActivateMidiStream()) { diff --git a/src/app-sdk/winrt/MidiEndpointConnection_Receive.cpp b/src/app-sdk/winrt/MidiEndpointConnection_Receive.cpp index 578fd2f97..23c09d765 100644 --- a/src/app-sdk/winrt/MidiEndpointConnection_Receive.cpp +++ b/src/app-sdk/winrt/MidiEndpointConnection_Receive.cpp @@ -36,7 +36,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation return S_OK; } -//#ifdef _DEBUG +#ifdef _DEBUG // performance-critical function, so only trace when in a debug build TraceLoggingWrite( Midi2SdkTelemetryProvider::Provider(), @@ -48,7 +48,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::implementation TraceLoggingWideString(m_endpointDeviceId.c_str(), MIDI_SDK_TRACE_ENDPOINT_DEVICE_ID_FIELD), TraceLoggingGuid(m_connectionId, MIDI_SDK_TRACE_CONNECTION_ID_FIELD) ); -//#endif +#endif try diff --git a/src/app-sdk/winrt/MidiMessageBuilder.cpp b/src/app-sdk/winrt/MidiMessageBuilder.cpp index 99dbacc51..8bd63cc5a 100644 --- a/src/app-sdk/winrt/MidiMessageBuilder.cpp +++ b/src/app-sdk/winrt/MidiMessageBuilder.cpp @@ -151,12 +151,12 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation return midi2::MidiMessage128( timestamp, (uint32_t)( - 0x5 << 28 | - group.Index() << 24 | - internal::CleanupNibble((uint8_t)status) << 20 | - internal::CleanupNibble(numberOfValidDataBytesThisMessage) << 16 | - streamId << 8 | - dataByte00), + (uint32_t)0x5 << 28 | + static_cast(group.Index()) << 24 | + static_cast(internal::CleanupNibble((uint8_t)status)) << 20 | + static_cast(internal::CleanupNibble(numberOfValidDataBytesThisMessage)) << 16 | + static_cast(streamId) << 8 | + static_cast(dataByte00)), internal::MidiWordFromBytes(dataByte01, dataByte02, dataByte03, dataByte04), internal::MidiWordFromBytes(dataByte05, dataByte06, dataByte07, dataByte08), internal::MidiWordFromBytes(dataByte09, dataByte10, dataByte11, dataByte12) @@ -184,23 +184,23 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation // message type is 5. status is 8 word0 = - 0x5 << 28 | - group.Index() << 24 | - 0x8 << 20 | - internal::CleanupNibble(mdsId) << 16 | - numberValidDataBytesInThisChunk; + (uint32_t)0x5 << 28 | + static_cast(group.Index()) << 24 | + (uint32_t)0x8 << 20 | + static_cast(internal::CleanupNibble(mdsId)) << 16 | + static_cast(numberValidDataBytesInThisChunk); word1 = - numberChunksInMixedDataSet << 16 | - numberOfThisChunk; + static_cast(numberChunksInMixedDataSet) << 16 | + static_cast(numberOfThisChunk); word2 = - manufacturerId << 16 | - deviceId; + static_cast(manufacturerId) << 16 | + static_cast(deviceId); word3 = - subId1 << 16 | - subId2; + static_cast(subId1) << 16 | + static_cast(subId2); return midi2::MidiMessage128( @@ -239,30 +239,30 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation // message type is 5. status is 8 word0 = - 0x5 << 28 | - group.Index() << 24 | - 0x9 << 20 | - internal::CleanupNibble(mdsId) << 16 | - dataByte00 << 8 | - dataByte01; + (uint32_t)0x5 << 28 | + static_cast(group.Index()) << 24 | + (uint32_t)0x9 << 20 | + static_cast(internal::CleanupNibble(mdsId)) << 16 | + static_cast(dataByte00) << 8 | + static_cast(dataByte01); word1 = - dataByte02 << 24 | - dataByte03 << 16 | - dataByte04 << 8 | - dataByte05; + static_cast(dataByte02) << 24 | + static_cast(dataByte03) << 16 | + static_cast(dataByte04) << 8 | + static_cast(dataByte05); word2 = - dataByte06 << 24 | - dataByte07 << 16 | - dataByte08 << 8 | - dataByte09; + static_cast(dataByte06) << 24 | + static_cast(dataByte07) << 16 | + static_cast(dataByte08) << 8 | + static_cast(dataByte09); word3 = - dataByte10 << 24 | - dataByte11 << 16 | - dataByte12 << 8 | - dataByte13; + static_cast(dataByte10) << 24 | + static_cast(dataByte11) << 16 | + static_cast(dataByte12) << 8 | + static_cast(dataByte13); return midi2::MidiMessage128( @@ -291,12 +291,12 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation return midi2::MidiMessage128( timestamp, (uint32_t)( - 0xD << 28 | - group.Index() << 24 | - internal::CleanupCrumb(form) << 22 | - internal::CleanupCrumb(address) << 20 | - channel.Index() << 16 | - statusBank << 8 | + static_cast(0xD) << 28 | + static_cast(group.Index()) << 24 | + static_cast(internal::CleanupCrumb(form)) << 22 | + static_cast(internal::CleanupCrumb(address)) << 20 | + static_cast(channel.Index()) << 16 | + static_cast(statusBank) << 8 | status), word1Data, word2Data, @@ -319,9 +319,9 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation return midi2::MidiMessage128( timestamp, (uint32_t)( - 0xF << 28 | - internal::CleanupCrumb(form) << 26 | - internal::CleanupInt10(status) << 16 | + static_cast(0xF) << 28 | + static_cast(internal::CleanupCrumb(form)) << 26 | + static_cast(internal::CleanupInt10(status)) << 16 | word0RemainingData), word1Data, word2Data, diff --git a/src/app-sdk/winrt/MidiStreamMessageBuilder.cpp b/src/app-sdk/winrt/MidiStreamMessageBuilder.cpp index 67f2d3e31..21837bc12 100644 --- a/src/app-sdk/winrt/MidiStreamMessageBuilder.cpp +++ b/src/app-sdk/winrt/MidiStreamMessageBuilder.cpp @@ -56,23 +56,23 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation if (hasStaticFunctionBlocks) word1 = 0x80000000; // MSB is the static function blocks + 7 bit number of function blocks - word1 |= (internal::CleanupByte7(numberOfFunctionBlocks) << 24); + word1 |= (static_cast(internal::CleanupByte7(numberOfFunctionBlocks)) << 24); // bit 9 (reading from least sig to most) is midi 1, bit 10 is midi 2 - if (supportsMidi10Protocol) word1 |= 0x100; - if (supportsMidi20Protocol) word1 |= 0x200; + if (supportsMidi10Protocol) word1 |= (uint32_t)0x0100; + if (supportsMidi20Protocol) word1 |= (uint32_t)0x0200; // first bit is tx jr, second bit 2 is rx jr - if (supportsSendingJitterReductionTimestamps) word1 |= 0x1; - if (supportsReceivingJitterReductionTimestamps) word1 |= 0x2; + if (supportsSendingJitterReductionTimestamps) word1 |= (uint32_t)0x01; + if (supportsReceivingJitterReductionTimestamps) word1 |= (uint32_t)0x02; return MidiMessageBuilder::BuildStreamMessage( timestamp, MIDI_STREAM_MESSAGE_STANDARD_FORM0, MIDI_STREAM_MESSAGE_STATUS_ENDPOINT_INFO_NOTIFICATION, - (uint16_t)umpVersionMajor << 8 | umpVersionMinor, // ump major is msb, ump minor is lsb + static_cast(umpVersionMajor) << 8 | static_cast(umpVersionMinor), // ump major is msb, ump minor is lsb word1, MIDI_RESERVED_WORD, // reserved word2 MIDI_RESERVED_WORD // reserved word3 @@ -99,19 +99,19 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation uint32_t word2{ 0 }; uint32_t word3{ 0 }; - word1 |= internal::CleanupByte7(deviceManufacturerSysExIdByte1) << 16; - word1 |= internal::CleanupByte7(deviceManufacturerSysExIdByte2) << 8; - word1 |= internal::CleanupByte7(deviceManufacturerSysExIdByte3); + word1 |= static_cast(internal::CleanupByte7(deviceManufacturerSysExIdByte1)) << 16; + word1 |= static_cast(internal::CleanupByte7(deviceManufacturerSysExIdByte2)) << 8; + word1 |= static_cast(internal::CleanupByte7(deviceManufacturerSysExIdByte3)); - word2 |= internal::CleanupByte7(deviceFamilyLsb) << 24; - word2 |= internal::CleanupByte7(deviceFamilyMsb) << 16; - word2 |= internal::CleanupByte7(deviceFamilyModelNumberLsb) << 8; - word2 |= internal::CleanupByte7(deviceFamilyModelNumberMsb); + word2 |= static_cast(internal::CleanupByte7(deviceFamilyLsb)) << 24; + word2 |= static_cast(internal::CleanupByte7(deviceFamilyMsb)) << 16; + word2 |= static_cast(internal::CleanupByte7(deviceFamilyModelNumberLsb)) << 8; + word2 |= static_cast(internal::CleanupByte7(deviceFamilyModelNumberMsb)); - word3 |= internal::CleanupByte7(softwareRevisionLevelByte1) << 24; - word3 |= internal::CleanupByte7(softwareRevisionLevelByte2) << 16; - word3 |= internal::CleanupByte7(softwareRevisionLevelByte3) << 8; - word3 |= internal::CleanupByte7(softwareRevisionLevelByte4); + word3 |= static_cast(internal::CleanupByte7(softwareRevisionLevelByte1)) << 24; + word3 |= static_cast(internal::CleanupByte7(softwareRevisionLevelByte2)) << 16; + word3 |= static_cast(internal::CleanupByte7(softwareRevisionLevelByte3)) << 8; + word3 |= static_cast(internal::CleanupByte7(softwareRevisionLevelByte4)); return MidiMessageBuilder::BuildStreamMessage( @@ -223,12 +223,12 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation if (characterCountFirstWord == 2) { - word0 |= packetBytes[currentIndex++] << 8; + word0 |= static_cast(packetBytes[currentIndex++]) << 8; } if (characterCountFirstWord >= 1) { - word0 |= packetBytes[currentIndex++]; + word0 |= static_cast(packetBytes[currentIndex++]); } umpProjected.Word0(word0); @@ -236,22 +236,22 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation // remaining packets are filled with the data we have umpProjected.Word1( - packetBytes[currentIndex++] << 24 | - packetBytes[currentIndex++] << 16 | - packetBytes[currentIndex++] << 8 | - packetBytes[currentIndex++]); + static_cast(packetBytes[currentIndex++]) << 24 | + static_cast(packetBytes[currentIndex++]) << 16 | + static_cast(packetBytes[currentIndex++]) << 8 | + static_cast(packetBytes[currentIndex++])); umpProjected.Word2( - packetBytes[currentIndex++] << 24 | - packetBytes[currentIndex++] << 16 | - packetBytes[currentIndex++] << 8 | - packetBytes[currentIndex++]); + static_cast(packetBytes[currentIndex++]) << 24 | + static_cast(packetBytes[currentIndex++]) << 16 | + static_cast(packetBytes[currentIndex++]) << 8 | + static_cast(packetBytes[currentIndex++])); umpProjected.Word3( - packetBytes[currentIndex++] << 24 | - packetBytes[currentIndex++] << 16 | - packetBytes[currentIndex++] << 8 | - packetBytes[currentIndex++]); + static_cast(packetBytes[currentIndex++]) << 24 | + static_cast(packetBytes[currentIndex++]) << 16 | + static_cast(packetBytes[currentIndex++]) << 8 | + static_cast(packetBytes[currentIndex++])); messages.Append(umpProjected); @@ -310,7 +310,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation { uint16_t word0Remaining{ 0 }; - word0Remaining |= ((uint16_t)protocol << 8); + word0Remaining |= (static_cast(protocol) << 8); if (expectToReceiveJRTimestamps) word0Remaining |= 0x02; // second bit @@ -340,7 +340,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation { uint16_t word0Remaining{ 0 }; - word0Remaining |= ((uint16_t)protocol << 8); + word0Remaining |= (static_cast(protocol) << 8); if (confirmationWillReceiveJRTimestamps) word0Remaining |= 0x02; // second bit @@ -368,7 +368,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation { uint16_t word0Remaining{ 0 }; - word0Remaining |= ((uint16_t)functionBlockNumber << 8); + word0Remaining |= (static_cast(functionBlockNumber) << 8); word0Remaining |= (uint8_t)requestFlags; @@ -401,10 +401,10 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation uint32_t word1{ 0 }; - word0Remaining |= (uint16_t)internal::CleanupByte7(functionBlockNumber) << 8; - word0Remaining |= (uint16_t)uiHint << 4; - word0Remaining |= (uint16_t)midi10 << 2; - word0Remaining |= (uint16_t)direction; + word0Remaining |= static_cast(internal::CleanupByte7(functionBlockNumber)) << 8; + word0Remaining |= static_cast(uiHint) << 4; + word0Remaining |= static_cast(midi10) << 2; + word0Remaining |= static_cast(direction); if (active) { @@ -412,10 +412,10 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation } word1 = - (uint32_t)firstGroup << 24 | - (uint32_t)numberOfGroups << 16 | - (uint32_t)midiCIVersionFormat << 8 | - (uint32_t)maxNumberSysEx8Streams; + static_cast(firstGroup) << 24 | + static_cast(numberOfGroups) << 16 | + static_cast(midiCIVersionFormat) << 8 | + static_cast(maxNumberSysEx8Streams); return MidiMessageBuilder::BuildStreamMessage( @@ -440,7 +440,7 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Messages::implementation { // fb notifications include the function block number as the second // to last byte - uint16_t word0Remainder = (uint16_t)functionBlockNumber << 8; + uint16_t word0Remainder = static_cast(functionBlockNumber) << 8; return BuildSplitTextMessages( timestamp, diff --git a/src/app-sdk/winrt/MidiVirtualDevice.cpp b/src/app-sdk/winrt/MidiVirtualDevice.cpp index 28947a2b3..ac25a34aa 100644 --- a/src/app-sdk/winrt/MidiVirtualDevice.cpp +++ b/src/app-sdk/winrt/MidiVirtualDevice.cpp @@ -30,6 +30,12 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme m_id = winrt::Windows::Foundation::GuidHelper::CreateNewGuid(); m_associationId = config.AssociationId(); + + for (auto const& fb : config.FunctionBlocks()) + { + m_functionBlocks.Insert(fb.Number(), fb); + } + } @@ -274,15 +280,28 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme { bool handled = false; + //OutputDebugString(L"MIDI SDK: MidiVirtualDevice::ProcessIncomingMessage\n"); + if (args.MessageType() == MidiMessageType::Stream128) { midi2::MidiMessage128 message{}; if (args.FillMessage128(message)) { - // if a endpoint discovery request, handle it with the data we have + // if an endpoint discovery request, handle it with the data we have if (internal::MessageIsEndpointDiscoveryRequest(message.Word0())) { + TraceLoggingWrite( + Midi2SdkTelemetryProvider::Provider(), + MIDI_SDK_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, MIDI_SDK_TRACE_THIS_FIELD), + TraceLoggingWideString(L"Endpoint discovery request received.", MIDI_SDK_TRACE_MESSAGE_FIELD) + ); + + //OutputDebugString(L"MIDI SDK: Incoming message is endpoint discovery request\n"); + uint8_t filterFlags = internal::GetEndpointDiscoveryMessageFilterFlagsFromSecondWord(message.Word1()); if (internal::EndpointDiscoveryFilterRequestsEndpointInfoNotification(filterFlags)) @@ -291,16 +310,18 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme auto notification = msgs::MidiStreamMessageBuilder::BuildEndpointInfoNotificationMessage( MidiClock::TimestampConstantSendImmediately(), - MIDI_PREFERRED_UMP_VERSION_MAJOR, - MIDI_PREFERRED_UMP_VERSION_MINOR, + m_declaredEndpointInfo.SpecificationVersionMajor, + m_declaredEndpointInfo.SpecificationVersionMinor, m_declaredEndpointInfo.HasStaticFunctionBlocks, - (uint8_t)m_functionBlocks.Size(), + m_declaredEndpointInfo.DeclaredFunctionBlockCount, /*(uint8_t)m_functionBlocks.Size(), */ m_declaredEndpointInfo.SupportsMidi20Protocol, m_declaredEndpointInfo.SupportsMidi10Protocol, m_declaredEndpointInfo.SupportsReceivingJitterReductionTimestamps, m_declaredEndpointInfo.SupportsSendingJitterReductionTimestamps ); + //OutputDebugString(L"MIDI SDK: Responding with Endpoint Info Notification\n"); + if (midi2::MidiEndpointConnection::SendMessageFailed(m_endpointConnection.SendSingleMessagePacket(notification))) { LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info @@ -339,6 +360,8 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme m_declaredDeviceIdentity.SoftwareRevisionLevelByte4 // byte 4 ); + //OutputDebugString(L"MIDI SDK: Responding with Device Identity Notification\n"); + if (midi2::MidiEndpointConnection::SendMessageFailed(m_endpointConnection.SendSingleMessagePacket(identityNotification))) { LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info @@ -367,6 +390,8 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme m_declaredEndpointInfo.Name ); + //OutputDebugString(L"MIDI SDK: Responding with Endpoint Name Notification\n"); + if (midi2::MidiEndpointConnection::SendMessageFailed(m_endpointConnection.SendMultipleMessagesPacketList(nameMessages.GetView()))) { LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info @@ -394,6 +419,8 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme m_declaredEndpointInfo.ProductInstanceId ); + //OutputDebugString(L"MIDI SDK: Responding with Product Instance Id Notification\n"); + if (midi2::MidiEndpointConnection::SendMessageFailed(m_endpointConnection.SendMultipleMessagesPacketList(instanceIdMessages.GetView()))) { LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info @@ -426,6 +453,8 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme m_declaredEndpointInfo.SupportsSendingJitterReductionTimestamps ); + //OutputDebugString(L"MIDI SDK: Responding with Stream Configuration Notification\n"); + if (midi2::MidiEndpointConnection::SendMessageFailed(m_endpointConnection.SendSingleMessagePacket(streamConfigurationNotification))) { LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info @@ -441,9 +470,22 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme } } + + handled = true; } else if (internal::MessageIsFunctionBlockDiscoveryRequest(message.Word0())) { + TraceLoggingWrite( + Midi2SdkTelemetryProvider::Provider(), + MIDI_SDK_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, MIDI_SDK_TRACE_THIS_FIELD), + TraceLoggingWideString(L"Function block discovery request received.", MIDI_SDK_TRACE_MESSAGE_FIELD) + ); + + //OutputDebugString(L"MIDI SDK: Incoming message is function block discovery request\n"); + uint8_t filterFlags = internal::GetFunctionBlockDiscoveryMessageFilterFlagsFromFirstWord(message.Word0()); bool requestInfo = internal::FunctionBlockDiscoveryFilterRequestsInfoNotification(filterFlags); @@ -455,23 +497,56 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme { // send all function blocks - for (uint8_t i = 0; i < (uint8_t)m_functionBlocks.Size(); i++) + TraceLoggingWrite( + Midi2SdkTelemetryProvider::Provider(), + MIDI_SDK_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, MIDI_SDK_TRACE_THIS_FIELD), + TraceLoggingWideString(L"Sending ALL function blocks, as requested.", MIDI_SDK_TRACE_MESSAGE_FIELD), + TraceLoggingUInt8(m_declaredEndpointInfo.DeclaredFunctionBlockCount, "Declared FB Count"), + TraceLoggingUInt32(m_functionBlocks.Size(), "Actual FB count") + ); + + for (uint8_t i = 0; i < min(m_declaredEndpointInfo.DeclaredFunctionBlockCount, (uint8_t)m_functionBlocks.Size()); i++) { + // OutputDebugString(L"MIDI SDK: Responding with Function Block Info notification\n"); + if (requestInfo) SendFunctionBlockInfoNotificationMessage(m_functionBlocks.Lookup(i)); + //OutputDebugString(L"MIDI SDK: Responding with Function Block Name notification\n"); + if (requestName) SendFunctionBlockNameNotificationMessages(m_functionBlocks.Lookup(i)); } + + handled = true; } else { + TraceLoggingWrite( + Midi2SdkTelemetryProvider::Provider(), + MIDI_SDK_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, MIDI_SDK_TRACE_THIS_FIELD), + TraceLoggingWideString(L"Sending single requested function block.", MIDI_SDK_TRACE_MESSAGE_FIELD), + TraceLoggingUInt8(fbNumber, "Function block number") + ); + // send single requested function block if (m_functionBlocks.HasKey(fbNumber)) { auto fb = m_functionBlocks.Lookup(fbNumber); + //OutputDebugString(L"MIDI SDK: Responding with Function Block Info notification\n"); + if (requestInfo) SendFunctionBlockInfoNotificationMessage(fb); + //OutputDebugString(L"MIDI SDK: Responding with Function Block Name notification\n"); + if (requestName) SendFunctionBlockNameNotificationMessages(fb); + + handled = true; } else { @@ -495,6 +570,8 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme if (m_streamConfigurationRequestReceivedEvent) { m_streamConfigurationRequestReceivedEvent(*this, *reqArgs); + + handled = true; } } else @@ -523,7 +600,6 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme { // not a stream message. Ignore - } @@ -539,55 +615,4 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Endpoints::Virtual::impleme } } - - - - - //_Use_decl_annotations_ - //void MidiVirtualDevice::InternalSetDeviceDefinition( - // _In_ midi2::MidiVirtualDeviceDefinition definition) - //{ - // internal::LogInfo(__FUNCTION__, L"Enter"); - - // try - // { - // // populate all the views, properties, blocks, etc. - - // m_areFunctionBlocksStatic = definition.AreFunctionBlocksStatic(); - - // for (uint8_t i = 0; i < definition.FunctionBlocks().Size(); i++) - // { - // auto fb = definition.FunctionBlocks().GetAt(i); - - // // this is required, so we enforce it here - // fb.Number(i); - - // // TODO: Set the fb as read-only - // - - // - // // add the block - // m_functionBlocks.Insert(i, fb); - // } - - // m_endpointName = definition.EndpointName(); - // m_endpointProductInstanceId = definition.EndpointProductInstanceId(); - - - // // TODO: All the other stuff we'll want to report on - - - - // m_virtualEndpointDeviceDefinition = definition; - - // } - // catch (...) - // { - // // todo log - // internal::LogGeneralError(__FUNCTION__, L"Exception attempting to set device definition"); - - // } - - //} - } diff --git a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointSendMessageCommand.cs b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointSendMessageCommand.cs index 276b110df..d06d80a91 100644 --- a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointSendMessageCommand.cs +++ b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointSendMessageCommand.cs @@ -184,7 +184,7 @@ public override int Execute(CommandContext context, Settings settings) return (int)MidiConsoleReturnCode.ErrorCreatingSession; } - var connection = session.CreateEndpointConnection(endpointId); + var connection = session.CreateEndpointConnection(endpointId, true); if (connection != null) { openSuccess = connection.Open(); @@ -202,6 +202,8 @@ public override int Execute(CommandContext context, Settings settings) } + connection.EndpointDeviceDisconnected += Connection_EndpointDeviceDisconnected; + connection.EndpointDeviceReconnected += Connection_EndpointDeviceReconnected; uint messagesSent = 0; @@ -226,6 +228,13 @@ public override int Execute(CommandContext context, Settings settings) while (stillSending && messagesAttempted < settings.Count) { + if (_disconnected) + { + // if we disconnect, we just have a short delay and then skip the rest of the loop + Thread.Sleep(200); + continue; + } + UInt64 baseTimestamp = MidiClock.Now; UInt64 timestamp = 0; @@ -249,7 +258,6 @@ public override int Execute(CommandContext context, Settings settings) _parsedWords![_parsedWords!.Count() - 1] = (_parsedWords![_parsedWords!.Count() - 1] + 1) % UInt32.MaxValue; } - messagesAttempted++; var sendResult = connection.SendSingleMessageWordArray(timestamp, 0, (byte)_parsedWords!.Count(), _parsedWords); @@ -438,5 +446,26 @@ public override int Execute(CommandContext context, Settings settings) } } + + bool _disconnected = false; + + // Auto-reconnect takes care of the internals. We're just reporting here + private void Connection_EndpointDeviceReconnected(IMidiEndpointConnectionSource sender, object args) + { + AnsiConsole.MarkupLine(AnsiMarkupFormatter.FormatSuccess(Strings.EndpointReconnected)); + + _disconnected = false; + } + + // Auto-reconnect takes care of the internals. We're just reporting here + private void Connection_EndpointDeviceDisconnected(IMidiEndpointConnectionSource sender, object args) + { + AnsiConsole.MarkupLine(AnsiMarkupFormatter.FormatError(Strings.EndpointDisconnected)); + + _disconnected = true; + } + + + } }