phosphor_app/state/
track.rs1use phosphor_core::project::TrackKind;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum TrackElement {
9 Label,
10 Fx,
11 Volume,
12 Mute,
13 Solo,
14 RecordArm,
15 Clip(usize),
16}
17
18impl TrackElement {
19 pub fn move_right(self, num_clips: usize) -> Self {
20 match self {
21 Self::Label => Self::Fx,
22 Self::Fx => Self::Volume,
23 Self::Volume => Self::Mute,
24 Self::Mute => Self::Solo,
25 Self::Solo => Self::RecordArm,
26 Self::RecordArm => {
27 if num_clips > 0 { Self::Clip(0) } else { Self::RecordArm }
28 }
29 Self::Clip(i) => {
30 if i + 1 < num_clips { Self::Clip(i + 1) } else { Self::Clip(i) }
31 }
32 }
33 }
34
35 pub fn move_left(self) -> Self {
36 match self {
37 Self::Label => Self::Label,
38 Self::Fx => Self::Label,
39 Self::Volume => Self::Fx,
40 Self::Mute => Self::Volume,
41 Self::Solo => Self::Mute,
42 Self::RecordArm => Self::Solo,
43 Self::Clip(0) => Self::RecordArm,
44 Self::Clip(i) => Self::Clip(i - 1),
45 }
46 }
47}
48
49#[derive(Debug, Clone)]
52pub struct Clip {
53 pub number: usize,
54 pub width: u16,
55 pub has_content: bool,
56 pub start_tick: i64,
58 pub length_ticks: i64,
60 pub notes: Vec<phosphor_core::clip::NoteSnapshot>,
62 pub hidden_notes: Vec<(i64, i64, u8, u8)>,
67}
68
69#[derive(Debug, Clone)]
70pub struct TrackState {
71 pub name: String,
72 pub muted: bool,
73 pub soloed: bool,
74 pub armed: bool,
75 pub color_index: usize,
76 pub kind: TrackKind,
77 pub clips: Vec<Clip>,
78 pub fx_chain: Vec<super::FxInstance>,
80 pub volume: f32,
82 pub mixer_id: Option<usize>,
84 pub handle: Option<std::sync::Arc<phosphor_core::project::TrackHandle>>,
87 pub instrument_type: Option<super::InstrumentType>,
89 pub synth_params: Vec<f32>,
91}
92
93impl TrackState {
94 pub fn new(name: &str, color_index: usize, armed: bool, kind: TrackKind, clips: Vec<Clip>) -> Self {
95 Self {
96 name: name.to_string(),
97 muted: false,
98 soloed: false,
99 armed,
100 color_index,
101 kind,
102 clips,
103 fx_chain: Vec::new(),
104 volume: 0.75,
105 mixer_id: None,
106 handle: None,
107 instrument_type: None,
108 synth_params: Vec::new(),
109 }
110 }
111
112 pub fn sync_to_audio(&self) {
114 if let Some(ref h) = self.handle {
115 h.config.muted.store(self.muted, std::sync::atomic::Ordering::Relaxed);
116 h.config.soloed.store(self.soloed, std::sync::atomic::Ordering::Relaxed);
117 h.config.armed.store(self.armed, std::sync::atomic::Ordering::Relaxed);
118 h.config.set_volume(self.volume);
119 }
120 }
121
122 pub fn vu_levels(&self) -> (f32, f32) {
124 self.handle.as_ref().map(|h| h.vu.get()).unwrap_or((0.0, 0.0))
125 }
126
127 pub fn is_live(&self) -> bool {
129 self.handle.is_some()
130 }
131}