Implement receive for missing event types and added ControlChange

This commit is contained in:
Patric Kanngießer 2020-12-26 16:16:32 +01:00
parent dea3594e37
commit 9db505d659
2 changed files with 36 additions and 15 deletions

View file

@ -8,6 +8,7 @@ use core::convert::TryFrom;
use crate::data::usb_midi::usb_midi_event_packet::MidiPacketParsingError;
type Velocity = U7;
type ControllerNumber = U7;
/// Represents midi messages
/// Note: not current exhaustive and SysEx messages end up
@ -20,15 +21,17 @@ pub enum Message {
PolyphonicAftertouch(Channel,Note,U7),
ProgramChange(Channel,U7),
ChannelAftertouch(Channel,U7),
PitchWheelChange(Channel,U7,U7)
PitchWheelChange(Channel,U7,U7),
ControlChange(Channel, ControllerNumber, U7)
}
const NOTE_OFF_MASK :u8 = 0b1000_0000;
const NOTE_ON_MASK :u8 = 0b1001_0000;
const POLYPHONIC_MASK :u8 = 0b1010_0000;
const PROGRAM_MASK :u8 = 0b1100_0000;
const CHANNEL_AFTERTOUCH_MASK :u8 = 0b1101_0000;
const PITCH_BEND_MASK :u8 = 0b1110_0000;
const NOTE_OFF_MASK :u8 = 0b1000_0000;
const NOTE_ON_MASK :u8 = 0b1001_0000;
const POLYPHONIC_MASK :u8 = 0b1010_0000;
const PROGRAM_MASK :u8 = 0b1100_0000;
const CHANNEL_AFTERTOUCH_MASK :u8 = 0b1101_0000;
const PITCH_BEND_MASK :u8 = 0b1110_0000;
const CONTROL_CHANGE_MASK :u8 = 0b1011_0000;
impl From<Message> for Raw {
fn from(value:Message) -> Raw {
@ -62,8 +65,12 @@ impl From<Message> for Raw {
let payload = Payload::DoubleByte(lsb,msb);
let status = PITCH_BEND_MASK | u8::from(chan);
Raw {status , payload}
},
Message::ControlChange(chan, controller_number, value) => {
let payload = Payload::DoubleByte(controller_number, value);
let status = CONTROL_CHANGE_MASK | u8::from(chan);
Raw {status, payload}
}
}
}
}
@ -78,21 +85,34 @@ impl<'a> TryFrom<&'a [u8]> for Message {
let channel = Channel::try_from(channel_bytes).ok().unwrap();
match event_type {
NOTE_OFF_MASK => Ok(Message::NoteOff(channel, get_note(data)?, get_velocity(data))),
NOTE_ON_MASK => Ok(Message::NoteOn(channel, get_note(data)?, get_velocity(data))),
NOTE_ON_MASK => Ok(Message::NoteOn(channel, get_note(data)?, get_u7_at(data, 2)?)),
NOTE_OFF_MASK => Ok(Message::NoteOff(channel, get_note(data)?, get_u7_at(data, 2)?)),
POLYPHONIC_MASK => Ok(Message::PolyphonicAftertouch(channel, get_note(data)?, get_u7_at(data, 2)?)),
PROGRAM_MASK => Ok(Message::ProgramChange(channel, get_u7_at(data, 1)?)),
CHANNEL_AFTERTOUCH_MASK => Ok(Message::ChannelAftertouch(channel, get_u7_at(data, 1)?)),
PITCH_BEND_MASK => Ok(Message::PitchWheelChange(channel, get_u7_at(data, 1)?, get_u7_at(data, 2)?)),
CONTROL_CHANGE_MASK => Ok(Message::ControlChange(channel, get_u7_at(data, 1)?, get_u7_at(data, 2)?)),
_ => Err(MidiPacketParsingError::InvalidEventType(event_type))
}
}
}
fn get_note(data: &[u8]) -> Result<Note, MidiPacketParsingError> {
let note_byte = data[1];
let note_byte = get_byte_at_position(data, 1)?;
match Note::try_from(note_byte) {
Ok(note) => Ok(note),
Err(_) => Err(MidiPacketParsingError::InvalidNote(note_byte))
}
}
fn get_velocity(data: &[u8]) -> U7 {
U7::from_clamped(data[2])
fn get_u7_at(data: &[u8], index: usize) -> Result<U7, MidiPacketParsingError> {
let data_byte = get_byte_at_position(data, index)?;
Ok(U7::from_clamped(data_byte))
}
fn get_byte_at_position(data: &[u8], index: usize) -> Result<u8, MidiPacketParsingError> {
match data.get(index) {
Some(byte) => Ok(*byte),
None => Err(MidiPacketParsingError::MissingDataPacket)
}
}

View file

@ -71,7 +71,8 @@ impl CodeIndexNumber {
Message::ChannelAftertouch(_,_) => CodeIndexNumber::CHANNEL_PRESSURE,
Message::PitchWheelChange(_,_,_) => CodeIndexNumber::PITCHBEND_CHANGE,
Message::PolyphonicAftertouch(_,_,_) => CodeIndexNumber::POLY_KEYPRESS,
Message::ProgramChange(_,_) => CodeIndexNumber::PROGRAM_CHANGE
Message::ProgramChange(_,_) => CodeIndexNumber::PROGRAM_CHANGE,
Message::ControlChange(_,_,_) => CodeIndexNumber::CONTROL_CHANGE
}
}
}