Skip to main content

maolan_engine/
lib.rs

1mod audio;
2mod audio_codec;
3pub mod client;
4mod engine;
5pub use engine::Engine;
6pub mod history;
7mod hw;
8pub mod kind;
9pub mod message;
10mod midi;
11pub mod mutex;
12mod osc;
13pub mod plugins;
14mod routing;
15#[cfg(unix)]
16mod rubberband;
17pub mod simd;
18pub mod state;
19mod track;
20pub mod workers;
21pub use workers::worker;
22
23pub use plugins::clap_proc;
24#[cfg(all(unix, not(target_os = "macos")))]
25pub use plugins::lv2_proc;
26pub use plugins::vst3_proc;
27
28// Re-export plugin info/state types for backward compatibility with the DAW
29// and internal engine code.
30pub mod clap {
31    pub use crate::plugins::types::is_supported_clap_binary;
32    pub use crate::plugins::types::{
33        ClapMidiOutputEvent, ClapParameterInfo, ClapPluginInfo, ClapPluginState,
34    };
35}
36pub mod vst3 {
37    pub use crate::plugins::types::{Vst3PluginInfo, Vst3PluginState};
38    pub mod interfaces {
39        pub use crate::plugins::types::Vst3GuiInfo;
40    }
41    pub mod port {
42        pub use crate::plugins::types::ParameterInfo;
43    }
44    pub mod state {
45        pub use crate::plugins::types::Vst3PluginState;
46    }
47}
48#[cfg(all(unix, not(target_os = "macos")))]
49pub mod lv2 {
50    pub use crate::plugins::types::Lv2PluginInfo;
51}
52
53use tokio::sync::mpsc::{Sender, channel};
54use tokio::task::JoinHandle;
55
56#[cfg(target_os = "macos")]
57pub fn discover_coreaudio_devices() -> Vec<String> {
58    hw::coreaudio::device::list_devices()
59        .into_iter()
60        .map(|d| d.name)
61        .collect()
62}
63
64/// Enables Flush-to-Zero (FTZ) and Denormals-Are-Zero (DAZ) on x86/x86_64,
65/// or flush-to-zero on aarch64. This prevents subnormal floating-point numbers
66/// from causing severe performance degradation in audio DSP code.
67pub fn enable_flush_denormals_to_zero() {
68    #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
69    unsafe {
70        let mut mxcsr: u32 = 0;
71        std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr);
72        mxcsr |= 0x8040; // FTZ (1 << 15) | DAZ (1 << 6)
73        std::arch::asm!("ldmxcsr [{}]", in(reg) &mxcsr);
74    }
75
76    #[cfg(target_arch = "aarch64")]
77    unsafe {
78        let mut fpcr: u64;
79        std::arch::asm!("mrs {0}, fpcr", out(reg) fpcr);
80        fpcr |= 1 << 24; // FZ bit
81        std::arch::asm!("msr fpcr, {0}", in(reg) fpcr);
82    }
83}
84
85pub fn init() -> (Sender<message::Message>, JoinHandle<()>) {
86    let (tx, rx) = channel::<message::Message>(32);
87    let mut engine = engine::Engine::new(rx, tx.clone());
88    let handle = tokio::spawn(async move {
89        engine.init().await;
90        engine.work().await;
91    });
92    (tx.clone(), handle)
93}