Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "rimd"
description = "Library for handling Midi and reading and writing Standard Midi Files in Rust"
version = "0.0.3"
authors = ["Nick Lanham <nick@afternight.org>"]
authors = ["Nick Lanham <nick@afternight.org>", "Alex Kesling <alex@kesling.co>"]
homepage = "https://github.com/RustAudio/rimd"
repository = "https://github.com/RustAudio/rimd"
documentation = "https://nicklan.github.io/rimd/target/doc/rimd/index.html"
Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2015 Nick Lanham
Copyright (c) 2020 Alex Kesling

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
28 changes: 9 additions & 19 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ pub struct AbsoluteEvent {
impl AbsoluteEvent {
pub fn new_midi(time: u64, midi: MidiMessage) -> AbsoluteEvent {
AbsoluteEvent {
time: time,
time,
event: Event::Midi(midi),
}
}
pub fn new_meta(time: u64, meta: MetaEvent) -> AbsoluteEvent {
AbsoluteEvent {
time: time,
time,
event: Event::Meta(meta),
}
}
Expand Down Expand Up @@ -74,10 +74,6 @@ impl PartialEq for AbsoluteEvent {
false
}
}

fn ne(&self, other: &AbsoluteEvent) -> bool {
!(self.eq(other))
}
}

// Implement `Ord` and sort messages by time
Expand All @@ -101,15 +97,9 @@ impl Ord for AbsoluteEvent {
(&Event::Midi(ref me),&Event::Midi(ref you)) => {
if me.data(0) < you.data(0) { Ordering::Less }
else if me.data(0) > you.data(0) { Ordering::Greater }
else {
if me.data(1) < you.data(1) {
Ordering::Less
} else if me.data(1) > you.data(1) {
Ordering::Greater
} else {
res
}
}
else if me.data(1) < you.data(1) { Ordering::Less }
else if me.data(1) > you.data(1) { Ordering::Greater }
else { res }
},
}
}
Expand Down Expand Up @@ -154,7 +144,7 @@ impl TrackBuilder {
};
prev_time = ev.time;
events.push(TrackEvent {
vtime: vtime,
vtime,
event: ev.event,
});
}
Expand Down Expand Up @@ -215,7 +205,7 @@ impl SMFBuilder {
let vtime = bev.time - cur_time;
cur_time = vtime;
TrackEvent {
vtime: vtime,
vtime,
event: bev.event.clone(),
}
}).collect();
Expand Down Expand Up @@ -270,7 +260,7 @@ impl SMFBuilder {
match self.tracks.index_mut(track).events {
EventContainer::Heap(ref mut heap) => {
heap.push(AbsoluteEvent {
time: time,
time,
event: Event::Midi(msg),
});
}
Expand Down Expand Up @@ -302,7 +292,7 @@ impl SMFBuilder {
match self.tracks.index_mut(track).events {
EventContainer::Heap(ref mut heap) => {
heap.push(AbsoluteEvent {
time: time,
time,
event: Event::Meta(event),
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ impl SMF {
division: self.division,
};
for events in &mut tracks {
if events.len() > 0 {
if !events.is_empty() {
let mut time = 0;
for event in events.iter_mut() {
let tmp = event.vtime;
Expand Down
18 changes: 9 additions & 9 deletions src/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ impl fmt::Display for MetaEvent {
MetaCommand::CuePoint => format!("CuePoint: {}", latin1_decode(&self.data)),
MetaCommand::MIDIChannelPrefixAssignment => format!("MIDI Channel Prefix Assignment, channel: {}", self.data[0]+1),
MetaCommand::MIDIPortPrefixAssignment => format!("MIDI Port Prefix Assignment, port: {}", self.data[0]),
MetaCommand::EndOfTrack => format!("End Of Track"),
MetaCommand::EndOfTrack => "End Of Track".to_string(),
MetaCommand::TempoSetting => format!("Set Tempo, microseconds/quarter note: {}", self.data_as_u64(3)),
MetaCommand::SMPTEOffset => format!("SMPTEOffset"),
MetaCommand::SMPTEOffset => "SMPTEOffset".to_string(),
MetaCommand::TimeSignature => format!("Time Signature: {}/{}, {} ticks/metronome click, {} 32nd notes/quarter note",
self.data[0],
2usize.pow(self.data[1] as u32),
Expand All @@ -132,7 +132,7 @@ impl fmt::Display for MetaEvent {
1 => "Minor",
_ => "Invalid Signature",
}),
MetaCommand::SequencerSpecificEvent => format!("SequencerSpecificEvent"),
MetaCommand::SequencerSpecificEvent => "SequencerSpecificEvent".to_string(),
MetaCommand::Unknown => format!("Unknown, length: {}", self.data.len()),
})
}
Expand All @@ -157,16 +157,16 @@ impl MetaEvent {
Some(c) => {c},
None => MetaCommand::Unknown,
};
let len = match SMFReader::read_vtime(reader) {
let length = match SMFReader::read_vtime(reader) {
Ok(t) => { t }
Err(_) => { return Err(MetaError::OtherErr("Couldn't read time for meta command")); }
};
let mut data = Vec::new();
read_amount(reader,&mut data,len as usize)?;
read_amount(reader,&mut data,length as usize)?;
Ok(MetaEvent{
command: command,
length: len,
data: data
command,
length,
data,
})
}

Expand Down Expand Up @@ -350,7 +350,7 @@ impl MetaEvent {
MetaEvent {
command: MetaCommand::SequencerSpecificEvent,
length: data.len() as u64,
data: data,
data,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/midi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ impl fmt::Display for MidiMessage {
else if self.data.len() == 3 {
write!(f, "{}: [{},{}]\tchannel: {:?}", self.status(), self.data[1], self.data[2], self.channel())
}
else if self.data.len() == 0 {
else if self.data.is_empty() {
write!(f, "{}: [no data]\tchannel: {:?}", self.status(), self.channel())
}
else {
Expand Down
46 changes: 21 additions & 25 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ impl SMFReader {
let tracks = (header[10] as u16) << 8 | header[11] as u16;
let division = (header[12] as i16) << 8 | header[13] as i16;

Ok(SMF { format: format,
tracks: Vec::with_capacity(tracks as usize),
division: division } )
Ok(SMF {
format,
tracks: Vec::with_capacity(tracks as usize),
division,
})
}

fn next_event(reader: &mut dyn Read, laststat: u8, was_running: &mut bool) -> Result<TrackEvent,SMFError> {
Expand Down Expand Up @@ -106,25 +108,22 @@ impl SMFReader {
let last = { // use status from last midi event, skip meta events
let mut last = 0u8;
for e in res.iter().rev() {
match e.event {
Event::Midi(ref m) => { last = m.data[0]; break; }
_ => ()
if let Event::Midi(ref m) = e.event {
last = m.data[0];
break;
}
}
last
};
let mut was_running = false;
match SMFReader::next_event(reader,last,&mut was_running) {
Ok(event) => {
match event.event {
Event::Meta(ref me) => {
match me.command {
MetaCommand::CopyrightNotice => copyright = Some(latin1_decode(&me.data)),
MetaCommand::SequenceOrTrackName => name = Some(latin1_decode(&me.data)),
_ => {}
}
},
_ => {}
if let Event::Meta(ref me) = event.event {
match me.command {
MetaCommand::CopyrightNotice => copyright = Some(latin1_decode(&me.data)),
MetaCommand::SequenceOrTrackName => name = Some(latin1_decode(&me.data)),
_ => {}
}
}
read_so_far += event.len();
if was_running {
Expand Down Expand Up @@ -156,9 +155,9 @@ impl SMFReader {
}
}
Ok(Track {
copyright: copyright,
name: name,
events: res
copyright,
name,
events: res,
})
}

Expand All @@ -179,21 +178,18 @@ impl SMFReader {
if (next & cont_mask) == 0 {
break;
}
res = res << 7;
res <<= 7;
}
Ok(res)
}

/// Read an entire SMF file
pub fn read_smf(reader: &mut dyn Read) -> Result<SMF,SMFError> {
let mut smf = SMFReader::parse_header(reader);
match smf {
Ok(ref mut s) => {
for _ in 0..s.tracks.capacity() {
s.tracks.push(SMFReader::parse_track(reader)?);
}
if let Ok(ref mut s) = smf {
for _ in 0..s.tracks.capacity() {
s.tracks.push(SMFReader::parse_track(reader)?);
}
_ => {}
}
smf
}
Expand Down
10 changes: 5 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
use std::iter;
use std::io::{Read,Error,ErrorKind};

static NSTRS: &'static str = "C C#D D#E F F#G G#A A#B ";
static NSTRS: &str = "C C#D D#E F F#G G#A A#B ";

/// convert a midi note number to a name
pub fn note_num_to_name(num: u32) -> String {
let oct = (num as f32 /12 as f32).floor()-1.0;
let oct = (num as f32 / 12_f32).floor()-1.0;
let nmt = ((num%12)*2) as usize;
let slice =
if NSTRS.as_bytes()[nmt+1] == ' ' as u8{
if NSTRS.as_bytes()[nmt+1] == b' ' {
&NSTRS[nmt..(nmt+1)]
} else {
&NSTRS[nmt..(nmt+2)]
Expand All @@ -21,7 +21,7 @@ pub fn note_num_to_name(num: u32) -> String {
/// Read a single byte from a Reader
pub fn read_byte(reader: &mut dyn Read) -> Result<u8,Error> {
let mut b = [0; 1];
reader.read(&mut b)?;
reader.read_exact(&mut b)?;
Ok(b[0])
}

Expand Down Expand Up @@ -74,7 +74,7 @@ pub fn latin1_decode(s: &[u8]) -> String {
Ok(s) => s,
Err(_) => match str::from_utf8(s) {
Ok(s) => s.to_string(),
Err(_) => format!("[invalid string data]"),
Err(_) => "[invalid string data]".to_string(),
}
}
}
Expand Down
25 changes: 11 additions & 14 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl SMFWriter {
pub fn new_with_division(ticks: i16) -> SMFWriter {
SMFWriter {
format: 1,
ticks: ticks,
ticks,
tracks: Vec::new(),
}
}
Expand All @@ -45,7 +45,7 @@ impl SMFWriter {
pub fn new_with_division_and_format(format: SMFFormat, ticks: i16) -> SMFWriter {
SMFWriter {
format: format as u16,
ticks: ticks,
ticks,
tracks: Vec::new(),
}
}
Expand Down Expand Up @@ -81,7 +81,7 @@ impl SMFWriter {
let val_mask = 0x7F as u64;
loop {
let mut to_write = (cur & val_mask) as u8;
cur = cur >> 7;
cur >>= 7;
if continuation {
// we're writing a continuation byte, so set the bit
to_write |= cont_mask;
Expand Down Expand Up @@ -114,12 +114,12 @@ impl SMFWriter {
}

fn write_event(&self, vec: &mut Vec<u8>, event: &Event, length: &mut u32, saw_eot: &mut bool) {
match event {
&Event::Midi(ref midi) => {
match *event {
Event::Midi(ref midi) => {
vec.extend(midi.data.iter());
*length += midi.data.len() as u32;
}
&Event::Meta(ref meta) => {
Event::Meta(ref meta) => {
vec.push(0xff); // indicate we're writing a meta event
vec.push(meta.command as u8);
// +2 on next line for the 0xff and the command byte we just wrote
Expand Down Expand Up @@ -147,7 +147,7 @@ impl SMFWriter {
let lbyte = (*length & 0xFF) as u8;
// 7-i because smf is big endian and we want to put this in bytes 4-7
vec[7-i] = lbyte;
*length = (*length)>>8;
*length >>= 8;
}
}

Expand All @@ -167,13 +167,10 @@ impl SMFWriter {
let mut cur_time: u64 = 0;
let mut saw_eot = false;

match name {
Some(n) => {
let namemeta = Event::Meta(MetaEvent::sequence_or_track_name(n));
length += SMFWriter::write_vtime(0,&mut vec).unwrap();
self.write_event(&mut vec, &namemeta, &mut length, &mut saw_eot);
}
None => {}
if let Some(n) = name {
let namemeta = Event::Meta(MetaEvent::sequence_or_track_name(n));
length += SMFWriter::write_vtime(0,&mut vec).unwrap();
self.write_event(&mut vec, &namemeta, &mut length, &mut saw_eot);
}

for ev in track {
Expand Down