From b7e0fa06ca5454314f1341a63148001f497ff018 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Sat, 27 Aug 2022 15:38:23 +0800 Subject: some new songs and small modifications --- src/instruments.rs | 54 ++++++++++++++++++++++++++++++++++++++++++------------ src/lib.rs | 13 +++++++++++++ 2 files changed, 55 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/instruments.rs b/src/instruments.rs index 15ac7d4..622754c 100644 --- a/src/instruments.rs +++ b/src/instruments.rs @@ -192,6 +192,8 @@ impl Instrument for PianoWOver { let mut result: Vec = vec![]; + let mut current_adsr = 0f64; + for i in 0..nb_samples { let mut y = f64::sin(theta); // let mut y = 0.6f64 * f64::sin(theta) + 0.4f64 * f64::sin(2f64 * theta); @@ -201,6 +203,10 @@ impl Instrument for PianoWOver { y *= *volume; + current_adsr = adsr(i, nb_samples, current_adsr); + + y *= current_adsr; + result.push(y.into()); theta += step; @@ -247,6 +253,8 @@ impl Instrument for PianoVideo { let mut result: Vec = vec![]; + let mut current_adsr = 0f64; + for i in 0..nb_samples { let mut y = 0.6f64 * f64::sin(theta) + 0.4f64 * f64::sin(2f64 * theta); y *= f64::exp((-0.0015f64) * theta); @@ -255,6 +263,10 @@ impl Instrument for PianoVideo { y *= *volume; + current_adsr = adsr(i, nb_samples, current_adsr); + + y *= current_adsr; + result.push(y.into()); theta += step; @@ -307,6 +319,8 @@ impl Instrument for PianoStackoverflow { let mut result: Vec = vec![]; + let mut current_adsr = 0f64; + for i in 0..nb_samples { let mut y = f64::sin(theta) + (1f64 / 2f64) * f64::sin(2f64 * theta) @@ -320,6 +334,10 @@ impl Instrument for PianoStackoverflow { y *= *volume; + current_adsr = adsr(i, nb_samples, current_adsr); + + y *= current_adsr; + result.push(y.into()); theta += step; @@ -329,7 +347,6 @@ impl Instrument for PianoStackoverflow { } } -#[allow(dead_code)] fn adsr(step: usize, total: usize, current: f64) -> f64 { if step < 4320 { if current <= 1f64 { @@ -371,6 +388,29 @@ impl Instrument for PianoFromC { let duration = duration.into(); let volume = volume.into(); + let (note_octave, note_rem): (usize, usize) = note.octave(); + + let exp_coeff = match note_octave { + n if n <= 3 => 0.0015f64, + 4 => 0.0015f64, + 5 => 0.001f64, + 6 => { + if note_rem < 9 { + 0.0005f64 + } else { + 0.0003f64 + } + } + 7 => { + if note_rem < 5 { + 0.0003f64 + } else { + 0.00009f64 + } + } + _ => 0.00009f64, + }; + let bpm = bpm.into(); let duration_per_beat: Seconds = bpm.into(); let duration: Seconds = (*duration * *duration_per_beat).into(); @@ -379,9 +419,6 @@ impl Instrument for PianoFromC { let note_h: Hertz = note.into(); - // dbg!(note); - // dbg!(note_h); - let step = *note_h * 2f64 * PI / *rate; let mut theta = 0f64; @@ -390,12 +427,11 @@ impl Instrument for PianoFromC { let mut adsr_factor = 1f64; - #[allow(unused_variables)] for i in 0..nb_samples { let mut y = 0.65f64 * f64::sin(theta) + 0.475f64 * f64::sin(2f64 * theta) + 0.05f64 * f64::sin(3f64 * theta); - y *= f64::exp((-0.0015f64) * theta); + y *= f64::exp((-exp_coeff) * theta); y += y * y * y; y *= 1f64 + 16f64 * i as f64 * f64::exp((-6f64) * i as f64); @@ -404,12 +440,6 @@ impl Instrument for PianoFromC { y *= *volume; - // if y >= 1f64 { - // y = 1f64; - // } else if y <= -1f64 { - // y = -1f64; - // } - result.push(y.into()); theta += step; diff --git a/src/lib.rs b/src/lib.rs index 5fa7e79..23fffe2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -245,6 +245,19 @@ impl Default for Hertz { } } +impl Semitones { + /// Return the octave of the semitone. + fn octave(self) -> (usize, usize) { + let translated = *self + 9f64; + + let quotient = translated.div_euclid(12f64) as i64; + + let rem = translated.rem_euclid(12f64) as usize; + + ((quotient + 4) as usize, rem) + } +} + impl From for Hertz { fn from(st: Semitones) -> Self { (*Self::default() * STD_BASE.powf(*st)).into() -- cgit v1.2.3-18-g5258