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