From 5e3c4bbfcc237d8adede4c6da88be1a00e4d36bd Mon Sep 17 00:00:00 2001 From: Pete Brown Date: Wed, 6 Mar 2024 21:19:29 -0500 Subject: [PATCH 1/4] Update samples to Dev Preview 5 --- build/staging/version/BundleInfo.wxi | 2 +- .../api-client-basics.vcxproj | 8 +-- samples/cpp-winrt/api-client-basics/main.cpp | 6 +-- .../api-client-basics/packages.config | 2 +- .../api-client-send-speed.vcxproj | 8 +-- .../cpp-winrt/api-client-send-speed/main.cpp | 50 ++++++++++--------- .../api-client-send-speed/packages.config | 2 +- .../api-enum-endpoints-cpp.vcxproj | 8 +-- samples/cpp-winrt/api-enum-endpoints/main.cpp | 17 ++++--- .../api-enum-endpoints/packages.config | 2 +- .../api-loopback-endpoints.vcxproj | 8 +-- .../cpp-winrt/api-loopback-endpoints/main.cpp | 14 ++++-- .../api-loopback-endpoints/packages.config | 2 +- .../cpp-winrt/api-watch-endpoints/main.cpp | 10 ++-- .../api-client-basics-cs/Program.cs | 6 +-- .../api-client-basics-cs.csproj | 4 +- .../MidiSample.AppToAppMidi.csproj | 2 +- ...Midi2.LoopbackMidiConfigurationManager.cpp | 2 +- .../Midi2.LoopbackMidiEndpointManager.cpp | 19 +++---- .../MidiLoopbackDeviceTable.h | 16 ++++-- .../nuget/Windows.Devices.Midi2.nuspec | 2 +- 21 files changed, 102 insertions(+), 88 deletions(-) diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi index 81d83418..da0383ac 100644 --- a/build/staging/version/BundleInfo.wxi +++ b/build/staging/version/BundleInfo.wxi @@ -1,4 +1,4 @@ - + diff --git a/samples/cpp-winrt/api-client-basics/api-client-basics.vcxproj b/samples/cpp-winrt/api-client-basics/api-client-basics.vcxproj index 725f6c2c..becf0f8f 100644 --- a/samples/cpp-winrt/api-client-basics/api-client-basics.vcxproj +++ b/samples/cpp-winrt/api-client-basics/api-client-basics.vcxproj @@ -1,6 +1,6 @@ - + true @@ -150,7 +150,7 @@ - + @@ -158,7 +158,7 @@ - - + + \ No newline at end of file diff --git a/samples/cpp-winrt/api-client-basics/main.cpp b/samples/cpp-winrt/api-client-basics/main.cpp index 57fbfb42..52bf704a 100644 --- a/samples/cpp-winrt/api-client-basics/main.cpp +++ b/samples/cpp-winrt/api-client-basics/main.cpp @@ -93,9 +93,9 @@ int main() auto ump32 = MidiMessageBuilder::BuildMidi1ChannelVoiceMessage( MidiClock::Now(), // use current timestamp - 5, // group 5 + MidiGroup(5), // group 5 Midi1ChannelVoiceMessageStatus::NoteOn, // 9 - 3, // channel 3 + MidiChannel(3), // channel 3 120, // note 120 - hex 0x78 100); // velocity 100 hex 0x64 @@ -104,7 +104,7 @@ int main() std::cout << "Sending single UMP..." << std::endl; auto ump = ump32.as(); - auto sendResult = sendEndpoint.SendMessagePacket(ump); // could also use the SendWords methods, etc. + auto sendResult = sendEndpoint.SendSingleMessagePacket(ump); // could also use the SendWords methods, etc. std::cout << std::endl << " ** Wait for the sent UMP to arrive, and then press enter to cleanup. **" << std::endl; diff --git a/samples/cpp-winrt/api-client-basics/packages.config b/samples/cpp-winrt/api-client-basics/packages.config index c9c963b4..4773d392 100644 --- a/samples/cpp-winrt/api-client-basics/packages.config +++ b/samples/cpp-winrt/api-client-basics/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/api-client-send-speed/api-client-send-speed.vcxproj b/samples/cpp-winrt/api-client-send-speed/api-client-send-speed.vcxproj index 27ed970d..f48a4bea 100644 --- a/samples/cpp-winrt/api-client-send-speed/api-client-send-speed.vcxproj +++ b/samples/cpp-winrt/api-client-send-speed/api-client-send-speed.vcxproj @@ -1,6 +1,6 @@ - + true @@ -150,7 +150,7 @@ - + @@ -158,7 +158,7 @@ - - + + \ No newline at end of file diff --git a/samples/cpp-winrt/api-client-send-speed/main.cpp b/samples/cpp-winrt/api-client-send-speed/main.cpp index e03905d5..d0a98aeb 100644 --- a/samples/cpp-winrt/api-client-send-speed/main.cpp +++ b/samples/cpp-winrt/api-client-send-speed/main.cpp @@ -39,6 +39,8 @@ void DisplaySingleResult(std::wstring label, uint64_t totalTime, uint64_t errorC #define MESSAGE_COUNT_PER_ITERATION 100 #define ITERATION_COUNT 2000 +#define TOTAL_WORD_COUNT_PER_ITERATION (MESSAGE_COUNT_PER_ITERATION * 3) + int main() { @@ -92,17 +94,17 @@ int main() auto ump64 = MidiMessageBuilder::BuildMidi2ChannelVoiceMessage( MidiClock::TimestampConstantSendImmediately(), - 5, // group 5 + MidiGroup(5), // group 5 Midi2ChannelVoiceMessageStatus::NoteOn, - 3, // channel 3 + MidiChannel(3), // channel 3 120, // note 120 - hex 0x78 100); // velocity 100 hex 0x64 auto ump32 = MidiMessageBuilder::BuildMidi1ChannelVoiceMessage( MidiClock::TimestampConstantSendImmediately(), - 5, // group 5 - Midi1ChannelVoiceMessageStatus::NoteOn, - 2, // channel 3 + MidiGroup(5), // group 5 + Midi1ChannelVoiceMessageStatus::NoteOn, + MidiChannel(2), // channel 3 110, // note 110 200); // velocity 200 @@ -114,7 +116,7 @@ int main() auto wordList = winrt::single_threaded_vector(); auto structList = winrt::single_threaded_vector(); auto wordListList = std::vector>(); - uint32_t wordArray[MESSAGE_COUNT_PER_ITERATION * 3]; // that *3 needs to change if we mix up more than just the ump32 and ump64 per iteration + uint32_t wordArray[TOTAL_WORD_COUNT_PER_ITERATION]; // that *3 needs to change if we mix up more than just the ump32 and ump64 per iteration MidiMessageStruct structArray[MESSAGE_COUNT_PER_ITERATION]; @@ -122,7 +124,7 @@ int main() // if we change the types of messages we send, we need to change this as well - foundation::MemoryBuffer buffer(MESSAGE_COUNT_PER_ITERATION * sizeof(uint32_t) * 3); + foundation::MemoryBuffer buffer(TOTAL_WORD_COUNT_PER_ITERATION * sizeof(uint32_t)); uint32_t memoryBufferOffset = 0; @@ -135,12 +137,12 @@ int main() messageList.Append(ump32); // word list - ump64.AppendAllMessageWordsToVector(wordList); - ump32.AppendAllMessageWordsToVector(wordList); + ump64.AppendAllMessageWordsToList(wordList); + ump32.AppendAllMessageWordsToList(wordList); // buffer - ump64.AddAllMessageBytesToBuffer(buffer, memoryBufferOffset); - ump32.AddAllMessageBytesToBuffer(buffer, memoryBufferOffset); + ump64.FillBuffer(memoryBufferOffset, buffer); + ump32.FillBuffer(memoryBufferOffset, buffer); // structs @@ -154,8 +156,8 @@ int main() structList.Append(str32); // for sending words one message at a time - wordListList.push_back(ump64.GetAllWords()); - wordListList.push_back(ump32.GetAllWords()); + wordListList.push_back(ump64.GetAllWords().GetView()); + wordListList.push_back(ump32.GetAllWords().GetView()); bytesWritten += sizeof(ump64) + sizeof(ump32); @@ -172,7 +174,7 @@ int main() uint64_t startTick{}; uint64_t stopTick{}; - MidiSendMessageResult result; + MidiSendMessageResults result; // individual message tests --------------------------------------------------------------------- @@ -182,13 +184,13 @@ int main() for (auto const& message : wordListList) { if (message.Size() == 4) - result = sendEndpoint.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1), message.GetAt(2), message.GetAt(3)); + result = sendEndpoint.SendSingleMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1), message.GetAt(2), message.GetAt(3)); else if (message.Size() == 3) - result = sendEndpoint.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1), message.GetAt(2)); + result = sendEndpoint.SendSingleMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1), message.GetAt(2)); else if (message.Size() == 2) - result = sendEndpoint.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1)); + result = sendEndpoint.SendSingleMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0), message.GetAt(1)); else if (message.Size() == 1) - result = sendEndpoint.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0)); + result = sendEndpoint.SendSingleMessageWords(MidiClock::TimestampConstantSendImmediately(), message.GetAt(0)); if (MidiEndpointConnection::SendMessageFailed(result)) { @@ -206,7 +208,7 @@ int main() startTick = MidiClock::Now(); for (auto const& message : structList) { - result = sendEndpoint.SendMessageStruct(MidiClock::TimestampConstantSendImmediately(), message, (uint8_t)MidiMessageUtility::GetPacketTypeFromMessageFirstWord(message.Word0)); + result = sendEndpoint.SendSingleMessageStruct(MidiClock::TimestampConstantSendImmediately(), (uint8_t)MidiMessageUtility::GetPacketTypeFromMessageFirstWord(message.Word0), message); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsIndividualMessageStructs++; @@ -222,7 +224,7 @@ int main() startTick = MidiClock::Now(); for (auto const& message : messageList) { - result = sendEndpoint.SendMessagePacket(message); + result = sendEndpoint.SendSingleMessagePacket(message); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsIndividualMessagePackets++; @@ -243,7 +245,7 @@ int main() // send vector of words startTick = MidiClock::Now(); - result = sendEndpoint.SendMultipleMessagesWordList(MidiClock::TimestampConstantSendImmediately(), wordList.GetView()); + result = sendEndpoint.SendMultipleMessagesWordList(MidiClock::TimestampConstantSendImmediately(), wordList); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsVectorMessageWords++; @@ -254,7 +256,7 @@ int main() // send array of words startTick = MidiClock::Now(); - result = sendEndpoint.SendMultipleMessagesWordArray(MidiClock::TimestampConstantSendImmediately(), wordArray); + result = sendEndpoint.SendMultipleMessagesWordArray(MidiClock::TimestampConstantSendImmediately(), 0, TOTAL_WORD_COUNT_PER_ITERATION, wordArray); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsArrayMessageWords++; @@ -289,7 +291,7 @@ int main() // send array of message structs startTick = MidiClock::Now(); - result = sendEndpoint.SendMultipleMessagesStructArray(MidiClock::TimestampConstantSendImmediately(), structArray); + result = sendEndpoint.SendMultipleMessagesStructArray(MidiClock::TimestampConstantSendImmediately(), 0, MESSAGE_COUNT_PER_ITERATION, structArray); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsArrayMessageStructs++; @@ -301,7 +303,7 @@ int main() // send multiple through buffer startTick = MidiClock::Now(); - result = sendEndpoint.SendMultipleMessagesBuffer(MidiClock::TimestampConstantSendImmediately(), buffer, 0, bytesWritten); + result = sendEndpoint.SendMultipleMessagesBuffer(MidiClock::TimestampConstantSendImmediately(), 0, bytesWritten, buffer); if (MidiEndpointConnection::SendMessageFailed(result)) { TotalSendErrorsMultipleMessageBuffer++; diff --git a/samples/cpp-winrt/api-client-send-speed/packages.config b/samples/cpp-winrt/api-client-send-speed/packages.config index dd3c63d6..4773d392 100644 --- a/samples/cpp-winrt/api-client-send-speed/packages.config +++ b/samples/cpp-winrt/api-client-send-speed/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/api-enum-endpoints/api-enum-endpoints-cpp.vcxproj b/samples/cpp-winrt/api-enum-endpoints/api-enum-endpoints-cpp.vcxproj index e7d3db33..3cb00f56 100644 --- a/samples/cpp-winrt/api-enum-endpoints/api-enum-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/api-enum-endpoints/api-enum-endpoints-cpp.vcxproj @@ -1,6 +1,6 @@ - + true @@ -150,7 +150,7 @@ - + @@ -158,7 +158,7 @@ - - + + \ No newline at end of file diff --git a/samples/cpp-winrt/api-enum-endpoints/main.cpp b/samples/cpp-winrt/api-enum-endpoints/main.cpp index b3d51074..d84afdc4 100644 --- a/samples/cpp-winrt/api-enum-endpoints/main.cpp +++ b/samples/cpp-winrt/api-enum-endpoints/main.cpp @@ -32,10 +32,10 @@ int main() auto endpoints = MidiEndpointDeviceInformation::FindAll( MidiEndpointDeviceInformationSortOrder::Name, - MidiEndpointDeviceInformationFilter::IncludeClientByteStreamNative | - MidiEndpointDeviceInformationFilter::IncludeClientUmpNative | - MidiEndpointDeviceInformationFilter::IncludeDiagnosticLoopback | - MidiEndpointDeviceInformationFilter::IncludeVirtualDeviceResponder + MidiEndpointDeviceInformationFilters::IncludeClientByteStreamNative | + MidiEndpointDeviceInformationFilters::IncludeClientUmpNative | + MidiEndpointDeviceInformationFilters::IncludeDiagnosticLoopback | + MidiEndpointDeviceInformationFilters::IncludeVirtualDeviceResponder ); std::cout << endpoints.Size() << " endpoints returned" << std::endl << std::endl; @@ -86,9 +86,10 @@ int main() std::cout << std::endl << "User-supplied Metadata" << std::endl; std::cout << "- User-supplied Name: " << winrt::to_string(endpoint.UserSuppliedName()) << std::endl; - std::cout << "- Description: " << winrt::to_string(endpoint.Description()) << std::endl; - std::cout << "- Small Image Path: " << winrt::to_string(endpoint.SmallImagePath()) << std::endl; - std::cout << "- Large Image Path: " << winrt::to_string(endpoint.LargeImagePath()) << std::endl; + std::cout << "- Description: " << winrt::to_string(endpoint.TransportSuppliedDescription()) << std::endl; + std::cout << "- User Description: " << winrt::to_string(endpoint.UserSuppliedDescription()) << std::endl; + std::cout << "- Small Image Path: " << winrt::to_string(endpoint.UserSuppliedSmallImagePath()) << std::endl; + std::cout << "- Large Image Path: " << winrt::to_string(endpoint.UserSuppliedLargeImagePath()) << std::endl; std::cout << std::endl << "Endpoint Supported Capabilities" << std::endl; std::cout << "- UMP Major.Minor: " << endpoint.SpecificationVersionMajor() << "." << endpoint.SpecificationVersionMinor() << std::endl; @@ -102,7 +103,7 @@ int main() std::cout << std::endl << "Transport Information" << std::endl; std::cout << "- Transport-supplied Name: " << winrt::to_string(endpoint.TransportSuppliedName()) << std::endl; - std::cout << "- Transport Id: " << winrt::to_string(endpoint.TransportId()) << std::endl; + std::cout << "- Transport Id: " << winrt::to_string(winrt::to_hstring(endpoint.TransportId())) << std::endl; std::cout << "- Transport Mnemonic: " << winrt::to_string(endpoint.TransportMnemonic()) << std::endl; if (endpoint.NativeDataFormat() == MidiEndpointNativeDataFormat::ByteStream) diff --git a/samples/cpp-winrt/api-enum-endpoints/packages.config b/samples/cpp-winrt/api-enum-endpoints/packages.config index cc28a191..4773d392 100644 --- a/samples/cpp-winrt/api-enum-endpoints/packages.config +++ b/samples/cpp-winrt/api-enum-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/api-loopback-endpoints/api-loopback-endpoints.vcxproj b/samples/cpp-winrt/api-loopback-endpoints/api-loopback-endpoints.vcxproj index e6d18308..872ea4ca 100644 --- a/samples/cpp-winrt/api-loopback-endpoints/api-loopback-endpoints.vcxproj +++ b/samples/cpp-winrt/api-loopback-endpoints/api-loopback-endpoints.vcxproj @@ -1,6 +1,6 @@ - + true @@ -112,7 +112,7 @@ - + @@ -120,7 +120,7 @@ - - + + \ No newline at end of file diff --git a/samples/cpp-winrt/api-loopback-endpoints/main.cpp b/samples/cpp-winrt/api-loopback-endpoints/main.cpp index c903149c..fe0312cd 100644 --- a/samples/cpp-winrt/api-loopback-endpoints/main.cpp +++ b/samples/cpp-winrt/api-loopback-endpoints/main.cpp @@ -140,20 +140,24 @@ int main() auto ump32 = MidiMessageBuilder::BuildMidi1ChannelVoiceMessage( MidiClock::Now(), // use current timestamp - 5, // group 5 + MidiGroup(5), // group 5 Midi1ChannelVoiceMessageStatus::NoteOn, // 9 - 3, // channel 3 + MidiChannel(3), // channel 3 120, // note 120 - hex 0x78 100); // velocity 100 hex 0x64 // here you would set other values in the UMP word(s) - std::cout << "Sending single UMP..." << std::endl; + std::cout << "Sending single UMP " << std::hex << ump32.Word0() << " ..." << std::endl; + std::cout << std::endl << " ** Wait for the sent UMP to arrive, and then press enter to cleanup. **" << std::endl; auto ump = ump32.as(); - auto sendResult = sendEndpoint.SendMessagePacket(ump); // could also use the SendWords methods, etc. + auto sendResult = sendEndpoint.SendSingleMessagePacket(ump); // could also use the SendWords methods, etc. - std::cout << std::endl << " ** Wait for the sent UMP to arrive, and then press enter to cleanup. **" << std::endl; + if (MidiEndpointConnection::SendMessageFailed(sendResult)) + { + std::cout << std::endl << "Send message failed..." << std::endl; + } system("pause"); diff --git a/samples/cpp-winrt/api-loopback-endpoints/packages.config b/samples/cpp-winrt/api-loopback-endpoints/packages.config index c9c963b4..4773d392 100644 --- a/samples/cpp-winrt/api-loopback-endpoints/packages.config +++ b/samples/cpp-winrt/api-loopback-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/api-watch-endpoints/main.cpp b/samples/cpp-winrt/api-watch-endpoints/main.cpp index faf0fe76..4ef10b39 100644 --- a/samples/cpp-winrt/api-watch-endpoints/main.cpp +++ b/samples/cpp-winrt/api-watch-endpoints/main.cpp @@ -43,25 +43,25 @@ int main() - auto OnWatcherStopped = [&](MidiEndpointDeviceWatcher const& sender, foundation::IInspectable const& args) + auto OnWatcherStopped = [&](MidiEndpointDeviceWatcher const& /*sender*/, foundation::IInspectable const& /*args*/) { std::cout << std::endl; std::cout << "Watcher stopped." << std::endl; }; - auto OnWatcherEnumerationCompleted = [&](MidiEndpointDeviceWatcher const& sender, foundation::IInspectable const& args) + auto OnWatcherEnumerationCompleted = [&](MidiEndpointDeviceWatcher const& /*sender*/, foundation::IInspectable const& args) { std::cout << std::endl; std::cout << "Initial enumeration completed." << std::endl; }; - auto OnWatcherDeviceRemoved = [&](MidiEndpointDeviceWatcher const& sender, winrt::Windows::Devices::Enumeration::DeviceInformationUpdate const& args) + auto OnWatcherDeviceRemoved = [&](MidiEndpointDeviceWatcher const& /*sender*/, winrt::Windows::Devices::Enumeration::DeviceInformationUpdate const& args) { std::cout << std::endl; std::cout << "Removed: " << winrt::to_string(args.Id()) << std::endl; }; - auto OnWatcherDeviceUpdated = [&](MidiEndpointDeviceWatcher const& sender, MidiEndpointDeviceInformationUpdateEventArgs const& args) + auto OnWatcherDeviceUpdated = [&](MidiEndpointDeviceWatcher const& /*sender*/, MidiEndpointDeviceInformationUpdateEventArgs const& args) { std::cout << std::endl; std::cout << "Updated: " << winrt::to_string(args.Id()) << std::endl; @@ -69,7 +69,7 @@ int main() // TODO: Show how to use the various data update flags here }; - auto OnWatcherDeviceAdded = [&](MidiEndpointDeviceWatcher const& sender, MidiEndpointDeviceInformation const& args) + auto OnWatcherDeviceAdded = [&](MidiEndpointDeviceWatcher const& /*sender*/, MidiEndpointDeviceInformation const& args) { std::cout << std::endl; std::cout << "Added : " << winrt::to_string(args.Name()) << std::endl; diff --git a/samples/csharp-net/api-client-basics-cs/Program.cs b/samples/csharp-net/api-client-basics-cs/Program.cs index 5a64a247..12c29fb2 100644 --- a/samples/csharp-net/api-client-basics-cs/Program.cs +++ b/samples/csharp-net/api-client-basics-cs/Program.cs @@ -59,13 +59,13 @@ void MessageReceivedHandler(object sender, MidiMessageReceivedEventArgs args) var ump32 = MidiMessageBuilder.BuildMidi1ChannelVoiceMessage( MidiClock.Now, // use current timestamp - 5, // group 5 + new MidiGroup(5), // group 5 Midi1ChannelVoiceMessageStatus.NoteOn, // 9 - 3, // channel 3 + new MidiChannel(3), // channel 3 120, // note 120 - hex 0x78 100); // velocity 100 hex 0x64 - sendEndpoint.SendMessagePacket((IMidiUniversalPacket)ump32); // could also use the SendWords methods, etc. + sendEndpoint.SendSingleMessagePacket((IMidiUniversalPacket)ump32); // could also use the SendWords methods, etc. Console.WriteLine(" ** Wait for the message to arrive, and then press enter to cleanup. ** "); Console.ReadLine(); diff --git a/samples/csharp-net/api-client-basics-cs/api-client-basics-cs.csproj b/samples/csharp-net/api-client-basics-cs/api-client-basics-cs.csproj index 0e066d5f..36132b22 100644 --- a/samples/csharp-net/api-client-basics-cs/api-client-basics-cs.csproj +++ b/samples/csharp-net/api-client-basics-cs/api-client-basics-cs.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/samples/csharp-net/app-to-app-midi-cs/MidiSample.AppToAppMidi.csproj b/samples/csharp-net/app-to-app-midi-cs/MidiSample.AppToAppMidi.csproj index b3abed7e..86555c4d 100644 --- a/samples/csharp-net/app-to-app-midi-cs/MidiSample.AppToAppMidi.csproj +++ b/samples/csharp-net/app-to-app-midi-cs/MidiSample.AppToAppMidi.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiConfigurationManager.cpp b/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiConfigurationManager.cpp index 744a2da0..de741e7e 100644 --- a/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiConfigurationManager.cpp +++ b/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiConfigurationManager.cpp @@ -185,7 +185,7 @@ CMidi2LoopbackMidiConfigurationManager::UpdateConfiguration( auto endpointIdBVal = json::JsonValue::CreateStringValue(definitionB->CreatedEndpointInterfaceId); responseObject.SetNamedValue( MIDI_CONFIG_JSON_ENDPOINT_LOOPBACK_DEVICE_RESPONSE_CREATED_ENDPOINT_B_ID_KEY, - endpointIdAVal); + endpointIdBVal); } else diff --git a/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiEndpointManager.cpp b/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiEndpointManager.cpp index caecdbf4..454865e2 100644 --- a/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiEndpointManager.cpp +++ b/src/api/Abstraction/LoopbackMidiAbstraction/Midi2.LoopbackMidiEndpointManager.cpp @@ -152,6 +152,11 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( { RETURN_HR_IF_NULL(E_INVALIDARG, definition); + RETURN_HR_IF_MSG(E_INVALIDARG, definition->EndpointName.empty(), "Empty endpoint name"); + RETURN_HR_IF_MSG(E_INVALIDARG, definition->InstanceIdPrefix.empty(), "Empty endpoint prefix"); + RETURN_HR_IF_MSG(E_INVALIDARG, definition->EndpointUniqueIdentifier.empty(), "Empty endpoint unique id"); + + TraceLoggingWrite( MidiLoopbackMidiAbstractionTelemetryProvider::Provider(), __FUNCTION__, @@ -165,10 +170,6 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( ); - RETURN_HR_IF_MSG(E_INVALIDARG, definition->EndpointName.empty(), "Empty endpoint name"); - RETURN_HR_IF_MSG(E_INVALIDARG, definition->InstanceIdPrefix.empty(), "Empty endpoint prefix"); - RETURN_HR_IF_MSG(E_INVALIDARG, definition->EndpointUniqueIdentifier.empty(), "Empty endpoint unique id"); - std::wstring mnemonic(TRANSPORT_MNEMONIC); @@ -192,7 +193,7 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( TraceLoggingWrite( MidiLoopbackMidiAbstractionTelemetryProvider::Provider(), __FUNCTION__, - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), TraceLoggingWideString(definition->AssociationId.c_str(), "association id"), TraceLoggingWideString(definition->EndpointUniqueIdentifier.c_str(), "unique identifier"), @@ -200,7 +201,7 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( TraceLoggingWideString(friendlyName.c_str(), "friendlyName"), TraceLoggingWideString(mnemonic.c_str(), "mnemonic"), TraceLoggingWideString(endpointName.c_str(), "endpointName"), - TraceLoggingWideString(endpointDescription.c_str(), "endpointName") + TraceLoggingWideString(endpointDescription.c_str(), "endpointDescription") ); // this is needed for the loopback endpoints to have a relationship with each other @@ -228,7 +229,7 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( TraceLoggingWrite( MidiLoopbackMidiAbstractionTelemetryProvider::Provider(), __FUNCTION__, - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), TraceLoggingWideString(definition->AssociationId.c_str(), "association id"), TraceLoggingWideString(definition->EndpointUniqueIdentifier.c_str(), "unique identifier"), @@ -272,7 +273,7 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( TraceLoggingWrite( MidiLoopbackMidiAbstractionTelemetryProvider::Provider(), __FUNCTION__, - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), TraceLoggingWideString(definition->AssociationId.c_str(), "association id"), TraceLoggingWideString(definition->EndpointUniqueIdentifier.c_str(), "unique identifier"), @@ -292,7 +293,7 @@ CMidi2LoopbackMidiEndpointManager::CreateSingleEndpoint( TraceLoggingWrite( MidiLoopbackMidiAbstractionTelemetryProvider::Provider(), __FUNCTION__, - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), TraceLoggingPointer(this, "this"), TraceLoggingWideString(definition->AssociationId.c_str(), "association id"), TraceLoggingWideString(definition->EndpointUniqueIdentifier.c_str(), "unique identifier"), diff --git a/src/api/Abstraction/LoopbackMidiAbstraction/MidiLoopbackDeviceTable.h b/src/api/Abstraction/LoopbackMidiAbstraction/MidiLoopbackDeviceTable.h index ad4cc49d..b53ae15b 100644 --- a/src/api/Abstraction/LoopbackMidiAbstraction/MidiLoopbackDeviceTable.h +++ b/src/api/Abstraction/LoopbackMidiAbstraction/MidiLoopbackDeviceTable.h @@ -16,9 +16,11 @@ class MidiLoopbackDeviceTable MidiLoopbackDevice* GetDevice(std::wstring associationId) { - if (m_devices.find(associationId) != m_devices.end()) + auto cleanId = internal::ToLowerTrimmedWStringCopy(associationId); + + if (m_devices.find(cleanId) != m_devices.end()) { - return &m_devices[associationId]; + return &m_devices[cleanId]; } else { @@ -28,16 +30,20 @@ class MidiLoopbackDeviceTable void SetDevice(std::wstring associationId, MidiLoopbackDevice device) { - m_devices[associationId] = device; + auto cleanId = internal::ToLowerTrimmedWStringCopy(associationId); + + m_devices[cleanId] = device; } void RemoveDevice(std::wstring associationId) { - if (auto device = m_devices.find(associationId); device != m_devices.end()) + auto cleanId = internal::ToLowerTrimmedWStringCopy(associationId); + + if (auto device = m_devices.find(cleanId); device != m_devices.end()) { device->second.Cleanup(); - m_devices.erase(associationId); + m_devices.erase(cleanId); } } diff --git a/src/api/Client/Midi2Client-Projection/nuget/Windows.Devices.Midi2.nuspec b/src/api/Client/Midi2Client-Projection/nuget/Windows.Devices.Midi2.nuspec index 291dc8e4..6503deec 100644 --- a/src/api/Client/Midi2Client-Projection/nuget/Windows.Devices.Midi2.nuspec +++ b/src/api/Client/Midi2Client-Projection/nuget/Windows.Devices.Midi2.nuspec @@ -2,7 +2,7 @@ Windows.Devices.Midi2 - 1.0.0-preview.5-0184 + 1.0.0-preview.5-0185 Microsoft Corporation Windows MIDI Services API. Minimum package necessary to use Windows MIDI Services from an app on a PC that has Windows MIDI Services installed. MIT From 81de47a80738fd32fda4bf30b368b50567bdf4fa Mon Sep 17 00:00:00 2001 From: Pete Brown Date: Wed, 6 Mar 2024 21:19:44 -0500 Subject: [PATCH 2/4] Update docs for Dev Preview 5 --- .../Windows.Devices.Midi2/clock/MidiClock.md | 9 ++++++++- .../connections/MidiMessageReceivedEventArgs.md | 7 ++++--- .../enumeration/MidiEndpointDeviceInformation.md | 8 +++++--- .../messages/IMidiUniversalPacket.md | 7 +++++++ docs/index.md | 10 +++++++++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md b/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md index d537fe68..ba25ea12 100644 --- a/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md +++ b/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md @@ -23,7 +23,7 @@ You can learn more about high-resolution timestamps in Windows at [https://aka.m | `TimestampFrequency` | Returns the number of timestamp ticks per second. This is calculated the first time it is called, and then cached for future calls. | | `TimestampConstantSendImmediately` | Returns the constant to use when you want to send messages immediately and bypass outgoing message scheduling. Developers may use this value or simply provide `0` in place of the timestamp when sending messages. | -## Static Functions +## Static Functions for Conversion The static functions are for convenience in calculating offsets to a timestamp, and for converting between units. @@ -32,6 +32,13 @@ The static functions are for convenience in calculating offsets to a timestamp, | `ConvertTimestampToMicroseconds(timestampValue)` | Converts the provided timestamp to microseconds | | `ConvertTimestampToMilliseconds(timestampValue)` | Converts the provided timestamp to milliseconds | | `ConvertTimestampToSeconds(timestampValue)` | Converts the provided timestamp to seconds | + +## Static Functions for Offset + +When scheduling messages, you may want to use a more convenient time units. These functions make that easy. + +| Static Function | Description | +| --------------- | ----------- | | `OffsetTimestampByTicks(timestampValue, offsetTicks)` | Offsets a given timestamp by the provided (signed) number of ticks | | `OffsetTimestampByMicroseconds(timestampValue, offsetMicroseconds)` | Offsets a given timestamp by the provided (signed) number of microseconds | | `OffsetTimestampByMilliseconds(timestampValue, offsetMilliseconds)` | Offsets a given timestamp by the provided (signed) number of milliseconds | diff --git a/docs/developer-docs/Windows.Devices.Midi2/connections/MidiMessageReceivedEventArgs.md b/docs/developer-docs/Windows.Devices.Midi2/connections/MidiMessageReceivedEventArgs.md index cba6177b..93043012 100644 --- a/docs/developer-docs/Windows.Devices.Midi2/connections/MidiMessageReceivedEventArgs.md +++ b/docs/developer-docs/Windows.Devices.Midi2/connections/MidiMessageReceivedEventArgs.md @@ -32,9 +32,10 @@ This is the main class to use when receving MIDI data from a message source such | `FillMessage64(message)` | Adds the data to the provided MidiMessage64 runtimeclass. The reference behavior is projection-dependent. Returns true if the provided type matches the expected packet type and the data has been written. | | `FillMessage96(message)` | Adds the data to the provided MidiMessage96 runtimeclass. The reference behavior is projection-dependent. Returns true if the provided type matches the expected packet type and the data has been written. | | `FillMessage128(message)` | Adds the data to the provided MidiMessage128 runtimeclass. The reference behavior is projection-dependent. Returns true if the provided type matches the expected packet type and the data has been written. | -| `FillWordArray(words, startIndex)`| Writes the data starting at the zero-based `startIndex`. Some projections pass a copy of all the data, so this may not always be an efficient approach. Returns the number of words written. | -| `FillByteArray(bytes, startIndex)`| Writes the data starting at the zero-based `startIndex`. Some projections pass a copy of all the data, so this may not always be an efficient approach. Returns the number of bytes written. | -| `FillBuffer(buffer, byteOffset)`| Writes the data to the buffer starting at byteOffset. Returns the number of bytes written. | +| `FillWordArray(startIndex, words)`| Writes the data starting at the zero-based `startIndex`. Some projections pass a copy of all the data, so this may not always be an efficient approach. Returns the number of words written. | +| `FillByteArray(startIndex, bytes)`| Writes the data starting at the zero-based `startIndex`. Some projections pass a copy of all the data, so this may not always be an efficient approach. Returns the number of bytes written. | +| `FillBuffer(byteOffset, buffer)`| Writes the data to the buffer starting at byteOffset. Returns the number of bytes written. | +| `AppendWordsToList(wordList)`| Adds the message words to the end of the provided list, and returns the number of words added. | ## IDL diff --git a/docs/developer-docs/Windows.Devices.Midi2/enumeration/MidiEndpointDeviceInformation.md b/docs/developer-docs/Windows.Devices.Midi2/enumeration/MidiEndpointDeviceInformation.md index 658b5b84..e8c04e8c 100644 --- a/docs/developer-docs/Windows.Devices.Midi2/enumeration/MidiEndpointDeviceInformation.md +++ b/docs/developer-docs/Windows.Devices.Midi2/enumeration/MidiEndpointDeviceInformation.md @@ -24,7 +24,7 @@ When a device is first enumerated by the MIDI Service, if it is a UMP-native dev | Property | Source | Description | | --------------- | ------ | ----------- | -| `Id` | Windows | The endpoint device interface id | +| `Id` | Windows | The endpoint device interface id. This is sometimes called "the SWD" in short-hand because it's the string that uniquely identifies the software device interface that represents the endpoint. | | `ContainerId` | Windows | The device container | | `DeviceInstanceId` | Windows | The device instance id without the interface information | | `Name` | Various | This is the name which should be displayed in any application. It calculates the correct name based on the hierarchy of possible names, including a user-specified name. Always respect the user's choice here. | @@ -34,8 +34,8 @@ When a device is first enumerated by the MIDI Service, if it is a UMP-native dev | `ProductInstanceId` | MIDI 2.0 | Property of the same name discovered by MIDI 2.0 in-protocol endpoint information. | | `SpecificationVersionMajor` | MIDI 2.0 | Discovered UMP version | | `SpecificationVersionMinor` | MIDI 2.0 | Discovered UMP version | -| `SupportsMidi10Protocol` | MIDI 2.0 | Discovered protocol support | -| `SupportsMidi20Protocol` | MIDI 2.0 | Discovered protocol support | +| `SupportsMidi10Protocol` | MIDI 2.0 | Discovered protocol support. For all devices, this defaults to true. | +| `SupportsMidi20Protocol` | MIDI 2.0 | Discovered protocol support. For UMP-native devices, this defaults to true. | | `ConfiguredToReceiveJRTimestamps | MIDI 2.0 | Note that JR timestamps are handled entirely in the service and are not sent back down to the client. | | `ConfiguredToSendJRTimestamps | MIDI 2.0 | Note that JR timestamps are handled entirely in the service and are not sent back down to the client. | | `DeviceIdentitySystemExclusiveId` | MIDI 2.0 | Device Identity information @@ -47,6 +47,8 @@ When a device is first enumerated by the MIDI Service, if it is a UMP-native dev | `TransportId` | Windows | The Id of the transport abstraction that manages this endpoint | | `TransportMnemonic` | Windows | A short abbreviation for the transport. This can be used as a transport identifier. | | `TransportSuppliedSerialNumber` | Windows | iSerialNumber, when available in USB, and other ids from other transports. | +| `TransportSuppliedVendorId` | Windows | For a USB device, this is the VID of the parent device | +| `TransportSuppliedProductId` | Windows | For a USB device, this is the PID of the parent device | | `ManufacturerName` | Windows | The name of the manufacturer of the device, if available | | `SupportsMultiClient` | Windows | True if this endpoint supports multi-client use | | `NativeDataFormat` | Windows | Because the driver and service handle data format translation, it's not immediately obvious if the device is natively UMP or natively Byte Stream. This property provides that information | diff --git a/docs/developer-docs/Windows.Devices.Midi2/messages/IMidiUniversalPacket.md b/docs/developer-docs/Windows.Devices.Midi2/messages/IMidiUniversalPacket.md index 9f7c8aa4..dbca72e7 100644 --- a/docs/developer-docs/Windows.Devices.Midi2/messages/IMidiUniversalPacket.md +++ b/docs/developer-docs/Windows.Devices.Midi2/messages/IMidiUniversalPacket.md @@ -10,15 +10,22 @@ has_children: false This interface is implemented by the rich MidiMessageXX runtime class types. It may also be used as the interface for message-specific classes you create yourself. +## Properties + | Property | Description | | -------- | ----------- | | `Timestamp` | 64 bit timestamp set by the receiving transport in the case of incoming messages, or by the sender in the case of outgoing messages | | `MessageType` | A [MidiMessageType enumeration value](./MidiMessageTypeEnum.md) which represents the 4 bit MIDI Message type 0x0 - 0xF as defined by the MIDI UMP standard. | | `PacketType` | A [MidiPacketType enumeration value](./MidiPacketTypeEnum.md) which can be cast to an int to get the number of 32-bit words in the message packet | +## Functions + | Function | Description | | -------- | ----------- | | `PeekFirstWord()` | Provides access to the first word of data, even if the message type and size is not yet known by the API user | +| `GetAllWords()` | Returns all the message words as a list of 32-bit words | +| `AppendAllMessageWordsToList(targetList)` | Appends all the message words from this message to the target list, and returns the count of words added. | +| `FillBuffer(byteOffset, targetList)` | Adds the message bytes to the buffer starting at the specified offset, and returns the count of bytes added. | ## IDL diff --git a/docs/index.md b/docs/index.md index 0bb34377..e4b99d1f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,10 +5,18 @@ has_children: true --- # Windows MIDI Services +Windows MIDI Services is an open source project, which has been developed with input and feedback from the community. + > [Source repo and developer releases on GitHub](https://aka.ms/midirepo) > [Discord Server for discussion about this project](https://aka.ms/mididiscord) +## Get started + +While we're in developer preview, get started by downloading and installing the latest release from GitHub here: + +- [Latest Developer Releases](https://github.com/microsoft/MIDI/releases) + ## NAMM Show 2024 Presentation [![Pete's Windows MIDI Services Presentation at NAMM Show 2024](https://img.youtube.com/vi/-pe29zIVUCA/mqdefault.jpg)](https://www.youtube.com/watch?v=-pe29zIVUCA) @@ -25,7 +33,7 @@ has_children: true * **UMP-Centric**. The new API fully embraces MIDI 2.0 and the Universal MIDI Packet format and handles all required translation in the service and driver. This makes the app model simple while ensuring all your existing devices continue to work. * **Open Source**. The source code is open and available to everyone under a permissive license. Not sure how something works? Want to create a transport but aren't sure how we did it? Want to investigate a bug or contribute a feature? The code is there for you to explore. -Note: Additionally MIDI CI functionality, which does not technically require OS support, will be coming after version 1.0. We intend to add helpers for profiles, property exchange, MUID tracking, and more. In the meantime, applications can send and receive MIDI CI messages without anything in their way, using custom code or third-party libraries. MIDI CI is just MIDI 1.0-compatible SysEx. +> Note: Additionally MIDI CI functionality, which does not technically require OS support, will be coming after version 1.0. We intend to add helpers for profiles, property exchange, MUID tracking, and more. In the meantime, applications can send and receive MIDI CI messages without anything in their way, using custom code or third-party libraries. MIDI CI is just MIDI 1.0-compatible SysEx. ## Developer Samples From 4891953c89429dd2483a07f651ced742b88d9e4b Mon Sep 17 00:00:00 2001 From: Pete Brown Date: Wed, 6 Mar 2024 21:20:06 -0500 Subject: [PATCH 3/4] Update tools NuGet packages --- src/user-tools/midi-console/Midi/Midi.csproj | 2 +- .../Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user-tools/midi-console/Midi/Midi.csproj b/src/user-tools/midi-console/Midi/Midi.csproj index a437cb0f..986e7868 100644 --- a/src/user-tools/midi-console/Midi/Midi.csproj +++ b/src/user-tools/midi-console/Midi/Midi.csproj @@ -31,7 +31,7 @@ - + diff --git a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj index 5ea93dd6..a5452e69 100644 --- a/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj +++ b/src/user-tools/midi-settings/Microsoft.Midi.Settings/Microsoft.Midi.Settings.csproj @@ -84,7 +84,7 @@ - + From 6cd9fe094542f251b07435950429901dc6712f48 Mon Sep 17 00:00:00 2001 From: Pete Brown Date: Wed, 6 Mar 2024 21:20:28 -0500 Subject: [PATCH 4/4] API tweaks --- .../Midi2Client/IMidiUniversalPacket.idl | 4 ++-- .../MidiEndpointDeviceInformation.cpp | 18 ++++++++++++++--- .../MidiEndpointDeviceInformation.idl | 3 --- src/api/Client/Midi2Client/MidiMessage128.cpp | 4 ++-- src/api/Client/Midi2Client/MidiMessage128.h | 4 ++-- src/api/Client/Midi2Client/MidiMessage32.cpp | 4 ++-- src/api/Client/Midi2Client/MidiMessage32.h | 4 ++-- src/api/Client/Midi2Client/MidiMessage64.cpp | 4 ++-- src/api/Client/Midi2Client/MidiMessage64.h | 4 ++-- src/api/Client/Midi2Client/MidiMessage96.cpp | 4 ++-- src/api/Client/Midi2Client/MidiMessage96.h | 4 ++-- .../MidiMessageReceivedEventArgs.cpp | 20 +++++++++++++++++++ .../MidiMessageReceivedEventArgs.h | 4 ++++ .../MidiMessageReceivedEventArgs.idl | 3 +++ .../Client/Midi2Client/MidiMessageUtility.cpp | 2 +- 15 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/api/Client/Midi2Client/IMidiUniversalPacket.idl b/src/api/Client/Midi2Client/IMidiUniversalPacket.idl index 7cc3b86e..9c8ede65 100644 --- a/src/api/Client/Midi2Client/IMidiUniversalPacket.idl +++ b/src/api/Client/Midi2Client/IMidiUniversalPacket.idl @@ -29,8 +29,8 @@ namespace Windows.Devices.Midi2 IVector GetAllWords(); - UInt8 AppendAllMessageWordsToVector(IVector targetVector); + UInt8 AppendAllMessageWordsToList(IVector targetList); - UInt8 AddAllMessageBytesToBuffer(UInt32 byteOffset, Windows.Foundation.IMemoryBuffer buffer); + UInt8 FillBuffer(UInt32 byteOffset, Windows.Foundation.IMemoryBuffer buffer); }; } \ No newline at end of file diff --git a/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.cpp b/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.cpp index 01db7a5f..b161f147 100644 --- a/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.cpp +++ b/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.cpp @@ -113,20 +113,22 @@ namespace winrt::Windows::Devices::Midi2::implementation additionalProperties.Append(STRING_PKEY_MIDI_TransportMnemonic); additionalProperties.Append(STRING_PKEY_MIDI_NativeDataFormat); + additionalProperties.Append(STRING_PKEY_MIDI_SupportsMulticlient); additionalProperties.Append(STRING_PKEY_MIDI_SupportedDataFormats); + additionalProperties.Append(STRING_PKEY_MIDI_ManufacturerName); + additionalProperties.Append(STRING_PKEY_MIDI_GenerateIncomingTimestamp); + additionalProperties.Append(STRING_PKEY_MIDI_TransportSuppliedEndpointName); additionalProperties.Append(STRING_PKEY_MIDI_TransportSuppliedDescription); - additionalProperties.Append(STRING_PKEY_MIDI_SupportsMulticlient); - additionalProperties.Append(STRING_PKEY_MIDI_GenerateIncomingTimestamp); + // USB / KS Properties =============================================================== // TODO: Group Terminal Blocks will likely be a single property additionalProperties.Append(STRING_PKEY_MIDI_IN_GroupTerminalBlocks); additionalProperties.Append(STRING_PKEY_MIDI_OUT_GroupTerminalBlocks); additionalProperties.Append(STRING_PKEY_MIDI_AssociatedUMP); - additionalProperties.Append(STRING_PKEY_MIDI_ManufacturerName); additionalProperties.Append(STRING_PKEY_MIDI_SerialNumber); additionalProperties.Append(STRING_PKEY_MIDI_UsbVID); additionalProperties.Append(STRING_PKEY_MIDI_UsbPID); @@ -135,6 +137,8 @@ namespace winrt::Windows::Devices::Midi2::implementation // Major Known Endpoint Types ======================================================== additionalProperties.Append(STRING_PKEY_MIDI_EndpointDevicePurpose); + additionalProperties.Append(STRING_PKEY_MIDI_EndpointRequiresMetadataHandler); + // In-protocol Endpoint information ================================================== additionalProperties.Append(STRING_PKEY_MIDI_EndpointSupportsMidi2Protocol); additionalProperties.Append(STRING_PKEY_MIDI_EndpointSupportsMidi1Protocol); @@ -142,6 +146,7 @@ namespace winrt::Windows::Devices::Midi2::implementation additionalProperties.Append(STRING_PKEY_MIDI_EndpointSupportsSendingJRTimestamps); additionalProperties.Append(STRING_PKEY_MIDI_EndpointUmpVersionMajor); additionalProperties.Append(STRING_PKEY_MIDI_EndpointUmpVersionMinor); + additionalProperties.Append(STRING_PKEY_MIDI_EndpointProvidedName); additionalProperties.Append(STRING_PKEY_MIDI_EndpointProvidedProductInstanceId); additionalProperties.Append(STRING_PKEY_MIDI_DeviceIdentity); @@ -176,6 +181,13 @@ namespace winrt::Windows::Devices::Midi2::implementation additionalProperties.Append(STRING_PKEY_MIDI_FunctionBlocksLastUpdateTime); + additionalProperties.Append(STRING_PKEY_MIDI_MidiOutCalculatedLatencyTicks); + additionalProperties.Append(STRING_PKEY_MIDI_MidiOutUserSuppliedLatencyTicks); + additionalProperties.Append(STRING_PKEY_MIDI_MidiOutLatencyTicksUserOverride); + + + additionalProperties.Append(STRING_PKEY_MIDI_VirtualMidiEndpointAssociator); + // Calculated metrics ================================================================= // we don't load them here because they would spam device information update events diff --git a/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.idl b/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.idl index 5bd32bb9..baae7538 100644 --- a/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.idl +++ b/src/api/Client/Midi2Client/MidiEndpointDeviceInformation.idl @@ -136,9 +136,6 @@ namespace Windows.Devices.Midi2 - - - // The settings app allows the user to add some metadata, like a description String UserSuppliedName{ get; }; // name supplied by the user, if available String UserSuppliedDescription{ get; }; diff --git a/src/api/Client/Midi2Client/MidiMessage128.cpp b/src/api/Client/Midi2Client/MidiMessage128.cpp index 40dc932a..cb21a25f 100644 --- a/src/api/Client/Midi2Client/MidiMessage128.cpp +++ b/src/api/Client/Midi2Client/MidiMessage128.cpp @@ -25,7 +25,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage128::AppendAllMessageWordsToVector(collections::IVector targetVector) const noexcept + uint8_t MidiMessage128::AppendAllMessageWordsToList(collections::IVector targetVector) const noexcept { targetVector.Append(m_ump.word0); targetVector.Append(m_ump.word1); @@ -36,7 +36,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage128::AddAllMessageBytesToBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept + uint8_t MidiMessage128::FillBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept { const uint8_t numWordsInPacket = 4; const uint8_t numBytesInPacket = numWordsInPacket * sizeof(uint32_t); diff --git a/src/api/Client/Midi2Client/MidiMessage128.h b/src/api/Client/Midi2Client/MidiMessage128.h index 84f99ede..8bffc89b 100644 --- a/src/api/Client/Midi2Client/MidiMessage128.h +++ b/src/api/Client/Midi2Client/MidiMessage128.h @@ -66,10 +66,10 @@ namespace winrt::Windows::Devices::Midi2::implementation collections::IVector GetAllWords() const noexcept; - uint8_t AppendAllMessageWordsToVector( + uint8_t AppendAllMessageWordsToList( _Inout_ collections::IVector targetVector) const noexcept; - uint8_t AddAllMessageBytesToBuffer( + uint8_t FillBuffer( _In_ uint32_t const byteOffset, _In_ foundation::IMemoryBuffer const& buffer ) const noexcept; diff --git a/src/api/Client/Midi2Client/MidiMessage32.cpp b/src/api/Client/Midi2Client/MidiMessage32.cpp index 384b3656..0b12a437 100644 --- a/src/api/Client/Midi2Client/MidiMessage32.cpp +++ b/src/api/Client/Midi2Client/MidiMessage32.cpp @@ -25,7 +25,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage32::AppendAllMessageWordsToVector(collections::IVector targetVector) const noexcept + uint8_t MidiMessage32::AppendAllMessageWordsToList(collections::IVector targetVector) const noexcept { targetVector.Append(m_ump.word0); @@ -33,7 +33,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage32::AddAllMessageBytesToBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept + uint8_t MidiMessage32::FillBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept { const uint8_t numWordsInPacket = 2; const uint8_t numBytesInPacket = numWordsInPacket * sizeof(uint32_t); diff --git a/src/api/Client/Midi2Client/MidiMessage32.h b/src/api/Client/Midi2Client/MidiMessage32.h index 93c67e39..d8a4b72d 100644 --- a/src/api/Client/Midi2Client/MidiMessage32.h +++ b/src/api/Client/Midi2Client/MidiMessage32.h @@ -47,11 +47,11 @@ namespace winrt::Windows::Devices::Midi2::implementation uint32_t PeekFirstWord() { return Word0(); } collections::IVector GetAllWords() const noexcept; - uint8_t AppendAllMessageWordsToVector( + uint8_t AppendAllMessageWordsToList( _Inout_ collections::IVector targetVector ) const noexcept; - uint8_t AddAllMessageBytesToBuffer( + uint8_t FillBuffer( _In_ uint32_t const byteOffset, _In_ foundation::IMemoryBuffer const& buffer ) const noexcept; diff --git a/src/api/Client/Midi2Client/MidiMessage64.cpp b/src/api/Client/Midi2Client/MidiMessage64.cpp index ae3dab54..5fa35453 100644 --- a/src/api/Client/Midi2Client/MidiMessage64.cpp +++ b/src/api/Client/Midi2Client/MidiMessage64.cpp @@ -24,7 +24,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage64::AppendAllMessageWordsToVector(collections::IVector targetVector) const noexcept + uint8_t MidiMessage64::AppendAllMessageWordsToList(collections::IVector targetVector) const noexcept { targetVector.Append(m_ump.word0); targetVector.Append(m_ump.word1); @@ -33,7 +33,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage64::AddAllMessageBytesToBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept + uint8_t MidiMessage64::FillBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept { const uint8_t numWordsInPacket = 2; const uint8_t numBytesInPacket = numWordsInPacket * sizeof(uint32_t); diff --git a/src/api/Client/Midi2Client/MidiMessage64.h b/src/api/Client/Midi2Client/MidiMessage64.h index 0181cef8..2dd9ffc4 100644 --- a/src/api/Client/Midi2Client/MidiMessage64.h +++ b/src/api/Client/Midi2Client/MidiMessage64.h @@ -59,10 +59,10 @@ namespace winrt::Windows::Devices::Midi2::implementation winrt::hstring ToString(); collections::IVector GetAllWords() const noexcept; - uint8_t AppendAllMessageWordsToVector( + uint8_t AppendAllMessageWordsToList( _Inout_ collections::IVector targetVector) const noexcept; - uint8_t AddAllMessageBytesToBuffer( + uint8_t FillBuffer( _In_ uint32_t const byteOffset, _In_ foundation::IMemoryBuffer const& buffer ) const noexcept; diff --git a/src/api/Client/Midi2Client/MidiMessage96.cpp b/src/api/Client/Midi2Client/MidiMessage96.cpp index 8d0cdfd3..ef266cdf 100644 --- a/src/api/Client/Midi2Client/MidiMessage96.cpp +++ b/src/api/Client/Midi2Client/MidiMessage96.cpp @@ -24,7 +24,7 @@ namespace winrt::Windows::Devices::Midi2::implementation } _Use_decl_annotations_ - uint8_t MidiMessage96::AppendAllMessageWordsToVector(collections::IVector targetVector) const noexcept + uint8_t MidiMessage96::AppendAllMessageWordsToList(collections::IVector targetVector) const noexcept { targetVector.Append(m_ump.word0); targetVector.Append(m_ump.word1); @@ -35,7 +35,7 @@ namespace winrt::Windows::Devices::Midi2::implementation _Use_decl_annotations_ - uint8_t MidiMessage96::AddAllMessageBytesToBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept + uint8_t MidiMessage96::FillBuffer(uint32_t const byteOffset, foundation::IMemoryBuffer const& buffer) const noexcept { const uint8_t numWordsInPacket = 3; const uint8_t numBytesInPacket = numWordsInPacket * sizeof(uint32_t); diff --git a/src/api/Client/Midi2Client/MidiMessage96.h b/src/api/Client/Midi2Client/MidiMessage96.h index 356356f4..9a8b276d 100644 --- a/src/api/Client/Midi2Client/MidiMessage96.h +++ b/src/api/Client/Midi2Client/MidiMessage96.h @@ -61,10 +61,10 @@ namespace winrt::Windows::Devices::Midi2::implementation { return midi2::MidiPacketType::UniversalMidiPacket96; } collections::IVector GetAllWords() const noexcept; - uint8_t AppendAllMessageWordsToVector( + uint8_t AppendAllMessageWordsToList( _Inout_ collections::IVector targetVector) const noexcept; - uint8_t AddAllMessageBytesToBuffer( + uint8_t FillBuffer( _In_ uint32_t const byteOffset, _In_ foundation::IMemoryBuffer const& buffer ) const noexcept; diff --git a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.cpp b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.cpp index e0c78a02..dd895735 100644 --- a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.cpp +++ b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.cpp @@ -276,6 +276,26 @@ namespace winrt::Windows::Devices::Midi2::implementation return messageWordCount; } + _Use_decl_annotations_ + uint8_t MidiMessageReceivedEventArgs::AppendWordsToList( + collections::IVector wordList + ) + { + uint8_t messageWordCount = GetValidMessageWordCount(); + + // copy over the words + + uint32_t* umpData = (uint32_t*)&m_data; + + for (int i = 0; i < messageWordCount; i++) + { + wordList.Append(umpData[i]); + } + + return messageWordCount; + } + + _Use_decl_annotations_ uint8_t MidiMessageReceivedEventArgs::FillByteArray( uint32_t const startIndex, diff --git a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.h b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.h index b06f3042..51a89cdd 100644 --- a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.h +++ b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.h @@ -75,6 +75,10 @@ namespace winrt::Windows::Devices::Midi2::implementation _In_ foundation::IMemoryBuffer const& buffer ); + uint8_t AppendWordsToList( + _In_ collections::IVector wordList + ); + private: uint8_t GetValidMessageWordCount() { return internal::GetUmpLengthInMidiWordsFromFirstWord(m_data.Word0); } diff --git a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.idl b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.idl index d26a6a95..d8eb6568 100644 --- a/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.idl +++ b/src/api/Client/Midi2Client/MidiMessageReceivedEventArgs.idl @@ -68,5 +68,8 @@ namespace Windows.Devices.Midi2 // Fill a spot in an existing IMemoryBuffer controlled by the caller. Returns the number of BYTES written UInt8 FillBuffer(UInt32 byteOffset, Windows.Foundation.IMemoryBuffer buffer); + // Adds the message words to the end of the provided list, and returns the number of words added. + UInt8 AppendWordsToList(IVector wordList); + } } \ No newline at end of file diff --git a/src/api/Client/Midi2Client/MidiMessageUtility.cpp b/src/api/Client/Midi2Client/MidiMessageUtility.cpp index 40eaa24d..a748fabe 100644 --- a/src/api/Client/Midi2Client/MidiMessageUtility.cpp +++ b/src/api/Client/Midi2Client/MidiMessageUtility.cpp @@ -97,7 +97,7 @@ namespace winrt::Windows::Devices::Midi2::implementation for (auto const& message : messages) { - message.AppendAllMessageWordsToVector(result); + message.AppendAllMessageWordsToList(result); } return result;