private static int ConvertHMPToMIDI(ProgramCall prog) { if (prog.HmqMode != FMMode.None) { PrintHelp(); return(2); } MIDISequence midi; try { midi = MIDISequence.LoadHMP(ReadFile(prog.SourceFile)); } catch (Exception ex) { Console.Error.WriteLine("Could not load HMP!"); Console.Error.WriteLine(ex.ToString()); return(2); } midi.Convert(MIDIFormat.Type1); midi.PulsesPerQuarter = 60; midi.AdjustPPQ(480); if (prog.Flags.HasFlag(ProgramFlags.FaithfulConversionToMIDI)) { // add track volume 0 to all tracks without them // (this is how the original SOS engine works) foreach (MIDITrack trk in midi.Tracks) { IEnumerable <MIDIMessage> messages = trk.GetAllEvents().Select(e => e.Data); if (!messages.OfType <MIDIControlChangeMessage>().Where(m => m.Controller == MIDIControl.ChannelVolumeMSB).Any()) { MIDIMessage chm = messages.Where(m => !m.IsExtendedEvent).FirstOrDefault(); if (chm != null) { trk.AddEvent(new MIDIEvent(0, new MIDIControlChangeMessage(chm.Channel, MIDIControl.ChannelVolumeMSB, 0)), true); } } } } try { if (!Overwrite(prog.Flags, prog.TargetFile)) { return(0); } WriteFile(midi, prog.TargetFile); } catch (Exception ex) { Console.Error.WriteLine("Could not save MIDI!"); Console.Error.WriteLine(ex.ToString()); return(2); } Console.Out.WriteLine("Successfully converted and saved MIDI file"); return(0); }
private static int ConvertMIDIToHMP(ProgramCall prog) { MIDISequence midi; try { midi = MIDISequence.LoadMIDI(ReadFile(prog.SourceFile)); } catch (Exception ex) { Console.Error.WriteLine("Could not load MIDI!"); Console.Error.WriteLine(ex.ToString()); return(2); } midi.Convert(MIDIFormat.HMI); // ============================== // clean up MIDI sequence for HMP // ============================== // remove tempo changes but hard-apply them onto the track midi.NormalizeTempo(); // set PPQ to 60 and adjust timings midi.AdjustPPQ(60); // add track volume messages to tracks that don't have them, otherwise they get muted foreach (MIDITrack trk in midi.Tracks) { IEnumerable <MIDIMessage> messages = trk.GetAllEvents().Select(e => e.Data); if (!messages.OfType <MIDIControlChangeMessage>().Where(m => m.Controller == MIDIControl.ChannelVolumeMSB).Any()) { MIDIMessage chm = messages.Where(m => !m.IsExtendedEvent).FirstOrDefault(); if (chm != null) { trk.AddEvent(new MIDIEvent(0, new MIDIControlChangeMessage(chm.Channel, MIDIControl.ChannelVolumeMSB, 127)), true); } } } // remove SysEx and meta events, as well as forbidden control change events foreach (MIDITrack trk in midi.Tracks) { trk.RemoveMessages(m => m.IsExtendedEvent || m is MIDIControlChangeMessage cm && forbiddenControls.Contains(cm.Controller)); } try { if (!Overwrite(prog.Flags, prog.TargetFile)) { return(0); } WriteFile(midi, prog.TargetFile); } catch (Exception ex) { Console.Error.WriteLine("Could not save HMP!"); Console.Error.WriteLine(ex.ToString()); return(2); } if (prog.HmqMode != FMMode.None) { string outHmq = Path.ChangeExtension(prog.TargetFile, ".hmq"); Console.WriteLine("Preparing HMQ for"); Console.Write(" "); switch (prog.HmqMode) { case FMMode.Melodic: Console.Write("MELODIC.BNK DRUM.BNK"); midi.RemapProgram(programMapMelodic); break; case FMMode.Intmelo: Console.Write("INTMELO.BNK INTDRUM.BNK"); midi.RemapProgram(programMapIntmelo); break; case FMMode.Hammelo: Console.Write("HAMMELO.BNK HAMDRUM.BNK"); midi.RemapProgram(programMapHammelo); break; case FMMode.Rickmelo: Console.Write("RICKMELO.BNK RICKDRUM.BNK"); midi.RemapProgram(programMapRickmelo); break; case FMMode.D2melod: Console.Write("D2MELOD.BNK D2DRUMS.BNK"); midi.RemapProgram(programMapD2melod); break; } Console.WriteLine(""); try { if (!Overwrite(prog.Flags, outHmq)) { return(0); } WriteFile(midi, outHmq); } catch (Exception ex) { Console.Error.WriteLine("Could not save HMQ!"); Console.Error.WriteLine(ex.ToString()); return(2); } } Console.Out.WriteLine("Successfully converted and saved HMP file(s)"); return(0); }
static int ParseArgs(string[] args, out ProgramCall call) { call = new ProgramCall(); List <string> normalArgs = new List <string>(); foreach (string arg in args) { if (arg.Equals("/?", StringComparison.InvariantCultureIgnoreCase)) { PrintHelp(); return(0); } else if (arg.Equals("/H", StringComparison.InvariantCultureIgnoreCase)) { if (call.Mode != ProgramMode.None) { PrintHelp(); return(2); } call.Mode = ProgramMode.MIDIToHMP; } else if (arg.Equals("/M", StringComparison.InvariantCultureIgnoreCase)) { if (call.Mode != ProgramMode.None) { PrintHelp(); return(2); } call.Mode = ProgramMode.HMPToMIDI; } else if (arg.Equals("/Y", StringComparison.InvariantCultureIgnoreCase)) { call.Flags |= ProgramFlags.Overwrite; } else if (arg.Equals("/D", StringComparison.InvariantCultureIgnoreCase)) { call.Flags |= ProgramFlags.FaithfulConversionToMIDI; } else if (arg.StartsWith("/F:", StringComparison.InvariantCultureIgnoreCase)) { try { int mode = int.Parse(arg.Substring(3)); if (mode < 1 || mode > 5) { throw new ArgumentException(); } call.HmqMode = (FMMode)mode; } catch (Exception) { PrintHelp(); return(2); } } else if (arg.StartsWith("/", StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Unknown command flag " + arg); PrintHelp(); return(2); } else { normalArgs.Add(arg); } } if (normalArgs.Count != 2) { PrintHelp(); return(2); } call.SourceFile = normalArgs[0]; call.TargetFile = normalArgs[1]; return(0); }