diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi index 81d834187..da0383ac1 100644 --- a/build/staging/version/BundleInfo.wxi +++ b/build/staging/version/BundleInfo.wxi @@ -1,4 +1,4 @@ - + diff --git a/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md b/docs/developer-docs/Windows.Devices.Midi2/clock/MidiClock.md index d537fe681..ba25ea128 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 cba6177b5..930430123 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 658b5b841..e8c04e8cb 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 9f7c8aa48..dbca72e7b 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 0bb343771..e4b99d1fd 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 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 725f6c2c8..becf0f8f9 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 57fbfb42c..52bf704a2 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 c9c963b46..4773d392b 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 27ed970d4..f48a4bea9 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 e03905d57..d0a98aeb5 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 dd3c63d65..4773d392b 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 e7d3db338..3cb00f56f 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 b3d510744..d84afdc47 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 cc28a1913..4773d392b 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 e6d183080..872ea4caf 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 c903149c9..fe0312cd2 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 c9c963b46..4773d392b 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 faf0fe769..4ef10b397 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 5a64a2470..12c29fb23 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 0e066d5fe..36132b22d 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 b3abed7ea..86555c4d5 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 744a2da05..de741e7e8 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 caecdbf4a..454865e2e 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 ad4cc49dc..b53ae15bc 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 291dc8e4d..6503deecb 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 diff --git a/src/api/Client/Midi2Client/IMidiUniversalPacket.idl b/src/api/Client/Midi2Client/IMidiUniversalPacket.idl index 7cc3b86e7..9c8ede65c 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 01db7a5f2..b161f147c 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 5bd32bb90..baae7538c 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 40dc932ad..cb21a25f7 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 84f99edeb..8bffc89b6 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 384b36561..0b12a4370 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 93c67e394..d8a4b72db 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 ae3dab54e..5fa35453a 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 0181cef8e..2dd9ffc4e 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 8d0cdfd36..ef266cdf4 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 356356f4d..9a8b276dd 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 e0c78a021..dd8957351 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 b06f30422..51a89cdd3 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 d26a6a956..d8eb65689 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 40eaa24df..a748fabe9 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; diff --git a/src/user-tools/midi-console/Midi/Midi.csproj b/src/user-tools/midi-console/Midi/Midi.csproj index a437cb0f2..986e7868a 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 5ea93dd65..a5452e697 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 @@ - +