Beispiel #1
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}");
                }
            }
        }
Beispiel #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)}");
        }
Beispiel #3
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);
            }
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }
Beispiel #6
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);
        }