Skip to content

Commit

Permalink
Applied some clippy suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcebox committed May 25, 2024
1 parent 71bcc5a commit bbae45b
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 158 deletions.
141 changes: 0 additions & 141 deletions src/data/midi/message/message.rs

This file was deleted.

146 changes: 143 additions & 3 deletions src/data/midi/message/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,144 @@
pub mod message;
pub mod raw;
pub use crate::data::midi::message::message::Message;
pub mod control_function;
pub mod raw;

use crate::data::byte::from_traits::FromClamped;
use crate::data::byte::u7::U7;
use crate::data::midi::channel::Channel;
use crate::data::midi::message::control_function::ControlFunction;
use crate::data::midi::message::raw::{Payload, Raw};
use crate::data::midi::notes::Note;
use crate::data::usb_midi::usb_midi_event_packet::MidiPacketParsingError;
use core::convert::TryFrom;

type Velocity = U7;

/// Represents midi messages
/// Note: not current exhaustive and SysEx messages end up
/// being a confusing case. So are currently note implemented
/// they are sort-of unbounded
#[derive(Debug, Eq, PartialEq)]
pub enum Message {
NoteOff(Channel, Note, Velocity),
NoteOn(Channel, Note, Velocity),
PolyphonicAftertouch(Channel, Note, U7),
ProgramChange(Channel, U7),
ChannelAftertouch(Channel, U7),
PitchWheelChange(Channel, U7, U7),
ControlChange(Channel, ControlFunction, 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 CONTROL_CHANGE_MASK: u8 = 0b1011_0000;

impl From<Message> for Raw {
fn from(value: Message) -> Raw {
match value {
Message::NoteOn(chan, note, vel) => {
let payload = Payload::DoubleByte(note.into(), vel);
let status = NOTE_ON_MASK | u8::from(chan);
Raw { status, payload }
}
Message::NoteOff(chan, note, vel) => {
let payload = Payload::DoubleByte(note.into(), vel);
let status = NOTE_OFF_MASK | u8::from(chan);
Raw { status, payload }
}
Message::PolyphonicAftertouch(chan, note, pressure) => {
let payload = Payload::DoubleByte(note.into(), pressure);
let status = POLYPHONIC_MASK | u8::from(chan);
Raw { status, payload }
}
Message::ProgramChange(chan, program) => {
let payload = Payload::SingleByte(program);
let status = PROGRAM_MASK | u8::from(chan);
Raw { status, payload }
}
Message::ChannelAftertouch(chan, pressure) => {
let payload = Payload::SingleByte(pressure);
let status = CHANNEL_AFTERTOUCH_MASK | u8::from(chan);
Raw { status, payload }
}
Message::PitchWheelChange(chan, lsb, msb) => {
let payload = Payload::DoubleByte(lsb, msb);
let status = PITCH_BEND_MASK | u8::from(chan);
Raw { status, payload }
}
Message::ControlChange(chan, control_function, value) => {
let payload = Payload::DoubleByte(control_function.0, value);
let status = CONTROL_CHANGE_MASK | u8::from(chan);
Raw { status, payload }
}
}
}
}

impl<'a> TryFrom<&'a [u8]> for Message {
type Error = MidiPacketParsingError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
let status_byte = match data.first() {
Some(byte) => byte,
None => return Err(MidiPacketParsingError::MissingDataPacket),
};

let event_type = status_byte & 0b1111_0000;
let channel_bytes = (status_byte) & 0b0000_1111;

let channel = Channel::try_from(channel_bytes).ok().unwrap();

match event_type {
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,
ControlFunction(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 = get_byte_at_position(data, 1)?;
match Note::try_from(note_byte) {
Ok(note) => Ok(note),
Err(_) => Err(MidiPacketParsingError::InvalidNote(note_byte)),
}
}

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),
}
}
6 changes: 3 additions & 3 deletions src/data/midi/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ pub enum Note {
Gs9,
}

impl Into<u8> for Note {
fn into(self) -> u8 {
self as u8
impl From<Note> for u8 {
fn from(val: Note) -> Self {
val as u8
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/data/usb_midi/midi_packet_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ impl<'a> Iterator for MidiPacketBufferReader<'a> {

fn next(&mut self) -> Option<Self::Item> {
if self.position <= MAX_PACKET_SIZE && self.position < self.raw_bytes_received {
let packet = match self
let packet = self
.buffer
.get(self.position..(self.position + MIDI_PACKET_SIZE))
{
Some(packet) => Some(UsbMidiEventPacket::try_from(packet)),
None => None,
};
.map(UsbMidiEventPacket::try_from);

self.position += MIDI_PACKET_SIZE;
return packet;
Expand Down
4 changes: 2 additions & 2 deletions src/data/usb_midi/usb_midi_event_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ impl TryFrom<&[u8]> for UsbMidiEventPacket {
type Error = MidiPacketParsingError;

fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let raw_cable_number = match value.get(0) {
let raw_cable_number = match value.first() {
Some(byte) => *byte >> 4,
None => return Err(MidiPacketParsingError::MissingDataPacket),
};

let cable_number = match CableNumber::try_from(u8::from(raw_cable_number)) {
let cable_number = match CableNumber::try_from(raw_cable_number) {
Ok(val) => val,
_ => return Err(MidiPacketParsingError::InvalidCableNumber(raw_cable_number)),
};
Expand Down
8 changes: 4 additions & 4 deletions src/midi_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,23 @@ impl<B: UsbBus> MidiClass<'_, B> {
/// calculates the index'th external midi in jack id
fn in_jack_id_ext(&self, index: u8) -> u8 {
debug_assert!(index < self.n_in_jacks);
return 2 * index + 1;
2 * index + 1
}
/// calculates the index'th embedded midi out jack id
fn out_jack_id_emb(&self, index: u8) -> u8 {
debug_assert!(index < self.n_in_jacks);
return 2 * index + 2;
2 * index + 2
}

/// calculates the index'th external midi out jack id
fn out_jack_id_ext(&self, index: u8) -> u8 {
debug_assert!(index < self.n_out_jacks);
return 2 * self.n_in_jacks + 2 * index + 1;
2 * self.n_in_jacks + 2 * index + 1
}
/// calculates the index'th embedded midi in jack id
fn in_jack_id_emb(&self, index: u8) -> u8 {
debug_assert!(index < self.n_out_jacks);
return 2 * self.n_in_jacks + 2 * index + 2;
2 * self.n_in_jacks + 2 * index + 2
}
}

Expand Down

0 comments on commit bbae45b

Please sign in to comment.