refactor pulse duration field to offset field.

This commit is contained in:
Vixalie 2025-03-06 14:50:07 +08:00
parent 9177f90b51
commit b92dad0346
3 changed files with 32 additions and 18 deletions

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::fraction::Fraction; use crate::fraction::Fraction;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum FrequencyShifting { pub enum FrequencyShifting {
Linear, Linear,
Quadratic, Quadratic,
@ -56,7 +56,7 @@ pub fn shifting_frequency(
sample_tick, sample_tick,
start_timing, start_timing,
start_pulse.frequency, start_pulse.frequency,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
end_pulse.frequency, end_pulse.frequency,
(0.0, 0.0), (0.0, 0.0),
(1.0, 1.0), (1.0, 1.0),
@ -65,7 +65,7 @@ pub fn shifting_frequency(
sample_tick, sample_tick,
start_timing, start_timing,
start_pulse.frequency, start_pulse.frequency,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
end_pulse.frequency, end_pulse.frequency,
(1.0, 0.0), (1.0, 0.0),
(1.0, 1.0), (1.0, 1.0),
@ -74,7 +74,7 @@ pub fn shifting_frequency(
sample_tick, sample_tick,
start_timing, start_timing,
start_pulse.frequency, start_pulse.frequency,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
end_pulse.frequency, end_pulse.frequency,
(0.9, 0.1), (0.9, 0.1),
(1.0, 0.2), (1.0, 0.2),
@ -83,7 +83,7 @@ pub fn shifting_frequency(
sample_tick, sample_tick,
start_timing, start_timing,
start_pulse.frequency, start_pulse.frequency,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
end_pulse.frequency, end_pulse.frequency,
(0.33, 0.0), (0.33, 0.0),
(0.67, 1.0), (0.67, 1.0),
@ -91,14 +91,14 @@ pub fn shifting_frequency(
FrequencyShifting::Pulsating => periodic_shifting( FrequencyShifting::Pulsating => periodic_shifting(
sample_tick, sample_tick,
start_timing, start_timing,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
start_pulse.frequency.min(end_pulse.frequency), start_pulse.frequency.min(end_pulse.frequency),
end_pulse.frequency.max(start_pulse.frequency), end_pulse.frequency.max(start_pulse.frequency),
), ),
FrequencyShifting::Spiking => periodic_shifting( FrequencyShifting::Spiking => periodic_shifting(
sample_tick, sample_tick,
start_timing, start_timing,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
start_pulse.frequency.min(end_pulse.frequency), start_pulse.frequency.min(end_pulse.frequency),
start_pulse.frequency.max(end_pulse.frequency) * 2.0, start_pulse.frequency.max(end_pulse.frequency) * 2.0,
), ),
@ -111,7 +111,7 @@ pub fn shifting_frequency(
sample_tick, sample_tick,
start_timing, start_timing,
start_pulse.frequency, start_pulse.frequency,
start_timing + start_pulse.duration, start_timing + end_pulse.offset,
end_pulse.frequency, end_pulse.frequency,
end_pulse.control_point_1.into(), end_pulse.control_point_1.into(),
end_pulse.control_point_2.into(), end_pulse.control_point_2.into(),

View File

@ -14,6 +14,8 @@ use serde::{Deserialize, Serialize};
use sled::IVec; use sled::IVec;
use uuid::Uuid; use uuid::Uuid;
static SMOOTH_REPEAT_FADE_OFFSET: u32 = 100;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Pattern { pub struct Pattern {
@ -65,10 +67,9 @@ impl Pattern {
pub fn total_duration(&self) -> u32 { pub fn total_duration(&self) -> u32 {
let mut duration = 0; let mut duration = 0;
for (index, pulse) in self.pulses.iter().enumerate() { for (index, pulse) in self.pulses.iter().enumerate() {
if (index == self.pulses.len() - 1 && self.smooth_repeat) duration += pulse.offset;
|| index < self.pulses.len() - 1 if index == self.pulses.len() - 1 && self.smooth_repeat {
{ duration += SMOOTH_REPEAT_FADE_OFFSET;
duration += pulse.duration;
} }
} }
duration duration

View File

@ -3,7 +3,10 @@ use std::collections::VecDeque;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use super::frequency_shifting::{self, deserialize_frequency_shifting, FrequencyShifting}; use super::{
frequency_shifting::{self, deserialize_frequency_shifting, FrequencyShifting},
SMOOTH_REPEAT_FADE_OFFSET,
};
use crate::fraction::Fraction; use crate::fraction::Fraction;
pub fn calculate_output_ratio(waveform_frequency: f64) -> Fraction { pub fn calculate_output_ratio(waveform_frequency: f64) -> Fraction {
@ -30,7 +33,7 @@ pub struct Pulse {
pub order: u32, pub order: u32,
pub id: Uuid, pub id: Uuid,
#[serde(default)] #[serde(default)]
pub duration: u32, pub offset: u32,
pub width: u32, pub width: u32,
pub maniac: bool, pub maniac: bool,
pub frequency: f64, pub frequency: f64,
@ -41,6 +44,7 @@ pub struct Pulse {
} }
#[derive(Debug, Clone, Copy, Serialize)] #[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RawPulse { pub struct RawPulse {
pub tick_order: u32, pub tick_order: u32,
pub z: u16, pub z: u16,
@ -86,13 +90,22 @@ pub fn generate_pulse_sequence<P: IntoIterator<Item = Pulse>>(
let mut peekable_pulses = sorted_pulses.iter().peekable(); let mut peekable_pulses = sorted_pulses.iter().peekable();
while let Some(p) = peekable_pulses.next() { while let Some(p) = peekable_pulses.next() {
if let Some(next_pulse) = peekable_pulses.peek() { if let Some(next_pulse) = peekable_pulses.peek() {
while sample_tick < (timing + p.duration) { while sample_tick < (timing + next_pulse.offset) {
sample_queue.push_back((sample_tick, timing, p.clone(), (*next_pulse).clone())); sample_queue.push_back((sample_tick, timing, p.clone(), (*next_pulse).clone()));
sample_tick += 25; sample_tick += 25;
} }
timing += p.duration; timing += next_pulse.offset;
} else if smooth_repeat && head_pulse.is_some() { } else if smooth_repeat && head_pulse.is_some() {
sample_queue.push_back((sample_tick, timing, p.clone(), head_pulse.unwrap().clone())); sample_queue.push_back((
sample_tick,
timing,
p.clone(),
Pulse {
offset: SMOOTH_REPEAT_FADE_OFFSET,
order: p.order + 1,
..head_pulse.unwrap().clone()
},
));
} else { } else {
break; break;
} }
@ -107,7 +120,7 @@ pub fn generate_pulse_sequence<P: IntoIterator<Item = Pulse>>(
y: prev.frequency, y: prev.frequency,
}, },
CanvasPoint { CanvasPoint {
x: (timing + prev.duration) as f64, x: (timing + next.offset) as f64,
y: next.frequency, y: next.frequency,
}, },
prev.control_point_1, prev.control_point_1,