internal process dsp, skipping ladspa pipewire attempt, and reworked waveforms

This commit is contained in:
Bendik Aagaard Lynghaug
2026-05-27 22:04:08 +02:00
parent f81608734a
commit 39095f3a4a
11 changed files with 1606 additions and 838 deletions
+48 -32
View File
@@ -1,5 +1,13 @@
use std::path::PathBuf;
// ─── Defaults ───────────────────────────────────────────────────────────────
pub const PITCH_DEFAULT: f32 = 0.0;
pub const TEMPO_DEFAULT: f32 = 1.0;
pub const CUTOFF_DEFAULT: f32 = 0.0;
pub const REVERB_DEFAULT: f32 = 0.0;
pub const FADER_DEFAULT: f32 = 0.8;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DeckId {
A = 0,
@@ -63,53 +71,57 @@ pub struct Deck {
pub id: DeckId,
// Track
pub track: Option<PathBuf>,
pub track: Option<PathBuf>,
pub track_name: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
// Transport
pub play_state: PlayState,
pub position: u64, // samples
pub duration: u64, // samples
pub play_state: PlayState,
pub position: u64,
pub duration: u64,
pub sample_rate: u32,
pub cue_point: Option<u64>,
pub cue_point: Option<u64>,
// Per-deck mix controls
/// 0.0 – 1.0, sent to wpctl on the deck's PipeWire stream node
pub fader: f32,
// Mix / effect controls (mirror of the realtime DSP state in audio.rs)
pub fader: f32, // 0.0 .. 1.5
pub pitch: f32, // semitones, -12 .. +12
pub tempo: f32, // 0.5 .. 2.0
pub cutoff: f32, // < 0 lowpass Hz, > 0 highpass Hz, 0 flat
pub reverb: f32, // 0.0 .. 1.0
// Effect chain parameters (sent to pw-cli / filter-chain node)
/// Semitones -12.0 .. +12.0
pub pitch: f32,
/// Tempo multiplier 0.5 .. 2.0
pub tempo: f32,
// VU (updated by audio engine)
// VU (updated by audio engine at ~60 Hz)
pub vu: (f32, f32),
// PipeWire object IDs (populated after graph setup)
/// Object ID of the deck's playback stream node
pub stream_node_id: Option<u32>,
/// Object ID of the filter-chain node for this deck
pub filter_node_id: Option<u32>,
// Per-bucket band peaks for the waveform: [bass, mid, high], one entry per
// ~0.1 s of audio (PEAK_BUCKET frames). Sent in WaveformChunks during decode.
pub waveform_bands: Vec<[f32; 3]>,
/// BPM estimate from the decode-time analyzer; `None` until detected.
pub bpm: Option<f32>,
}
impl Deck {
pub fn new(id: DeckId) -> Self {
Self {
id,
track: None,
track_name: None,
play_state: PlayState::Stopped,
position: 0,
duration: 0,
track: None,
track_name: None,
artist: None,
album: None,
play_state: PlayState::Stopped,
position: 0,
duration: 0,
sample_rate: 44100,
cue_point: None,
fader: 0.8,
pitch: 0.0,
tempo: 1.0,
vu: (0.0, 0.0),
stream_node_id: None,
filter_node_id: None,
cue_point: None,
fader: FADER_DEFAULT,
pitch: PITCH_DEFAULT,
tempo: TEMPO_DEFAULT,
cutoff: CUTOFF_DEFAULT,
reverb: REVERB_DEFAULT,
vu: (0.0, 0.0),
waveform_bands: Vec::new(),
bpm: None,
}
}
@@ -117,6 +129,10 @@ impl Deck {
self.track.is_some()
}
pub fn peaks_empty(&self) -> bool {
self.waveform_bands.is_empty()
}
pub fn progress(&self) -> f32 {
if self.duration == 0 { 0.0 } else {
(self.position as f32 / self.duration as f32).clamp(0.0, 1.0)