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}