use std::ffi::c_void;
use std::os::raw::c_int;
use crate::{AVAudioFifo, AVSampleFormat, AvError};
pub unsafe fn alloc(
sample_fmt: AVSampleFormat,
channels: c_int,
nb_samples: c_int,
) -> Result<*mut AVAudioFifo, AvError> {
let fifo = unsafe { crate::av_audio_fifo_alloc(sample_fmt, channels, nb_samples) };
if fifo.is_null() {
Err(AvError::new(-1))
} else {
Ok(fifo)
}
}
pub unsafe fn free(fifo: *mut AVAudioFifo) {
unsafe { crate::av_audio_fifo_free(fifo) };
}
pub unsafe fn write(
fifo: *mut AVAudioFifo,
data: *const *mut c_void,
nb_samples: c_int,
) -> Result<c_int, AvError> {
let ret = unsafe { crate::av_audio_fifo_write(fifo, data, nb_samples) };
if ret < 0 {
Err(AvError::new(ret))
} else {
Ok(ret)
}
}
pub unsafe fn read(
fifo: *mut AVAudioFifo,
data: *const *mut c_void,
nb_samples: c_int,
) -> Result<c_int, AvError> {
let ret = unsafe { crate::av_audio_fifo_read(fifo, data, nb_samples) };
if ret < 0 {
Err(AvError::new(ret))
} else {
Ok(ret)
}
}
pub unsafe fn size(fifo: *mut AVAudioFifo) -> c_int {
unsafe { crate::av_audio_fifo_size(fifo) }
}
pub unsafe fn write_frame(
fifo: *mut AVAudioFifo,
src: &crate::Frame,
nb_samples: c_int,
) -> Result<c_int, AvError> {
let data = unsafe { (*src.as_ptr()).data.as_ptr().cast::<*mut c_void>() };
unsafe { write(fifo, data, nb_samples) }
}
pub unsafe fn read_frame(
fifo: *mut AVAudioFifo,
dst: &mut crate::Frame,
nb_samples: c_int,
) -> Result<c_int, AvError> {
let data = unsafe { (*dst.as_mut_ptr()).data.as_ptr().cast::<*mut c_void>() };
unsafe { read(fifo, data, nb_samples) }
}
#[cfg(test)]
mod tests {
use super::{alloc, free, read_frame, size, write_frame};
use crate::Frame;
use crate::swresample::{channel_layout, sample_format};
fn get_buffered_audio_frame(nb_samples: i32) -> Frame {
let mut f = Frame::new().expect("frame alloc");
f.set_format(sample_format::FLTP);
f.set_sample_rate(48_000);
f.set_nb_samples(nb_samples);
f.set_ch_layout(&channel_layout::with_channels(2))
.expect("set ch_layout");
f.get_buffer(0).expect("get_buffer");
f
}
#[test]
fn write_frame_then_read_frame_should_round_trip_the_sample_count() {
unsafe {
let fifo = alloc(sample_format::FLTP, 2, 1024).expect("fifo alloc");
let src = get_buffered_audio_frame(256);
assert_eq!(write_frame(fifo, &src, 256).expect("write_frame"), 256);
assert_eq!(size(fifo), 256);
let mut dst = get_buffered_audio_frame(256);
assert_eq!(read_frame(fifo, &mut dst, 256).expect("read_frame"), 256);
assert_eq!(size(fifo), 0);
free(fifo);
}
}
}