Output endpoint
In DryWetMIDI an output MIDI endpoint is represented by the IOutputEndpoint interface. It allows to send events to a MIDI device. To understand what an output MIDI endpoint is in DryWetMIDI, please read the Overview article.
The library provides built-in implementation of IOutputEndpoint: OutputEndpoint. To get an instance of OutputEndpoint you can use GetByName static method. To retrieve the count of output MIDI endpoints presented in the system there is the GetEndpointsCount method. You can get all output MIDI endpoints with GetAll method:
using System;
using Melanchall.DryWetMidi.Multimedia;
// ...
foreach (var outputEndpoint in OutputEndpoint.GetAll())
{
Console.WriteLine(outputEndpoint.Name);
}
Warning
You can use OutputEndpoint built-in implementation of IOutputEndpoint only on the systems listed in the Supported OS article. Of course you can create your own implementation of IOutputEndpoint as described in the Custom output endpoint section below.
After an instance of OutputEndpoint is obtained, you can send MIDI events to the device via SendEvent method. You cannot send meta events since such events can be inside a MIDI file only. If you pass an instance of meta event class, SendEvent will do nothing. EventSent event will be fired for each event sent with SendEvent (except meta events) holding the MIDI event sent. The value of DeltaTime property of MIDI events will be ignored, events will be sent to the device immediately. To take delta-times into account, use Playback class.
If you need to interrupt all currently sounding notes, call the TurnAllNotesOff method which will send Note Off events on all channels for all note numbers (a kind of "panic" button on MIDI devices).
Small example that shows sending MIDI data:
using System;
using Melanchall.DryWetMidi.Multimedia;
using Melanchall.DryWetMidi.Core;
// ...
private IOutputEndpoint _outputEndpoint;
// ...
_outputEndpoint = OutputEndpoint.GetByName("Some MIDI device");
_outputEndpoint.EventSent += OnEventSent;
_outputEndpoint.SendEvent(new NoteOnEvent());
_outputEndpoint.SendEvent(new NoteOffEvent());
// ...
private void OnEventSent(object sender, MidiEventSentEventArgs e)
{
var midiEndpoint = (MidiEndpoint)sender;
Console.WriteLine($"Event sent to '{midiEndpoint.Name}' at {DateTime.Now}: {e.Event}");
}
// ...
_outputEndpoint?.Dispose();
Warning
You must always take care about disposing an OutputEndpoint, so use it inside using block or call Dispose manually. Without it all resources taken by the endpoint will live until GC collects them via the finalizer of the OutputEndpoint. It means that sometimes you will not be able to use different instances of the same endpoint across multiple applications or different pieces of a program.
Warning
If you use an instance of the OutputEndpoint within a using block, you need to be very careful. In general it's not a good practice and can cause problems. For example, with this code
using (var outputEndpoint = OutputEndpoint.GetByName("Some MIDI device"))
{
outputEndpoint.SendEvent(new NoteOnEvent());
}
the NoteOnEvent can be not sent (it's a matter of race conditions) since the program leaves the using block before that, and thus the endpoint instance will be destroyed.
First call of the SendEvent method can take some time for allocating resources for a device, so if you want to eliminate this operation on sending a MIDI event, you can call PrepareForEventsSending method before any MIDI event will be sent.
Custom output endpoint
You can create your own output endpoint implementation and use it in your app. For example, let's create super simple endpoint that just outputs MIDI events to console:
private sealed class ConsoleOutputEndpoint : IOutputEndpoint
{
public event EventHandler<MidiEventSentEventArgs> EventSent;
public void PrepareForEventsSending()
{
}
public void SendEvent(MidiEvent midiEvent)
{
Console.WriteLine(midiEvent);
}
public void Dispose()
{
}
}
You can then use this endpoint, for example, for debugging in Playback.
Another use case for custom output endpoint is plugging some synth. So you create an output endpoint where SendEvent will redirect MIDI events to the synth.