public void CopyMetaData(TrackChunk trackToCopy) { this.Channel = trackToCopy.Channel; this.Comments = trackToCopy.Comments; this.CopyrightNotice = trackToCopy.CopyrightNotice; this.CuePoint = trackToCopy.CuePoint; this.DeviceName = trackToCopy.DeviceName; this.EndOfTrack = trackToCopy.EndOfTrack; this.InstrumentName = trackToCopy.InstrumentName; this.KeySignature = trackToCopy.KeySignature; this.Lyrics = trackToCopy.Lyrics; this.Marker = trackToCopy.Marker; this.Port = trackToCopy.Port; this.SequenceNumber = trackToCopy.SequenceNumber; this.SMPTEOffSet = trackToCopy.SMPTEOffSet; this.Tempo = trackToCopy.Tempo; this.TimeSignature = trackToCopy.TimeSignature; this.TrackName = trackToCopy.TrackName; }
private static void CreateFileTest(String pathAndFilename) { MidiFile myFile = new MidiFile(); myFile.Header.FormatType = TrackFormatType.Single; myFile.Header.NumberOfTracks = 1; myFile.Header.PulsesPerQuarterNote = 960; TrackChunk tc1 = new TrackChunk(); tc1.File = myFile; myFile.Tracks.Add(tc1); tc1.File = myFile; tc1.SequenceNumber = new SequenceNumberEvent(0, 0); tc1.Comments = new TextEvent("Comments"); tc1.CopyrightNotice = new CopyrightNoticeEvent("CopyrightNotice"); tc1.TrackName = new TrackNameEvent("TrackName"); tc1.InstrumentName = new InstrumentNameEvent("InstrumentName"); tc1.Lyrics = new LyricsEvent("Lyrics"); tc1.Marker = new MarkerEvent("Marker"); tc1.CuePoint = new CuePointEvent("CuePoint"); tc1.DeviceName = new DeviceNameEvent("DeviceName"); tc1.Channel = new MidiChannelEvent(3); tc1.Port = new MidiPortEvent(6); tc1.TimeSignature = new TimeSignatureEvent(4, 4, 24, 8); tc1.Tempo = new TempoEvent(130.0); //tc1.SMPTEOffSet = new SMPTEOffSetEvent(); tc1.KeySignature = new KeySignatureEvent(0, 1); tc1.ChannelEvents.Add(ChannelMidiEvent.CreateNoteOnChannelMidiEvent(0, 64, 100, 0)); tc1.ChannelEvents.Add(ChannelMidiEvent.CreateNoteOffChannelMidiEvent(0, 64, 960)); tc1.ChannelEvents.Add(ChannelMidiEvent.CreateNoteOnChannelMidiEvent(0, 63, 90, 0)); tc1.ChannelEvents.Add(ChannelMidiEvent.CreateNoteOffChannelMidiEvent(0, 63, 960)); myFile.Export(pathAndFilename); }
public void ConvertToMidiFilesByTrack(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) { MidiFile newFile = newFile = new MidiFile(); newFile.FileNameAndPath = outputPath + Path.DirectorySeparatorChar + origTrack.TrackName.Text + ".mid"; newFile.Header.NumberOfTracks = 1; newFile.Header.FormatType = TrackFormatType.Single; newFile.Header.PulsesPerQuarterNote = this.Header.PulsesPerQuarterNote; midiFiles.Add(newFile); TrackChunk newTrack = new TrackChunk(); //newTrack.TrackName = new TrackNameEvent(origTrack.TrackName.Text); 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); foreach (var channelEvent in origTrack.ChannelEvents) { newTrack.ChannelEvents.Add(channelEvent); } } foreach (MidiFile mf in midiFiles) { mf.Export(mf.FileNameAndPath); } }
public void Import(String midiFilePathAndFileName) { this.FileNameAndPath = midiFilePathAndFileName; String path = Path.GetDirectoryName(midiFilePathAndFileName); String regionDefinitionPathAndFileName = Path.ChangeExtension(midiFilePathAndFileName, "csv"); if (File.Exists(regionDefinitionPathAndFileName)) { this.LoadRegions(regionDefinitionPathAndFileName); } using (BinaryReader binaryReader = new BinaryReader(File.Open(midiFilePathAndFileName, FileMode.Open, FileAccess.Read), Encoding.Default)) { if (binaryReader.ReadChar() == 'M') { if (binaryReader.ReadChar() == 'T') { if (binaryReader.ReadChar() == 'h') { if (binaryReader.ReadChar() == 'd') { Debug.WriteLine(this.FileNameAndPath); this.Header = new HeaderChunk(); this.Header.File = this; this.Header.ConvertFromBinary(binaryReader); Debug.WriteLine(this.Header); //this.CreateTracks(this.Header.NumberOfTracks); //TrackChunk metaTrack = null; while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { if (binaryReader.ReadChar() == 'M') { if (binaryReader.ReadChar() == 'T') { if (binaryReader.ReadChar() == 'r') { if (binaryReader.ReadChar() == 'k') { if (this.Header.FormatType == TrackFormatType.MetaAndChannel && this.MetaTrack == null) { this.MetaTrack = new TrackChunk(); this.MetaTrack.ConvertFromBinary(binaryReader); } else { TrackChunk track = new TrackChunk(); this.AddTrack(track); track.CopyMetaData(this.MetaTrack); track.ConvertFromBinary(binaryReader); track.Tempo = new TempoEvent(track.Tempo.MicroSecondsPerQuarterNote, track.TimeSignature.Denominator); //track.Tempo.BPM = track.Tempo.CalculateBPM(this.Header.PulsesPerQuarterNote, track.TimeSignature.Denominator);//have to calculate at a point when we have time signature and tempo track.ConvertEventsToNotes(); //Debug.WriteLine(track); } } } } } } //if (this.Header.NumberOfTracks != this.Tracks.Count) // throw new ApplicationException("number of tracks defined in header does not match the number of actual tracks found"); } else { throw new ApplicationException("file did not contain expected header"); } } } } } }
public void AddTrack(TrackChunk track) { this.Tracks.Add(track); track.File = this; }
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); } }
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); } }