summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/instruments.rs54
-rw-r--r--src/lib.rs13
2 files changed, 55 insertions, 12 deletions
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<Pulse> = 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<Pulse> = 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<Pulse> = 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<Semitones> for Hertz {
fn from(st: Semitones) -> Self {
(*Self::default() * STD_BASE.powf(*st)).into()