Phase continuity
This commit is contained in:
parent
bf8f7f397e
commit
bda18d8b46
27
src/piece.rs
27
src/piece.rs
@ -27,6 +27,19 @@ impl Wave {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sample_from_phase(self, phase: f64) -> f64 {
|
||||||
|
match self {
|
||||||
|
Wave::Square => {
|
||||||
|
if phase < 0.5 {
|
||||||
|
1.0
|
||||||
|
} else {
|
||||||
|
-1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Wave::Triangle => 4.0 * (phase - 0.5).abs() - 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoteEvent {
|
pub struct NoteEvent {
|
||||||
@ -50,6 +63,7 @@ pub struct Track {
|
|||||||
pub amplitude: f64,
|
pub amplitude: f64,
|
||||||
pub notes: Vec<NoteEvent>,
|
pub notes: Vec<NoteEvent>,
|
||||||
pub current_tick: Tick,
|
pub current_tick: Tick,
|
||||||
|
pub phase: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Track {
|
impl Track {
|
||||||
@ -59,6 +73,7 @@ impl Track {
|
|||||||
amplitude,
|
amplitude,
|
||||||
notes: vec![],
|
notes: vec![],
|
||||||
current_tick: Tick(0),
|
current_tick: Tick(0),
|
||||||
|
phase: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +135,8 @@ impl Piece {
|
|||||||
let seconds_per_tick = 60.0 / (self.bpm as u64 * TICKS_PER_BEAT) as f64;
|
let seconds_per_tick = 60.0 / (self.bpm as u64 * TICKS_PER_BEAT) as f64;
|
||||||
let params = wav::Params::new();
|
let params = wav::Params::new();
|
||||||
|
|
||||||
|
let mut track_phases: Vec<f64> = vec![0.0; self.tracks.len()];
|
||||||
|
|
||||||
let total_samples =
|
let total_samples =
|
||||||
(self.max_beat() as f64 * seconds_per_beat * params.sampling_rate as f64).ceil() as u32;
|
(self.max_beat() as f64 * seconds_per_beat * params.sampling_rate as f64).ceil() as u32;
|
||||||
|
|
||||||
@ -134,12 +151,18 @@ impl Piece {
|
|||||||
for i in 0..total_samples {
|
for i in 0..total_samples {
|
||||||
let t = i as f64 / params.sampling_rate as f64;
|
let t = i as f64 / params.sampling_rate as f64;
|
||||||
let mut value: f64 = 0.0;
|
let mut value: f64 = 0.0;
|
||||||
for track in &self.tracks {
|
for (track, phase) in self.tracks.iter().zip(track_phases.iter_mut()) {
|
||||||
for event in &track.notes {
|
for event in &track.notes {
|
||||||
let start_time = event.start.0 as f64 * seconds_per_tick;
|
let start_time = event.start.0 as f64 * seconds_per_tick;
|
||||||
let end_time = (event.start + event.duration).0 as f64 * seconds_per_tick;
|
let end_time = (event.start + event.duration).0 as f64 * seconds_per_tick;
|
||||||
if t >= start_time && t < end_time {
|
if t >= start_time && t < end_time {
|
||||||
value += track.amplitude * track.wave.sample(&event.note, t);
|
let freq = event.note.freq();
|
||||||
|
// value += track.amplitude * track.wave.sample(&event.note, t);
|
||||||
|
value += track.amplitude * track.wave.sample_from_phase(*phase);
|
||||||
|
|
||||||
|
// Update phase
|
||||||
|
*phase += freq / params.sampling_rate as f64;
|
||||||
|
*phase %= 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ pub fn technology() -> Piece {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn bass_track() -> Track {
|
pub fn bass_track() -> Track {
|
||||||
let mut bass_track = Track::new(Wave::Square, 0.05);
|
let mut bass_track = Track::new(Wave::Triangle, 0.5);
|
||||||
for _ in 0..4 {
|
for _ in 0..4 {
|
||||||
bass_track.add(A1, Tick::bar());
|
bass_track.add(A1, Tick::bar());
|
||||||
bass_track.add(G0, Tick::beats(2));
|
bass_track.add(G0, Tick::beats(2));
|
||||||
@ -121,7 +121,7 @@ pub fn chords() -> Track {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_track() -> Track {
|
pub fn main_track() -> Track {
|
||||||
let mut track = Track::new(Wave::Square, 0.1);
|
let mut track = Track::new(Wave::Square, 0.075);
|
||||||
track.add_silence(Tick::bars(4));
|
track.add_silence(Tick::bars(4));
|
||||||
|
|
||||||
// Lick 1
|
// Lick 1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user