public void ConvertToMidiFilesByRegionAndTrack(String outputPath) { if (this.Header.FormatType != TrackFormatType.MetaAndChannel) { throw new ApplicationException("cannot split file"); } List <MidiFile> midiFiles = new List <MidiFile>(); foreach (TrackChunk origTrack in this.Tracks) { /// do conversion in this order. by doing these conversions we also remove any /// overlapping notes. origTrack.MakeAllNotesSameKey(60); //good for drums where we want the same note for all drum hits. this also means we will clear a lot more duplicate notes. origTrack.MakeAllNotesSameLength(240); origTrack.RemoveNotesThatDoNotLieCompletelyWithinARegion(); origTrack.RemoveDuplicateNotes(); origTrack.CombineOverlappingNotes(); //origTrack.ApplyScaleToNotesRandomly(5, NoteMap.C, NoteMap.CSharp, NoteMap.F, NoteMap.G, NoteMap.GSharp, NoteMap.A); //C, C#, F, G, G#, A //origTrack.ApplyScaleToNotesInSequence(5, 0, true, NoteMap.C, NoteMap.CSharp, NoteMap.F, NoteMap.G, NoteMap.GSharp, NoteMap.A); //C, C#, F, G, G#, A TrackChunk newTrack = null; MidiFile newFile = null; Region currentRegion = null; Note lastNote = null; foreach (var note in origTrack.Notes) { if (note.AveragePosition.Region != currentRegion) { currentRegion = note.StartPosition.Region; newFile = new MidiFile(); //String temp = origTrack.TrackName.Text.Substring(0, 2); //if (temp.StartsWith("0")) // temp = temp.Substring(1); String fileNameNoExt = Path.GetFileNameWithoutExtension(this.FileNameAndPath); String newTrackName = "R" + note.StartPosition.Region.Ordinal.ToString().PadLeft(2, '0') + " - " + origTrack.TrackName.Text + " - " + fileNameNoExt; newFile.FileNameAndPath = outputPath + Path.DirectorySeparatorChar + newTrackName + ".mid"; newFile.Header.NumberOfTracks = 1; newFile.Header.FormatType = TrackFormatType.Single; newFile.Header.PulsesPerQuarterNote = this.Header.PulsesPerQuarterNote; midiFiles.Add(newFile); newTrack = new TrackChunk(); newTrack.TrackName = new TrackNameEvent(newTrackName); newTrack.TimeSignature = new TimeSignatureEvent(origTrack.TimeSignature.Numerator, origTrack.TimeSignature.Denominator, origTrack.TimeSignature.MetronomePulse, origTrack.TimeSignature.ThirtySecondNotes); newTrack.Tempo = new TempoEvent(origTrack.Tempo.MicroSecondsPerQuarterNote, origTrack.TimeSignature.Denominator); newTrack.CopyrightNotice = new CopyrightNoticeEvent("Joe Bacon 2013"); newTrack.DeviceName = new DeviceNameEvent("MIDI-Bacon"); newFile.Tracks.Add(newTrack); lastNote = null; } uint deltaTime = 0; if (lastNote == null) { deltaTime = note.StartPosition.GetAsTotalTicks() - currentRegion.Start.GetAsTotalTicks(this.Header.PulsesPerQuarterNote, origTrack.TimeSignature); //occurs on first note of measure } else { deltaTime = note.StartPosition.GetAsTotalTicks() - lastNote.EndPosition.GetAsTotalTicks(); } ChannelMidiEvent noteOnEvent = ChannelMidiEvent.CreateNoteOnChannelMidiEvent(0, note.NoteNumber, note.Velocity, deltaTime); newTrack.ChannelEvents.Add(noteOnEvent); ChannelMidiEvent noteOffEvent = ChannelMidiEvent.CreateNoteOffChannelMidiEvent(0, note.NoteNumber, note.Length); newTrack.ChannelEvents.Add(noteOffEvent); lastNote = note; } } foreach (MidiFile mf in midiFiles) { mf.Export(mf.FileNameAndPath); } }
public void ConvertToMidiFilesByRegionAndBarAndTrack(String outputPath) { if (this.Header.FormatType != TrackFormatType.MetaAndChannel) { throw new ApplicationException("cannot split file"); } List <MidiFile> midiFiles = new List <MidiFile>(); foreach (TrackChunk origTrack in this.Tracks) { /// do conversion in this order. by doing these conversions we also remove any /// overlapping notes. origTrack.MakeAllNotesSameKey(48); //good for drums where we want the same note for all drum hits origTrack.MakeAllNotesSameLength(10); //smallest unit that wont overlap after cleaning duplicates //origTrack.ConstrainNotesToMeasureBoundaries(); //makes it easy to put the notes into 'measure' files //origTrack.RemoveNotesNotInMeasure(); origTrack.RemoveNotesWhereNoteStartIsNotWithinMeasure(); //origTrack.RemoveDuplicateNotes(); origTrack.RemoveDuplicateNotes(); //uint currentMeasure = 0; uint currentRegionMeasure = 0; TrackChunk newTrack = null; MidiFile newFile = null; Region currentRegion = null; MidiTime currentMeasureStart = null; Note lastNote = null; foreach (var note in origTrack.Notes) { if (note.StartPosition.Region == null) { Debug.WriteLine(origTrack.TrackName.Text + " null region @" + note.StartPosition); //Debug.WriteLine(note.ToString()); continue; } if (note.StartPosition.Region != currentRegion) { ///the first note in a new region /// currentRegion = note.StartPosition.Region; currentRegionMeasure = 0; //reset } if (currentMeasureStart == null || note.StartPosition.Measures != currentMeasureStart.Measures) { currentRegionMeasure++; ///the first note in a new measure /// newFile = new MidiFile(); String temp = origTrack.TrackName.Text.Substring(0, 2); //if (temp.StartsWith("0")) // temp = temp.Substring(1); String newTrackName = note.StartPosition.Region.ID + "-B" + currentRegionMeasure + "-T" + temp; newFile.FileNameAndPath = outputPath + Path.DirectorySeparatorChar + newTrackName + ".mid"; newFile.Header.NumberOfTracks = 1; newFile.Header.FormatType = TrackFormatType.Single; newFile.Header.PulsesPerQuarterNote = this.Header.PulsesPerQuarterNote; midiFiles.Add(newFile); newTrack = new TrackChunk(); newTrack.TrackName = new TrackNameEvent(newTrackName); newTrack.TimeSignature = new TimeSignatureEvent(origTrack.TimeSignature.Numerator, origTrack.TimeSignature.Denominator, origTrack.TimeSignature.MetronomePulse, origTrack.TimeSignature.ThirtySecondNotes); newTrack.Tempo = new TempoEvent(origTrack.Tempo.MicroSecondsPerQuarterNote, origTrack.TimeSignature.Denominator); newTrack.CopyrightNotice = new CopyrightNoticeEvent("Joe Bacon 2013"); newTrack.DeviceName = new DeviceNameEvent("MIDI-Bacon"); newFile.Tracks.Add(newTrack); currentMeasureStart = new MidiTime(this, note.StartPosition.Measures, 1, 0, origTrack.TimeSignature); lastNote = null; } uint deltaTime = 0; if (lastNote == null) { deltaTime = note.StartPosition.GetAsTotalTicks() - currentMeasureStart.GetAsTotalTicks(); //occurs on first note of measure } else { deltaTime = note.StartPosition.GetAsTotalTicks() - lastNote.EndPosition.GetAsTotalTicks(); } ChannelMidiEvent noteOnEvent = ChannelMidiEvent.CreateNoteOnChannelMidiEvent(0, note.NoteNumber, note.Velocity, deltaTime); newTrack.ChannelEvents.Add(noteOnEvent); ChannelMidiEvent noteOffEvent = ChannelMidiEvent.CreateNoteOffChannelMidiEvent(0, note.NoteNumber, note.Length); newTrack.ChannelEvents.Add(noteOffEvent); lastNote = note; } } foreach (MidiFile mf in midiFiles) { mf.Export(mf.FileNameAndPath); } }
private static void ReadFileTest(String pathAndFilename) { MidiFile mf = new MidiFile(); mf.Import(pathAndFilename); }