/** A NoteOff event occured. Find the MidiNote of the corresponding * NoteOn event, and update the duration of the MidiNote. */ public void NoteOff(int channel, int notenumber, int endtime) { for (int i = newTrack.Notes.Count - 1; i >= 0; i--) { MidiNote note = newTrack.Notes[i]; if (note.Channel == channel && note.Number == notenumber && note.Duration == 0) { note.NoteOff(endtime); return; } } }
/// <summary> /// Note_on_c = Note on event, but sometimes also a note off /// </summary> /// <param name="ar"></param> private void StartMidiNote(string[] ar) { if (ar.Length != 6) { throw new ArgumentException("Note On Length"); } // format of line: Track, Time, Note_on_c, Channel, Note, Velocity // format of Midinote: starttime, channel, notenumber, duration, velocity, selected int velocity = Convert.ToInt32(ar[5]); // velocity > 0 is a note on if (velocity > 0) { n = new MidiNote(Convert.ToInt32(ar[1]), Convert.ToInt32(ar[3]), Convert.ToInt32(ar[4]), 0, velocity, false); newNotes.Add(n); } else { // Note_on_c & velocity = 0 can be a note off in some midi files !!!! MidiNote no; int ticks = Convert.ToInt32(ar[1]); int notenumber = Convert.ToInt32(ar[4]); if (newNotes.Count > 0) { for (int i = 0; i < newNotes.Count; i++) { no = newNotes[i]; if (no.Duration == 0 && no.Number == notenumber) { no.Duration = Convert.ToInt32(ar[1]) - n.StartTime; track.addNote(no, false); newNotes.RemoveAt(i); break; } } } } }
private void ParseChannelMessage() { if (trackIndex >= trackData.Length) { //throw new MidiFileException("End of track unexpectedly reached."); Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)"); return; } cmBuilder.Command = ChannelMessage.UnpackCommand(status); cmBuilder.MidiChannel = ChannelMessage.UnpackMidiChannel(status); cmBuilder.Data1 = trackData[trackIndex]; // PROGRAM CHANGE if (cmBuilder.Command == ChannelCommand.ProgramChange) { newTrack.ProgramChange = cmBuilder.Data1; newTrack.MidiChannel = cmBuilder.MidiChannel; } trackIndex++; if (ChannelMessage.DataBytesPerType(cmBuilder.Command) == 2) { if (trackIndex >= trackData.Length) { //throw new MidiFileException("End of track unexpectedly reached."); Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)"); return; } // FAB : 07/08/2014 if (trackData[trackIndex] <= 127) { cmBuilder.Data2 = trackData[trackIndex]; } else { cmBuilder.Data2 = 127; } if (cmBuilder.Data1 == 0x07) { // Volume de la piste newTrack.Volume = cmBuilder.Data2; } else if (cmBuilder.Data1 == 0x5B) { // Reverb 91 // FAB 2017 newTrack.Reverb = cmBuilder.Data2; } else if (cmBuilder.Data1 == 0x0A) { // pan 10 // FAB 2017 newTrack.Pan = cmBuilder.Data2; } // Collecte des notes if (cmBuilder.Command == ChannelCommand.NoteOn) { newTrack.ContainsNotes = true; newTrack.Visible = true; // Data1 = Note number // Data2 = Velocity if (ticks >= 0 && cmBuilder.Data2 > 0) { // FAB : // Add a MidiNote to this track. This is called for each NoteOn event */ newTrack.MidiChannel = cmBuilder.MidiChannel; MidiNote note = new MidiNote(ticks, newTrack.MidiChannel, cmBuilder.Data1, 0, cmBuilder.Data2, false); newTrack.Notes.Add(note); } else { // FAB if (newTrack.Notes.Count > 0) { newTrack.MidiChannel = cmBuilder.MidiChannel; NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks); } } } else if (ticks >= 0 && cmBuilder.Command == ChannelCommand.NoteOff) { // FAB newTrack.ContainsNotes = true; newTrack.Visible = true; newTrack.MidiChannel = cmBuilder.MidiChannel; NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks); } trackIndex++; } cmBuilder.Build(); newTrack.Insert(ticks, cmBuilder.Result); runningStatus = status; }