diff options
Diffstat (limited to 'src/midifile.rs')
-rw-r--r-- | src/midifile.rs | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/midifile.rs b/src/midifile.rs index 71a861c..219a931 100644 --- a/src/midifile.rs +++ b/src/midifile.rs @@ -10,6 +10,7 @@ pub struct RawMidiEvent data: Vec<u8> } +#[derive(Clone)] pub enum MidiEvent { NoteOn{ch: u8, key: u8, vel: u8}, @@ -26,6 +27,7 @@ pub enum MidiEvent MetaEndOfTrack } +#[derive(Clone)] pub struct TimedMidiEvent { pub t: u32, @@ -39,7 +41,7 @@ impl From<&MidiEvent> for RawMidiEvent match e { MidiEvent::NoteOff{ch, key, vel} - if *vel == 0x40 => RawMidiEvent{ty: 0x90 | ch, p1: *key, p2: 0, data:vec![]}, + if *vel == 0x40 => RawMidiEvent{ty: 0x90 | ch, p1: *key, p2: 0, data: vec![]}, MidiEvent::NoteOff{ch, key, vel} => RawMidiEvent{ty: 0x80 | ch, p1: *key, p2: *vel, data: vec![]}, MidiEvent::NoteOn {ch, key, vel} => RawMidiEvent{ty: 0x90 | ch, p1: *key, p2: *vel, data: vec![]}, MidiEvent::KeyAfterTouch{ch, key, val} => RawMidiEvent{ty: 0xa0 | ch, p1: *key, p2: *val, data: vec![]}, @@ -64,12 +66,12 @@ impl From<&MidiEvent> for RawMidiEvent RawMidiEvent{ty: 0xff, p1: 0x03, p2: s.len() as u8, data: Vec::from(sb)} } MidiEvent::MetaEndOfTrack => - RawMidiEvent{ty: 0xff, p1: 0x2f, p2: 0xff, data: vec![]} + RawMidiEvent{ty: 0xff, p1: 0x2f, p2: 0, data: vec![]} } } } -type MidiTrack = Vec<TimedMidiEvent>; +pub type MidiTrack = Vec<TimedMidiEvent>; pub struct MidiFile { @@ -77,19 +79,19 @@ pub struct MidiFile pub tracks: Vec<MidiTrack> } -fn write_u16be(f: &mut File, v: u16) -> io::Result<()> +fn write_u16be<W>(f: &mut W, v: u16) -> io::Result<()> where W: Write { let bytes = v.to_be_bytes(); f.write_all(&bytes) } -fn write_u32be(f: &mut File, v: u32) -> io::Result<()> +fn write_u32be<W>(f: &mut W, v: u32) -> io::Result<()> where W: Write { let bytes = v.to_be_bytes(); f.write_all(&bytes) } -fn write_varlen(f: &mut File, v: u32) -> io::Result<()> +fn write_varlen<W>(f: &mut W, v: u32) -> io::Result<()> where W: Write { if v > 0x0fffffff { return Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid variable length value")); } @@ -103,7 +105,7 @@ fn write_varlen(f: &mut File, v: u32) -> io::Result<()> f.write_all(&buf[..]) } -fn write_raw_event(f: &mut File, re: &RawMidiEvent) -> io::Result<()> +fn write_raw_event<W>(f: &mut W, re: &RawMidiEvent) -> io::Result<()> where W: Write { let mut buf: Vec<u8> = Vec::new(); buf.push(re.ty); @@ -113,23 +115,26 @@ fn write_raw_event(f: &mut File, re: &RawMidiEvent) -> io::Result<()> f.write_all(&buf[..]) } -fn write_track(f: &mut File, trk: &MidiTrack) -> io::Result<()> +fn write_track<W>(f: &mut W, trk: &MidiTrack) -> io::Result<()> where W: Write { let header = "MTrk".as_bytes(); f.write_all(header)?; + let mut buf: Vec<u8> = Vec::new(); let mut curt = 0u32; for te in trk { let TimedMidiEvent{t, e} = te; - write_varlen(f, t - curt)?; + write_varlen(&mut buf, t - curt)?; curt = *t; let re = RawMidiEvent::from(e); - write_raw_event(f, &re)?; + write_raw_event(&mut buf, &re)?; } + write_u32be(f, buf.len() as u32)?; + f.write_all(&buf[..])?; Ok(()) } -fn write_file(filename: &str, mf: &MidiFile) -> io::Result<()> +pub fn write_file(filename: &str, mf: &MidiFile) -> io::Result<()> { let mut f = File::create(filename)?; let header = "MThd".as_bytes(); |