use opus_rs::silk::SilkResampler;
use opus_rs::silk::dec_api::SilkDecoder;
use opus_rs::silk::init_decoder::silk_decoder_set_fs;
use opus_rs::{Application, OpusDecoder, OpusEncoder};
use std::f32::consts::PI;
#[test]
fn p0_cross_bandwidth_plc_lag_no_panic() {
let wb_frame = 320usize; let mut wb_enc = OpusEncoder::new(16000, 1, Application::Voip).unwrap();
wb_enc.bitrate_bps = 24000;
wb_enc.use_cbr = true;
let wb_input: Vec<f32> = (0..wb_frame)
.map(|i| (2.0 * PI * 120.0 * (i as f32 / 16000.0)).sin() * 0.4)
.collect();
let nb_frame = 160usize; let mut nb_enc = OpusEncoder::new(8000, 1, Application::Voip).unwrap();
nb_enc.bitrate_bps = 12000;
nb_enc.use_cbr = true;
let nb_input = vec![0.0f32; nb_frame];
let mut dec = OpusDecoder::new(16000, 1).unwrap();
let mut wb_pkt = vec![0u8; 1500];
let n = wb_enc
.encode(&wb_input, wb_frame, &mut wb_pkt)
.expect("wb encode");
let mut pcm = vec![0.0f32; 2 * wb_frame];
dec.decode(&wb_pkt[..n], wb_frame, &mut pcm)
.expect("wb decode");
let _ = dec.decode(&[0x48u8], wb_frame, &mut pcm);
let mut nb_pkt = vec![0u8; 1500];
let m = nb_enc
.encode(&nb_input, nb_frame, &mut nb_pkt)
.expect("nb encode");
let res = dec.decode(&nb_pkt[..m], 2 * nb_frame, &mut pcm);
assert!(
res.is_ok(),
"cross-bandwidth recovery frame must not panic: {res:?}"
);
}
#[test]
fn p0_set_fs_resets_state_on_bandwidth_change() {
use opus_rs::silk::define::TYPE_NO_VOICE_ACTIVITY;
let mut dec = opus_rs::silk::dec_api::SilkDecoder::new();
assert_eq!(dec.init(16000, 1), 0);
dec.channel_state[0].lag_prev = 288;
dec.channel_state[0].prev_signal_type = 2; dec.channel_state[0].first_frame_after_reset = 0;
dec.channel_state[0].out_buf[10] = 1234;
assert_eq!(silk_decoder_set_fs(&mut dec.channel_state[0], 16, 16000), 0);
assert_eq!(dec.channel_state[0].lag_prev, 288);
assert_eq!(silk_decoder_set_fs(&mut dec.channel_state[0], 8, 16000), 0);
assert_eq!(dec.channel_state[0].lag_prev, 100);
assert_eq!(
dec.channel_state[0].prev_signal_type,
TYPE_NO_VOICE_ACTIVITY
);
assert_eq!(dec.channel_state[0].first_frame_after_reset, 1);
assert!(dec.channel_state[0].out_buf.iter().all(|&v| v == 0));
assert_eq!(dec.channel_state[0].lpc_order, 10); assert_eq!(dec.channel_state[0].ltp_mem_length, 160);
}
#[test]
fn p0_silk_layer_cross_bandwidth_recovery() {
use opus_rs::range_coder::RangeCoder;
use opus_rs::silk::decode_frame::{FLAG_DECODE_NORMAL, FLAG_PACKET_LOST};
let wb_frame = 320usize;
let nb_frame = 160usize;
let mut wb_enc = OpusEncoder::new(16000, 1, Application::Voip).unwrap();
wb_enc.bitrate_bps = 24000;
wb_enc.use_cbr = true;
let wb_input: Vec<f32> = (0..wb_frame)
.map(|i| (2.0 * PI * 120.0 * (i as f32 / 16000.0)).sin() * 0.4)
.collect();
let mut wb_pkt = vec![0u8; 1500];
let n = wb_enc
.encode(&wb_input, wb_frame, &mut wb_pkt)
.expect("enc");
let mut nb_enc = OpusEncoder::new(8000, 1, Application::Voip).unwrap();
nb_enc.bitrate_bps = 12000;
nb_enc.use_cbr = true;
let nb_input = vec![0.0f32; nb_frame];
let mut nb_pkt = vec![0u8; 1500];
let m = nb_enc
.encode(&nb_input, nb_frame, &mut nb_pkt)
.expect("enc2");
let mut dec = SilkDecoder::new();
assert_eq!(dec.init(16000, 1), 0);
let mut out = vec![0i16; wb_frame];
let mut rc1 = RangeCoder::new_decoder(&wb_pkt[2..n]);
let r1 = dec.decode(&mut rc1, &mut out, FLAG_DECODE_NORMAL, true, 20, 16000);
assert_eq!(r1, wb_frame as i32);
assert_eq!(dec.channel_state[0].prev_signal_type, 2); assert!(
dec.channel_state[0].lag_prev > 160,
"test requires a large WB lag"
);
let mut rc2 = RangeCoder::new_decoder(&[]);
let r2 = dec.decode(&mut rc2, &mut out, FLAG_PACKET_LOST, true, 20, 16000);
assert_eq!(r2, wb_frame as i32);
assert_eq!(dec.channel_state[0].loss_cnt, 1);
assert_eq!(silk_decoder_set_fs(&mut dec.channel_state[0], 8, 16000), 0);
assert_eq!(dec.channel_state[0].fs_khz, 8);
assert_eq!(dec.channel_state[0].lag_prev, 100);
let mut rc3 = RangeCoder::new_decoder(&nb_pkt[2..m]);
let r3 = dec.decode(&mut rc3, &mut out, FLAG_DECODE_NORMAL, true, 20, 8000);
assert_eq!(r3, nb_frame as i32);
}
#[test]
fn p1_resampler_init_zero_out_rate() {
let mut res = SilkResampler::default();
assert_eq!(res.init(16000, 0), -1);
let mut res2 = SilkResampler::default();
assert_eq!(res2.init(0, 16000), -1);
}
#[test]
fn p1_hp_cutoff_invalid_fs_no_panic() {
let input = vec![0.5f32; 160];
let mut output = vec![0i16; 160];
let mut hp_mem = [0i32; 2];
opus_rs::hp_cutoff::hp_cutoff(
&input,
60,
&mut output,
&mut hp_mem,
160,
1,
500, );
}
#[test]
fn p1_exp_rotation_zero_stride_no_panic() {
let mut x = vec![0.5f32; 64];
opus_rs::pvq::exp_rotation(&mut x, 64, -1, 0, 2, 1);
}
#[test]
#[should_panic(expected = "channels must be 1 or 2")]
fn p1_celt_encoder_new_rejects_channels() {
let _ = opus_rs::celt::CeltEncoder::new(opus_rs::modes::default_mode(), 3);
}
#[test]
#[should_panic(expected = "channels must be 1 or 2")]
fn p1_celt_decoder_new_rejects_channels() {
let _ = opus_rs::celt::CeltDecoder::new(opus_rs::modes::default_mode(), 3, 48000);
}
#[test]
fn p1_celt_decode_invalid_frame_size_rejected() {
let mut dec = opus_rs::celt::CeltDecoder::new(opus_rs::modes::default_mode(), 1, 48000);
let pkt = [0xABu8; 64];
let mut pcm = vec![0.0f32; 100];
assert_eq!(dec.decode(&pkt, 100, &mut pcm), 0);
let mut tiny = vec![0.0f32; 8];
assert_eq!(dec.decode(&pkt, 960, &mut tiny), 0);
}
#[test]
#[should_panic(expected = "encode: ft must be > 0")]
fn p1_range_coder_encode_ft_zero_panics() {
use opus_rs::range_coder::RangeCoder;
let mut rc = RangeCoder::new_encoder(16);
rc.encode(0, 0, 0);
}
#[test]
fn p1_pitch_xcorr_short_y_no_panic() {
let x = vec![0.25f32; 40];
let y = vec![0.5f32; 50]; let mut xcorr = vec![0.0f32; 60];
opus_rs::pitch::pitch_xcorr(&x, &y, &mut xcorr, 40, 60);
}
#[test]
fn p2_encoder_extreme_fields_no_panic() {
let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
enc.bitrate_bps = i32::MAX;
enc.complexity = i32::MAX;
enc.packet_loss_perc = i32::MAX;
let input = vec![0.0f32; 960];
let mut pkt = vec![0u8; 1500];
let res = enc.encode(&input, 960, &mut pkt);
assert!(res.is_ok(), "encode with extreme fields must not panic");
let mut enc2 = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
enc2.bitrate_bps = i32::MIN;
enc2.complexity = i32::MIN;
enc2.packet_loss_perc = i32::MIN;
let res2 = enc2.encode(&input, 960, &mut pkt);
assert!(res2.is_ok(), "encode with extreme fields must not panic");
}