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