use core::convert::TryFrom;
use crate::silk::cng::CngState;
use crate::silk::decode_indices::SideInfoIndices;
use crate::silk::decoder_set_fs::{DecoderSampleRateState, MAX_FRAME_LENGTH};
use crate::silk::vq_wmat_ec::LTP_ORDER;
use crate::silk::{FrameSignalType, MAX_FRAMES_PER_PACKET, MAX_LPC_ORDER};
const UNITY_Q16: i32 = 1 << 16;
const DEFAULT_PLC_SUBFRAME_LENGTH: i32 = 20;
const DEFAULT_PLC_SUBFRAME_COUNT: i32 = 2;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PacketLossConcealmentState {
pub pitch_l_q8: i32,
pub ltp_coef_q14: [i16; LTP_ORDER],
pub prev_lpc_q12: [i16; MAX_LPC_ORDER],
pub last_frame_lost: i32,
pub rand_seed: i32,
pub rand_scale_q14: i16,
pub conc_energy: i32,
pub conc_energy_shift: i32,
pub prev_ltp_scale_q14: i16,
pub prev_gain_q16: [i32; 2],
pub fs_khz: i32,
pub nb_subfr: i32,
pub subfr_length: i32,
pub enable_deep_plc: bool,
}
impl Default for PacketLossConcealmentState {
fn default() -> Self {
Self {
pitch_l_q8: 0,
ltp_coef_q14: [0; LTP_ORDER],
prev_lpc_q12: [0; MAX_LPC_ORDER],
last_frame_lost: 0,
rand_seed: 0,
rand_scale_q14: 0,
conc_energy: 0,
conc_energy_shift: 0,
prev_ltp_scale_q14: 0,
prev_gain_q16: [UNITY_Q16; 2],
fs_khz: 0,
nb_subfr: DEFAULT_PLC_SUBFRAME_COUNT,
subfr_length: DEFAULT_PLC_SUBFRAME_LENGTH,
enable_deep_plc: false,
}
}
}
impl PacketLossConcealmentState {
pub fn reset(&mut self, frame_length: usize) {
let samples = i32::try_from(frame_length)
.expect("decoder frame length must fit in a signed 32-bit integer");
self.pitch_l_q8 = samples << 7;
self.prev_gain_q16 = [UNITY_Q16; 2];
self.subfr_length = DEFAULT_PLC_SUBFRAME_LENGTH;
self.nb_subfr = DEFAULT_PLC_SUBFRAME_COUNT;
self.last_frame_lost = 0;
self.rand_seed = 0;
self.rand_scale_q14 = 0;
self.conc_energy = 0;
self.conc_energy_shift = 0;
self.prev_ltp_scale_q14 = 0;
self.fs_khz = 0;
self.enable_deep_plc = false;
self.ltp_coef_q14 = [0; LTP_ORDER];
self.prev_lpc_q12 = [0; MAX_LPC_ORDER];
}
}
#[derive(Debug)]
pub struct DecoderState {
pub sample_rate: DecoderSampleRateState,
pub prev_gain_q16: i32,
pub exc_q14: [i32; MAX_FRAME_LENGTH],
pub prev_nlsf_q15: [i16; MAX_LPC_ORDER],
pub indices: SideInfoIndices,
pub n_frames_decoded: i32,
pub n_frames_per_packet: i32,
pub ec_prev_signal_type: FrameSignalType,
pub ec_prev_lag_index: i16,
pub vad_flags: [i32; MAX_FRAMES_PER_PACKET],
pub lbrr_flag: i32,
pub lbrr_flags: [i32; MAX_FRAMES_PER_PACKET],
pub cng_state: CngState,
pub loss_count: i32,
pub arch: i32,
pub plc_state: PacketLossConcealmentState,
}
impl Default for DecoderState {
fn default() -> Self {
Self {
sample_rate: DecoderSampleRateState::default(),
prev_gain_q16: UNITY_Q16,
exc_q14: [0; MAX_FRAME_LENGTH],
prev_nlsf_q15: [0; MAX_LPC_ORDER],
indices: SideInfoIndices::default(),
n_frames_decoded: 0,
n_frames_per_packet: 0,
ec_prev_signal_type: FrameSignalType::Inactive,
ec_prev_lag_index: 0,
vad_flags: [0; MAX_FRAMES_PER_PACKET],
lbrr_flag: 0,
lbrr_flags: [0; MAX_FRAMES_PER_PACKET],
cng_state: CngState::default(),
loss_count: 0,
arch: 0,
plc_state: PacketLossConcealmentState::default(),
}
}
}
impl DecoderState {
pub fn sample_rate(&self) -> &DecoderSampleRateState {
&self.sample_rate
}
pub fn sample_rate_mut(&mut self) -> &mut DecoderSampleRateState {
&mut self.sample_rate
}
pub fn excitation_q14(&self) -> &[i32; MAX_FRAME_LENGTH] {
&self.exc_q14
}
pub fn excitation_q14_mut(&mut self) -> &mut [i32; MAX_FRAME_LENGTH] {
&mut self.exc_q14
}
}
#[cfg(test)]
mod tests {
use super::{
DEFAULT_PLC_SUBFRAME_COUNT, DEFAULT_PLC_SUBFRAME_LENGTH, DecoderState,
PacketLossConcealmentState, UNITY_Q16,
};
use crate::silk::decoder_set_fs::MAX_FRAME_LENGTH;
use crate::silk::{MAX_FRAMES_PER_PACKET, MAX_LPC_ORDER};
#[test]
fn decoder_state_defaults_are_zeroed() {
let state = DecoderState::default();
assert_eq!(state.prev_gain_q16, UNITY_Q16);
assert_eq!(state.exc_q14, [0; MAX_FRAME_LENGTH]);
assert_eq!(state.prev_nlsf_q15, [0; MAX_LPC_ORDER]);
assert_eq!(state.n_frames_decoded, 0);
assert_eq!(state.n_frames_per_packet, 0);
assert_eq!(state.loss_count, 0);
assert_eq!(state.lbrr_flag, 0);
assert_eq!(state.lbrr_flags, [0; MAX_FRAMES_PER_PACKET]);
}
#[test]
fn plc_reset_matches_reference_defaults() {
let mut plc = PacketLossConcealmentState::default();
plc.reset(160);
assert_eq!(plc.pitch_l_q8, 160 << 7);
assert_eq!(plc.prev_gain_q16, [UNITY_Q16; 2]);
assert_eq!(plc.subfr_length, DEFAULT_PLC_SUBFRAME_LENGTH);
assert_eq!(plc.nb_subfr, DEFAULT_PLC_SUBFRAME_COUNT);
}
}