1use crate::clap::{ClapParameterInfo, ClapPluginInfo};
2#[cfg(all(unix, not(target_os = "macos")))]
3use crate::lv2::Lv2PluginInfo;
4use crate::midi::io::MidiEvent;
5use crate::vst3::Vst3PluginInfo;
6use crate::{kind::Kind, mutex::UnsafeMutex, track::Track};
7use std::sync::{Arc, atomic::AtomicBool};
8use tokio::sync::mpsc::Sender;
9
10#[derive(Clone, Debug)]
11pub struct MidiNoteData {
12 pub start_sample: usize,
13 pub length_samples: usize,
14 pub pitch: u8,
15 pub velocity: u8,
16 pub channel: u8,
17}
18
19#[derive(Clone, Debug)]
20pub struct MidiControllerData {
21 pub sample: usize,
22 pub controller: u8,
23 pub value: u8,
24 pub channel: u8,
25}
26
27#[derive(Debug, Clone)]
28pub struct MidiRawEventData {
29 pub sample: usize,
30 pub data: Vec<u8>,
31}
32
33#[derive(Clone, Debug)]
34pub struct HwMidiEvent {
35 pub device: String,
36 pub event: MidiEvent,
37}
38
39#[derive(Clone, Debug)]
40pub struct OfflineAutomationPoint {
41 pub sample: usize,
42 pub value: f32,
43}
44
45#[derive(Clone, Debug)]
46pub enum OfflineAutomationTarget {
47 Volume,
48 Balance,
49 Mute,
50 #[cfg(all(unix, not(target_os = "macos")))]
51 Lv2Parameter {
52 instance_id: usize,
53 index: u32,
54 min: f32,
55 max: f32,
56 },
57 Vst3Parameter {
58 instance_id: usize,
59 param_id: u32,
60 },
61 ClapParameter {
62 instance_id: usize,
63 param_id: u32,
64 min: f64,
65 max: f64,
66 },
67}
68
69#[derive(Clone, Debug)]
70pub struct OfflineAutomationLane {
71 pub target: OfflineAutomationTarget,
72 pub points: Vec<OfflineAutomationPoint>,
73}
74
75#[derive(Clone, Debug)]
76pub struct OfflineBounceWork {
77 pub state: Arc<UnsafeMutex<crate::state::State>>,
78 pub track_name: String,
79 pub output_path: String,
80 pub start_sample: usize,
81 pub length_samples: usize,
82 pub tempo_bpm: f64,
83 pub tsig_num: u16,
84 pub tsig_denom: u16,
85 pub automation_lanes: Vec<OfflineAutomationLane>,
86 pub cancel: Arc<AtomicBool>,
87}
88
89#[derive(Clone, Debug)]
90pub struct ClipMoveFrom {
91 pub track_name: String,
92 pub clip_index: usize,
93}
94
95#[derive(Clone, Debug)]
96pub struct ClipMoveTo {
97 pub track_name: String,
98 pub sample_offset: usize,
99 pub input_channel: usize,
100}
101
102#[cfg(unix)]
103#[derive(Clone, Debug, PartialEq, Eq, Hash)]
104pub enum PluginGraphNode {
105 TrackInput,
106 TrackOutput,
107 Lv2PluginInstance(usize),
108 Vst3PluginInstance(usize),
109 ClapPluginInstance(usize),
110}
111
112#[cfg(unix)]
113#[derive(Clone, Debug, PartialEq)]
114pub struct PluginGraphPlugin {
115 pub node: PluginGraphNode,
116 pub instance_id: usize,
117 pub format: String,
118 pub uri: String,
119 pub plugin_id: String,
120 pub name: String,
121 pub main_audio_inputs: usize,
122 pub main_audio_outputs: usize,
123 pub audio_inputs: usize,
124 pub audio_outputs: usize,
125 pub midi_inputs: usize,
126 pub midi_outputs: usize,
127 pub state: Option<Lv2PluginState>,
128}
129
130#[cfg(unix)]
131#[derive(Clone, Debug, PartialEq)]
132pub struct Lv2StatePortValue {
133 pub index: u32,
134 pub value: f32,
135}
136
137#[cfg(unix)]
138#[derive(Clone, Debug, PartialEq, Eq)]
139pub struct Lv2StateProperty {
140 pub key_uri: String,
141 pub type_uri: String,
142 pub flags: u32,
143 pub value: Vec<u8>,
144}
145
146#[cfg(unix)]
147#[derive(Clone, Debug, PartialEq)]
148pub struct Lv2PluginState {
149 pub port_values: Vec<Lv2StatePortValue>,
150 pub properties: Vec<Lv2StateProperty>,
151}
152
153#[cfg(all(unix, not(target_os = "macos")))]
154#[derive(Clone, Debug, PartialEq)]
155pub struct Lv2ControlPortInfo {
156 pub index: u32,
157 pub name: String,
158 pub min: f32,
159 pub max: f32,
160 pub value: f32,
161}
162
163#[cfg(unix)]
164#[derive(Clone, Debug, PartialEq, Eq)]
165pub struct PluginGraphConnection {
166 pub from_node: PluginGraphNode,
167 pub from_port: usize,
168 pub to_node: PluginGraphNode,
169 pub to_port: usize,
170 pub kind: Kind,
171}
172
173#[cfg(unix)]
174pub type PluginGraphSnapshot = (Vec<PluginGraphPlugin>, Vec<PluginGraphConnection>);
175
176#[derive(Clone, Debug, PartialEq, Eq, Hash)]
178pub enum Vst3GraphNode {
179 TrackInput,
180 TrackOutput,
181 PluginInstance(usize),
182}
183
184#[derive(Clone, Debug)]
185pub struct Vst3GraphPlugin {
186 pub instance_id: usize,
187 pub name: String,
188 pub path: String,
189 pub audio_inputs: usize,
190 pub audio_outputs: usize,
191 pub parameters: Vec<crate::vst3::port::ParameterInfo>,
192}
193
194#[derive(Clone, Debug, PartialEq, Eq)]
195pub struct Vst3GraphConnection {
196 pub from_node: Vst3GraphNode,
197 pub from_port: usize,
198 pub to_node: Vst3GraphNode,
199 pub to_port: usize,
200 pub kind: Kind,
201}
202
203#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
204pub struct AudioWarpMarker {
205 pub timeline_sample: usize,
206 pub source_sample: usize,
207}
208
209#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
210pub struct MidiLearnBinding {
211 pub device: Option<String>,
212 pub channel: u8,
213 pub cc: u8,
214}
215
216#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
217pub enum TrackMidiLearnTarget {
218 Volume,
219 Balance,
220 Mute,
221 Solo,
222 Arm,
223 InputMonitor,
224 DiskMonitor,
225}
226
227#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
228pub enum GlobalMidiLearnTarget {
229 PlayPause,
230 Stop,
231 RecordToggle,
232}
233
234#[derive(Clone, Debug)]
235pub enum Action {
236 Quit,
237 Play,
238 Stop,
239 TransportPosition(usize),
240 SetLoopEnabled(bool),
241 SetLoopRange(Option<(usize, usize)>),
242 SetPunchEnabled(bool),
243 SetPunchRange(Option<(usize, usize)>),
244 SetMetronomeEnabled(bool),
245 SetTempo(f64),
246 SetTimeSignature {
247 numerator: u16,
248 denominator: u16,
249 },
250 SetClipPlaybackEnabled(bool),
251 SetRecordEnabled(bool),
252 SetSessionPath(String),
253 BeginHistoryGroup,
254 EndHistoryGroup,
255 ClearHistory,
256 BeginSessionRestore,
257 EndSessionRestore,
258 AddTrack {
259 name: String,
260 audio_ins: usize,
261 midi_ins: usize,
262 audio_outs: usize,
263 midi_outs: usize,
264 },
265 TrackAddAudioInput(String),
266 TrackAddAudioOutput(String),
267 TrackRemoveAudioInput(String),
268 TrackRemoveAudioOutput(String),
269 AddClip {
270 name: String,
271 track_name: String,
272 start: usize,
273 length: usize,
274 offset: usize,
275 input_channel: usize,
276 muted: bool,
277 kind: Kind,
278 fade_enabled: bool,
279 fade_in_samples: usize,
280 fade_out_samples: usize,
281 warp_markers: Vec<AudioWarpMarker>,
282 },
283 RemoveClip {
284 track_name: String,
285 kind: Kind,
286 clip_indices: Vec<usize>,
287 },
288 SetClipFade {
289 track_name: String,
290 clip_index: usize,
291 kind: Kind,
292 fade_enabled: bool,
293 fade_in_samples: usize,
294 fade_out_samples: usize,
295 },
296 SetClipBounds {
297 track_name: String,
298 clip_index: usize,
299 kind: Kind,
300 start: usize,
301 length: usize,
302 offset: usize,
303 },
304 SetClipMuted {
305 track_name: String,
306 clip_index: usize,
307 kind: Kind,
308 muted: bool,
309 },
310 SetAudioClipWarpMarkers {
311 track_name: String,
312 clip_index: usize,
313 warp_markers: Vec<AudioWarpMarker>,
314 },
315 RenameClip {
316 track_name: String,
317 kind: Kind,
318 clip_index: usize,
319 new_name: String,
320 },
321 RenameTrack {
322 old_name: String,
323 new_name: String,
324 },
325 RemoveTrack(String),
326 TrackLevel(String, f32),
327 TrackBalance(String, f32),
328 TrackAutomationLevel(String, f32),
329 TrackAutomationBalance(String, f32),
330 TrackAutomationMute(String, bool),
331 TrackMeters {
332 track_name: String,
333 output_db: Vec<f32>,
334 },
335 RequestMeterSnapshot,
336 MeterSnapshot {
337 hw_out_db: Arc<Vec<f32>>,
338 track_meters: Arc<Vec<(String, Vec<f32>)>>,
339 },
340 TrackToggleArm(String),
341 TrackToggleMute(String),
342 TrackToggleSolo(String),
343 TrackToggleInputMonitor(String),
344 TrackToggleDiskMonitor(String),
345 TrackArmMidiLearn {
346 track_name: String,
347 target: TrackMidiLearnTarget,
348 },
349 GlobalArmMidiLearn {
350 target: GlobalMidiLearnTarget,
351 },
352 TrackSetMidiLearnBinding {
353 track_name: String,
354 target: TrackMidiLearnTarget,
355 binding: Option<MidiLearnBinding>,
356 },
357 SetGlobalMidiLearnBinding {
358 target: GlobalMidiLearnTarget,
359 binding: Option<MidiLearnBinding>,
360 },
361 TrackSetVcaMaster {
362 track_name: String,
363 master_track: Option<String>,
364 },
365 TrackSetMidiLaneChannel {
366 track_name: String,
367 lane: usize,
368 channel: Option<u8>,
369 },
370 TrackSetFrozen {
371 track_name: String,
372 frozen: bool,
373 },
374 TrackOfflineBounce {
375 track_name: String,
376 output_path: String,
377 start_sample: usize,
378 length_samples: usize,
379 automation_lanes: Vec<OfflineAutomationLane>,
380 },
381 TrackOfflineBounceCancel {
382 track_name: String,
383 },
384 TrackOfflineBounceCanceled {
385 track_name: String,
386 },
387 TrackOfflineBounceProgress {
388 track_name: String,
389 progress: f32,
390 operation: Option<String>,
391 },
392 PianoKey {
393 track_name: String,
394 note: u8,
395 velocity: u8,
396 on: bool,
397 },
398 ModifyMidiNotes {
399 track_name: String,
400 clip_index: usize,
401 note_indices: Vec<usize>,
402 new_notes: Vec<MidiNoteData>,
403 old_notes: Vec<MidiNoteData>,
404 },
405 ModifyMidiControllers {
406 track_name: String,
407 clip_index: usize,
408 controller_indices: Vec<usize>,
409 new_controllers: Vec<MidiControllerData>,
410 old_controllers: Vec<MidiControllerData>,
411 },
412 DeleteMidiControllers {
413 track_name: String,
414 clip_index: usize,
415 controller_indices: Vec<usize>,
416 deleted_controllers: Vec<(usize, MidiControllerData)>,
417 },
418 InsertMidiControllers {
419 track_name: String,
420 clip_index: usize,
421 controllers: Vec<(usize, MidiControllerData)>,
422 },
423 DeleteMidiNotes {
424 track_name: String,
425 clip_index: usize,
426 note_indices: Vec<usize>,
427 deleted_notes: Vec<(usize, MidiNoteData)>,
428 },
429 InsertMidiNotes {
430 track_name: String,
431 clip_index: usize,
432 notes: Vec<(usize, MidiNoteData)>,
433 },
434 SetMidiSysExEvents {
435 track_name: String,
436 clip_index: usize,
437 new_sysex_events: Vec<MidiRawEventData>,
438 old_sysex_events: Vec<MidiRawEventData>,
439 },
440 #[cfg(all(unix, not(target_os = "macos")))]
441 TrackLoadLv2Plugin {
442 track_name: String,
443 plugin_uri: String,
444 },
445 TrackClearDefaultPassthrough {
446 track_name: String,
447 },
448 #[cfg(all(unix, not(target_os = "macos")))]
449 TrackSetLv2PluginState {
450 track_name: String,
451 instance_id: usize,
452 state: Lv2PluginState,
453 },
454 #[cfg(all(unix, not(target_os = "macos")))]
455 TrackUnloadLv2PluginInstance {
456 track_name: String,
457 instance_id: usize,
458 },
459 #[cfg(all(unix, not(target_os = "macos")))]
460 TrackGetLv2PluginControls {
461 track_name: String,
462 instance_id: usize,
463 },
464 #[cfg(all(unix, not(target_os = "macos")))]
465 TrackLv2PluginControls {
466 track_name: String,
467 instance_id: usize,
468 controls: Vec<Lv2ControlPortInfo>,
469 instance_access_handle: Option<usize>,
470 },
471 #[cfg(all(unix, not(target_os = "macos")))]
472 TrackGetLv2Midnam {
473 track_name: String,
474 },
475 #[cfg(all(unix, not(target_os = "macos")))]
476 TrackLv2Midnam {
477 track_name: String,
478 note_names: std::collections::HashMap<u8, String>,
479 },
480 #[cfg(all(unix, not(target_os = "macos")))]
481 TrackSetLv2ControlValue {
482 track_name: String,
483 instance_id: usize,
484 index: u32,
485 value: f32,
486 },
487 #[cfg(unix)]
488 TrackGetPluginGraph {
489 track_name: String,
490 },
491 #[cfg(unix)]
492 TrackPluginGraph {
493 track_name: String,
494 plugins: Vec<PluginGraphPlugin>,
495 connections: Vec<PluginGraphConnection>,
496 },
497 #[cfg(unix)]
498 TrackConnectPluginAudio {
499 track_name: String,
500 from_node: PluginGraphNode,
501 from_port: usize,
502 to_node: PluginGraphNode,
503 to_port: usize,
504 },
505 #[cfg(unix)]
506 TrackConnectPluginMidi {
507 track_name: String,
508 from_node: PluginGraphNode,
509 from_port: usize,
510 to_node: PluginGraphNode,
511 to_port: usize,
512 },
513 #[cfg(unix)]
514 TrackDisconnectPluginAudio {
515 track_name: String,
516 from_node: PluginGraphNode,
517 from_port: usize,
518 to_node: PluginGraphNode,
519 to_port: usize,
520 },
521 #[cfg(unix)]
522 TrackDisconnectPluginMidi {
523 track_name: String,
524 from_node: PluginGraphNode,
525 from_port: usize,
526 to_node: PluginGraphNode,
527 to_port: usize,
528 },
529 #[cfg(all(unix, not(target_os = "macos")))]
530 ListLv2Plugins,
531 #[cfg(all(unix, not(target_os = "macos")))]
532 Lv2Plugins(Vec<Lv2PluginInfo>),
533 ListVst3Plugins,
534 Vst3Plugins(Vec<Vst3PluginInfo>),
535 ListClapPlugins,
536 ListClapPluginsWithCapabilities,
537 ClapPlugins(Vec<ClapPluginInfo>),
538 TrackLoadClapPlugin {
539 track_name: String,
540 plugin_path: String,
541 },
542 TrackUnloadClapPlugin {
543 track_name: String,
544 plugin_path: String,
545 },
546 TrackSetClapParameter {
547 track_name: String,
548 instance_id: usize,
549 param_id: u32,
550 value: f64,
551 },
552 TrackSetClapParameterAt {
553 track_name: String,
554 instance_id: usize,
555 param_id: u32,
556 value: f64,
557 frame: u32,
558 },
559 TrackBeginClapParameterEdit {
560 track_name: String,
561 instance_id: usize,
562 param_id: u32,
563 frame: u32,
564 },
565 TrackEndClapParameterEdit {
566 track_name: String,
567 instance_id: usize,
568 param_id: u32,
569 frame: u32,
570 },
571 TrackGetClapParameters {
572 track_name: String,
573 instance_id: usize,
574 },
575 TrackClapParameters {
576 track_name: String,
577 instance_id: usize,
578 parameters: Vec<ClapParameterInfo>,
579 },
580 TrackClapSnapshotState {
581 track_name: String,
582 instance_id: usize,
583 },
584 TrackClapStateSnapshot {
585 track_name: String,
586 instance_id: usize,
587 plugin_path: String,
588 state: crate::clap::ClapPluginState,
589 },
590 TrackClapRestoreState {
591 track_name: String,
592 instance_id: usize,
593 state: crate::clap::ClapPluginState,
594 },
595 TrackSnapshotAllClapStates {
596 track_name: String,
597 },
598 TrackLoadVst3Plugin {
599 track_name: String,
600 plugin_path: String,
601 },
602 TrackUnloadVst3PluginInstance {
603 track_name: String,
604 instance_id: usize,
605 },
606 TrackGetVst3Graph {
607 track_name: String,
608 },
609 TrackVst3Graph {
610 track_name: String,
611 plugins: Vec<Vst3GraphPlugin>,
612 connections: Vec<Vst3GraphConnection>,
613 },
614 TrackSetVst3Parameter {
615 track_name: String,
616 instance_id: usize,
617 param_id: u32,
618 value: f32,
619 },
620 TrackGetVst3Parameters {
621 track_name: String,
622 instance_id: usize,
623 },
624 TrackVst3Parameters {
625 track_name: String,
626 instance_id: usize,
627 parameters: Vec<crate::vst3::port::ParameterInfo>,
628 },
629 TrackVst3SnapshotState {
630 track_name: String,
631 instance_id: usize,
632 },
633 TrackVst3StateSnapshot {
634 track_name: String,
635 instance_id: usize,
636 state: crate::vst3::state::Vst3PluginState,
637 },
638 TrackVst3RestoreState {
639 track_name: String,
640 instance_id: usize,
641 state: crate::vst3::state::Vst3PluginState,
642 },
643 TrackConnectVst3Audio {
644 track_name: String,
645 from_node: Vst3GraphNode,
646 from_port: usize,
647 to_node: Vst3GraphNode,
648 to_port: usize,
649 },
650 TrackDisconnectVst3Audio {
651 track_name: String,
652 from_node: Vst3GraphNode,
653 from_port: usize,
654 to_node: Vst3GraphNode,
655 to_port: usize,
656 },
657 ClipMove {
658 kind: Kind,
659 from: ClipMoveFrom,
660 to: ClipMoveTo,
661 copy: bool,
662 },
663 Connect {
664 from_track: String,
665 from_port: usize,
666 to_track: String,
667 to_port: usize,
668 kind: Kind,
669 },
670 Disconnect {
671 from_track: String,
672 from_port: usize,
673 to_track: String,
674 to_port: usize,
675 kind: Kind,
676 },
677 OpenAudioDevice {
678 device: String,
679 input_device: Option<String>,
680 sample_rate_hz: i32,
681 bits: i32,
682 exclusive: bool,
683 period_frames: usize,
684 nperiods: usize,
685 sync_mode: bool,
686 },
687 OpenMidiInputDevice(String),
688 OpenMidiOutputDevice(String),
689 RequestSessionDiagnostics,
690 RequestMidiLearnMappingsReport,
691 ClearAllMidiLearnBindings,
692 SessionDiagnosticsReport {
693 track_count: usize,
694 frozen_track_count: usize,
695 audio_clip_count: usize,
696 midi_clip_count: usize,
697 #[cfg(all(unix, not(target_os = "macos")))]
698 lv2_instance_count: usize,
699 vst3_instance_count: usize,
700 clap_instance_count: usize,
701 pending_requests: usize,
702 workers_total: usize,
703 workers_ready: usize,
704 pending_hw_midi_events: usize,
705 playing: bool,
706 transport_sample: usize,
707 tempo_bpm: f64,
708 sample_rate_hz: usize,
709 cycle_samples: usize,
710 },
711 MidiLearnMappingsReport {
712 lines: Vec<String>,
713 },
714 HWInfo {
715 channels: usize,
716 rate: usize,
717 input: bool,
718 },
719 Undo,
720 Redo,
721 Panic,
722}
723
724#[derive(Clone, Debug)]
725pub enum Message {
726 Ready(usize),
727 Finished {
728 worker_id: usize,
729 track_name: String,
730 output_linear: Vec<f32>,
731 process_epoch: usize,
732 },
733 TracksFinished,
734
735 ProcessTrack(Arc<UnsafeMutex<Box<Track>>>),
736 ProcessOfflineBounce(OfflineBounceWork),
737 Channel(Sender<Self>),
738
739 Request(Action),
740 Response(Result<Action, String>),
741 HWMidiEvents(Vec<HwMidiEvent>),
742 HWMidiOutEvents(Vec<HwMidiEvent>),
743 ClearHWMidiOutEvents,
744 HWFinished,
745 OfflineBounceFinished {
746 result: Result<Action, String>,
747 },
748}