Skip to main content

opus_rs/silk/
control_codec.rs

1use crate::silk::define::*;
2use crate::silk::structs::*;
3use crate::silk::tables_nlsf::*;
4
5pub const FIND_PITCH_LPC_WIN_MS: i32 = 20 + (LA_PITCH_MS as i32 * 2);
6pub const FIND_PITCH_LPC_WIN_MS_2_SF: i32 = 10 + (LA_PITCH_MS as i32 * 2);
7pub const MAX_DEL_DEC_STATES: i32 = 4;
8pub const LA_SHAPE_MAX: i32 = LA_SHAPE_MS as i32 * MAX_FS_KHZ as i32;
9pub const SHAPE_LPC_WIN_MAX: i32 = 15 * MAX_FS_KHZ as i32;
10
11pub const WARPING_MULTIPLIER_Q16: i32 = 983;
12
13pub fn silk_setup_fs(ps_enc: &mut SilkEncoderState, fs_khz: i32, packet_size_ms: i32) -> i32 {
14    let cmn = &mut ps_enc.s_cmn;
15
16    if packet_size_ms <= 10 {
17        cmn.n_frames_per_packet = 1;
18        cmn.nb_subfr = if packet_size_ms == 10 { 2 } else { 1 };
19        cmn.frame_length = packet_size_ms * fs_khz;
20        cmn.pitch_lpc_win_length = FIND_PITCH_LPC_WIN_MS_2_SF * fs_khz;
21    } else {
22        cmn.n_frames_per_packet = packet_size_ms / MAX_FRAME_LENGTH_MS as i32;
23        cmn.nb_subfr = MAX_NB_SUBFR as i32;
24        cmn.frame_length = 20 * fs_khz;
25        cmn.pitch_lpc_win_length = FIND_PITCH_LPC_WIN_MS * fs_khz;
26    }
27    cmn.packet_size_ms = packet_size_ms;
28
29    if cmn.fs_khz != fs_khz {
30        ps_enc.s_nsq = SilkNSQState::default();
31        cmn.prev_nlsf_q15 = [0; MAX_LPC_ORDER];
32
33        cmn.prev_lag = 100;
34        cmn.first_frame_after_reset = 1;
35        ps_enc.s_shape.last_gain_index = 10;
36        ps_enc.s_nsq.lag_prev = 100;
37        ps_enc.s_nsq.prev_gain_q16 = 65536;
38        cmn.prev_signal_type = TYPE_NO_VOICE_ACTIVITY;
39
40        cmn.fs_khz = fs_khz;
41
42        if fs_khz == 8 || fs_khz == 12 {
43            cmn.predict_lpc_order = MIN_LPC_ORDER as i32;
44            ps_enc.ps_nlsf_cb = Some(&SILK_NLSF_CB_NB_MB);
45        } else {
46            cmn.predict_lpc_order = MAX_LPC_ORDER as i32;
47            ps_enc.ps_nlsf_cb = Some(&SILK_NLSF_CB_WB);
48        }
49
50        cmn.subfr_length = SUB_FRAME_LENGTH_MS as i32 * fs_khz;
51        cmn.frame_length = cmn.subfr_length * cmn.nb_subfr;
52        cmn.ltp_mem_length = LTP_MEM_LENGTH_MS as i32 * fs_khz;
53        cmn.la_pitch = LA_PITCH_MS as i32 * fs_khz;
54
55        if cmn.nb_subfr == MAX_NB_SUBFR as i32 {
56            cmn.pitch_lpc_win_length = FIND_PITCH_LPC_WIN_MS * fs_khz;
57        } else {
58            cmn.pitch_lpc_win_length = FIND_PITCH_LPC_WIN_MS_2_SF * fs_khz;
59        }
60    }
61
62    SILK_NO_ERROR
63}
64
65pub fn silk_setup_complexity(ps_enc: &mut SilkEncoderState, complexity: i32) -> i32 {
66    let cmn = &mut ps_enc.s_cmn;
67
68    if complexity < 1 {
69        cmn.pitch_estimation_complexity = SILK_PE_MIN_COMPLEX as i32;
70        cmn.pitch_estimation_threshold_q16 = (0.8f32 * 65536.0) as i32;
71        ps_enc.pitch_estimation_lpc_order = 6;
72        cmn.shaping_lpc_order = 12;
73        cmn.la_shape = 3 * cmn.fs_khz;
74        cmn.n_states_delayed_decision = 1;
75        cmn.use_interpolated_nlsfs = 0;
76        cmn.n_nlsf_survivors = 2;
77        cmn.warping_q16 = 0;
78    } else if complexity < 2 {
79        cmn.pitch_estimation_complexity = SILK_PE_MID_COMPLEX as i32;
80        cmn.pitch_estimation_threshold_q16 = (0.76f32 * 65536.0) as i32;
81        ps_enc.pitch_estimation_lpc_order = 8;
82        cmn.shaping_lpc_order = 14;
83        cmn.la_shape = 5 * cmn.fs_khz;
84        cmn.n_states_delayed_decision = 1;
85        cmn.use_interpolated_nlsfs = 0;
86        cmn.n_nlsf_survivors = 3;
87        cmn.warping_q16 = 0;
88    } else if complexity < 3 {
89        cmn.pitch_estimation_complexity = SILK_PE_MIN_COMPLEX as i32;
90        cmn.pitch_estimation_threshold_q16 = (0.8f32 * 65536.0) as i32;
91        ps_enc.pitch_estimation_lpc_order = 6;
92        cmn.shaping_lpc_order = 12;
93        cmn.la_shape = 3 * cmn.fs_khz;
94        cmn.n_states_delayed_decision = 2;
95        cmn.use_interpolated_nlsfs = 0;
96        cmn.n_nlsf_survivors = 2;
97        cmn.warping_q16 = 0;
98    } else if complexity < 4 {
99        cmn.pitch_estimation_complexity = SILK_PE_MID_COMPLEX as i32;
100        cmn.pitch_estimation_threshold_q16 = (0.76f32 * 65536.0) as i32;
101        ps_enc.pitch_estimation_lpc_order = 8;
102        cmn.shaping_lpc_order = 14;
103        cmn.la_shape = 5 * cmn.fs_khz;
104        cmn.n_states_delayed_decision = 2;
105        cmn.use_interpolated_nlsfs = 0;
106        cmn.n_nlsf_survivors = 4;
107        cmn.warping_q16 = 0;
108    } else if complexity < 6 {
109        cmn.pitch_estimation_complexity = SILK_PE_MID_COMPLEX as i32;
110        cmn.pitch_estimation_threshold_q16 = (0.74f32 * 65536.0) as i32;
111        ps_enc.pitch_estimation_lpc_order = 10;
112        cmn.shaping_lpc_order = 16;
113        cmn.la_shape = 5 * cmn.fs_khz;
114        cmn.n_states_delayed_decision = 2;
115        cmn.use_interpolated_nlsfs = 1;
116        cmn.n_nlsf_survivors = 6;
117        cmn.warping_q16 = cmn.fs_khz * WARPING_MULTIPLIER_Q16;
118    } else if complexity < 8 {
119        cmn.pitch_estimation_complexity = SILK_PE_MID_COMPLEX as i32;
120        cmn.pitch_estimation_threshold_q16 = (0.72f32 * 65536.0) as i32;
121        ps_enc.pitch_estimation_lpc_order = 12;
122        cmn.shaping_lpc_order = 20;
123        cmn.la_shape = 5 * cmn.fs_khz;
124        cmn.n_states_delayed_decision = 3;
125        cmn.use_interpolated_nlsfs = 1;
126        cmn.n_nlsf_survivors = 8;
127        cmn.warping_q16 = cmn.fs_khz * WARPING_MULTIPLIER_Q16;
128    } else {
129        cmn.pitch_estimation_complexity = SILK_PE_MAX_COMPLEX as i32;
130        cmn.pitch_estimation_threshold_q16 = (0.7f32 * 65536.0) as i32;
131        ps_enc.pitch_estimation_lpc_order = 16;
132        cmn.shaping_lpc_order = 24;
133        cmn.la_shape = 5 * cmn.fs_khz;
134        cmn.n_states_delayed_decision = MAX_DEL_DEC_STATES;
135        cmn.use_interpolated_nlsfs = 1;
136        cmn.n_nlsf_survivors = 16;
137        cmn.warping_q16 = cmn.fs_khz * WARPING_MULTIPLIER_Q16;
138    }
139
140    ps_enc.pitch_estimation_lpc_order =
141        ps_enc.pitch_estimation_lpc_order.min(cmn.predict_lpc_order);
142    cmn.shape_win_length = SUB_FRAME_LENGTH_MS as i32 * cmn.fs_khz + 2 * cmn.la_shape;
143    cmn.complexity = complexity;
144
145    SILK_NO_ERROR
146}
147
148pub fn silk_control_encoder(
149    ps_enc: &mut SilkEncoderState,
150    fs_khz: i32,
151    packet_size_ms: i32,
152    target_rate_bps: i32,
153    complexity: i32,
154) -> i32 {
155    let mut ret = silk_setup_fs(ps_enc, fs_khz, packet_size_ms);
156    ret += silk_setup_complexity(ps_enc, complexity);
157
158    ps_enc.s_cmn.target_rate_bps = target_rate_bps;
159
160    ret
161}