diff --git a/src/decoder.rs b/src/decoder.rs index 962b0d1..5ae64a6 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -258,6 +258,36 @@ impl Decoder { map_sys_error!(result => ()) } + #[cfg(feature = "dred")] + #[inline] + ///Configures the decoder's computational complexity. + /// + ///The supported range is 0-10 inclusive with 10 representing the highest complexity. + ///Values of 5 or above will use deep packet loss concealment. + pub fn set_complexity(&mut self, value: u8) -> Result<(), ErrorCode> { + let result = unsafe { + sys::opus_decoder_ctl( + self.inner.as_mut(), + sys::OPUS_SET_COMPLEXITY_REQUEST, + value as i32, + ) + }; + + map_sys_error!(result => ()) + } + + #[cfg(feature = "dred")] + #[inline] + ///Gets the decoder's complexity configuration. + pub fn get_complexity(&mut self) -> Result { + let mut value: i32 = 0; + let result = unsafe { + sys::opus_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_COMPLEXITY_REQUEST, &mut value) + }; + + map_sys_error!(result => value as u8) + } + #[inline] ///Gets the decoder's last bandpass pub fn get_bandwidth(&mut self) -> Result { diff --git a/tests/opus.rs b/tests/opus.rs index 18e090a..b61cb77 100644 --- a/tests/opus.rs +++ b/tests/opus.rs @@ -255,6 +255,49 @@ fn should_verify_decoder_building() { } } +#[test] +#[cfg(feature = "dred")] +fn should_verify_decoder_complexity() { + let mut decoder = Decoder::new(Channels::Stereo, SampleRate::Hz48000).expect("Create"); + decoder.set_complexity(5).expect("set complexity"); + let value = decoder.get_complexity().expect("get complexity"); + assert_eq!(value, 5); +} + +#[test] +#[cfg(feature = "dred")] +fn should_produce_different_artifacts_on_packet_loss() { + const SIZE_20MS: usize = frame_bytes_size(SampleRate::Hz48000, Channels::Stereo, 20); + + //Helper to prime a decoder and get the concealed audio from a subsequent packet loss. + fn get_concealed_audio(complexity: u8, packet: &[u8]) -> Vec { + let mut decoder = Decoder::new(Channels::Stereo, SampleRate::Hz48000).expect("Failed to create decoder"); + decoder.set_complexity(complexity).expect("Failed to set complexity"); + + let mut buffer = [0u16; SIZE_20MS]; + //Prime the decoder with one real frame. + decoder.decode_to_slice(packet, &mut buffer, false).expect("Failed to decode initial packet"); + //Get the concealed audio from a lost frame. + let len = decoder.decode_to_slice(&[], &mut buffer, false).expect("Failed to decode lost packet"); + buffer[..len].to_vec() + } + + //Create a non-silent audio frame to encode. + let mut encoder = Encoder::new(Channels::Stereo, SampleRate::Hz48000, Application::Audio).expect("Failed to create encoder"); + let input = [123u16; SIZE_20MS]; + let mut packet_buffer = [0u8; 256]; + let packet_len = encoder.encode_to_slice(&input, &mut packet_buffer).expect("Failed to encode"); + let packet = &packet_buffer[..packet_len]; + + //Get concealed audio for different complexities. + let concealed_c0 = get_concealed_audio(0, packet); + let concealed_c10 = get_concealed_audio(10, packet); + + //Assert the outputs are different. + assert_eq!(concealed_c0.len(), concealed_c10.len()); + assert_ne!(concealed_c0, concealed_c10, "Concealed audio should differ by complexity"); +} + #[test] fn should_fail_to_repacketizer() { let mut packet = [0u8; 1277];