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)
            {
            }
        }
Esempio n. 2
0
        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)}");
        }
Esempio n. 3
0
        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}");
                }
            }
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        private void SetSelectedMidiDeviceFromSettings()
        {
            int MidiDevIDFromReg = GetMidiDeviceInRegistry();

            if (MidiDevIDFromReg < MidiDevices.Count - 1)
            {
                SelectedMidiDevice = MidiDevices.ElementAt(0);
            }
            else
            {
                SelectedMidiDevice = MidiDevices.ElementAt(MidiDevIDFromReg);
            }
        }
Esempio n. 8
0
        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));
            }
        }
Esempio n. 9
0
        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();
            }
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
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);
        }
Esempio n. 12
0
        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);
            }
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
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);
        }
Esempio n. 15
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++;
            }
        }
Esempio n. 16
0
        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);
            }
        }
Esempio n. 17
0
        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) });
        }
Esempio n. 19
0
        public bool Open()
        {
            var inputDevice = MidiDevices.FirstOrDefault(device => device.IsInput);

            if (inputDevice.Equals(default))