diff --git a/Cargo.toml b/Cargo.toml index 864b52c8..24321691 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ coreaudio-sys-utils = { path = "coreaudio-sys-utils" } cubeb-backend = "0.13" float-cmp = "0.6" libc = "0.2" -lazy_static = "1.2" mach = "0.3" audio-mixer = "0.2" ringbuf = "0.2.6" diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 3917171b..82e4bdb6 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -4,7 +4,6 @@ // accompanying file LICENSE for details. #![allow(unused_assignments)] #![allow(unused_must_use)] - extern crate coreaudio_sys_utils; extern crate libc; extern crate ringbuf; @@ -106,16 +105,6 @@ bitflags! { } } -lazy_static! { - static ref HOST_TIME_TO_NS_RATIO: (u32, u32) = { - let mut timebase_info = mach_timebase_info { numer: 0, denom: 0 }; - unsafe { - mach_timebase_info(&mut timebase_info); - } - (timebase_info.numer, timebase_info.denom) - }; -} - #[cfg(feature = "audio-dump")] fn dump_audio(stream: cubeb_audio_dump_stream_t, audio_samples: *mut c_void, count: u32) { unsafe { @@ -682,10 +671,10 @@ extern "C" fn audiounit_input_callback( } } -fn host_time_to_ns(host_time: u64) -> u64 { +fn host_time_to_ns(ctx: &AudioUnitContext, host_time: u64) -> u64 { let mut rv: f64 = host_time as f64; - rv *= HOST_TIME_TO_NS_RATIO.0 as f64; - rv /= HOST_TIME_TO_NS_RATIO.1 as f64; + rv *= ctx.host_time_to_ns_ratio.0 as f64; + rv /= ctx.host_time_to_ns_ratio.1 as f64; rv as u64 } @@ -697,7 +686,7 @@ fn compute_output_latency(stm: &AudioUnitStream, audio_output_time: u64, now: u6 // The total output latency is the timestamp difference + the stream latency + the hardware // latency. let total_output_latency_ns = - fixed_latency_ns + host_time_to_ns(audio_output_time.saturating_sub(now)); + fixed_latency_ns + host_time_to_ns(stm.context, audio_output_time.saturating_sub(now)); (total_output_latency_ns * output_hw_rate / NS2S) as u32 } @@ -710,7 +699,7 @@ fn compute_input_latency(stm: &AudioUnitStream, audio_input_time: u64, now: u64) // The total input latency is the timestamp difference + the stream latency + // the hardware latency. let total_input_latency_ns = - host_time_to_ns(now.saturating_sub(audio_input_time)) + fixed_latency_ns; + host_time_to_ns(stm.context, now.saturating_sub(audio_input_time)) + fixed_latency_ns; (total_input_latency_ns * input_hw_rate / NS2S) as u32 } @@ -729,6 +718,14 @@ extern "C" fn audiounit_output_callback( assert!(!user_ptr.is_null()); let stm = unsafe { &mut *(user_ptr as *mut AudioUnitStream) }; + if output_frames == 0 { + cubeb_alog!( + "({:p}) output callback empty.", + stm as *const AudioUnitStream + ); + return NO_ERR; + } + let out_buffer_list_ref = unsafe { &mut (*out_buffer_list) }; assert_eq!(out_buffer_list_ref.mNumberBuffers, 1); let buffers = unsafe { @@ -879,6 +876,7 @@ extern "C" fn audiounit_output_callback( output_frames ); + assert_ne!(output_frames, 0); let outframes = stm.core_stream_data.resampler.fill( input_buffer, if input_buffer.is_null() { @@ -2474,6 +2472,7 @@ pub struct AudioUnitContext { serial_queue: Queue, latency_controller: Mutex, devices: Mutex, + host_time_to_ns_ratio: (u32, u32), // Storage for a context-global vpio unit. Duplex streams that need one will take this // and return it when done. shared_voice_processing_unit: SharedVoiceProcessingUnitManager, @@ -2488,11 +2487,19 @@ impl AudioUnitContext { format!("{}.context.shared_vpio", DISPATCH_QUEUE_LABEL).as_str(), &serial_queue, ); + let host_time_to_ns_ratio = { + let mut timebase_info = mach_timebase_info { numer: 0, denom: 0 }; + unsafe { + mach_timebase_info(&mut timebase_info); + } + (timebase_info.numer, timebase_info.denom) + }; Self { _ops: &OPS as *const _, serial_queue, latency_controller: Mutex::new(LatencyController::default()), devices: Mutex::new(SharedDevices::default()), + host_time_to_ns_ratio, shared_voice_processing_unit: SharedVoiceProcessingUnitManager::new(shared_vp_queue), } } @@ -4922,7 +4929,7 @@ impl<'ctx> StreamOps for AudioUnitStream<'ctx> { let now = unsafe { mach_absolute_time() }; let diff = now - timestamp; let interpolated_frames = cmp::min( - host_time_to_ns(diff) + host_time_to_ns(self.context, diff) * self.core_stream_data.output_stream_params.rate() as u64 / NS2S, buffer_size, diff --git a/src/lib.rs b/src/lib.rs index 87efbf54..bf1ae96f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,8 +10,6 @@ extern crate bitflags; extern crate cubeb_backend; #[macro_use] extern crate float_cmp; -#[macro_use] -extern crate lazy_static; extern crate mach; mod backend;