Skip to main content

forge_audio/
stubs.rs

1//! Stub types for modules not included in the public release.
2//!
3//! The core mixing architecture works without them.
4//! Full implementations available under the Commercial B2B License.
5
6use serde::{Deserialize, Serialize};
7
8/// Stub: beat grid for tempo-synced mixing.
9#[derive(Clone, Debug, Default, Serialize, Deserialize)]
10pub struct BeatGrid {
11    pub bpm: f64,
12    pub offset_samples: i64,
13    pub sample_rate: u32,
14    pub beat_interval: f64,
15}
16
17impl BeatGrid {
18    pub fn from_bpm(bpm: f64, offset: i64, sr: u32, _len: u32) -> Self {
19        Self {
20            bpm,
21            offset_samples: offset,
22            sample_rate: sr,
23            beat_interval: 60.0 / bpm * sr as f64,
24        }
25    }
26    pub fn beat_at_sample(&self, sample: i64) -> f64 {
27        let secs = (sample - self.offset_samples) as f64 / self.sample_rate as f64;
28        secs * self.bpm / 60.0
29    }
30    pub fn sample_at_beat(&self, beat: f64) -> i64 {
31        let secs = beat * 60.0 / self.bpm;
32        self.offset_samples + (secs * self.sample_rate as f64) as i64
33    }
34    pub fn snap_to_beat(&self, sample: i64) -> i64 {
35        let beat = self.beat_at_sample(sample).round();
36        self.sample_at_beat(beat)
37    }
38    pub fn phase_at(&self, sample: i64) -> f64 {
39        let beat = self.beat_at_sample(sample);
40        beat - beat.floor()
41    }
42}
43
44/// Stub: effects pipeline (proprietary DSP chain).
45/// Full implementation requires Commercial B2B License.
46#[derive(Clone, Debug, Default)]
47pub struct EffectsPipeline;
48impl EffectsPipeline {
49    pub fn apply(&self, _buf: &mut [f32]) {}
50}
51
52/// Stub: FX processor trait.
53pub trait FxProcessor: Send {
54    fn process(&mut self, buf: &mut [f32]);
55    fn name(&self) -> &str;
56    fn set_intensity(&mut self, _intensity: f32) {}
57    fn init(&mut self, _sample_rate: u32) {}
58}
59
60/// Stub: mix bus (engine binding).
61#[derive(Clone, Debug, Default)]
62pub struct MixBus {
63    pub deck_keys: [Option<u8>; 4],
64    pub deck_bpm: [f64; 4],
65    pub vocal_collision: bool,
66    pub vocal_energy: f32,
67}
68impl MixBus {
69    pub fn new() -> Self { Self::default() }
70    pub fn detect_vocal(&self, _buf: &[f32]) -> f32 { 0.0 }
71    pub fn update_derived(&mut self) {}
72}
73
74/// Stub: network presence hook trait.
75pub trait NetworkPresenceHook: Send {
76    fn on_message(&mut self, data: &[u8]);
77}
78
79/// Stub: procedural DSP module check.
80pub fn is_dsp_module(_name: &str) -> bool { false }
81
82/// Stub: procedural DSP processor creation.
83pub fn create_dsp_processor(_name: &str) -> Result<Box<dyn FxProcessor>, String> {
84    Err("Advanced procedural DSP modules require the Commercial B2B License — contact dev@deveraux.dev".into())
85}
86
87/// Stub: preset loading.
88pub fn load_preset(_name: &str, _intensity: f32) -> Result<EffectsPipeline, String> {
89    Err("Presets require the Commercial B2B License — contact dev@deveraux.dev".into())
90}
91
92/// Stub: audio command sender.
93#[derive(Clone, Debug)]
94pub struct AudioCommandTx;
95
96/// Deck identifier (0-3 for a 4-deck mixer).
97#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
98pub struct DeckId(pub u8);
99impl DeckId {
100    pub const A: Self = Self(0);
101    pub const B: Self = Self(1);
102    pub const C: Self = Self(2);
103    pub const D: Self = Self(3);
104    pub fn as_usize(self) -> usize { self.0 as usize }
105}
106impl From<DeckId> for usize {
107    fn from(d: DeckId) -> usize { d.0 as usize }
108
109}
110
111/// Sync mode for beat-matched mixing.
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
113pub enum SyncMode {
114    #[default]
115    Free,
116    Leader,
117    Follower,
118    Off,
119    BeatSync,
120    BarSync,
121    PhaseSync,
122}
123
124/// Minimal deck state for phase sync calculations.
125#[derive(Clone, Debug, Default)]
126pub struct Deck {
127    pub id: DeckId,
128    pub bpm: f64,
129    pub playing: bool,
130    pub position_samples: i64,
131    pub beatgrid: Option<BeatGrid>,
132    pub sync_mode: SyncMode,
133}