// Author: Gockner, Simon // Created: 2021-04-09 // Copyright(c) 2021 SimonG. All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; using Lib.Driver.Interfaces; using Lib.Midi.Interfaces; using Lib.Midi.Messages.Factories; using Lib.Midi.Messages.Interfaces; using NAudio.Midi; namespace Lib.Midi { public class MidiCommunication : IMidiCommunication { private readonly IMidiMessageFactory _midiMessageFactory; private readonly MidiIn _midiIn; private readonly MidiOut _midiOut; public MidiCommunication(IDriver driver, IMidiMessageFactory midiMessageFactory) { _midiMessageFactory = midiMessageFactory; var midiInput = MidiInputs.FirstOrDefault(i => i.midiInCapabilities.ProductId == driver.ProductId); var midiOutput = MidiOutputs.FirstOrDefault(o => o.midiOutCapabilities.ProductId == driver.ProductId); _midiIn = new MidiIn(midiInput.index); _midiOut = new MidiOut(midiOutput.index); } private IEnumerable<(MidiInCapabilities midiInCapabilities, int index)> MidiInputs { get { for (int i = 0; i < MidiIn.NumberOfDevices; i++) yield return (MidiIn.DeviceInfo(i), i); } } private IEnumerable<(MidiOutCapabilities midiOutCapabilities, int index)> MidiOutputs { get { for (int i = 0; i < MidiOut.NumberOfDevices; i++) yield return (MidiOut.DeviceInfo(i), i); } } public void Open() { _midiIn.MessageReceived += OnMidiInMessageReceived; _midiIn.ErrorReceived += OnMidiInErrorReceived; _midiIn.Start(); } public void Close() { _midiIn.Stop(); _midiIn.MessageReceived -= OnMidiInMessageReceived; _midiIn.ErrorReceived -= OnMidiInErrorReceived; _midiIn.Close(); _midiOut.Close(); } public void Send(IMidiMessage message) => _midiOut.Send(message.RawMessage); private void OnMidiInMessageReceived(object? sender, MidiInMessageEventArgs args) => MessageReceived?.Invoke(this, _midiMessageFactory.Create(args)); private void OnMidiInErrorReceived(object? sender, MidiInMessageEventArgs args) => ErrorReceived?.Invoke(this, _midiMessageFactory.Create(args)); public event EventHandler? MessageReceived; public event EventHandler? ErrorReceived; } }