Skip to content

Commit

Permalink
chore: Finished updating messages to support input
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed May 21, 2020
1 parent 671c70a commit e2556f8
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 97 deletions.
10 changes: 10 additions & 0 deletions src/Uno.UWP/Devices/Midi/Internal/MidiHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ internal static byte GetChannel(byte firstMessageByte)
return (byte)(firstMessageByte & 0b0000_1111);
}

internal static byte GetFrame(byte frameByte)
{
return (byte)(frameByte & 0b1111_0000);
}

internal static byte GetFrameValues(byte frameByte)
{
return (byte)(frameByte & 0b0000_1111);
}

/// <summary>
/// Returns the MIDI bend value from two bytes in message.
/// </summary>
Expand Down
9 changes: 7 additions & 2 deletions src/Uno.UWP/Devices/Midi/Internal/MidiMessageParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ namespace Uno.Devices.Midi.Internal
{
internal enum MidiMessageParameter
{
Frame = 7,
FrameValues = 15,
Channel = 15,
Velocity = 127,
Pressure = 127,
Note = 127,
Controller = 127,
Control = 127,
Bend = 16383
ControlValue = 127,
Program = 127,
Song = 127,
Bend = 16383,
Beats = 16383,
}
}
11 changes: 7 additions & 4 deletions src/Uno.UWP/Devices/Midi/MidiChannelPressureMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ public partial class MidiChannelPressureMessage : IMidiMessage
/// <param name="channel">The channel from 0-15 that this message applies to.</param>
/// <param name="pressure">The pressure from 0-127.</param>
public MidiChannelPressureMessage(byte channel, byte pressure)
: this(new byte[]
{
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(pressure, MidiMessageParameter.Pressure);

_buffer = new InMemoryBuffer(new byte[]
{
(byte)((byte)MidiMessageType.ChannelPressure | channel),
(byte)((byte)Type | channel),
pressure
})
{
});
}

internal MidiChannelPressureMessage(byte[] rawData)
Expand Down
12 changes: 8 additions & 4 deletions src/Uno.UWP/Devices/Midi/MidiControlChangeMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ public partial class MidiControlChangeMessage : IMidiMessage
/// <param name="controller">The controller from 0-127 to receive this message.</param>
/// <param name="controlValue">The value from 0-127 to apply to the controller.</param>
public MidiControlChangeMessage(byte channel, byte controller, byte controlValue)
: this(new byte[]
{
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(controller, MidiMessageParameter.Controller);
MidiMessageValidators.VerifyRange(controlValue, MidiMessageParameter.ControlValue);

_buffer = new InMemoryBuffer(new byte[]
{
(byte)((byte)MidiMessageType.ControlChange | channel),
controller,
controlValue
})
{
});
}

internal MidiControlChangeMessage(byte[] rawData)
Expand All @@ -33,7 +37,7 @@ internal MidiControlChangeMessage(byte[] rawData)
MidiMessageValidators.VerifyMessageType(rawData[0], MidiMessageType.ControlChange);
MidiMessageValidators.VerifyRange(MidiHelpers.GetChannel(rawData[0]), MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(rawData[1], MidiMessageParameter.Controller);
MidiMessageValidators.VerifyRange(rawData[2], MidiMessageParameter.Control);
MidiMessageValidators.VerifyRange(rawData[2], MidiMessageParameter.ControlValue);

_buffer = new InMemoryBuffer(rawData);
}
Expand Down
12 changes: 8 additions & 4 deletions src/Uno.UWP/Devices/Midi/MidiNoteOffMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ public partial class MidiNoteOffMessage : IMidiMessage
/// <param name="note">The note which is specified as a value from 0-127.</param>
/// <param name="velocity">The velocity which is specified as a value from 0-127.</param>
public MidiNoteOffMessage(byte channel, byte note, byte velocity)
: this(new byte[] {
(byte)((byte)MidiMessageType.NoteOff| channel),
{
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(note, MidiMessageParameter.Note);
MidiMessageValidators.VerifyRange(velocity, MidiMessageParameter.Velocity);

_buffer = new InMemoryBuffer(new byte[] {
(byte)((byte)Type | channel),
note,
velocity
})
{
});
}

internal MidiNoteOffMessage(byte[] rawData)
Expand Down
19 changes: 11 additions & 8 deletions src/Uno.UWP/Devices/Midi/MidiNoteOnMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ public partial class MidiNoteOnMessage : IMidiMessage
/// <param name="channel">The channel from 0-15 that this message applies to.</param>
/// <param name="note">The note which is specified as a value from 0-127.</param>
/// <param name="velocity">The velocity which is specified as a value from 0-127.</param>
public MidiNoteOnMessage(byte channel, byte note, byte velocity)
: this(new byte[]
{
(byte)((byte)Type | Channel),
Note,
Velocity
})
{
public MidiNoteOnMessage(byte channel, byte note, byte velocity)
{
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(note, MidiMessageParameter.Note);
MidiMessageValidators.VerifyRange(velocity, MidiMessageParameter.Velocity);

_buffer = new InMemoryBuffer(new byte[] {
(byte)((byte)Type | channel),
note,
velocity
});
}

internal MidiNoteOnMessage(byte[] rawData)
Expand Down
11 changes: 7 additions & 4 deletions src/Uno.UWP/Devices/Midi/MidiPitchBendChangeMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ public partial class MidiPitchBendChangeMessage : IMidiMessage
/// <param name="channel">Channel.</param>
/// <param name="bend">Bend.</param>
public MidiPitchBendChangeMessage(byte channel, ushort bend)
: this(new byte[]
{
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(bend, MidiMessageParameter.Bend);

_buffer = new InMemoryBuffer(new byte[]
{
(byte)((byte)MidiMessageType.PitchBendChange | channel),
(byte)((byte)Type | channel),
(byte)(bend & 0b0111_1111),
(byte)(bend >> 7)
})
{
});
}

internal MidiPitchBendChangeMessage(byte[] rawData)
Expand Down
55 changes: 32 additions & 23 deletions src/Uno.UWP/Devices/Midi/MidiPolyphonicKeyPressureMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,59 +9,68 @@ namespace Windows.Devices.Midi
/// </summary>
public partial class MidiPolyphonicKeyPressureMessage : IMidiMessage
{
private readonly InMemoryBuffer _buffer;

/// <summary>
/// Creates a new MidiPolyphonicKeyPressureMessage object.
/// </summary>
/// <param name="channel">The channel from 0-15 that this message applies to.</param>
/// <param name="note">The note which is specified as a value from 0-127.</param>
/// <param name="pressure">The polyphonic key pressure which is specified as a value from 0-127.</param>
public MidiPolyphonicKeyPressureMessage(byte channel, byte note, byte pressure)
public MidiPolyphonicKeyPressureMessage(byte channel, byte note, byte pressure)
{
MidiMessageValidators.VerifyRange(channel, 15, nameof(channel));
MidiMessageValidators.VerifyRange(note, 127, nameof(note));
MidiMessageValidators.VerifyRange(pressure, 127, nameof(pressure));
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(note, MidiMessageParameter.Note);
MidiMessageValidators.VerifyRange(pressure, MidiMessageParameter.Pressure);

Channel = channel;
Note = note;
Pressure = pressure;
RawData = new InMemoryBuffer(new byte[]
_buffer = new InMemoryBuffer(new byte[]
{
(byte)((byte)Type | Channel),
Note,
Pressure
(byte)((byte)Type | channel),
note,
pressure
});
}

internal MidiPolyphonicKeyPressureMessage(byte[] rawData)
{
MidiMessageValidators.VerifyMessageLength(rawData, 3, Type);
MidiMessageValidators.VerifyMessageType(rawData[0], Type);
MidiMessageValidators.VerifyRange(MidiHelpers.GetChannel(rawData[0]), MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(rawData[1], MidiMessageParameter.Note);
MidiMessageValidators.VerifyRange(rawData[2], MidiMessageParameter.Pressure);

_buffer = new InMemoryBuffer(rawData);
}

/// <summary>
/// Gets the type of this MIDI message.
/// </summary>
public MidiMessageType Type => MidiMessageType.PolyphonicKeyPressure;

/// <summary>
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// Gets the channel from 0-15 that this message applies to.
/// </summary>
public IBuffer RawData { get; }
public byte Channel => MidiHelpers.GetChannel(_buffer.Data[0]);

/// <summary>
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// Gets the note which is specified as a value from 0-127.
/// </summary>
public TimeSpan Timestamp { get; }
public byte Note => _buffer.Data[1];

/// <summary>
/// Gets the channel from 0-15 that this message applies to.
/// Gets the polyphonic key pressure which is specified as a value from 0-127.
/// </summary>
public byte Channel { get; }
public byte Pressure => _buffer.Data[2];

/// <summary>
/// Gets the note which is specified as a value from 0-127.
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// </summary>
public byte Note { get; }
public IBuffer RawData => _buffer;

/// <summary>
/// Gets the polyphonic key pressure which is specified as a value from 0-127.
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// </summary>
public byte Pressure { get; }

public TimeSpan Timestamp { get; internal set; } = TimeSpan.Zero;
}
}
44 changes: 27 additions & 17 deletions src/Uno.UWP/Devices/Midi/MidiProgramChangeMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,59 @@ namespace Windows.Devices.Midi
/// </summary>
public partial class MidiProgramChangeMessage : IMidiMessage
{
private readonly InMemoryBuffer _buffer;

/// <summary>
/// Creates a new MidiProgramChangeMessage object.
/// </summary>
/// <param name="channel">The channel from 0-15 that this message applies to.</param>
/// <param name="program">The program to change from 0-127.</param>
public MidiProgramChangeMessage(byte channel, byte program)
public MidiProgramChangeMessage(byte channel, byte program)
{
MidiMessageValidators.VerifyRange(channel, 15, nameof(channel));
MidiMessageValidators.VerifyRange(program, 127, nameof(program));
MidiMessageValidators.VerifyRange(channel, MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(program, MidiMessageParameter.Program);

Channel = channel;
Program = program;
RawData = new InMemoryBuffer(new byte[]
_buffer = new InMemoryBuffer(new byte[]
{
(byte)((byte)Type | Channel),
Program,
(byte)((byte)MidiMessageType.ProgramChange | channel),
program,
});
}

internal MidiProgramChangeMessage(byte[] rawData)
{
MidiMessageValidators.VerifyMessageLength(rawData, 2, Type);
MidiMessageValidators.VerifyMessageType(rawData[0], Type);
MidiMessageValidators.VerifyRange(MidiHelpers.GetChannel(rawData[0]), MidiMessageParameter.Channel);
MidiMessageValidators.VerifyRange(rawData[1], MidiMessageParameter.Program);

_buffer = new InMemoryBuffer(rawData);
}

/// <summary>
/// Gets the type of this MIDI message.
/// </summary>
public MidiMessageType Type => MidiMessageType.ProgramChange;

/// <summary>
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// Gets the channel from 0-15 that this message applies to.
/// </summary>
public IBuffer RawData { get; }
public byte Channel => MidiHelpers.GetChannel(_buffer.Data[0]);

/// <summary>
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// Gets the program to change from 0-127.
/// </summary>
public TimeSpan Timestamp { get; }
public byte Program => _buffer.Data[1];

/// <summary>
/// Gets the channel from 0-15 that this message applies to.
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// </summary>
public byte Channel { get; }
public IBuffer RawData => _buffer;

/// <summary>
/// Gets the program to change from 0-127.
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// </summary>
public byte Program { get; }
public TimeSpan Timestamp { get; internal set; } = TimeSpan.Zero;
}
}
32 changes: 21 additions & 11 deletions src/Uno.UWP/Devices/Midi/MidiSongPositionPointerMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,52 @@ namespace Windows.Devices.Midi
/// </summary>
public partial class MidiSongPositionPointerMessage : IMidiMessage
{
private readonly InMemoryBuffer _buffer;

/// <summary>
/// Creates a new MidiSongPositionPointerMessage object.
/// </summary>
/// <param name="beats">The song position pointer encoded in a 14-bit value from 0-16383.</param>
public MidiSongPositionPointerMessage(ushort beats)
{
MidiMessageValidators.VerifyRange(beats, 16383, nameof(beats));
MidiMessageValidators.VerifyRange(beats, MidiMessageParameter.Beats);

Beats = beats;
RawData = new InMemoryBuffer(new byte[]
_buffer = new InMemoryBuffer(new byte[]
{
(byte)Type,
(byte)MidiMessageType.SongPositionPointer,
(byte)(beats & 0b0111_1111),
(byte)(beats >> 7)
});
}

internal MidiSongPositionPointerMessage(byte[] rawData)
{
MidiMessageValidators.VerifyMessageLength(rawData, 3, Type);
MidiMessageValidators.VerifyMessageType(rawData[0], Type);
MidiMessageValidators.VerifyRange(MidiHelpers.GetBeats(rawData[1], rawData[2]), MidiMessageParameter.Beats);

_buffer = new InMemoryBuffer(rawData);
}

/// <summary>
/// Gets the type of this MIDI message.
/// </summary>
public MidiMessageType Type => MidiMessageType.SongPositionPointer;

/// <summary>
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// Gets the song position pointer encoded in a 14-bit value from 0-16383.
/// </summary>
public IBuffer RawData { get; }
public ushort Beats => MidiHelpers.GetBeats(_buffer.Data[1], _buffer.Data[2]);

/// <summary>
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// Gets the array of bytes associated with the MIDI message, including status byte.
/// </summary>
public TimeSpan Timestamp { get; } = TimeSpan.Zero;
public IBuffer RawData => _buffer;

/// <summary>
/// Gets the song position pointer encoded in a 14-bit value from 0-16383.
/// Gets the duration from when the MidiInPort was created to the time the message was received.
/// For messages being sent to a MidiOutPort, this value has no meaning.
/// </summary>
public ushort Beats { get; }
public TimeSpan Timestamp { get; internal set; } = TimeSpan.Zero;
}
}
Loading

0 comments on commit e2556f8

Please sign in to comment.