View Single Post
Old 08-05-2017, 04:52 AM   #25
Airal
Banned
 
Join Date: Nov 2015
Posts: 406
Default

Quote:
Originally Posted by EvilDragon View Post
Not sure if it creates a MIDI device, but it allows using all UWP MIDI API commands in a win32 application. So I assume somebody would still need to write a driver that converts MIDI BT devices to regular MIDI devices. Not sure. Code can be checked on github, though!
Cool!

He says they cannot be enumerated but you can do this using the the link I originally gave. I basically wrote a small program to do it and it did list my devices:

"Ah yeah, hopefully we can include that wrapper at some point. The wrapper is missing a few things though, like the ability to get device IDs..."

So, if that's all he needs to get support in reaper I'm sure he could hack something together.

It requires using two uwp dll's: Windows.winmd and System.Runtime.WindowsRuntime.dll.



Here's the code(It's C# and .Net but I see no reason why it couldn't be used, if necessary, to modify winrtmidi... which probably have the deviceID's somewhere anyways):

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
using System.Windows;



using Windows.Devices.Midi;
using Windows.Devices.Enumeration;



namespace UWPMidiTest
{

    class UWPMidi
    {
        public List<MidiInPort> midiInPorts = new List<MidiInPort>();
        public List<DeviceInformation> midiInDevices = new List<DeviceInformation>();


        public void CloseMidiDevices()
        {

            // Close all MidiInPorts
            foreach (MidiInPort inPort in midiInPorts)
                inPort.Dispose();

            midiInPorts.Clear();
        }

        public async void ListMidiDevices()
        {
            // Enumerate Input devices

            var deviceList = await DeviceInformation.FindAllAsync(MidiInPort.GetDeviceSelector());

            foreach (var deviceInfo in deviceList)
            {
                System.Diagnostics.Debug.WriteLine(deviceInfo.Id);
                System.Diagnostics.Debug.WriteLine(deviceInfo.Name);
                System.Diagnostics.Debug.WriteLine("----------");
                Console.WriteLine(deviceInfo.Id);
                Console.WriteLine(deviceInfo.Name);
                Console.WriteLine("----------");
                midiInDevices.Add(deviceInfo);

            }

            // Output devices are enumerated the same way, but 
            // using MidiOutPort.GetDeviceSelector()

        }

        public async void InitMidiInDevice(int index)
        { 
            var devInfo = midiInDevices[index];
            //var currentMidiInputDevice = midiInPorts[index];
            var currentMidiInputDevice = await MidiInPort.FromIdAsync(devInfo.Id);
            if (currentMidiInputDevice == null)
            {
                Console.WriteLine("Unable to create MidiInPort from input device");
                return;
            }

            // We have successfully created a MidiInPort; add the device to the list of active devices, and set up message receiving
            if (!midiInPorts.Contains(currentMidiInputDevice))
            {
                midiInPorts.Add(currentMidiInputDevice);
                currentMidiInputDevice.MessageReceived += MidiInputDevice_MessageReceived;
            }

            // Clear any previous input messages

        }


        public void MidiInputDevice_MessageReceived(MidiInPort sender, MidiMessageReceivedEventArgs args)
        {
            IMidiMessage receivedMidiMessage = args.Message;

            // Build the received MIDI message into a readable format
            StringBuilder outputMessage = new StringBuilder();
            outputMessage.Append(receivedMidiMessage.Timestamp.ToString()).Append(", Type: ").Append(receivedMidiMessage.Type);

            // Add MIDI message parameters to the output, depending on the type of message
            switch (receivedMidiMessage.Type)
            {
                case MidiMessageType.NoteOff:
                    var noteOffMessage = (MidiNoteOffMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(noteOffMessage.Channel).Append(", Note: ").Append(noteOffMessage.Note).Append(", Velocity: ").Append(noteOffMessage.Velocity);
                    break;
                case MidiMessageType.NoteOn:
                    var noteOnMessage = (MidiNoteOnMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(noteOnMessage.Channel).Append(", Note: ").Append(noteOnMessage.Note).Append(", Velocity: ").Append(noteOnMessage.Velocity);
                    break;
                case MidiMessageType.PolyphonicKeyPressure:
                    var polyphonicKeyPressureMessage = (MidiPolyphonicKeyPressureMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(polyphonicKeyPressureMessage.Channel).Append(", Note: ").Append(polyphonicKeyPressureMessage.Note).Append(", Pressure: ").Append(polyphonicKeyPressureMessage.Pressure);
                    break;
                case MidiMessageType.ControlChange:
                    var controlChangeMessage = (MidiControlChangeMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(controlChangeMessage.Channel).Append(", Controller: ").Append(controlChangeMessage.Controller).Append(", Value: ").Append(controlChangeMessage.ControlValue);
                    break;
                case MidiMessageType.ProgramChange:
                    var programChangeMessage = (MidiProgramChangeMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(programChangeMessage.Channel).Append(", Program: ").Append(programChangeMessage.Program);
                    break;
                case MidiMessageType.ChannelPressure:
                    var channelPressureMessage = (MidiChannelPressureMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(channelPressureMessage.Channel).Append(", Pressure: ").Append(channelPressureMessage.Pressure);
                    break;
                case MidiMessageType.PitchBendChange:
                    var pitchBendChangeMessage = (MidiPitchBendChangeMessage)receivedMidiMessage;
                    outputMessage.Append(", Channel: ").Append(pitchBendChangeMessage.Channel).Append(", Bend: ").Append(pitchBendChangeMessage.Bend);
                    break;
                case MidiMessageType.SystemExclusive:
                    var systemExclusiveMessage = (MidiSystemExclusiveMessage)receivedMidiMessage;
                    outputMessage.Append(", ");

                    // Read the SysEx bufffer
                    /*
                    var sysExDataReader = DataReader.FromBuffer(systemExclusiveMessage.RawData);
                    while (sysExDataReader.UnconsumedBufferLength > 0)
                    {
                        byte byteRead = sysExDataReader.ReadByte();
                        // Pad with leading zero if necessary
                        outputMessage.Append(byteRead.ToString("X2")).Append(" ");
                    }*/
                    break;
                case MidiMessageType.MidiTimeCode:
                    var timeCodeMessage = (MidiTimeCodeMessage)receivedMidiMessage;
                    outputMessage.Append(", FrameType: ").Append(timeCodeMessage.FrameType).Append(", Values: ").Append(timeCodeMessage.Values);
                    break;
                case MidiMessageType.SongPositionPointer:
                    var songPositionPointerMessage = (MidiSongPositionPointerMessage)receivedMidiMessage;
                    outputMessage.Append(", Beats: ").Append(songPositionPointerMessage.Beats);
                    break;
                case MidiMessageType.SongSelect:
                    var songSelectMessage = (MidiSongSelectMessage)receivedMidiMessage;
                    outputMessage.Append(", Song: ").Append(songSelectMessage.Song);
                    break;
                case MidiMessageType.TuneRequest:
                    var tuneRequestMessage = (MidiTuneRequestMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.TimingClock:
                    var timingClockMessage = (MidiTimingClockMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.Start:
                    var startMessage = (MidiStartMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.Continue:
                    var continueMessage = (MidiContinueMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.Stop:
                    var stopMessage = (MidiStopMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.ActiveSensing:
                    var activeSensingMessage = (MidiActiveSensingMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.SystemReset:
                    var systemResetMessage = (MidiSystemResetMessage)receivedMidiMessage;
                    break;
                case MidiMessageType.None:
                    throw new InvalidOperationException();
                default:
                    break;
            }

            Console.WriteLine(outputMessage.ToString());
        }
    }

    static class Program
    {





        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var uwpMidi = new UWPMidi();

            for (int i = 0; i < 10; i++)
                uwpMidi.ListMidiDevices();

            uwpMidi.InitMidiInDevice(3);
            Console.ReadKey();
        }
    }
}

Last edited by Airal; 08-05-2017 at 08:45 AM.
Airal is offline   Reply With Quote