use crate::{sys, mem, Decoder, ErrorCode, SampleRate, Bandwidth};
use core::num;
pub const DRED_PACKET_SIZE: usize = 10592;
pub fn dred_packet_size() -> usize {
unsafe {
sys::opus_dred_get_size() as _
}
}
#[repr(transparent)]
pub struct DredPacket {
inner: mem::Unique<sys::OpusDRED>
}
impl DredPacket {
pub fn new() -> Result<Self, ErrorCode> {
match mem::Unique::new(DRED_PACKET_SIZE) {
Some(inner) => Ok(DredPacket {
inner,
}),
None => Err(ErrorCode::AllocFail),
}
}
}
unsafe impl Send for DredPacket {}
pub struct Dred {
inner: mem::Unique<sys::OpusDREDDecoder>,
decoder: Decoder,
packet: DredPacket,
}
impl Dred {
pub fn new(decoder: Decoder) -> Result<Self, ErrorCode> {
let size = unsafe {
sys::opus_dred_decoder_get_size()
};
if size == 0 {
return Err(ErrorCode::Internal);
}
let packet = DredPacket::new()?;
let mut decoder = match mem::Unique::new(size as _) {
Some(inner) => Dred {
inner,
decoder,
packet,
},
None => return Err(ErrorCode::AllocFail)
};
let result = unsafe {
sys::opus_dred_decoder_init(decoder.inner.as_mut())
};
map_sys_error!(result => decoder)
}
pub fn decoder(&mut self) -> &Decoder {
&self.decoder
}
pub fn decoder_mut(&mut self) -> &mut Decoder {
&mut self.decoder
}
pub fn decode_to(&mut self, input: &[u8], output: &mut [mem::MaybeUninit<i16>]) -> Result<usize, ErrorCode> {
const MAX_SAMPLE_RATE: i32 = SampleRate::Hz48000 as _;
let mut _dred_end = 0;
let input_ptr = input.as_ptr();
let input_len = input.len() as _;
let frame_size = (output.len() / self.decoder.channels() as usize) as _;
let result = unsafe {
sys::opus_dred_parse(self.inner.as_mut(), self.packet.inner.as_mut(),
input_ptr, input_len,
MAX_SAMPLE_RATE, MAX_SAMPLE_RATE,
&mut _dred_end, 0)
};
if result < 0 {
return Err(result.into());
}
let result = unsafe {
sys::opus_decoder_dred_decode(
self.decoder.inner.as_mut(), self.packet.inner.as_ptr(),
frame_size, output.as_ptr() as _, frame_size
)
};
map_sys_error!(result => result as _)
}
#[inline(always)]
pub fn decode_to_slice(&mut self, input: &[u8], output: &mut [u16]) -> Result<usize, ErrorCode> {
self.decode_to(input, unsafe { mem::transmute(output) })
}
pub fn decode_float_to(&mut self, input: &[u8], output: &mut [mem::MaybeUninit<f32>]) -> Result<usize, ErrorCode> {
const MAX_SAMPLE_RATE: i32 = SampleRate::Hz48000 as _;
let mut _dred_end = 0;
let input_ptr = input.as_ptr();
let input_len = input.len() as _;
let frame_size = (output.len() / self.decoder.channels() as usize) as _;
let result = unsafe {
sys::opus_dred_parse(self.inner.as_mut(), self.packet.inner.as_mut(),
input_ptr, input_len,
MAX_SAMPLE_RATE, MAX_SAMPLE_RATE,
&mut _dred_end, 0)
};
if result < 0 {
return Err(result.into());
}
let result = unsafe {
sys::opus_decoder_dred_decode_float(
self.decoder.inner.as_mut(), self.packet.inner.as_ptr(),
frame_size, output.as_ptr() as _, frame_size
)
};
map_sys_error!(result => result as _)
}
#[inline(always)]
pub fn decode_float_to_slice(&mut self, input: &[u8], output: &mut [f32]) -> Result<usize, ErrorCode> {
self.decode_float_to(input, unsafe { mem::transmute(output) })
}
#[inline]
pub fn reset(&mut self) -> Result<(), ErrorCode> {
self.decoder.reset()?;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_RESET_STATE)
};
map_sys_error!(result => ())
}
#[inline]
pub fn get_pitch(&mut self) -> Result<Option<num::NonZeroU32>, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_PITCH_REQUEST, &mut value)
};
map_sys_error!(result => num::NonZeroU32::new(result as _))
}
#[inline]
pub fn get_last_packet_duration(&mut self) -> Result<u32, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_LAST_PACKET_DURATION_REQUEST, &mut value)
};
map_sys_error!(result => value as _)
}
#[inline]
pub fn get_gain(&mut self) -> Result<i32, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_GAIN_REQUEST, &mut value)
};
map_sys_error!(result => value)
}
#[inline]
pub fn set_gain(&mut self, value: i32) -> Result<(), ErrorCode> {
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_SET_GAIN_REQUEST, value)
};
map_sys_error!(result => ())
}
#[inline]
pub fn get_bandwidth(&mut self) -> Result<Bandwidth, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_BANDWIDTH_REQUEST, &mut value)
};
map_sys_error!(result => value.into())
}
#[inline]
pub fn get_sample_rate(&mut self) -> Result<SampleRate, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_SAMPLE_RATE_REQUEST, &mut value)
};
map_sys_error!(result => match value {
8000 => SampleRate::Hz8000,
12000 => SampleRate::Hz12000,
16000 => SampleRate::Hz16000,
24000 => SampleRate::Hz24000,
48000 => SampleRate::Hz48000,
_ => return Err(ErrorCode::unknown())
})
}
#[inline]
pub fn get_phase_inversion_disabled(&mut self) -> Result<bool, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, &mut value)
};
map_sys_error!(result => value == 1)
}
#[inline]
pub fn set_phase_inversion_disabled(&mut self, value: bool) -> Result<(), ErrorCode> {
let value: i32 = match value {
true => 1,
false => 0,
};
let result = unsafe {
sys::opus_dred_decoder_ctl(self.inner.as_mut(), sys::OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, value)
};
map_sys_error!(result => ())
}
}
unsafe impl Send for Dred {}