mirror of
https://github.com/italicsjenga/usbd-midi.git
synced 2024-12-23 12:21:30 +11:00
Implement receive for missing event types and added ControlChange
This commit is contained in:
parent
dea3594e37
commit
9db505d659
|
@ -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,7 +21,8 @@ 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;
|
||||
|
@ -29,6 +31,7 @@ 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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue