/// <summary> /// Opens a new midi device and *should* automatically close the previous connection /// </summary> /// <param name="deviceInput">Midi input device ID</param> /// <param name="deviceOutput">Midi output device ID</param> public void OpenMidiDevice(IMidiPortDetails deviceInput, IMidiPortDetails deviceOutput) { if (midiOutput != null) { midiOutput.CloseAsync();//Will this wait for the port to be closed or does it really matter? } if (midiInput != null) { midiInput.MessageReceived -= MidiInput_MessageReceived; midiInput.CloseAsync();//Will this wait for the port to be closed or does it really matter? } var access = MidiAccessManager.Default; try { midiOutput = access.OpenOutputAsync(deviceOutput.Id).Result; midiInput = access.OpenInputAsync(deviceInput.Id).Result; midiInput.MessageReceived += MidiInput_MessageReceived; } catch (Exception e) { Console.WriteLine(e); } }
private void closeDevice(IMidiInput device) { device.MessageReceived -= onMidiMessageReceived; // some devices may take some time to close, so this should be fire-and-forget. // the internal implementations look to have their own (eventual) timeout logic. Task.Factory.StartNew(() => device.CloseAsync(), TaskCreationOptions.LongRunning); }
public void Dispose() { // Calling CloseAsync is significantly faster than calling Dispose. // This is slightly odd, as the implementation for desktop seems to call // CloseAsync too. Not sure what's going on, and maybe we should be waiting // the task to complete... but it doesn't seem to cause any harm. input.CloseAsync(); output.CloseAsync(); }
private void closeDevice(IMidiInput device) { device.CloseAsync().Wait(); device.MessageReceived -= onMidiMessageReceived; }
public void Dispose() { // FIXME input.CloseAsync(); output.CloseAsync(); }
static async Task Main(string[] args) { Console.WriteLine("MIDI to BLE Bridge"); var access = MidiAccessManager.Default; var midiPort = access.Inputs.FirstOrDefault(inp => inp.Name.Contains("mio", StringComparison.OrdinalIgnoreCase)); if (midiPort == null) { midiPort = access.Inputs.FirstOrDefault(inp => inp.Name.Contains("vmpk", StringComparison.OrdinalIgnoreCase)); } IMidiInput input = null; if (midiPort != null) { Console.WriteLine($"Found {midiPort.Name}. Opening..."); input = await access.OpenInputAsync(midiPort.Id); // There seems to be a pretty bad race condition inside the library. // If your MIDI device is streaming data but there is no MessageReceived delegate, it will // throw a NRE. So register this dummy here for now. input.MessageReceived += (obj, e) => {}; } else { Console.WriteLine("No suitable MIDI port found."); } Task.Run(async() => { using (var connection = new Connection(Address.System)) { await connection.ConnectAsync(); var hci0Path = new ObjectPath("/org/bluez/hci0"); var serviceName = "org.bluez"; var hci0Adapter = connection.CreateProxy <IAdapter1>(serviceName, hci0Path); // Based on BlueZ sample code. Verify what it does. Does it really turn my BT adapeter on if it was off? Console.WriteLine("Setting power to true on device 1"); await hci0Adapter.SetPoweredAsync(true); var advertisement = new LEAdvertisement(new LEAdvertisementProperties { Type = "peripheral", LocalName = "MIDI-BRIDGE" }); advertisement.LEAdvertisementProperties.ServiceUUIDs = new string[] { "03B80E5A-EDE8-4B33-A751-6CE34EC4C700" }; // Generic computer icon advertisement.LEAdvertisementProperties.Appearance = 0x0080; // We need to register the LEAdvertisement object. This basically publishes the object // so that when we get the DBus callback to read all the properties, we're good to go. await connection.RegisterObjectAsync(advertisement); var advertisingManager = connection.CreateProxy <ILEAdvertisingManager1>(serviceName, hci0Path); await advertisingManager.RegisterAdvertisementAsync(advertisement, new Dictionary <string, object>()); Application application = new Application(@"/org/bluez/example"); GattService1 service = new GattService1(application.ObjectPath, 0, "03B80E5A-EDE8-4B33-A751-6CE34EC4C700", true); GattCharacteristic1 gattCharacteristic1 = new GattCharacteristic1(service.ObjectPath, 0, "7772E5DB-3868-4112-A1A9-F2669D106BF3", new string[] { "notify", "read", "write-without-response" }); // TODO: Remove PlayNote out of gattCharacteristic. Bridge should handle locking. Bridge midiBleBridge = new Bridge(data => gattCharacteristic1.Value = data); midiBleBridge.StartActiveSense(); if (input != null) { input.MessageReceived += (obj, e) => { midiBleBridge.ReceiveMidiMessage(e.Length, e.Data); }; } service.AddCharacteristic(gattCharacteristic1); application.AddService(service); await connection.RegisterObjectAsync(application); var gattManager = connection.CreateProxy <IGattManager1>(serviceName, new ObjectPath(@"/org/bluez/hci0")); await connection.RegisterObjectAsync(gattCharacteristic1); await gattManager.RegisterApplicationAsync(application, new Dictionary <string, object>()); Console.WriteLine("Press <Ctrl>+c to exit..."); await Task.Delay(int.MaxValue); } }).Wait(); await input.CloseAsync(); }
public async void Close() => await MidiInput.CloseAsync();
public async void SetInputPort(IMidiPortDetails port) { await input.CloseAsync(); this.input = access.OpenInputAsync(port.Id).Result; }