partial void Execute_MidiOnCommand() { _MidiDevices.Clear(); for (var device = 0; device < NAudio.Midi.MidiIn.NumberOfDevices; device++) { _MidiDevices.Add(NAudio.Midi.MidiIn.DeviceInfo(device).ProductName); } if (_MidiDevices.Count > 0) { MidiDevice = MidiDevices[0]; } var selectedMidiDevice = MidiDevices.IndexOf(MidiDevice); try { if (selectedMidiDevice >= 0) { MidiEnabled = true; midiIn = new MidiIn(selectedMidiDevice); midiIn.MessageReceived += MidiMessageReceived; midiIn.Start(); } } catch (Exception) { } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var inputDevices = MidiDevices.ListInputDevices(); string requestedDeviceName = context.ParseResult.ValueForOption <string>("device"); var device = inputDevices.FirstOrDefault(d => d.Name == requestedDeviceName); if (device is null) { console.WriteLine($"Device '{requestedDeviceName}' not found."); var names = string.Join(", ", inputDevices.Select(d => $"'{d.Name}'")); console.WriteLine($"Available devices: {names}"); return(1); } // It's slightly annoying to use the underlying MIDI implementation rather than RawMidiClient, but we can always change // it if necessary, and RawMidiClient expects input *and* output (and is currently internal). using (var input = await MidiDevices.Manager.OpenInputAsync(device)) { console.WriteLine($"Listening for one minute - or press Ctrl-C to quit."); input.MessageReceived += DisplayMessage; // Wait for one minute - or until the user kills the process. await Task.Delay(TimeSpan.FromMinutes(1)); } return(0); void DisplayMessage(object sender, MidiMessage message) => console.WriteLine($"Received: {BitConverter.ToString(message.Data)}"); }
private async Task ListKits() { if (!await MaybeInitializeMidi()) { return; } inputDevices = string.Join(", ", MidiDevices.ListInputDevices().Select(device => $"{device.SystemDeviceId} ({device.Name})")); outputDevices = string.Join(", ", MidiDevices.ListOutputDevices().Select(device => $"{device.SystemDeviceId} ({device.Name})")); Log("Detecting Roland devices (this can take a few seconds)"); var client = await MidiDevices.DetectSingleRolandMidiClientAsync(logger, ModuleSchema.KnownSchemas.Keys); if (client is object) { await Task.Yield(); var schema = ModuleSchema.KnownSchemas[client.Identifier].Value; Log($"Listing {schema.Identifier.Name} kits:"); var deviceController = new DeviceController(client, NullLogger.Instance); for (int i = 1; i <= schema.Kits; i++) { var name = await deviceController.LoadKitNameAsync(i, CancellationToken.None); Log($"Kit {i}: {name}"); } } }
static async Task Main(string[] args) { // Just so we can write synchronous code when we want to await Task.Yield(); try { var inputs = MidiDevices.ListInputDevices(); foreach (var input in inputs) { Console.WriteLine($"Input: {input}"); } var outputs = MidiDevices.ListOutputDevices(); foreach (var output in outputs) { Console.WriteLine($"Output: {output}"); } var td17Input = inputs.Single(input => input.Name == "2- TD-17"); var td17Output = outputs.Single(output => output.Name == "2- TD-17"); var identities = await MidiDevices.ListDeviceIdentities(td17Input, td17Output, TimeSpan.FromSeconds(0.5)); foreach (var identity in identities) { Console.WriteLine(identity); } } catch (Exception e) { Console.WriteLine(e); } }
private InputDevice CreateDeviceByName(string name) { var deviceNumber = MidiDevices.Select((obj, idx) => new { obj = obj, idx = idx }).Where(x => x.obj == name).FirstOrDefault(); if (deviceNumber != null) { return(new InputDevice(deviceNumber.idx)); } return(null); }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var clients = await MidiDevices.DetectRolandMidiClientsAsync(new ConsoleLogger(console), SchemaRegistry.KnownSchemas.Keys).ToListAsync(); foreach (var client in clients) { client.Dispose(); } return(0); }
private void SetSelectedMidiDeviceFromSettings() { int MidiDevIDFromReg = GetMidiDeviceInRegistry(); if (MidiDevIDFromReg < MidiDevices.Count - 1) { SelectedMidiDevice = MidiDevices.ElementAt(0); } else { SelectedMidiDevice = MidiDevices.ElementAt(MidiDevIDFromReg); } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var client = await MidiDevices.DetectSingleRolandMidiClientAsync(new ConsoleLogger(console), ModuleSchema.KnownSchemas.Keys); if (client == null) { return(1); } using (client) { return(await InvokeAsync(context, console, client)); } }
partial void Execute_MidiOnCommand() { var selectedMidiDevice = MidiDevices.IndexOf(MidiDevice); if (selectedMidiDevice >= 0) { MidiEnabled = true; midiIn = new MidiIn(selectedMidiDevice); midiIn.MessageReceived += MidiMessageReceived; // midiIn.ErrorReceived += MidiErrorReceived; midiIn.Start(); ResetCanExecute(); } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var kit = context.ParseResult.ValueForOption <int>("kit"); var file = context.ParseResult.ValueForOption <string>("file"); var client = await MidiDevices.DetectSingleRolandMidiClientAsync(new ConsoleLogger(console), SchemaRegistry.KnownSchemas.Keys); if (client == null) { return(1); } var schema = SchemaRegistry.KnownSchemas[client.Identifier].Value; using (client) { if (!schema.KitRoots.TryGetValue(kit, out _)) { console.WriteLine($"Kit {kit} out of range"); return(1); } ; // Allow up to 30 seconds in total, and 1 second per container. var overallToken = new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token; try { Stopwatch sw = Stopwatch.StartNew(); var kitToSave = await KitUtilities.ReadKit(schema, client, kit, console); console.WriteLine($"Finished loading in {(int) sw.Elapsed.TotalSeconds} seconds"); using (var stream = File.Create(file)) { kitToSave.Save(stream); } console.WriteLine($"Saved kit to {file}"); } catch (OperationCanceledException) { console.WriteLine("Data loading from device was cancelled"); return(1); } catch (Exception ex) { console.WriteLine($"Error loading data from device: {ex}"); return(1); } } return(0); }
internal static async Task <(RolandMidiClient client, ModuleSchema schema)> DetectDeviceAsync(IStandardStreamWriter console) { var inputDevices = MidiDevices.ListInputDevices(); var outputDevices = MidiDevices.ListOutputDevices(); var commonNames = inputDevices.Select(input => input.Name) .Intersect(outputDevices.Select(output => output.Name)) .OrderBy(x => x) .ToList(); if (commonNames.Count != 1) { console.WriteLine("Error: No input and output MIDI ports with the same name detected."); return(null, null); } string name = commonNames[0]; var matchedInputs = inputDevices.Where(input => input.Name == name).ToList(); var matchedOutputs = outputDevices.Where(output => output.Name == name).ToList(); if (matchedInputs.Count != 1 || matchedOutputs.Count != 1) { console.WriteLine($"Error: Name {name} matches multiple input or output MIDI ports."); return(null, null); } var identities = await MidiDevices.ListDeviceIdentities(matchedInputs[0], matchedOutputs[0], TimeSpan.FromSeconds(1)); if (identities.Count != 1) { console.WriteLine($"Error: {(identities.Count == 0 ? "No" : "Multiple")} devices detected for MIDI port {name}."); return(null, null); } var schemaKeys = SchemaRegistry.KnownSchemas.Keys; var identity = identities[0]; var matchingKeys = schemaKeys.Where(sk => sk.FamilyCode == identity.FamilyCode && sk.FamilyNumberCode == identity.FamilyNumberCode).ToList(); if (matchingKeys.Count != 1) { console.WriteLine($"Error: {(matchingKeys.Count == 0 ? "No" : "Multiple")} schemas detected for MIDI device."); return(null, null); } var schema = SchemaRegistry.KnownSchemas[matchingKeys[0]]; var moduleIdentifier = schema.Value.Identifier; var client = await MidiDevices.CreateRolandMidiClientAsync(matchedInputs[0], matchedOutputs[0], identity, moduleIdentifier.ModelId); return(client, schema.Value); }
private void LoadSetup() { Setups = new List <MidiDeviceSetup>(); MidiDevices devices = new MidiDevices(); int idx = 0; foreach (var InDevice in devices.InDevices) { MidiDeviceSetup ctrl = new MidiDeviceSetup(DbFile, InDevice, idx++); Setups.Add(ctrl); TabPage page = new TabPage(InDevice); page.Controls.Add(ctrl); ctrl.Dock = DockStyle.Fill; devicesTabControl.TabPages.Add(page); } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; console.WriteLine("Input devices:"); var inputDevices = MidiDevices.ListInputDevices(); foreach (var device in inputDevices) { console.WriteLine($"{device.SystemDeviceId}: {device.Name}"); } console.WriteLine(); console.WriteLine("Output devices:"); var outputDevices = MidiDevices.ListOutputDevices(); foreach (var device in outputDevices) { console.WriteLine($"{device.SystemDeviceId}: {device.Name}"); } console.WriteLine(); var commonNames = inputDevices.Select(input => input.Name) .Intersect(outputDevices.Select(output => output.Name)) .OrderBy(x => x) .ToList(); foreach (var name in commonNames) { var matchedInputs = inputDevices.Where(input => input.Name == name).ToList(); var matchedOutputs = outputDevices.Where(output => output.Name == name).ToList(); if (matchedInputs.Count != 1 || matchedOutputs.Count != 1) { continue; } console.WriteLine($"Detecting device identities for {name}..."); var identities = await MidiDevices.ListDeviceIdentities(matchedInputs[0], matchedOutputs[0], TimeSpan.FromSeconds(1)); foreach (var identity in identities) { console.WriteLine(identity.ToString()); } console.WriteLine(); } return(0); }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; if (!SendKeysUtilities.HasSendKeys) { console.WriteLine($"SendKeys not detected; this command can only be run on Windows."); return(1); } var client = await MidiDevices.DetectSingleRolandMidiClientAsync(new ConsoleLogger(console), SchemaRegistry.KnownSchemas.Keys); if (client is null) { return(1); } var schema = SchemaRegistry.KnownSchemas[client.Identifier].Value; using (client) { var channel = context.ParseResult.ValueForOption <int>("channel"); var keys = context.ParseResult.ValueForOption <string>("keys"); var midiNote = context.ParseResult.ValueForOption <int>("note"); var noteOn = (byte)(0x90 | (channel - 1)); // Now listen for the foot switch... client.MessageReceived += (sender, message) => { if (message.Data.Length == 3 && message.Data[0] == noteOn && message.Data[1] == midiNote) { console.WriteLine("Turning the page..."); SendKeysUtilities.SendWait(keys); } }; console.WriteLine("Listening for MIDI note"); await Task.Delay(TimeSpan.FromHours(1)); } return(0); }
public void Open() { if (bindings.Count > 0) { Close(); } MidiDevices devices = new MidiDevices(); DB = new Midi2CatDatabase(DbFile); int Idx = 0; foreach (string inDevice in devices.InDevices) { // see if we can find settings for this device List <ControllerMapping> mappings = DB.GetMappings(inDevice, MappingFilter.Active); if (mappings.Count > 0) { InitDevice(inDevice, mappings, Idx); } Idx++; } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var kit = context.ParseResult.ValueForOption <int>("kit"); var file = context.ParseResult.ValueForOption <string>("file"); var client = await MidiDevices.DetectSingleRolandMidiClientAsync(new ConsoleLogger(console), SchemaRegistry.KnownSchemas.Keys); if (client == null) { return(1); } var schema = SchemaRegistry.KnownSchemas[client.Identifier].Value; if (!schema.KitRoots.TryGetValue(kit, out var kitRoot)) { console.WriteLine($"Kit {kit} out of range"); return(1); } ; var moduleData = new ModuleData(); // Note: a lot of this logic is copied from SoundRecorderDialog. It should go in a model. var instrumentRoot = kitRoot.DescendantNodesAndSelf().FirstOrDefault(node => node.InstrumentNumber == 1); if (instrumentRoot == null) { console.WriteLine($"No instrument root available. Please email a bug report to [email protected]"); return(1); } List <FixedContainer> instrumentContainers = instrumentRoot.DescendantNodesAndSelf() .SelectMany(node => node.Details) .Select(detail => detail.Container) .Where(fc => fc != null) .Distinct() .ToList(); var originalData = await LoadContainers(); var predictedData = originalData.Clone(); var differences = new List <Difference>(); using (client) { var(instrumentFieldContext, instrumentField) = (from ct in instrumentContainers orderby ct.Address from field in ct.Container.Fields where field is InstrumentField select(ct, (InstrumentField)field)).FirstOrDefault(); if (instrumentFieldContext == null) { console.WriteLine($"No instrument field available. Please email a bug report to [email protected]"); return(1); } try { foreach (var instrument in schema.PresetInstruments) { predictedData.Snapshot(); // Make the change on the real module and load the data. await RawSetInstrument(instrumentFieldContext, instrumentField, instrument); var realData = await LoadContainers(); // Make the change in the model. instrumentField.SetInstrument(instrumentFieldContext, predictedData, instrument); // Compare the two. bool anyDifferences = false; foreach (var container in instrumentContainers) { foreach (var field in container.GetChildren(realData).OfType <NumericField>()) { var realValue = field.GetRawValue(container, realData); var predictedValue = field.GetRawValue(container, predictedData); if (realValue != predictedValue) { anyDifferences = true; differences.Add(new Difference(instrument, container, field, realValue, predictedValue)); } } } console.Write(anyDifferences ? "!" : "."); predictedData.RevertSnapshot(); } } finally { await RestoreData(); } } foreach (var difference in differences) { console.WriteLine(difference.ToString()); } console.WriteLine($"Total differences: {differences.Count}"); return(0); async Task <ModuleData> LoadContainers() { var data = new ModuleData(); foreach (var container in instrumentContainers) { await LoadContainerAsync(data, container); } return(data); } async Task LoadContainerAsync(ModuleData data, FixedContainer context) { var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token; var segment = await client.RequestDataAsync(context.Address.Value, context.Container.Size, cancellationToken); data.Populate(context.Address, segment); } async Task RestoreData() { console.WriteLine(); console.WriteLine("Restoring original data"); foreach (var segment in originalData.GetSegments()) { client.SendData(segment.Start.Value, segment.CopyData()); await Task.Delay(40); } } // Sets the instrument directly in the module, setting *only* that field. async Task RawSetInstrument(FixedContainer context, InstrumentField field, Instrument instrument) { var address = context.Address + field.Offset; byte[] bytes = { (byte)((instrument.Id >> 12) & 0xf), (byte)((instrument.Id >> 8) & 0xf), (byte)((instrument.Id >> 4) & 0xf), (byte)((instrument.Id >> 0) & 0xf) }; client.SendData(address.Value, bytes); await Task.Delay(40); } }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; var inputDevices = MidiDevices.ListInputDevices(); string inputName = context.ParseResult.ValueForOption <string>("input"); var inputDevice = inputDevices.FirstOrDefault(d => d.Name == inputName); if (inputDevice is null) { console.WriteLine($"Input device '{inputName}' not found."); return(1); } var outputDevices = MidiDevices.ListOutputDevices(); string outputName = context.ParseResult.ValueForOption <string>("output"); var outputDevice = outputDevices.FirstOrDefault(d => d.Name == outputName); if (outputDevice is null) { console.WriteLine($"Output device '{outputName}' not found."); return(1); } int inputChannel = context.ParseResult.ValueForOption <int>("inputChannel"); int outputChannel = context.ParseResult.ValueForOption <int>("outputChannel"); using var input = await MidiDevices.Manager.OpenInputAsync(inputDevice); using var output = await MidiDevices.Manager.OpenOutputAsync(outputDevice); console.WriteLine("Proxying"); input.MessageReceived += (sender, message) => { var type = message.Status & 0xf0; switch (type) { case 0b1000_0000: // Note off case 0b1001_0000: // Note on case 0b1010_0000: // Polyphonic key pressure (aftertouch) case 0b1101_0000: // Channel pressure (aftertouch) case 0b1110_0000: // Pitch bench change if ((message.Status & 0xf) == inputChannel) { message.Data[0] = (byte)(type | outputChannel); } output.Send(message); break; case 0b1011: // Control change case 0b1100: // Program change case 0b1111: // System exclusive break; } }; // Effectively "forever unless I forget to turn things off". await Task.Delay(TimeSpan.FromHours(1)); return(0); }
public async Task <int> InvokeAsync(InvocationContext context) { var console = context.Console.Out; if (!SendKeysUtilities.HasSendKeys) { console.WriteLine($"SendKeys not detected; this command can only be run on Windows."); return(1); } var client = await MidiDevices.DetectSingleRolandMidiClientAsync(new ConsoleLogger(console), SchemaRegistry.KnownSchemas.Keys); if (client is null) { return(1); } var schema = SchemaRegistry.KnownSchemas[client.Identifier].Value; using (client) { var channel = context.ParseResult.ValueForOption <int>("channel"); var keys = context.ParseResult.ValueForOption <string>("keys"); var targetKit = context.ParseResult.ValueForOption <int>("kit"); if (targetKit < 1 || targetKit + 1 > schema.KitRoots.Count) { console.WriteLine($"Kit {targetKit} is out of range for {schema.Identifier.Name} for this command."); console.WriteLine("Note that one extra kit is required after the specified one."); return(1); } // Detect the current kit // TODO: Stop assuming current kit is at address 0, although it is for TD-17, TD-50 and TD-27... var data = await client.RequestDataAsync(0, 1, new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token); var currentKit = data[0] + 1; // Copy current kit to target kit and target kit + 1 var kit = await KitUtilities.ReadKit(schema, client, currentKit, console); await KitUtilities.WriteKit(client, kit, targetKit, console); await KitUtilities.WriteKit(client, kit, targetKit + 1, console); SetCurrentKit(targetKit); var programChangeCommand = (byte)(0xc0 | (channel - 1)); // Now listen for the foot switch... client.MessageReceived += (sender, message) => { if (message.Data.Length == 2 && message.Data[0] == programChangeCommand) { console.WriteLine("Turning the page..."); SendKeysUtilities.SendWait(keys); SetCurrentKit(targetKit); } }; console.WriteLine("Listening for foot switch"); await Task.Delay(TimeSpan.FromHours(1)); } return(0); void SetCurrentKit(int newKitNumber) => client.SendData(0, new[] { (byte)(newKitNumber - 1) }); }
public bool Open() { var inputDevice = MidiDevices.FirstOrDefault(device => device.IsInput); if (inputDevice.Equals(default))