예제 #1
0
        public async Task <int> InvokeAsync(InvocationContext context)
        {
            var console = context.Console.Out;

            var(client, schema) = await DeviceDetection.DetectDeviceAsync(console);

            if (client is null)
            {
                return(1);
            }

            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...");
                        System.Windows.Forms.SendKeys.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) });
        }
예제 #2
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, schema) = await DeviceDetection.DetectDeviceAsync(console);

            if (client == null)
            {
                return(1);
            }

            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);
        }
예제 #3
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, schema) = await DeviceDetection.DetectDeviceAsync(console);

            if (client is null)
            {
                return(1);
            }

            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);
        }
예제 #4
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, schema) = await DeviceDetection.DetectDeviceAsync(console);

            if (client == null)
            {
                return(1);
            }
            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);
            }
        }
예제 #5
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, schema) = await DeviceDetection.DetectDeviceAsync(console);

            if (client == null)
            {
                return(1);
            }

            var moduleData = new ModuleData();

            using (client)
            {
                if (!schema.KitRoots.TryGetValue(kit, out var kitRoot))
                {
                    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       containers = kitRoot.Context.AnnotateDescendantsAndSelf().Where(c => c.Container.Loadable).ToList();
                    console.WriteLine($"Loading {containers.Count} containers from device {schema.Identifier.Name}");
                    foreach (var container in containers)
                    {
                        await PopulateSegment(moduleData, container, overallToken);
                    }
                    console.WriteLine($"Finished loading in {(int) sw.Elapsed.TotalSeconds} seconds");
                    var clonedData = kitRoot.Context.CloneData(moduleData, schema.KitRoots[1].Context.Address);
                    var kitToSave  = new Kit(schema, clonedData, kit);
                    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);

            async Task PopulateSegment(ModuleData data, AnnotatedContainer annotatedContainer, CancellationToken token)
            {
                var timerToken     = new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token;
                var effectiveToken = CancellationTokenSource.CreateLinkedTokenSource(token, timerToken).Token;

                try
                {
                    var segment = await client.RequestDataAsync(annotatedContainer.Context.Address.Value, annotatedContainer.Container.Size, effectiveToken);

                    data.Populate(annotatedContainer.Context.Address, segment);
                }
                catch (OperationCanceledException) when(timerToken.IsCancellationRequested)
                {
                    console.WriteLine($"Device didn't respond for container {annotatedContainer.Path}; skipping.");
                }
            }
        }