Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Midi routing to multiple devices #26

Closed
eriveraa opened this issue May 24, 2019 · 14 comments
Closed

Midi routing to multiple devices #26

eriveraa opened this issue May 24, 2019 · 14 comments
Labels
bug Bug in the library feature request API changes required
Projects

Comments

@eriveraa
Copy link

Hi Melanchall: is it possible to send received midi events to multiple outputDevices? (Midi Routing) If so, could you provide an example or reference please?.
Thanks.

@melanchall
Copy link
Owner

Hi,

You can just open several output devices and call SendEvent method:

var outputDevices = new[]
{
    OutputDevice.GetByName("Output Device 1"),
    OutputDevice.GetByName("Output Device 2"),
    OutputDevice.GetByName("Output Device 3")
};

//

var inputDevice = InputDevice.GetByName("Input Device");
inputDevice.StartEventsListening();
inputDevice.EventReceived += (sender, args) =>
{
    foreach (var outputDevice in outputDevices)
    {
        outputDevice.SendEvent(args.Event);
    }
};

//

inputDevice.Dispose();

foreach (var outputDevice in outputDevices)
{
    outputDevice.Dispose();
}

Also there is the DeviceConnector class which you can use to automatically redirect incoming events to another device. But I didn't test it with multiple devices.

foreach (var outputDevice in outputDevices)
{
    var deviceConnector = inputDevice.Connect(outputDevice);
}

@eriveraa
Copy link
Author

Hi, i will try the first aproach.
However, the second aproach (using DeviceConnector) does not working even with one to one. I created an input device and connected to a virtual port, and no luck. The automatic redirect is not working.
I am monitoring the virtual port, and no data was received. (the input device is working fine receiving events), but it looks like the DeviceConnector is not passing the events automatically.
Any ideas?

@melanchall
Copy link
Owner

I've created simple test which works on virtual MIDI ports:

var inputDevice = InputDevice.GetByName("MIDI A");
var inputDeviceOutput = OutputDevice.GetByName("MIDI A");

var outputDevice = OutputDevice.GetByName("MIDI B");
var outputDeviceInput = InputDevice.GetByName("MIDI B");

var devicesConnector = inputDevice.Connect(outputDevice);

inputDevice.StartEventsListening();

outputDeviceInput.StartEventsListening();
outputDeviceInput.EventReceived += (sender, args) =>
{
    // Program falls into this place with Note On event
};

inputDeviceOutput.SendEvent(new NoteOnEvent());

@eriveraa
Copy link
Author

eriveraa commented May 26, 2019

Hi, i am trying to understand your code, but i dont get it how to adapt this code to this scenario:

  • I have a external midi controller that would be an inputDevice. (This controller has only midi output port connected to computer, so it becomes inputDevice in your library - and does not apear as a output device).
  • How do i route/connect this midi controller to 2 or more output virtual ports (so i can use the with other programs / daws).

@melanchall
Copy link
Owner

Hi,

Please try this code:

var inputDevice = InputDevice.GetByName("MIDI Controller Name");

var outputDevice1 = OutputDevice.GetByName("MIDI Out 1");
var outputDevice2 = OutputDevice.GetByName("MIDI Out 2");

var devicesConnector1 = inputDevice.Connect(outputDevice1);
var devicesConnector2 = inputDevice.Connect(outputDevice2);

inputDevice.StartEventsListening();

But I think the second Connect will fail since an input device will be locked for use (DevicesConnector uses WinAPI Connect function and from my experience any such function locks device until it is released). But please try it. Also try connection with one output device. If it won't work, please use approach with manual events redirection since it definitely will work.

@eriveraa
Copy link
Author

I have tried your code, unfortunately it doesn´t work even with just one output device. I think there is something wrong in the DeviceConnector.
I verified that i receive input events on inputDevice, however the deviceConnector is not handling the messages to the ouputDevice1.
How is the deviceConnector supposed to work?.
Waiting your response. Thanks!

@melanchall
Copy link
Owner

DevicesConnector is supposed to redirect events from input device to output one. At now it uses WinAPI midiConnect function.

It seems it's difficult to make it work as expected in real scenarios. I'll try to get rid of midiConnect and do manual redirection since it's much more stable and also allows transfer incoming events to multiple output devices. Also it will give more flexibility in adjusting devices connections.

Thanks for reporting your use case and new ideas!

@eriveraa
Copy link
Author

Ok melanchall.
So, should i wait for your fix? or is there any workaround to this scenario?

@melanchall
Copy link
Owner

melanchall commented May 27, 2019

Workaround is the approach I've suggested in my first comment. Of course Dispose on devices should be called only when you've completely finished working with devices (for example, at the end of your program).

@melanchall
Copy link
Owner

I've refactored DevicesConnector so it now doesn't use midiConnect function. Changes are in develop branch.

@eriveraa
Copy link
Author

Hi Melanchall, what does that mean exactly? The functionality is different now? What should I expect now?

@melanchall
Copy link
Owner

It's just refactoring. Purpose of the DevicesConnector and API are still unchanged.

@melanchall
Copy link
Owner

With last change you can write:

var inputDevice = InputDevice.GetByName("MIDI In");

var outputDevice1 = OutputDevice.GetByName("MIDI Out 1");
var outputDevice2 = OutputDevice.GetByName("MIDI Out 2");

var devicesConnector = inputDevice.Connect(outputDevice1, outputDevice2);

inputDevice.StartEventsListening();

After that all events from inputDevice will be redirected to outputDevice1 and outputDevice2.

@melanchall
Copy link
Owner

@eriveraa I'm closing the issue. If you have new questions regarding this issue, reopen it.

@melanchall melanchall added bug Bug in the library feature request API changes required labels Feb 2, 2020
@melanchall melanchall added this to Done in DryWetMIDI Mar 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug in the library feature request API changes required
Projects
DryWetMIDI
  
Done
Development

No branches or pull requests

2 participants