public static int RunExtractAndReturnExitCode(ExtractOptions opts) { string fileName = opts.FileName; byte[] fileData = File.ReadAllBytes(fileName); Console.WriteLine($"SysEx file: '{fileName}' ({fileData.Length} bytes)"); List <byte[]> messages = Util.SplitBytesByDelimiter(fileData, 0xf7); Console.WriteLine($"Got {messages.Count} messages"); int programNumber = GetProgramNumber(opts.PatchNumber); foreach (byte[] message in messages) { SystemExclusiveHeader header = new SystemExclusiveHeader(message); if (header.Substatus2 != programNumber) { continue; } byte[] rawData = ExtractPatchData(message); byte[] data = Util.ConvertFromTwoNybbleFormat(rawData); SinglePatch s = new SinglePatch(data); int channel = opts.Channel - 1; // adjust channel 1...16 to range 0...15 byte[] newHeader = new byte[] { 0xF0, 0x40, (byte)(channel - 1), 0x20, 0x00, 0x02, 0x00, (byte)programNumber }; List <byte> newData = new List <byte>(); newData.AddRange(newHeader); newData.AddRange(Util.ConvertToTwoNybbleFormat(s.ToData())); newData.Add(0xf7); var folder = Environment.SpecialFolder.Desktop; var newFileName = Path.Combine(new string[] { Environment.GetFolderPath(folder), $"{s.Name.Trim()}.syx" }); Console.WriteLine($"Writing SysEx data to '{newFileName}'..."); File.WriteAllBytes(newFileName, newData.ToArray()); } return(0); }
private static byte[] GenerateSystemExclusiveMessage(SinglePatch patch, int patchNumber, int channel = 0) { List <byte> data = new List <byte>(); SystemExclusiveHeader header = new SystemExclusiveHeader(); header.ManufacturerID = 0x40; // Kawai header.Channel = (byte)channel; header.Function = (byte)SystemExclusiveFunction.OnePatchDataDump; header.Group = 0x00; // synth group header.MachineID = 0x04; // K4/K4r header.Substatus1 = 0x00; // INT header.Substatus2 = (byte)patchNumber; data.Add(SystemExclusiveHeader.Initiator); data.AddRange(header.ToData()); data.AddRange(patch.ToData()); data.Add(SystemExclusiveHeader.Terminator); return(data.ToArray()); }
public static int RunCreateAndReturnExitCode(CreateOptions opts) { //byte[] data = ExtractPatchData(message); //Single s = new Single(data); SinglePatch s = new SinglePatch(); s.Name = "FRANKENP"; byte[] newHarmonics = LeiterEngine.GetHarmonicLevels("saw", Source.HarmonicCount); for (int i = 0; i < Source.HarmonicCount; i++) { s.Source1.Harmonics[i].Level = newHarmonics[i]; s.Source2.Harmonics[i].Level = newHarmonics[i]; } s.Source1.Amplifier.EnvelopeSegments = Amplifier.Envelopes["regular"].Segments; s.Source2.Amplifier.EnvelopeSegments = Amplifier.Envelopes["silent"].Segments; int channel = 1; byte[] newHeader = new byte[] { 0xF0, 0x40, (byte)(channel - 1), 0x20, 0x00, 0x02, 0x00, 0x2F }; List <byte> newData = new List <byte>(); newData.AddRange(newHeader); newData.AddRange(Util.ConvertToTwoNybbleFormat(s.ToData())); newData.Add(0xf7); Console.WriteLine("Creating new patch, new SysEx data:\n{0}", Util.HexDump(newData.ToArray())); var folder = Environment.SpecialFolder.Desktop; var newFileName = Path.Combine(new string[] { Environment.GetFolderPath(folder), "Frankenpatch.syx" }); Console.WriteLine($"Writing SysEx data to '{newFileName}'..."); File.WriteAllBytes(newFileName, newData.ToArray()); return(0); }
public static int RunCreateAndReturnExitCode(CreateOptions opts) { var header = new SystemExclusiveHeader(0x00); header.Function = (byte)SystemExclusiveFunction.OneBlockDump; header.Group = 0x00; header.MachineID = 0x0A; header.Substatus1 = 0x00; // single // Get the right bank. Since it is a required parameter, I suppose we can trust that it exists. string bankName = opts.BankName.ToLower(); char ch = bankName[0]; switch (ch) { case 'a': header.Substatus2 = 0x00; break; case 'd': header.Substatus2 = 0x02; break; case 'e': header.Substatus2 = 0x03; break; case 'f': header.Substatus2 = 0x04; break; default: Console.WriteLine(string.Format("Unknown bank: '{0}'", opts.BankName)); return(-1); } var allData = new List <byte>(); // SysEx initiator and basic header data allData.Add(SystemExclusiveHeader.Initiator); allData.AddRange(header.ToData()); // Additional header data as required var patchNumber = opts.PatchNumber - 1; if (patchNumber < 0 || patchNumber > 127) { Console.WriteLine("Patch number must be 1...128"); return(-1); } allData.Add((byte)patchNumber); SinglePatchGenerator generator; SinglePatchDescriptor descriptor; if (opts.PatchType.Equals("single")) { if (!string.IsNullOrEmpty(opts.Descriptor)) // we have a JSON descriptor file, parse it { var jsonText = File.ReadAllText(opts.Descriptor); descriptor = JsonConvert.DeserializeObject <SinglePatchDescriptor>(jsonText); generator = new SinglePatchGenerator(descriptor); } else { descriptor = new SinglePatchDescriptor(); generator = new SinglePatchGenerator(descriptor); } SinglePatch single = generator.Generate(); byte[] singleData = single.ToData(); Console.Error.WriteLine(string.Format("Generated single data size: {0} bytes", singleData.Length)); Console.Error.WriteLine(single.ToString()); allData.AddRange(singleData); allData.Add(SystemExclusiveHeader.Terminator); File.WriteAllBytes(opts.OutputFileName, allData.ToArray()); } else if (opts.PatchType.Equals("multi")) { Console.WriteLine("Don't know how to make a multi patch yet"); return(1); } return(0); }
static int Main(string[] args) { if (args.Length < 2) { System.Console.WriteLine("Usage: K5KTool cmd filename.syx"); return(1); } string command = args[0]; string fileName = args[1]; string patchName = ""; if (args.Length > 2) { patchName = args[2]; } byte[] fileData = File.ReadAllBytes(fileName); System.Console.WriteLine($"SysEx file: '{fileName}' ({fileData.Length} bytes)"); List <byte[]> messages = Util.SplitBytesByDelimiter(fileData, Constants.SystemExclusiveTerminator); System.Console.WriteLine($"Got {messages.Count} messages"); foreach (byte[] message in messages) { SystemExclusiveHeader header = new SystemExclusiveHeader(message); //System.Console.WriteLine(Util.HexDump(header.Data)); System.Console.WriteLine(header.ToString()); int headerLength = header.Data.Length; // Examine the header to see what kind of message this is: SystemExclusiveFunction function = (SystemExclusiveFunction)header.Function; if (function == SystemExclusiveFunction.AllPatchDataDump) { // sub2: 0=I or E, 20H=i or e singles if (header.Substatus2 == 0x00 || header.Substatus2 == 0x20) { int offset = headerLength; for (int i = 0; i < NumSingles; i++) { byte[] singleData = new byte[SinglePatch.DataSize]; Buffer.BlockCopy(message, offset, singleData, 0, SinglePatch.DataSize); System.Console.WriteLine("INGOING SINGLE DATA = \n" + Util.HexDump(singleData)); SinglePatch single = new SinglePatch(singleData); System.Console.WriteLine(single.ToString()); byte[] sysExData = single.ToData(); System.Console.WriteLine("OUTCOMING SINGLE DATA = \n" + Util.HexDump(sysExData)); (bool result, int diffIndex) = Util.ByteArrayCompare(singleData, sysExData); System.Console.WriteLine(String.Format("match = {0}, diff index = {1}", result ? "YES :-)" : "NO :-(", diffIndex)); offset += SinglePatch.DataSize; } } else if (header.Substatus2 == 0x40) { System.Console.WriteLine("Multis not handled yet"); return(1); } } else if (function == SystemExclusiveFunction.OnePatchDataDump) { System.Console.WriteLine("One patch dumps not handled yet"); return(1); } } return(0); }