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());
}
}
}