using System; using System.IO; using System.Text; namespace NAudio.Midi { /// /// Represents a MIDI note on event /// public class NoteOnEvent : NoteEvent { private NoteEvent offEvent; /// /// Reads a new Note On event from a stream of MIDI data /// /// Binary reader on the MIDI data stream public NoteOnEvent(BinaryReader br) : base(br) { } /// /// Creates a NoteOn event with specified parameters /// /// Absolute time of this event /// MIDI channel number /// MIDI note number /// MIDI note velocity /// MIDI note duration public NoteOnEvent(long absoluteTime, int channel, int noteNumber, int velocity, int duration) : base(absoluteTime, channel, MidiCommandCode.NoteOn, noteNumber, velocity) { this.OffEvent = new NoteEvent(absoluteTime, channel, MidiCommandCode.NoteOff, noteNumber, 0); NoteLength = duration; } /// /// Creates a deep clone of this MIDI event. /// public override MidiEvent Clone() => new NoteOnEvent(AbsoluteTime, Channel, NoteNumber, Velocity, NoteLength); /// /// The associated Note off event /// public NoteEvent OffEvent { get { return offEvent; } set { if (!MidiEvent.IsNoteOff(value)) { throw new ArgumentException("OffEvent must be a valid MIDI note off event"); } if (value.NoteNumber != this.NoteNumber) { throw new ArgumentException("Note Off Event must be for the same note number"); } if (value.Channel != this.Channel) { throw new ArgumentException("Note Off Event must be for the same channel"); } offEvent = value; } } /// /// Get or set the Note Number, updating the off event at the same time /// public override int NoteNumber { get { return base.NoteNumber; } set { base.NoteNumber = value; if (OffEvent != null) { OffEvent.NoteNumber = NoteNumber; } } } /// /// Get or set the channel, updating the off event at the same time /// public override int Channel { get { return base.Channel; } set { base.Channel = value; if (OffEvent != null) { OffEvent.Channel = Channel; } } } /// /// The duration of this note /// /// /// There must be a note off event /// public int NoteLength { get { return (int)(offEvent.AbsoluteTime - this.AbsoluteTime); } set { if (value < 0) { throw new ArgumentException("NoteLength must be 0 or greater"); } offEvent.AbsoluteTime = this.AbsoluteTime + value; } } /// /// Calls base class export first, then exports the data /// specific to this event /// MidiEvent.Export /// public override string ToString() { if ((this.Velocity == 0) && (OffEvent == null)) { return String.Format("{0} (Note Off)", base.ToString()); } return String.Format("{0} Len: {1}", base.ToString(), (this.OffEvent == null) ? "?" : this.NoteLength.ToString()); } } }