Skip to main content

maolan_engine/
message.rs

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// VST3 graph types
177#[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}