1mod audio;
2pub mod audio_codec;
3#[cfg(target_os = "macos")]
4pub mod audio_devices {
5 pub use crate::hw::coreaudio::{
6 AudioDeviceDescriptor, default_input_device_id, default_output_device_id,
7 discover_coreaudio_audio_devices,
8 };
9}
10#[cfg(target_os = "freebsd")]
11pub mod audio_devices {
12 pub use crate::hw::freebsd::{AudioDeviceDescriptor, discover_freebsd_audio_devices};
13}
14pub mod client;
15pub mod connectable;
16mod engine;
17pub use engine::Engine;
18pub mod executor;
19pub mod history;
20mod hw;
21pub mod kind;
22pub mod message;
23pub mod meter;
24pub mod midi;
25pub mod modulator;
26mod osc;
27#[cfg(unix)]
28mod pitch_shift;
29mod plan_builder;
30pub mod plugins;
31pub mod render_plan;
32mod routing;
33pub mod simd;
34pub mod state;
35mod track;
36pub mod triple_buffer;
37pub mod workers;
38pub use workers::worker;
39
40pub use plugins::clap_proc;
41#[cfg(unix)]
42pub use plugins::lv2_proc;
43pub use plugins::vst3_proc;
44
45pub mod clap {
46 pub use crate::plugins::types::is_supported_clap_binary;
47 pub use crate::plugins::types::{
48 ClapMidiOutputEvent, ClapParameterInfo, ClapPluginInfo, ClapPluginState,
49 };
50}
51pub mod vst3 {
52 pub use crate::plugins::types::{Vst3PluginInfo, Vst3PluginState};
53 pub mod interfaces {
54 pub use crate::plugins::types::Vst3GuiInfo;
55 }
56 pub mod port {
57 pub use crate::plugins::types::ParameterInfo;
58 }
59 pub mod state {
60 pub use crate::plugins::types::Vst3PluginState;
61 }
62}
63#[cfg(unix)]
64pub mod lv2 {
65 pub use crate::plugins::types::Lv2PluginInfo;
66}
67
68use tokio::sync::mpsc::{Sender, channel};
69use tokio::task::JoinHandle;
70
71pub fn enable_flush_denormals_to_zero() {
72 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
73 unsafe {
74 let mut mxcsr: u32 = 0;
75 std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr);
76 mxcsr |= 0x8040;
77 std::arch::asm!("ldmxcsr [{}]", in(reg) &mxcsr);
78 }
79
80 #[cfg(target_arch = "aarch64")]
81 unsafe {
82 let mut fpcr: u64;
83 std::arch::asm!("mrs {0}, fpcr", out(reg) fpcr);
84 fpcr |= 1 << 24;
85 std::arch::asm!("msr fpcr, {0}", in(reg) fpcr);
86 }
87}
88
89#[cfg(target_os = "windows")]
91pub struct WindowsTimerResolutionGuard;
92
93#[cfg(target_os = "windows")]
94impl Drop for WindowsTimerResolutionGuard {
95 fn drop(&mut self) {
96 #[link(name = "winmm")]
97 unsafe extern "system" {
98 fn timeEndPeriod(period: u32) -> u32;
99 }
100 unsafe {
101 timeEndPeriod(1);
102 }
103 }
104}
105
106#[cfg(target_os = "windows")]
111pub fn enable_windows_high_resolution_timer() -> Option<WindowsTimerResolutionGuard> {
112 #[link(name = "winmm")]
113 unsafe extern "system" {
114 fn timeBeginPeriod(period: u32) -> u32;
115 }
116 unsafe {
117 if timeBeginPeriod(1) == 0 {
118 tracing::info!("Windows timer resolution set to 1 ms");
119 Some(WindowsTimerResolutionGuard)
120 } else {
121 tracing::warn!("Failed to set Windows timer resolution to 1 ms");
122 None
123 }
124 }
125}
126
127pub type EngineInit = (
128 Sender<message::Message>,
129 JoinHandle<()>,
130 triple_buffer::TripleBufferConsumer<meter::MeterSnapshot>,
131 triple_buffer::TripleBufferConsumer<meter::TransportSnapshot>,
132 triple_buffer::TripleBufferConsumer<meter::SessionRuntimeSnapshot>,
133);
134
135pub fn init() -> EngineInit {
136 let command_queue_capacity = num_cpus::get().saturating_mul(4).max(128);
137 let (tx, rx) = channel::<message::Message>(command_queue_capacity);
138 let (meter_producer, meter_consumer) =
139 triple_buffer::triple_buffer(meter::MeterSnapshot::default());
140 let (transport_producer, transport_consumer) =
141 triple_buffer::triple_buffer(meter::TransportSnapshot::default());
142 let (session_runtime_producer, session_runtime_consumer) =
143 triple_buffer::triple_buffer(meter::SessionRuntimeSnapshot::default());
144 let mut engine = engine::Engine::new_with_snapshots(
145 rx,
146 tx.clone(),
147 meter_producer,
148 transport_producer,
149 session_runtime_producer,
150 );
151 let handle = tokio::spawn(async move {
152 engine.init().await;
153 engine.work().await;
154 });
155 (
156 tx.clone(),
157 handle,
158 meter_consumer,
159 transport_consumer,
160 session_runtime_consumer,
161 )
162}