static void Main(string[] args) { if (args.Length < 2 || args.Length > 3) { Usage(); } string serialPortName = args[0]; string midiFileName = args[1]; string patchFileName; if (args.Length == 3) { patchFileName = args[2]; } else { patchFileName = null; } SerialPort uart = new SerialPort(serialPortName); uart.BaudRate = 115200; uart.Parity = Parity.None; uart.DataBits = 8; uart.StopBits = StopBits.One; uart.Handshake = Handshake.None; uart.ReadTimeout = 500; uart.WriteTimeout = 500; uart.Open(); // now write the patch file if one is supplied if (patchFileName != null) { Console.WriteLine("Uploading Patch..."); byte[] patchBytes = File.ReadAllBytes(patchFileName); if (patchBytes.Length != 0x1800) { throw new Exception("Invalid patch file size (not 0x1800)"); } byte[] patchStart = { 0xF0 }; byte[] patchEnd = { 0xF7 }; uart.Write(patchStart, 0, 1); uart.Write(patchBytes, 0, patchBytes.Length); uart.Write(patchEnd, 0, 1); Console.WriteLine("Done!"); } // now read midi and send it to device csmidi.MidiFile midi = new csmidi.MidiFile(); midi.loadMidiFromFile(midiFileName); int[] trackEventIndex = new int[midi.midiTracks.Count]; TimeBarrier tb = new TimeBarrier(); tb.SetInterval(60.0 / (midi.timeDivision * 120.0)); // default midi speed 120 bpm tb.Start(); Console.WriteLine("Playing MIDI..."); long currentTick = 0; while (true) { /* * Console.Write("tick: " + currentTick + " | "); * for (int i = 0; i < midi.midiTracks.Count; i++) * { * Console.Write(" " + trackEventIndex[i] + "/" + midi.midiTracks[i].midiEvents.Count); * } * Console.WriteLine(); */ int tracksStopped = 0; for (int cTrk = 0; cTrk < midi.midiTracks.Count; cTrk++) { csmidi.MidiTrack tr = midi.midiTracks[cTrk]; if (trackEventIndex[cTrk] >= tr.midiEvents.Count) { //Console.WriteLine("skipping track: " + cTrk); tracksStopped++; continue; } //Console.WriteLine("processing track: " + cTrk); while (currentTick >= tr.midiEvents[trackEventIndex[cTrk]].absoluteTicks) { //Console.WriteLine("crawling track: " + cTrk); csmidi.MidiEvent ev = tr.midiEvents[trackEventIndex[cTrk]]; if (ev is csmidi.MessageMidiEvent) { csmidi.MessageMidiEvent mev = ev as csmidi.MessageMidiEvent; byte[] data = mev.getEventData(); uart.Write(data, 0, data.Length); printHex(currentTick, data); } else if (ev is csmidi.MetaMidiEvent) { csmidi.MetaMidiEvent mev = ev as csmidi.MetaMidiEvent; if (mev.getMetaType() == csmidi.MetaType.TempoSetting) { byte[] tempo = mev.getEventData(); Debug.Assert(tempo.Length == 6); int us_per_beat = (tempo[3] << 16) | (tempo[4] << 8) | tempo[5]; double tickLength = (us_per_beat / 1000000.0) / midi.timeDivision; Console.WriteLine("Set to {0} BPM", 1000000.0 / us_per_beat * 60.0); tb.SetInterval(tickLength); } } if (++trackEventIndex[cTrk] >= tr.midiEvents.Count) { tracksStopped++; break; } } } //Console.WriteLine("stopped: " + tracksStopped); if (tracksStopped == midi.midiTracks.Count) { break; } currentTick++; tb.Wait(); } tb.Stop(); uart.Close(); }
static void Main(string[] args) { Stopwatch timer = new Stopwatch(); timer.Start(); string inputFile = ""; string outputFile = ""; double modScale = 0.5; byte modt = 0; bool fixAgbEvents = true; bool fixVolScale = true; bool fixLoop = true; // do an argument loop int isInputFile = 0; if (args.Length == 0) { showUsage(); } for (int i = 0; i < args.Length; i++) { string[] splitArg = args[i].Split('='); if (splitArg.Length == 1) { if (isInputFile == 0) { inputFile = splitArg[0]; isInputFile++; } else if (isInputFile == 1) { outputFile = splitArg[0]; isInputFile++; } else { showUsage(); return; } } else if (splitArg.Length == 2) // if regular argument { switch (splitArg[0]) { case "modscale": modScale = Convert.ToDouble(splitArg[1]); if (modScale < 0) { showUsage(); Console.WriteLine("The Mod Scale must not be negative!"); return; } break; case "modt": modt = Convert.ToByte(splitArg[1]); if (modt > 2) { showUsage(); Console.WriteLine("The MODT must be 0, 1 or 2!"); return; } break; case "fixloop": fixLoop = Convert.ToBoolean(splitArg[1]); break; case "fixvolscale": fixVolScale = Convert.ToBoolean(splitArg[1]); break; case "addagbevents": fixAgbEvents = Convert.ToBoolean(splitArg[1]); break; default: Console.WriteLine("Unknown argument: " + splitArg[0]); showUsage(); break; } } } // automatically name new outfile name if none is specified if (inputFile != "") { inputFile = Path.GetFullPath(inputFile); } if (inputFile != "" && outputFile == "") { outputFile = Path.GetFileNameWithoutExtension(inputFile) + "_FINAL.mid"; outputFile = Path.Combine(Path.GetDirectoryName(inputFile), outputFile); } else { outputFile = Path.GetFullPath(outputFile); } Console.WriteLine("Inputfile:"); Console.WriteLine(inputFile); Console.WriteLine("Outputfile:"); Console.WriteLine(outputFile); csmidi.MidiFile midiFile = new csmidi.MidiFile(); midiFile.loadMidiFromFile(inputFile); if (fixAgbEvents) { MidiFixer.addAgbCompatibleEvents(midiFile, modt); } if (fixVolScale) { MidiFixer.combineVolumeAndExpression(midiFile); } MidiFixer.addModulationScale(midiFile, modScale); if (fixVolScale) { MidiFixer.addExponentialScale(midiFile); } if (fixLoop) { MidiFixer.fixLoopCarryBack(midiFile); } midiFile.saveMidiToFile(outputFile); timer.Stop(); Console.WriteLine("Fixed midi in : " + timer.ElapsedMilliseconds.ToString() + "ms"); }