static void Main(string [] args) { MidiSequence sampleSequence = new CreateAndPlayDemo().CreateSequence(); sampleSequence = MidiSequence.Import("C:/Download/test.mid"); MidiPlayer.Play(sampleSequence); }
public void ImportMidiAndSaveToFile(string pMidiFile, string pXmlFile, string pArtist, string pTitle, int pTrack, int pBpm, int pSkipBeats) { var sequence = MidiSequence.Import(pMidiFile); var track = sequence.GetTracks()[pTrack]; MidiEventCollection midiEvents = track.Events; var midiImporter = new GuitarMidiImporter(midiEvents, pBpm, pSkipBeats); var song = new Song() { Author = pArtist, Name = pTitle, }; var xmlScoreWriter = new XmlScoreWriter(song, PlayingMode.EletricGuitarScore, midiImporter.ScoreNotes); if (File.Exists(pXmlFile)) { File.Delete(pXmlFile); } xmlScoreWriter.SaveXmlNotesToFile(pXmlFile); Assert.IsTrue(File.Exists(pXmlFile)); }
public void Guitar1Track() { var sequence = MidiSequence.Import(MIDI_for_whom_the_bell_tolls); Assert.IsTrue(sequence.GetTracks()[2].Events[0] is SequenceTrackName); var trackName = (SequenceTrackName)sequence.GetTracks()[2].Events[0]; Assert.AreEqual("Guitar 1", trackName.Text); }
public void ParametersTrack() { var sequence = MidiSequence.Import(MIDI_for_whom_the_bell_tolls); // 0 - a single multi-channel track // 1 - one or more simultaneous tracks // 2 - one or more sequentially independent single-track patterns Assert.AreEqual(1, sequence.Format); //Beats per minute (tempo) Assert.AreEqual(120, sequence.Division); }
static void Main(string [] args) { string midiFilename = ""; string codeFilename = ""; // Use parameter as input and output name if (args.Length == 1) { midiFilename = args[0]; codeFilename = args[0] + ".cs"; } // Ask user for filenames else { // Get the input file while (true) { Console.WriteLine("Give the full path to a MIDI file:"); midiFilename = Console.ReadLine(); if (!File.Exists(midiFilename)) { Console.WriteLine("The file does not exist."); } else { break; } } // Get the name of the output csharp file Console.WriteLine("Enter the name of an output csharp file:"); codeFilename = Console.ReadLine(); } // Generate the code for the midi sequence Console.WriteLine("Generating..."); MidiSequence sequence = MidiSequence.Import(midiFilename); using (StreamWriter writer = new StreamWriter(codeFilename)) { MidiCodeGenerator.GenerateMIDICode( new Microsoft.CSharp.CSharpCodeProvider().CreateGenerator(), sequence, "SampleMidi", writer); } Console.WriteLine("Complete."); }
private void btnBrowseMidi_Click(object sender, EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Title = "Open MIDI! File"; fileDialog.Filter = "MIDI files|*.mid"; if (fileDialog.ShowDialog() == DialogResult.OK) { try { txtMidiFile.Text = fileDialog.FileName; midiSequence = MidiSequence.Import(txtMidiFile.Text); } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } }
static void Main(string [] args) { foreach (string midiFilename in args) { try { // Open midi file MidiSequence sequence = MidiSequence.Import(midiFilename); // Spit out format info and ask for new format int oldFormat = sequence.Format; int newFormat = 0; if (oldFormat != newFormat) { // Create the new midi file MidiSequence newSequence = MidiSequence.Convert( sequence, newFormat, MidiSequence.FormatConversionOptions.CopyTrackToChannel); // Write out the new converted file string newFilename = midiFilename + "." + newFormat + ".mid"; newSequence.Save(newFilename); // Let the user know Console.WriteLine("Converted {0}\r\n\tFrom type {1}\r\n\tTo type {2}\r\n\tSaved to {3}", midiFilename, oldFormat, newFormat, newFilename); } else { Console.WriteLine("File {0} is already type {1}.", midiFilename, newFormat); } } catch (Exception exc) { // Let the user know something went wrong Console.WriteLine("Converting {0}\r\n\t{1}", midiFilename, exc.Message); } } Console.WriteLine(""); Console.WriteLine("Hit enter to exit..."); Console.ReadLine(); }
public void TotalTime() { var sequence = MidiSequence.Import(MIDI_for_whom_the_bell_tolls); //MediaPlayer: 4m54s = 294s //totalTime/120 = number of music beats var musicTime = (4 * 60) + 54; long maxTotalTime = 0; foreach (var track in sequence.GetTracks()) { long totalTime = 0; foreach (MidiEvent midiEvent in track.Events) { totalTime += midiEvent.DeltaTime; } if (totalTime > maxTotalTime) { maxTotalTime = totalTime; } //(60.0/120.0) = time of one beat (120bpm) var trackTime = (totalTime / sequence.Division) * (60.0 / sequence.Division); Assert.LessOrEqual(trackTime, musicTime); //Trace.TraceInformation(string.Format("Track {0}: {1} seconds", // ((SequenceTrackName)track.Events[0]).Text, // (totalTime / sequence.Division) * (60.0 / sequence.Division))); } var maxTrackTime = (maxTotalTime / sequence.Division) * (60.0 / sequence.Division); Assert.AreEqual(musicTime, maxTrackTime); }
public void CheckTheFirstChord() { var sequence = MidiSequence.Import(MIDI_for_whom_the_bell_tolls); var guitar1Track = sequence.GetTracks()[2]; var listOfChords = new List <List <NoteOn> >(); List <NoteOn> chordNotes = null; bool isPause = false; foreach (MidiEvent midiEvent in guitar1Track.Events) { if (midiEvent is NoteOn) { var note = (NoteOn)midiEvent; if (note.DeltaTime > 0) { if ((chordNotes != null) && (chordNotes.Count > 0)) { listOfChords.Add(chordNotes); } chordNotes = new List <NoteOn>(); isPause = (note.Velocity == 0); //used for the next notes of the acord (same time) } if ((note.Velocity > 0) && (!isPause)) { chordNotes.Add(note); } } } //start on 1680 from the beggining { var chord = listOfChords[0]; Assert.AreEqual(3, chord.Count); Assert.AreEqual(1680, chord[0].DeltaTime); Assert.AreEqual(100, chord[0].Velocity); Assert.AreEqual("C#4", MidiEvent.GetNoteName(chord[0].Note)); Assert.AreEqual("F#4", MidiEvent.GetNoteName(chord[1].Note)); Assert.AreEqual("F#3", MidiEvent.GetNoteName(chord[2].Note)); } //start on 40 after the last event { var chord = listOfChords[1]; Assert.AreEqual(3, chord.Count); Assert.AreEqual(40, chord[0].DeltaTime); Assert.AreEqual(100, chord[0].Velocity); Assert.AreEqual("C#4", MidiEvent.GetNoteName(chord[0].Note)); Assert.AreEqual("F#4", MidiEvent.GetNoteName(chord[1].Note)); Assert.AreEqual("F#3", MidiEvent.GetNoteName(chord[2].Note)); } //and so on... /* * track.Events.Add(new NoteOn(1680, 1, "C#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#3", 100)); * track.Events.Add(new NoteOn(40, 1, "F#3", 0)); * track.Events.Add(new NoteOn(0, 1, "F#4", 0)); * track.Events.Add(new NoteOn(0, 1, "C#4", 0)); * track.Events.Add(new NoteOn(0, 1, "C#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#3", 100)); * track.Events.Add(new NoteOn(40, 1, "F#3", 0)); * track.Events.Add(new NoteOn(0, 1, "F#4", 0)); * track.Events.Add(new NoteOn(0, 1, "C#4", 0)); * track.Events.Add(new NoteOn(40, 1, "C#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#4", 100)); * track.Events.Add(new NoteOn(0, 1, "F#3", 100)); */ }
public void LoadFile_Check10Tracks() { var sequence = MidiSequence.Import(MIDI_for_whom_the_bell_tolls); Assert.AreEqual(10, sequence.NumberOfTracks); }
/// <summary> /// Creates a notechart from the specified midi path and the actual charttype /// (i.e. ExpertSingle from notes.mid). Due to the overhead necessary to /// parse a midi file. I am going to cram all midi->chart operations into /// one function call. /// This function uses the Toub midi parser which is much faster than Sanford, /// but will throw an exception on certian midi files. /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <param name="chartInfo">The metadata on the chart.</param> /// <param name="BPMChanges">The list of BPM changes for this chart.</param> /// <returns> /// A filled out Notechart containing the needed information from the *.mid file. /// </returns> public static Notes ParseMidiInformationToub(ChartSelection chartSelection, Info chartInfo, List <BPMChange> BPMChanges) { Notes notechartToReturn = new Notes(); notechartToReturn.instrument = chartSelection.instrument; notechartToReturn.difficulty = chartSelection.difficulty; // The following two switch's are used to get the proper midi terminology for // the selected track and difficulty. string instrumentPart = null; string greenKey = null; string redKey = null; string yellowKey = null; string blueKey = null; string orangeKey = null; switch (chartSelection.instrument) { case "Single": instrumentPart = "PART GUITAR"; break; case "DoubleGuitar": instrumentPart = "PART GUITAR COOP"; break; case "DoubleBass": instrumentPart = "PART BASS"; break; case "Drums": instrumentPart = "PART DRUMS"; break; default: instrumentPart = "PART GUITAR"; break; } switch (chartSelection.difficulty) { case "Expert": greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; case "Hard": greenKey = "C7"; redKey = "C#7"; yellowKey = "D7"; blueKey = "D#7"; orangeKey = "E7"; break; case "Medium": greenKey = "C6"; redKey = "C#6"; yellowKey = "D6"; blueKey = "D#6"; orangeKey = "E6"; break; case "Easy": greenKey = "C5"; redKey = "C#5"; yellowKey = "D5"; blueKey = "D#5"; orangeKey = "E5"; break; default: greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; } MidiSequence mySequence = MidiSequence.Import(chartSelection.directory + "\\notes.mid"); MidiTrack[] myTracks = mySequence.GetTracks(); chartInfo.resolution = mySequence.Division; MidiTrack trackToUse = new MidiTrack(); uint totalTickValue = 0; // Go through each event in the first track (which contains the BPM changes) // and parse the resulting string. for (int i = 0; i < myTracks[0].Events.Count; i++) { Toub.Sound.Midi.MidiEvent currEvent = myTracks[0].Events[i]; string eventString = currEvent.ToString(); string[] splitEventString = eventString.Split('\t'); // Since ticks are stored relative to each other (e.g. 300 ticks // until next note), we must maintain the total tick amout. totalTickValue += Convert.ToUInt32(splitEventString[1]); if (splitEventString[0] == "Tempo") { // In midi files, bpm chages are stored as "microseconds per quarter note" // and must be converted to BPM, and then into the non decimal format the game // uses. double currBPMDouble = 60000000 / Convert.ToDouble(splitEventString[3]); uint BPMToAdd = (uint)(currBPMDouble * 1000); BPMChanges.Add(new BPMChange(totalTickValue, BPMToAdd)); } } trackToUse = new MidiTrack(); // Find the specified instrument's track foreach (MidiTrack currTrack in myTracks) { string trackHeader = currTrack.Events[0].ToString(); string[] splitHeader = trackHeader.Split('\t'); // -If we come across a "T1 GEMS" track, we're in GH1 territory. // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending // on the chart). if (((splitHeader[3] == instrumentPart) || (splitHeader[3] == "T1 GEMS")) || ((splitHeader[3] == "PART RHYTHM") && (instrumentPart == "PART BASS"))) { trackToUse = currTrack; } } totalTickValue = 0; uint currTickValue = 0; Note currNote = new Note(); bool blankNote = true; // Scan through and record every note specific to the selected difficulty for (int i = 0; i < trackToUse.Events.Count; i++) { string currEvent = trackToUse.Events[i].ToString(); string[] splitEvent = currEvent.Split('\t'); currTickValue = Convert.ToUInt32(splitEvent[1]); totalTickValue += currTickValue; // We need to specify wether a note is blank or not so we don't add // blank notes from other difficulties into the chart, but if we have // a filled out note, any nonzero tick value means we are moving to a // new note, so we must cut our ties and add this note to the chart. if ((currTickValue != 0) && !blankNote) { notechartToReturn.notes.Add(currNote); currNote = new Note(); blankNote = true; } // The "0x64" I think means "not was hit." There is another // set of notes that use "0x00" that all appear slightly after // the "0x64" notes. if ((splitEvent[0] == "NoteOn") && (splitEvent[4] != "0x00")) { // Only consider notes within the octave our difficulty is in. if ((splitEvent[3] == greenKey) || (splitEvent[3] == redKey) || (splitEvent[3] == yellowKey) || (splitEvent[3] == blueKey) || (splitEvent[3] == orangeKey)) { // If it's a new note, we need to setup the tick value of it. if (blankNote) { currNote.tickValue = totalTickValue; blankNote = false; } if (splitEvent[3] == greenKey) { currNote.addNote(0); } else if (splitEvent[3] == redKey) { currNote.addNote(1); } else if (splitEvent[3] == yellowKey) { currNote.addNote(2); } else if (splitEvent[3] == blueKey) { currNote.addNote(3); } else if (splitEvent[3] == orangeKey) { currNote.addNote(4); } } } } return(notechartToReturn); }