addressed some compilation errors on asio timestamp implementation
This commit is contained in:
parent
22eef32898
commit
225f441d5b
|
@ -896,7 +896,7 @@ extern "C" fn asio_message(
|
||||||
// Informs the driver whether the application is interested in time code info. If an
|
// Informs the driver whether the application is interested in time code info. If an
|
||||||
// application does not need to know about time code, the driver has less work to do.
|
// application does not need to know about time code, the driver has less work to do.
|
||||||
// TODO: Provide an option for this?
|
// TODO: Provide an option for this?
|
||||||
0
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => 0, // Unknown/unhandled message type.
|
_ => 0, // Unknown/unhandled message type.
|
||||||
|
@ -916,12 +916,12 @@ extern "C" fn buffer_switch_time_info(
|
||||||
) -> *mut ai::ASIOTime {
|
) -> *mut ai::ASIOTime {
|
||||||
// This lock is probably unavoidable, but locks in the audio stream are not great.
|
// This lock is probably unavoidable, but locks in the audio stream are not great.
|
||||||
let mut bcs = BUFFER_CALLBACK.lock().unwrap();
|
let mut bcs = BUFFER_CALLBACK.lock().unwrap();
|
||||||
let time: &mut AsioTime = unsafe {
|
let asio_time: &mut AsioTime = unsafe {
|
||||||
&mut *(time as *mut AsioTime)
|
&mut *(time as *mut AsioTime)
|
||||||
};
|
};
|
||||||
let callback_info = CallbackInfo {
|
let callback_info = CallbackInfo {
|
||||||
buffer_index: double_buffer_index,
|
buffer_index: double_buffer_index,
|
||||||
system_time: time.time_info.system_time,
|
system_time: asio_time.time_info.system_time,
|
||||||
};
|
};
|
||||||
for &mut (_, ref mut bc) in bcs.iter_mut() {
|
for &mut (_, ref mut bc) in bcs.iter_mut() {
|
||||||
bc.run(&callback_info);
|
bc.run(&callback_info);
|
||||||
|
|
|
@ -87,6 +87,7 @@ impl Device {
|
||||||
|
|
||||||
// Set the input callback.
|
// Set the input callback.
|
||||||
// This is most performance critical part of the ASIO bindings.
|
// This is most performance critical part of the ASIO bindings.
|
||||||
|
let config = config.clone();
|
||||||
let callback_id = self.driver.add_callback(move |callback_info| unsafe {
|
let callback_id = self.driver.add_callback(move |callback_info| unsafe {
|
||||||
// If not playing return early.
|
// If not playing return early.
|
||||||
if !playing.load(Ordering::SeqCst) {
|
if !playing.load(Ordering::SeqCst) {
|
||||||
|
@ -103,7 +104,7 @@ impl Device {
|
||||||
/// 1. Write from the ASIO buffer to the interleaved CPAL buffer.
|
/// 1. Write from the ASIO buffer to the interleaved CPAL buffer.
|
||||||
/// 2. Deliver the CPAL buffer to the user callback.
|
/// 2. Deliver the CPAL buffer to the user callback.
|
||||||
unsafe fn process_input_callback<A, B, D, F>(
|
unsafe fn process_input_callback<A, B, D, F>(
|
||||||
callback: &mut D,
|
data_callback: &mut D,
|
||||||
interleaved: &mut [u8],
|
interleaved: &mut [u8],
|
||||||
asio_stream: &sys::AsioStream,
|
asio_stream: &sys::AsioStream,
|
||||||
asio_info: &sys::CallbackInfo,
|
asio_info: &sys::CallbackInfo,
|
||||||
|
@ -136,9 +137,9 @@ impl Device {
|
||||||
let capture = callback
|
let capture = callback
|
||||||
.sub(delay)
|
.sub(delay)
|
||||||
.expect("`capture` occurs before origin of alsa `StreamInstant`");
|
.expect("`capture` occurs before origin of alsa `StreamInstant`");
|
||||||
let timestamp = InputStreamTimestamp { callback, capture };
|
let timestamp = crate::InputStreamTimestamp { callback, capture };
|
||||||
let info = InputCallbackInfo { timestamp };
|
let info = InputCallbackInfo { timestamp };
|
||||||
callback(&data, &info);
|
data_callback(&data, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
match (&stream_type, sample_format) {
|
match (&stream_type, sample_format) {
|
||||||
|
@ -269,6 +270,7 @@ impl Device {
|
||||||
let playing = Arc::clone(&stream_playing);
|
let playing = Arc::clone(&stream_playing);
|
||||||
let asio_streams = self.asio_streams.clone();
|
let asio_streams = self.asio_streams.clone();
|
||||||
|
|
||||||
|
let config = config.clone();
|
||||||
let callback_id = self.driver.add_callback(move |callback_info| unsafe {
|
let callback_id = self.driver.add_callback(move |callback_info| unsafe {
|
||||||
// If not playing, return early.
|
// If not playing, return early.
|
||||||
if !playing.load(Ordering::SeqCst) {
|
if !playing.load(Ordering::SeqCst) {
|
||||||
|
@ -288,7 +290,7 @@ impl Device {
|
||||||
// the current `buffer_index`.
|
// the current `buffer_index`.
|
||||||
//
|
//
|
||||||
// If not, we will silence it and set the opposite buffer half to unsilenced.
|
// If not, we will silence it and set the opposite buffer half to unsilenced.
|
||||||
let silence = match buffer_index {
|
let silence = match callback_info.buffer_index {
|
||||||
0 if !silence_asio_buffer.first => {
|
0 if !silence_asio_buffer.first => {
|
||||||
silence_asio_buffer.first = true;
|
silence_asio_buffer.first = true;
|
||||||
silence_asio_buffer.second = false;
|
silence_asio_buffer.second = false;
|
||||||
|
@ -309,7 +311,7 @@ impl Device {
|
||||||
/// 3. Finally, write the interleaved data to the non-interleaved ASIO buffer,
|
/// 3. Finally, write the interleaved data to the non-interleaved ASIO buffer,
|
||||||
/// performing endianness conversions as necessary.
|
/// performing endianness conversions as necessary.
|
||||||
unsafe fn process_output_callback<A, B, D, F>(
|
unsafe fn process_output_callback<A, B, D, F>(
|
||||||
callback: &mut D,
|
data_callback: &mut D,
|
||||||
interleaved: &mut [u8],
|
interleaved: &mut [u8],
|
||||||
silence_asio_buffer: bool,
|
silence_asio_buffer: bool,
|
||||||
asio_stream: &sys::AsioStream,
|
asio_stream: &sys::AsioStream,
|
||||||
|
@ -333,9 +335,9 @@ impl Device {
|
||||||
let playback = callback
|
let playback = callback
|
||||||
.add(delay)
|
.add(delay)
|
||||||
.expect("`playback` occurs beyond representation supported by `StreamInstant`");
|
.expect("`playback` occurs beyond representation supported by `StreamInstant`");
|
||||||
let timestamp = OutputStreamTimestamp { callback, playback };
|
let timestamp = crate::OutputStreamTimestamp { callback, playback };
|
||||||
let info = OutputCallbackInfo { timestamp };
|
let info = OutputCallbackInfo { timestamp };
|
||||||
callback(&mut data, &info);
|
data_callback(&mut data, &info);
|
||||||
|
|
||||||
// 2. Silence ASIO channels if necessary.
|
// 2. Silence ASIO channels if necessary.
|
||||||
let n_channels = interleaved.len() / n_frames;
|
let n_channels = interleaved.len() / n_frames;
|
||||||
|
@ -378,7 +380,7 @@ impl Device {
|
||||||
&mut interleaved,
|
&mut interleaved,
|
||||||
silence,
|
silence,
|
||||||
asio_stream,
|
asio_stream,
|
||||||
buffer_index as usize,
|
callback_info,
|
||||||
config.sample_rate,
|
config.sample_rate,
|
||||||
to_be,
|
to_be,
|
||||||
);
|
);
|
||||||
|
@ -608,10 +610,18 @@ impl AsioSample for f64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn asio_ns_to_double(val: sys::bindings::asio_import::ASIOTimeStamp) -> f64 {
|
||||||
|
let two_raised_to_32 = 4294967296.0;
|
||||||
|
val.lo as f64 + val.hi as f64 * two_raised_to_32
|
||||||
|
}
|
||||||
|
|
||||||
/// Asio retrieves system time via `timeGetTime` which returns the time in milliseconds.
|
/// Asio retrieves system time via `timeGetTime` which returns the time in milliseconds.
|
||||||
fn system_time_to_stream_instant(system_time: ai::ASIOTimeStamp) -> crate::StreamInstant {
|
fn system_time_to_stream_instant(
|
||||||
let secs = system_time as u64 / 1_000;
|
system_time: sys::bindings::asio_import::ASIOTimeStamp,
|
||||||
let nanos = ((system_time as u64 - secs * 1_000) * 1_000_000) as u32;
|
) -> crate::StreamInstant {
|
||||||
|
let systime_ns = asio_ns_to_double(system_time);
|
||||||
|
let secs = systime_ns as i64 / 1_000_000_000;
|
||||||
|
let nanos = (systime_ns as i64 - secs * 1_000_000_000) as u32;
|
||||||
crate::StreamInstant::new(secs, nanos)
|
crate::StreamInstant::new(secs, nanos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue