Skip to main content

opus_rs/silk/
structs.rs

1use crate::fixedvec::FixedVec;
2use crate::silk::define::*;
3
4/// SILK maximum frame length in samples (`5 * 4 * 16`). Used to size the
5/// heap-free stereo side buffer.
6const SILK_SIDE_MAX: usize = MAX_FRAME_LENGTH;
7
8#[derive(Clone, Default)]
9pub struct SilkStereoState {
10    pub s_mid: [i16; 2],
11
12    pub s_side: [i16; 2],
13
14    pub left: i16,
15
16    pub side: FixedVec<i16, SILK_SIDE_MAX>,
17}
18
19#[derive(Clone, Copy)]
20pub struct NLSFCodebook {
21    pub n_vectors: i16,
22    pub order: i16,
23    pub quant_step_size_q16: i32,
24    pub inv_quant_step_size_q6: i16,
25    pub cb1_nlsf_q8: &'static [u8],
26    pub cb1_wght_q9: &'static [i16],
27    pub cb1_icdf: &'static [u8],
28    pub pred_q8: &'static [u8],
29    pub ec_sel: &'static [u8],
30    pub ec_icdf: &'static [u8],
31    pub ec_rates_q5: &'static [u8],
32    pub delta_min_q15: &'static [i16],
33}
34
35#[derive(Clone, Copy)]
36pub struct SideInfoIndices {
37    pub gains_indices: [i8; MAX_NB_SUBFR],
38    pub ltp_index: [i8; MAX_NB_SUBFR],
39    pub nlsf_indices: [i8; MAX_LPC_ORDER + 1],
40    pub lag_index: i16,
41    pub contour_index: i8,
42    pub signal_type: i8,
43    pub voicing_idx: i8,
44    pub quant_offset_type: i8,
45    pub nlsf_interp_coef_q2: i8,
46    pub per_index: i8,
47    pub ltp_scale_index: i8,
48    pub seed: i8,
49
50    pub pred_idx: i8,
51
52    pub side_idx: i8,
53
54    pub only_middle: i8,
55}
56
57impl Default for SideInfoIndices {
58    fn default() -> Self {
59        Self {
60            gains_indices: [0; MAX_NB_SUBFR],
61            ltp_index: [0; MAX_NB_SUBFR],
62            nlsf_indices: [0; MAX_LPC_ORDER + 1],
63            lag_index: 0,
64            contour_index: 0,
65            signal_type: 0,
66            voicing_idx: 0,
67            quant_offset_type: 0,
68            nlsf_interp_coef_q2: 4,
69            per_index: 0,
70            ltp_scale_index: 0,
71            seed: 0,
72            pred_idx: 0,
73            side_idx: 0,
74            only_middle: 0,
75        }
76    }
77}
78
79#[derive(Clone, Copy, Default)]
80pub struct SilkShapeState {
81    pub last_gain_index: i8,
82    pub harm_boost_smth_q16: i32,
83    pub harm_shape_gain_smth_q16: i32,
84    pub tilt_smth_q16: i32,
85}
86
87#[derive(Clone, Copy)]
88pub struct SilkVADState {
89    pub ana_state: [i32; 2],
90    pub ana_state1: [i32; 2],
91    pub ana_state2: [i32; 2],
92    pub xnrg_subfr: [i32; VAD_N_BANDS],
93    pub nrg_ratio_smth_q8: [i32; VAD_N_BANDS],
94    pub hp_state: i16,
95    pub nl: [i32; VAD_N_BANDS],
96    pub inv_nl: [i32; VAD_N_BANDS],
97    pub noise_level_bias: [i32; VAD_N_BANDS],
98    pub counter: i32,
99}
100
101impl Default for SilkVADState {
102    fn default() -> Self {
103        Self {
104            ana_state: [0; 2],
105            ana_state1: [0; 2],
106            ana_state2: [0; 2],
107            xnrg_subfr: [0; VAD_N_BANDS],
108            nrg_ratio_smth_q8: [0; VAD_N_BANDS],
109            hp_state: 0,
110            nl: [0; VAD_N_BANDS],
111            inv_nl: [0; VAD_N_BANDS],
112            noise_level_bias: [0; VAD_N_BANDS],
113            counter: 0,
114        }
115    }
116}
117
118#[derive(Clone, Copy, Default)]
119pub struct SilkLPState {
120    pub in_lp_state: [i32; 2],
121    pub transition_frame_no: i32,
122    pub mode: i32,
123    pub saved_fs_khz: i32,
124}
125
126pub struct SilkEncoderStateCommon {
127    pub indices: SideInfoIndices,
128    pub in_hp_state: [i32; 2],
129    pub snr_db_q7: i32,
130    pub input_quality_bands_q15: [i32; VAD_N_BANDS],
131    pub speech_activity_q8: i32,
132    pub use_cbr: i32,
133    pub fs_khz: i32,
134    pub nb_subfr: i32,
135    pub warping_q16: i32,
136    pub la_shape: i32,
137    pub shape_win_length: i32,
138    pub shaping_lpc_order: i32,
139    pub predict_lpc_order: i32,
140    pub subfr_length: i32,
141    pub la_pitch: i32,
142    pub frame_length: i32,
143    pub ltp_mem_length: i32,
144    pub pitch_lpc_win_length: i32,
145    pub pitch_estimation_complexity: i32,
146    pub pitch_estimation_threshold_q16: i32,
147    pub first_frame_after_reset: i32,
148    pub prev_signal_type: i32,
149    pub input_tilt_q15: i32,
150    pub n_states_delayed_decision: i32,
151    pub prev_lag: i32,
152    pub x_buf: [i16; 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX],
153    pub x_buf_idx: i32,
154    pub prev_nlsf_q15: [i16; MAX_LPC_ORDER],
155    pub nlsf_mu_q20: i32,
156    pub n_nlsf_survivors: i32,
157    pub variable_hp_smth1_q15: i32,
158    pub variable_hp_smth2_q15: i32,
159    pub s_lp: SilkLPState,
160    pub s_vad: SilkVADState,
161    pub lbrr_enabled: i32,
162    pub indices_lbrr: [SideInfoIndices; MAX_FRAMES_PER_PACKET],
163    pub pulses_lbrr: [[i8; MAX_FRAME_LENGTH]; MAX_FRAMES_PER_PACKET],
164    pub n_frames_encoded: i32,
165    pub n_frames_per_packet: i32,
166    pub target_rate_bps: i32,
167    pub packet_size_ms: i32,
168    pub complexity: i32,
169    pub sum_log_gain_q7: i32,
170    pub packet_loss_perc: i32,
171    pub lbrr_flag: i8,
172    pub no_speech_counter: i32,
173    pub in_dtx: i32,
174    pub vad_flags: [i32; MAX_FRAMES_PER_PACKET],
175
176    pub frame_counter: i32,
177    pub ec_prev_signal_type: i32,
178    pub ec_prev_lag_index: i16,
179    pub frames_since_onset: i32,
180    pub input_buf: [i16; MAX_FRAME_LENGTH + 2],
181    pub input_buf_ix: i32,
182    pub controlled_since_last_payload: i32,
183    pub use_interpolated_nlsfs: i32,
184    pub use_dtx: i32,
185    pub use_in_band_fec: i32,
186    pub lbrr_gain_increases: i32,
187    pub lbrr_flags: [i32; MAX_FRAMES_PER_PACKET],
188    pub prefill_flag: i32,
189
190    pub n_channels: i32,
191}
192
193impl Default for SilkEncoderStateCommon {
194    fn default() -> Self {
195        Self {
196            indices: SideInfoIndices::default(),
197            in_hp_state: [0; 2],
198            snr_db_q7: 0,
199            input_quality_bands_q15: [0; VAD_N_BANDS],
200            speech_activity_q8: 0,
201            use_cbr: 0,
202            fs_khz: 0,
203            nb_subfr: 0,
204            warping_q16: 0,
205            la_shape: 0,
206            shape_win_length: 0,
207            shaping_lpc_order: 0,
208            predict_lpc_order: 0,
209            subfr_length: 0,
210            la_pitch: 0,
211            frame_length: 0,
212            ltp_mem_length: 0,
213            pitch_lpc_win_length: 0,
214            pitch_estimation_complexity: 0,
215            pitch_estimation_threshold_q16: 0,
216            first_frame_after_reset: 0,
217            prev_signal_type: 0,
218            input_tilt_q15: 0,
219            n_states_delayed_decision: 0,
220            prev_lag: 0,
221            x_buf: [0; 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX],
222            x_buf_idx: 0,
223            prev_nlsf_q15: [0; MAX_LPC_ORDER],
224            nlsf_mu_q20: 0,
225            n_nlsf_survivors: 0,
226            variable_hp_smth1_q15: 0,
227            variable_hp_smth2_q15: 0,
228            s_lp: SilkLPState::default(),
229            s_vad: SilkVADState::default(),
230            lbrr_enabled: 0,
231            indices_lbrr: [SideInfoIndices::default(); MAX_FRAMES_PER_PACKET],
232            pulses_lbrr: [[0; MAX_FRAME_LENGTH]; MAX_FRAMES_PER_PACKET],
233            n_frames_encoded: 0,
234            n_frames_per_packet: 0,
235            target_rate_bps: 0,
236            packet_size_ms: 0,
237            complexity: 0,
238            sum_log_gain_q7: 0,
239            packet_loss_perc: 0,
240            lbrr_flag: 0,
241            no_speech_counter: 0,
242            in_dtx: 0,
243            vad_flags: [0; MAX_FRAMES_PER_PACKET],
244            frame_counter: 0,
245            ec_prev_signal_type: 0,
246            ec_prev_lag_index: 0,
247            frames_since_onset: 0,
248            input_buf: [0; MAX_FRAME_LENGTH + 2],
249            input_buf_ix: 0,
250            controlled_since_last_payload: 0,
251            use_interpolated_nlsfs: 0,
252            use_dtx: 0,
253            use_in_band_fec: 0,
254            lbrr_gain_increases: 0,
255            lbrr_flags: [0; MAX_FRAMES_PER_PACKET],
256            prefill_flag: 0,
257            n_channels: 1,
258        }
259    }
260}
261
262pub struct SilkEncoderState {
263    pub s_cmn: SilkEncoderStateCommon,
264    pub s_shape: SilkShapeState,
265    pub pulses: [i8; MAX_FRAME_LENGTH],
266    pub s_nsq: SilkNSQState,
267    pub ltp_corr_q15: i32,
268    pub res_nrg_smth: i32,
269    pub pitch_estimation_lpc_order: i32,
270    pub ps_nlsf_cb: Option<&'static NLSFCodebook>,
271
272    pub stereo: SilkStereoState,
273
274    pub resampler_delay_buf: [i16; 48],
275}
276
277impl Default for SilkEncoderState {
278    fn default() -> Self {
279        Self {
280            s_cmn: SilkEncoderStateCommon::default(),
281            s_shape: SilkShapeState::default(),
282            pulses: [0; MAX_FRAME_LENGTH],
283            s_nsq: SilkNSQState::default(),
284            ltp_corr_q15: 0,
285            res_nrg_smth: 0,
286            pitch_estimation_lpc_order: 0,
287            ps_nlsf_cb: None,
288            stereo: SilkStereoState::default(),
289            resampler_delay_buf: [0; 48],
290        }
291    }
292}
293
294#[derive(Clone, Copy)]
295pub struct SilkNSQState {
296    pub xq: [i16; 2 * MAX_FRAME_LENGTH],
297    pub s_ltp_shp_q14: [i32; 2 * MAX_FRAME_LENGTH],
298    pub s_lpc_q14: [i32; MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH],
299    pub s_ar2_q14: [i32; MAX_SHAPE_LPC_ORDER],
300    pub s_lf_ar_q14: i32,
301    pub s_diff_shp_q14: i32,
302    pub lag_prev: i32,
303    pub s_ltp_buf_idx: i32,
304    pub s_ltp_shp_buf_idx: i32,
305    pub rand_seed: i32,
306    pub prev_gain_q16: i32,
307    pub rewhite_flag: i32,
308    pub prev_sig_type: i8,
309}
310
311impl Default for SilkNSQState {
312    fn default() -> Self {
313        Self {
314            xq: [0; 2 * MAX_FRAME_LENGTH],
315            s_ltp_shp_q14: [0; 2 * MAX_FRAME_LENGTH],
316            s_lpc_q14: [0; MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH],
317            s_ar2_q14: [0; MAX_SHAPE_LPC_ORDER],
318            s_lf_ar_q14: 0,
319            s_diff_shp_q14: 0,
320            lag_prev: 0,
321            s_ltp_buf_idx: 0,
322            s_ltp_shp_buf_idx: 0,
323            rand_seed: 0,
324            prev_gain_q16: 0,
325            rewhite_flag: 0,
326            prev_sig_type: 0,
327        }
328    }
329}
330
331#[derive(Clone, Copy)]
332pub struct SilkEncoderControl {
333    pub input_quality_q14: i32,
334    pub coding_quality_q14: i32,
335    pub pitch_l: [i32; MAX_NB_SUBFR],
336    pub gains_q16: [i32; MAX_NB_SUBFR],
337    pub gains_unq_q16: [i32; MAX_NB_SUBFR],
338    pub pred_coef_q12: [[i16; MAX_LPC_ORDER]; 2],
339    pub ltp_coef_q14: [i16; MAX_NB_SUBFR * LTP_ORDER],
340    pub ltp_scale_q14: i32,
341    pub ar_q13: [i16; MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
342    pub lf_shp_q14: [i32; MAX_NB_SUBFR],
343    pub tilt_q14: [i32; MAX_NB_SUBFR],
344    pub harm_shape_gain_q14: [i32; MAX_NB_SUBFR],
345    pub lambda_q10: i32,
346    pub pred_gain_q16: i32,
347    pub ltp_red_cod_gain_q7: i32,
348    pub res_nrg: [i32; MAX_NB_SUBFR],
349    pub res_nrg_q: [i32; MAX_NB_SUBFR],
350    pub last_gain_index_prev: i8,
351}
352
353impl Default for SilkEncoderControl {
354    fn default() -> Self {
355        Self {
356            input_quality_q14: 0,
357            coding_quality_q14: 0,
358            pitch_l: [0; MAX_NB_SUBFR],
359            gains_q16: [0; MAX_NB_SUBFR],
360            gains_unq_q16: [0; MAX_NB_SUBFR],
361            pred_coef_q12: [[0; MAX_LPC_ORDER]; 2],
362            ltp_coef_q14: [0; MAX_NB_SUBFR * LTP_ORDER],
363            ltp_scale_q14: 0,
364            ar_q13: [0; MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
365            lf_shp_q14: [0; MAX_NB_SUBFR],
366            tilt_q14: [0; MAX_NB_SUBFR],
367            harm_shape_gain_q14: [0; MAX_NB_SUBFR],
368            lambda_q10: 0,
369            pred_gain_q16: 0,
370            ltp_red_cod_gain_q7: 0,
371            res_nrg: [0; MAX_NB_SUBFR],
372            res_nrg_q: [0; MAX_NB_SUBFR],
373            last_gain_index_prev: 0,
374        }
375    }
376}