This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1use super::sync::SyncData; 2use serde::{Deserialize, Serialize}; 3use std::{ 4 collections::HashMap, 5 fmt::Display, 6 fs::File, 7 io::{BufReader, Write}, 8 path::{Path, PathBuf}, 9}; 10 11#[derive(Debug, Deserialize, Serialize)] 12pub struct Stem { 13 pub amplitude_db: Vec<f32>, 14 /// max amplitude of this stem 15 pub amplitude_max: f32, 16 /// in milliseconds 17 pub duration_ms: usize, 18 19 #[serde(default)] 20 pub notes: HashMap<usize, Vec<Note>>, 21 22 #[serde(default)] 23 pub name: String, 24} 25 26impl Stem { 27 pub fn load_from_cbor(path: &str) -> Stem { 28 let file = File::open(path).unwrap(); 29 let reader = BufReader::new(file); 30 let stem: Stem = serde_cbor::from_reader(reader).unwrap(); 31 stem 32 } 33 34 pub fn save_to_cbor(&self, path: &str) { 35 let mut file = File::create(path).unwrap(); 36 let bytes = serde_cbor::to_vec(&self).unwrap(); 37 file.write_all(&bytes).unwrap(); 38 } 39 40 pub fn cbor_path(path: PathBuf, name: String) -> String { 41 format!( 42 "{}/{}.cbor", 43 path.parent().unwrap_or(Path::new("./")).to_string_lossy(), 44 name, 45 ) 46 } 47} 48 49#[derive(Debug, Deserialize, Serialize, Clone, Copy)] 50pub struct Note { 51 pub pitch: u8, 52 pub velocity: u8, 53 pub tick: u32, 54} 55 56impl Note { 57 pub fn symbol(&self) -> String { 58 let scale = vec![ 59 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "B", 60 ]; 61 let (octave, scale_index) = ( 62 self.pitch as usize / scale.len(), 63 self.pitch as usize % scale.len(), 64 ); 65 format!("{}{}", scale[scale_index], octave) 66 } 67 68 pub fn is_off(&self) -> bool { 69 self.velocity == 0 70 } 71 72 pub fn is_on(&self) -> bool { 73 !self.is_off() 74 } 75} 76 77impl Display for SyncData { 78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 79 write!(f, "SyncData @ {} bpm, {} stems", self.bpm, self.stems.len()) 80 } 81} 82 83#[derive(Debug, Clone, Default)] 84pub struct AudioSyncPaths { 85 pub stems: String, 86 pub landmarks: String, 87 pub complete: String, 88 pub bpm: String, 89 pub midi: String, 90} 91 92pub type AudioStemToMIDITrack<'a> = HashMap<&'a str, &'a str>; 93 94pub enum MusicalDurationUnit { 95 Beats, 96 Halfs, 97 Thirds, 98 Quarters, 99 Eighths, 100 Sixteenths, 101} 102 103#[derive(Debug)] 104pub struct StemAtInstant { 105 pub amplitude: f32, 106 pub amplitude_max: f32, 107 pub duration: usize, 108 pub velocity_max: u8, 109 pub notes: Vec<Note>, 110} 111impl StemAtInstant { 112 pub fn amplitude_relative(&self) -> f32 { 113 self.amplitude / self.amplitude_max 114 } 115 116 pub fn velocity_relative(&self) -> f32 { 117 self.notes.iter().map(|n| n.velocity).sum::<u8>() as f32 118 / self.notes.len() as f32 119 / self.velocity_max as f32 120 } 121}