midia/
lib.rs

1mod event;
2mod header;
3pub mod pitch;
4pub mod track;
5pub mod typ;
6mod util;
7
8use std::{fmt::Display, fs::File, io::Write};
9
10use typ::TrackType;
11
12use crate::{header::MidiHeader, track::MidiTrack};
13
14pub struct MidiWriter {
15    data: MidiData,
16}
17
18impl MidiWriter {
19    pub fn new(typ: TrackType, track_number: u16, bpm: u16) -> Self {
20        let mut data = MidiData::new();
21        let header = MidiHeader::new(typ, track_number, bpm);
22        data.push_data(header);
23        Self { data }
24    }
25
26    pub fn add_track(&mut self, track: MidiTrack) -> &mut Self {
27        self.data.push_data(track);
28        self
29    }
30
31    pub fn write(&self, path: &str) {
32        let mut file = File::create(path).unwrap();
33        file.write_all(&self.data.0).unwrap();
34    }
35}
36
37impl Display for MidiData {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        let data_str = self
40            .0
41            .iter()
42            .map(|byte| format!("{:02x}", byte))
43            .collect::<Vec<_>>();
44        let str = data_str.join(" ");
45        write!(f, "{}", str)
46    }
47}
48
49#[derive(Default)]
50pub struct MidiData(Vec<u8>);
51
52impl MidiData {
53    pub fn new() -> Self {
54        Self(vec![])
55    }
56
57    pub fn push_str(&mut self, s: &str) {
58        self.0.append(&mut s.as_bytes().to_vec());
59    }
60
61    pub fn push_byte(&mut self, byte: u8) {
62        self.0.push(byte);
63    }
64
65    pub fn push_word(&mut self, word: u16) {
66        self.0.append(&mut word.to_be_bytes().to_vec());
67    }
68
69    pub fn push_dword(&mut self, dword: u32) {
70        self.0.append(&mut dword.to_be_bytes().to_vec());
71    }
72
73    pub fn push_bytes(&mut self, mut bytes: Vec<u8>) {
74        self.0.append(&mut bytes);
75    }
76
77    pub fn push_data(&mut self, data: impl IntoMidiData) {
78        self.0.append(&mut data.into_midi_data().0);
79    }
80}
81
82pub trait IntoMidiData {
83    fn into_midi_data(self) -> MidiData;
84}