1mod audio;
2pub mod audio_codec;
3pub mod client;
4pub mod connectable;
5mod engine;
6pub use engine::Engine;
7pub mod executor;
8pub mod history;
9mod hw;
10pub mod kind;
11pub mod loudness;
12pub use loudness::LoudnessValues;
13pub mod message;
14pub mod meter;
15mod midi;
16pub mod modulator;
17mod osc;
18mod plan_builder;
19pub mod plugins;
20pub mod render_plan;
21mod routing;
22#[cfg(unix)]
23mod rubberband;
24pub mod simd;
25pub mod state;
26mod track;
27pub mod triple_buffer;
28pub mod workers;
29pub use workers::worker;
30
31pub use plugins::clap_proc;
32#[cfg(all(unix, not(target_os = "macos")))]
33pub use plugins::lv2_proc;
34pub use plugins::vst3_proc;
35
36pub mod clap {
37 pub use crate::plugins::types::is_supported_clap_binary;
38 pub use crate::plugins::types::{
39 ClapMidiOutputEvent, ClapParameterInfo, ClapPluginInfo, ClapPluginState,
40 };
41}
42pub mod vst3 {
43 pub use crate::plugins::types::{Vst3PluginInfo, Vst3PluginState};
44 pub mod interfaces {
45 pub use crate::plugins::types::Vst3GuiInfo;
46 }
47 pub mod port {
48 pub use crate::plugins::types::ParameterInfo;
49 }
50 pub mod state {
51 pub use crate::plugins::types::Vst3PluginState;
52 }
53}
54#[cfg(all(unix, not(target_os = "macos")))]
55pub mod lv2 {
56 pub use crate::plugins::types::Lv2PluginInfo;
57}
58
59use tokio::sync::mpsc::{Sender, channel};
60use tokio::task::JoinHandle;
61
62#[cfg(target_os = "macos")]
63pub fn discover_coreaudio_devices() -> Vec<String> {
64 hw::coreaudio::device::list_devices()
65 .into_iter()
66 .map(|d| d.name)
67 .collect()
68}
69
70pub fn enable_flush_denormals_to_zero() {
71 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
72 unsafe {
73 let mut mxcsr: u32 = 0;
74 std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr);
75 mxcsr |= 0x8040;
76 std::arch::asm!("ldmxcsr [{}]", in(reg) &mxcsr);
77 }
78
79 #[cfg(target_arch = "aarch64")]
80 unsafe {
81 let mut fpcr: u64;
82 std::arch::asm!("mrs {0}, fpcr", out(reg) fpcr);
83 fpcr |= 1 << 24;
84 std::arch::asm!("msr fpcr, {0}", in(reg) fpcr);
85 }
86}
87
88pub type EngineInit = (
89 Sender<message::Message>,
90 JoinHandle<()>,
91 triple_buffer::TripleBufferConsumer<meter::MeterSnapshot>,
92 triple_buffer::TripleBufferConsumer<meter::TransportSnapshot>,
93 triple_buffer::TripleBufferConsumer<meter::SessionRuntimeSnapshot>,
94);
95
96pub fn init() -> EngineInit {
97 let command_queue_capacity = num_cpus::get().saturating_mul(4).max(128);
98 let (tx, rx) = channel::<message::Message>(command_queue_capacity);
99 let (meter_producer, meter_consumer) =
100 triple_buffer::triple_buffer(meter::MeterSnapshot::default());
101 let (transport_producer, transport_consumer) =
102 triple_buffer::triple_buffer(meter::TransportSnapshot::default());
103 let (session_runtime_producer, session_runtime_consumer) =
104 triple_buffer::triple_buffer(meter::SessionRuntimeSnapshot::default());
105 let mut engine = engine::Engine::new_with_snapshots(
106 rx,
107 tx.clone(),
108 meter_producer,
109 transport_producer,
110 session_runtime_producer,
111 );
112 let handle = tokio::spawn(async move {
113 engine.init().await;
114 engine.work().await;
115 });
116 (
117 tx.clone(),
118 handle,
119 meter_consumer,
120 transport_consumer,
121 session_runtime_consumer,
122 )
123}