finish parsing voice messages
This commit is contained in:
parent
36fafbf144
commit
2c6dbbf952
3 changed files with 33 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
|||
use std::{
|
||||
fs::File,
|
||||
io::{stdin, Read, Write},
|
||||
io::{stdin, Write},
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
|
@ -65,9 +65,9 @@ fn handle_midi_event(timestamp: u64, message: &[u8], file: &mut Option<File>) {
|
|||
let ts_buf = timestamp.to_be_bytes();
|
||||
let len_buf = message.len().to_be_bytes();
|
||||
|
||||
file.write(&ts_buf).unwrap();
|
||||
file.write(&len_buf).unwrap();
|
||||
file.write(message).unwrap();
|
||||
file.write_all(&ts_buf).unwrap();
|
||||
file.write_all(&len_buf).unwrap();
|
||||
file.write_all(message).unwrap();
|
||||
}
|
||||
|
||||
let hex_msg = hex::encode(message);
|
||||
|
|
|
@ -20,10 +20,10 @@ impl VoiceMessage {
|
|||
pub enum VoiceCategory {
|
||||
NoteOff { note: u8, velocity: u8 },
|
||||
NoteOn { note: u8, velocity: u8 },
|
||||
AfterTouch,
|
||||
AfterTouch { note: u8, pressure: u8 },
|
||||
ControlChange { controller: u8, value: u8 },
|
||||
ProgramChange { value: u8 },
|
||||
ChannelPressure,
|
||||
ChannelPressure { pressure: u8 },
|
||||
PitchWheel { value: u16 },
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ pub fn parse_message(bytes: &[u8]) -> IResult<&[u8], Message> {
|
|||
}
|
||||
|
||||
fn parse_status_message(_status_byte: u8, bytes: &[u8]) -> IResult<&[u8], SystemMessage> {
|
||||
return Err(nom::Err::Error(nom::error::Error {
|
||||
Err(nom::Err::Error(nom::error::Error {
|
||||
input: bytes,
|
||||
code: nom::error::ErrorKind::Fail,
|
||||
}));
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn parse_voice_message(status_byte: u8, remainder: &[u8]) -> IResult<&[u8], VoiceMessage> {
|
||||
|
@ -30,8 +30,10 @@ pub fn parse_voice_message(status_byte: u8, remainder: &[u8]) -> IResult<&[u8],
|
|||
let (remainder, category) = match category_nibble {
|
||||
0x80 => parse_voice_note(remainder, true)?,
|
||||
0x90 => parse_voice_note(remainder, false)?,
|
||||
0xa0 => parse_aftertouch(remainder)?,
|
||||
0xb0 => parse_control_change(remainder)?,
|
||||
0xc0 => parse_program_change(remainder)?,
|
||||
0xd0 => parse_channel_pressure(remainder)?,
|
||||
0xe0 => parse_pitch_wheel(remainder)?,
|
||||
_ => {
|
||||
return Err(nom::Err::Error(nom::error::Error {
|
||||
|
@ -92,7 +94,7 @@ pub fn parse_control_change(bytes: &[u8]) -> IResult<&[u8], VoiceCategory> {
|
|||
}
|
||||
|
||||
pub fn parse_program_change(bytes: &[u8]) -> IResult<&[u8], VoiceCategory> {
|
||||
if bytes.len() < 1 {
|
||||
if bytes.is_empty() {
|
||||
return Err(generic_error(bytes));
|
||||
}
|
||||
|
||||
|
@ -100,6 +102,28 @@ pub fn parse_program_change(bytes: &[u8]) -> IResult<&[u8], VoiceCategory> {
|
|||
|
||||
Ok((&bytes[1..], VoiceCategory::ProgramChange { value }))
|
||||
}
|
||||
|
||||
pub fn parse_aftertouch(bytes: &[u8]) -> IResult<&[u8], VoiceCategory> {
|
||||
if bytes.len() < 2 {
|
||||
return Err(generic_error(bytes));
|
||||
}
|
||||
|
||||
let note = bytes[0];
|
||||
let pressure = bytes[1];
|
||||
|
||||
Ok((&bytes[2..], VoiceCategory::AfterTouch { note, pressure }))
|
||||
}
|
||||
|
||||
pub fn parse_channel_pressure(bytes: &[u8]) -> IResult<&[u8], VoiceCategory> {
|
||||
if bytes.is_empty() {
|
||||
return Err(generic_error(bytes));
|
||||
}
|
||||
|
||||
let pressure = bytes[0];
|
||||
|
||||
Ok((&bytes[1..], VoiceCategory::ChannelPressure { pressure }))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{log::load_raw_log, midi::VoiceMessage};
|
||||
|
|
Loading…
Reference in a new issue