using System;
namespace NAudio.Midi
{
///
/// Represents a MIDI message
///
public class MidiMessage
{
private int rawData;
///
/// Creates a new MIDI message
///
/// Status
/// Data parameter 1
/// Data parameter 2
public MidiMessage(int status, int data1, int data2)
{
rawData = status + (data1 << 8) + (data2 << 16);
}
///
/// Creates a new MIDI message from a raw message
///
/// A packed MIDI message from an MMIO function
public MidiMessage(int rawData)
{
this.rawData = rawData;
}
///
/// Creates a Note On message
///
/// Note number (0 to 127)
/// Volume (0 to 127)
/// MIDI channel (1 to 16)
/// A new MidiMessage object
public static MidiMessage StartNote(int note, int volume, int channel)
{
ValidateNoteParameters(note, volume, channel);
return new MidiMessage((int)MidiCommandCode.NoteOn + channel - 1, note, volume);
}
private static void ValidateNoteParameters(int note, int volume, int channel)
{
ValidateChannel(channel);
if (note < 0 || note > 127)
{
throw new ArgumentOutOfRangeException("note", "Note number must be in the range 0-127");
}
if (volume < 0 || volume > 127)
{
throw new ArgumentOutOfRangeException("volume", "Velocity must be in the range 0-127");
}
}
private static void ValidateChannel(int channel)
{
if ((channel < 1) || (channel > 16))
{
throw new ArgumentOutOfRangeException("channel", channel,
String.Format("Channel must be 1-16 (Got {0})", channel));
}
}
///
/// Creates a Note Off message
///
/// Note number
/// Volume
/// MIDI channel (1-16)
/// A new MidiMessage object
public static MidiMessage StopNote(int note, int volume, int channel)
{
ValidateNoteParameters(note, volume, channel);
return new MidiMessage((int)MidiCommandCode.NoteOff + channel - 1, note, volume);
}
///
/// Creates a patch change message
///
/// The patch number
/// The MIDI channel number (1-16)
/// A new MidiMessageObject
public static MidiMessage ChangePatch(int patch, int channel)
{
ValidateChannel(channel);
return new MidiMessage((int)MidiCommandCode.PatchChange + channel - 1, patch, 0);
}
///
/// Creates a Control Change message
///
/// The controller number to change
/// The value to set the controller to
/// The MIDI channel number (1-16)
/// A new MidiMessageObject
public static MidiMessage ChangeControl(int controller, int value, int channel)
{
ValidateChannel(channel);
return new MidiMessage((int)MidiCommandCode.ControlChange + channel - 1, controller, value);
}
///
/// Returns the raw MIDI message data
///
public int RawData
{
get
{
return rawData;
}
}
}
}