From 3c8256faf77840ca0e7a6228886921141f38d7f6 Mon Sep 17 00:00:00 2001 From: D4VID Date: Fri, 20 Jun 2025 14:52:16 +0200 Subject: [PATCH] Convert midi to words --- .gitignore | 1 + Cargo.lock | 70 +++++++++++++++++++++++++++++++++ Cargo.toml | 7 ++++ media/TOUHOU - Bad Apple!!.mid | Bin 0 -> 19867 bytes src/main.rs | 60 ++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 media/TOUHOU - Bad Apple!!.mid create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..44f693f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,70 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bad-apple" +version = "0.1.0" +dependencies = [ + "midly", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "midly" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207d755f4cb882d20c4da58d707ca9130a0c9bc5061f657a4f299b8e36362b7a" +dependencies = [ + "rayon", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..70283b8 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "bad-apple" +version = "0.1.0" +edition = "2021" + +[dependencies] +midly = "0.5.3" diff --git a/media/TOUHOU - Bad Apple!!.mid b/media/TOUHOU - Bad Apple!!.mid new file mode 100644 index 0000000000000000000000000000000000000000..6c8ddc98411d6d98bed0575ab30a0afd7189c5d7 GIT binary patch literal 19867 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 YctL!E_7v?Mw0F_oLwg_XgX~@Z0@8ucJ^%m! literal 0 HcmV?d00001 diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..285a7db --- /dev/null +++ b/src/main.rs @@ -0,0 +1,60 @@ +use std::fs; + +use midly::Smf; + +const FILENAME: &str = "media/TOUHOU - Bad Apple!!.mid"; + +fn get_u32(bits: &[bool; 32]) -> u32 { + let mut result = 0u32; + for (i, &bit) in bits.iter().enumerate() { + if bit { + result |= 1 << (31 - i); + } + } + return result; +} + +fn main() { + let bytes = fs::read(FILENAME).expect("Failed to read input file!"); + let smf = Smf::parse(&bytes).unwrap(); + + let mut current_on = [false; 32]; + + let track = &smf.tracks[0]; + print!("const DATA: &[u32] = &["); + for (_, event) in track.iter().enumerate() { + // println!("{}", event.delta); + let mut delta = event.delta.as_int(); + while delta >= 96 { + delta -= 96; + let word = get_u32(¤t_on); + print!("0x{:x},", word); + } + match event.kind { + midly::TrackEventKind::Midi { channel: _, message } => match message { + midly::MidiMessage::NoteOff { key, vel: _ } => { + let index = key.as_int() as isize - 59; + if index >= 0 && index < 32 { + current_on[index as usize] = false; + } + } + midly::MidiMessage::NoteOn { key, vel: _ } => { + let index = key.as_int() as isize - 59; + if index >= 0 && index < 32 { + current_on[index as usize] = true; + } + } + _ => { + // println!("event {}: {:?}", i, message); + } + }, + _ => { + // println!("event {}: {:?}", i, event); + } + } + } + println!("];"); + // for (i, track) in smf.tracks.iter().enumerate() { + // println!("track {} has {} events", i, track.len()); + // } +}