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