Skip to content

Commit b499210

Browse files
committed
refactor: make silk_stereo_MS_to_LR safe
1 parent 570fb0b commit b499210

6 files changed

+82
-167
lines changed

src/silk/dec_API.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,10 @@ pub unsafe fn silk_Decode(
357357
if decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2 {
358358
silk_stereo_MS_to_LR(
359359
&mut psDec.sStereo,
360-
samplesOut1_tmp[0 as usize],
361-
samplesOut1_tmp[1 as usize],
362-
MS_pred_Q13.as_mut_ptr() as *const i32,
363-
channel_state[0].fs_kHz,
360+
std::slice::from_raw_parts_mut(samplesOut1_tmp[0], nSamplesOutDec as usize + 2),
361+
std::slice::from_raw_parts_mut(samplesOut1_tmp[1], nSamplesOutDec as usize + 2),
362+
&MS_pred_Q13,
363+
channel_state[0].fs_kHz as usize,
364364
nSamplesOutDec,
365365
);
366366
} else {

src/silk/define.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub const MAX_SHAPE_LPC_ORDER: i32 = 24;
1010
pub const HARM_SHAPE_FIR_TAPS: i32 = 3;
1111
pub const LTP_ORDER: i32 = 5;
1212
pub const NSQ_LPC_BUF_LENGTH: i32 = MAX_LPC_ORDER;
13-
pub const STEREO_INTERP_LEN_MS: i32 = 8;
13+
pub const STEREO_INTERP_LEN_MS: usize = 8;
1414
pub const LA_SHAPE_MS: i32 = 5;
1515
pub const STEREO_QUANT_SUB_STEPS: i32 = 5;
1616
pub const STEREO_QUANT_TAB_SIZE: i32 = 16;

src/silk/macros.rs

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ pub fn silk_SMLAWB(a32: i32, b32: i32, c32: i32) -> i32 {
2121
(a32 as i64 + ((b32 as i64 * c32 as i16 as i64) >> 16)) as i32
2222
}
2323

24+
/// (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int
25+
#[inline]
26+
pub fn silk_SMULBB(a32: i32, b32: i32) -> i32 {
27+
a32 as i16 as i32 * b32 as i16 as i32
28+
}
29+
2430
/// a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int
2531
#[inline]
2632
pub fn silk_SMULWW(a32: i32, b32: i32) -> i32 {

src/silk/stereo_LR_to_MS.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ pub unsafe fn silk_stereo_LR_to_MS(
277277
}
278278
if *mid_only_flag as i32 == 1 {
279279
(*state).silent_side_len = ((*state).silent_side_len as i32
280-
+ (frame_length - STEREO_INTERP_LEN_MS * fs_kHz))
280+
+ (frame_length - STEREO_INTERP_LEN_MS as i32 * fs_kHz))
281281
as i16;
282282
if ((*state).silent_side_len as i32) < LA_SHAPE_MS * fs_kHz {
283283
*mid_only_flag = 0;
@@ -328,7 +328,7 @@ pub unsafe fn silk_stereo_LR_to_MS(
328328
>> 16) as i32 as u32)
329329
<< 10) as i32;
330330
n = 0;
331-
while n < STEREO_INTERP_LEN_MS * fs_kHz {
331+
while n < STEREO_INTERP_LEN_MS as i32 * fs_kHz {
332332
pred0_Q13 += delta0_Q13;
333333
pred1_Q13 += delta1_Q13;
334334
w_Q24 += deltaw_Q24;
@@ -367,7 +367,7 @@ pub unsafe fn silk_stereo_LR_to_MS(
367367
pred0_Q13 = -pred_Q13[0 as usize];
368368
pred1_Q13 = -pred_Q13[1 as usize];
369369
w_Q24 = ((width_Q14 as u32) << 10) as i32;
370-
n = STEREO_INTERP_LEN_MS * fs_kHz;
370+
n = STEREO_INTERP_LEN_MS as i32 * fs_kHz;
371371
while n < frame_length {
372372
sum = (((*mid.offset(n as isize) as i32
373373
+ *mid.offset((n + 2) as isize) as i32

src/silk/stereo_MS_to_LR.rs

+67-158
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,81 @@
1-
pub mod typedef_h {
2-
pub const silk_int16_MIN: i32 = i16::MIN as i32;
3-
pub const silk_int16_MAX: i32 = i16::MAX as i32;
4-
}
51
use crate::silk::define::STEREO_INTERP_LEN_MS;
62

7-
pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN};
83
use crate::silk::structs::stereo_dec_state;
94

10-
use crate::externs::memcpy;
11-
pub unsafe fn silk_stereo_MS_to_LR(
12-
state: *mut stereo_dec_state,
13-
x1: *mut i16,
14-
x2: *mut i16,
15-
pred_Q13: *const i32,
16-
fs_kHz: i32,
5+
use crate::silk::macros::{silk_SMLAWB, silk_SMULBB};
6+
use crate::silk::SigProc_FIX::{silk_RSHIFT_ROUND, silk_SAT16};
7+
8+
/// Convert adaptive Mid/Side representation to Left/Right stereo signal
9+
///
10+
/// ```text
11+
/// state I/O State
12+
/// x1[] I/O Left input signal, becomes mid signal
13+
/// x2[] I/O Right input signal, becomes side signal
14+
/// pred_Q13[] I Predictors
15+
/// fs_kHz I Samples rate (kHz)
16+
/// frame_length I Number of samples
17+
/// ```
18+
pub fn silk_stereo_MS_to_LR(
19+
state: &mut stereo_dec_state,
20+
x1: &mut [i16],
21+
x2: &mut [i16],
22+
pred_Q13: &[i32; 2],
23+
fs_kHz: usize,
1724
frame_length: i32,
1825
) {
19-
let mut n: i32 = 0;
20-
let mut denom_Q16: i32 = 0;
21-
let mut delta0_Q13: i32 = 0;
22-
let mut delta1_Q13: i32 = 0;
23-
let mut sum: i32 = 0;
24-
let mut diff: i32 = 0;
25-
let mut pred0_Q13: i32 = 0;
26-
let mut pred1_Q13: i32 = 0;
27-
memcpy(
28-
x1 as *mut core::ffi::c_void,
29-
((*state).sMid).as_mut_ptr() as *const core::ffi::c_void,
30-
2_u64.wrapping_mul(::core::mem::size_of::<i16>() as u64),
31-
);
32-
memcpy(
33-
x2 as *mut core::ffi::c_void,
34-
((*state).sSide).as_mut_ptr() as *const core::ffi::c_void,
35-
2_u64.wrapping_mul(::core::mem::size_of::<i16>() as u64),
36-
);
37-
memcpy(
38-
((*state).sMid).as_mut_ptr() as *mut core::ffi::c_void,
39-
&mut *x1.offset(frame_length as isize) as *mut i16 as *const core::ffi::c_void,
40-
2_u64.wrapping_mul(::core::mem::size_of::<i16>() as u64),
26+
let frame_length = frame_length as usize;
27+
28+
assert_eq!(x1.len(), x2.len());
29+
assert_eq!(x1.len(), frame_length + 2);
30+
assert!(STEREO_INTERP_LEN_MS * fs_kHz <= frame_length);
31+
32+
/* Buffering */
33+
x1[..2].copy_from_slice(&state.sMid);
34+
x2[..2].copy_from_slice(&state.sSide);
35+
36+
state.sMid[..2].copy_from_slice(&x1[frame_length..]);
37+
state.sSide[..2].copy_from_slice(&x2[frame_length..]);
38+
39+
/* Interpolate predictors and add prediction to side channel */
40+
let mut pred0_Q13 = state.pred_prev_Q13[0] as i32;
41+
let mut pred1_Q13 = state.pred_prev_Q13[1] as i32;
42+
let denom_Q16 = ((1) << 16) / (8 * fs_kHz) as i32;
43+
let delta0_Q13 = silk_RSHIFT_ROUND(
44+
silk_SMULBB(pred_Q13[0] - state.pred_prev_Q13[0] as i32, denom_Q16),
45+
16,
4146
);
42-
memcpy(
43-
((*state).sSide).as_mut_ptr() as *mut core::ffi::c_void,
44-
&mut *x2.offset(frame_length as isize) as *mut i16 as *const core::ffi::c_void,
45-
2_u64.wrapping_mul(::core::mem::size_of::<i16>() as u64),
47+
let delta1_Q13 = silk_RSHIFT_ROUND(
48+
silk_SMULBB(pred_Q13[1] - state.pred_prev_Q13[1] as i32, denom_Q16),
49+
16,
4650
);
47-
pred0_Q13 = (*state).pred_prev_Q13[0 as usize] as i32;
48-
pred1_Q13 = (*state).pred_prev_Q13[1 as usize] as i32;
49-
denom_Q16 = ((1) << 16) / (8 * fs_kHz);
50-
delta0_Q13 = if 16 == 1 {
51-
((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32
52-
* denom_Q16 as i16 as i32
53-
>> 1)
54-
+ ((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16
55-
as i32
56-
* denom_Q16 as i16 as i32
57-
& 1)
58-
} else {
59-
((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32
60-
* denom_Q16 as i16 as i32
61-
>> 16 - 1)
62-
+ 1
63-
>> 1
64-
};
65-
delta1_Q13 = if 16 == 1 {
66-
((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32
67-
* denom_Q16 as i16 as i32
68-
>> 1)
69-
+ ((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16
70-
as i32
71-
* denom_Q16 as i16 as i32
72-
& 1)
73-
} else {
74-
((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32
75-
* denom_Q16 as i16 as i32
76-
>> 16 - 1)
77-
+ 1
78-
>> 1
79-
};
80-
n = 0;
81-
while n < STEREO_INTERP_LEN_MS * fs_kHz {
51+
52+
for n in 0..STEREO_INTERP_LEN_MS * fs_kHz {
8253
pred0_Q13 += delta0_Q13;
8354
pred1_Q13 += delta1_Q13;
84-
sum = (((*x1.offset(n as isize) as i32
85-
+ *x1.offset((n + 2) as isize) as i32
86-
+ ((*x1.offset((n + 1) as isize) as u32) << 1) as i32) as u32)
87-
<< 9) as i32;
88-
sum = (((*x2.offset((n + 1) as isize) as i32 as u32) << 8) as i32 as i64
89-
+ (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32;
90-
sum = (sum as i64
91-
+ (((*x1.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64
92-
* pred1_Q13 as i16 as i64
93-
>> 16)) as i32;
94-
*x2.offset((n + 1) as isize) = (if (if 8 == 1 {
95-
(sum >> 1) + (sum & 1)
96-
} else {
97-
(sum >> 8 - 1) + 1 >> 1
98-
}) > silk_int16_MAX
99-
{
100-
silk_int16_MAX
101-
} else if (if 8 == 1 {
102-
(sum >> 1) + (sum & 1)
103-
} else {
104-
(sum >> 8 - 1) + 1 >> 1
105-
}) < silk_int16_MIN
106-
{
107-
silk_int16_MIN
108-
} else if 8 == 1 {
109-
(sum >> 1) + (sum & 1)
110-
} else {
111-
(sum >> 8 - 1) + 1 >> 1
112-
}) as i16;
113-
n += 1;
55+
let sum = (x1[n] as i32 + x1[n + 2] as i32 + (x1[n + 1] << 1) as i32) << 9; /* Q11 */
56+
let sum = silk_SMLAWB((x2[n + 1] as i32) << 8, sum, pred0_Q13); /* Q8 */
57+
let sum = silk_SMLAWB(sum, (x1[n + 1] as i32) << 11, pred1_Q13); /* Q8 */
58+
x2[n + 1] = silk_SAT16(silk_RSHIFT_ROUND(sum, 8)) as i16;
11459
}
115-
pred0_Q13 = *pred_Q13.offset(0 as isize);
116-
pred1_Q13 = *pred_Q13.offset(1 as isize);
117-
n = STEREO_INTERP_LEN_MS * fs_kHz;
118-
while n < frame_length {
119-
sum = (((*x1.offset(n as isize) as i32
120-
+ *x1.offset((n + 2) as isize) as i32
121-
+ ((*x1.offset((n + 1) as isize) as u32) << 1) as i32) as u32)
122-
<< 9) as i32;
123-
sum = (((*x2.offset((n + 1) as isize) as i32 as u32) << 8) as i32 as i64
124-
+ (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32;
125-
sum = (sum as i64
126-
+ (((*x1.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64
127-
* pred1_Q13 as i16 as i64
128-
>> 16)) as i32;
129-
*x2.offset((n + 1) as isize) = (if (if 8 == 1 {
130-
(sum >> 1) + (sum & 1)
131-
} else {
132-
(sum >> 8 - 1) + 1 >> 1
133-
}) > silk_int16_MAX
134-
{
135-
silk_int16_MAX
136-
} else if (if 8 == 1 {
137-
(sum >> 1) + (sum & 1)
138-
} else {
139-
(sum >> 8 - 1) + 1 >> 1
140-
}) < silk_int16_MIN
141-
{
142-
silk_int16_MIN
143-
} else if 8 == 1 {
144-
(sum >> 1) + (sum & 1)
145-
} else {
146-
(sum >> 8 - 1) + 1 >> 1
147-
}) as i16;
148-
n += 1;
60+
61+
let pred0_Q13 = pred_Q13[0];
62+
let pred1_Q13 = pred_Q13[1];
63+
64+
for n in STEREO_INTERP_LEN_MS * fs_kHz..frame_length {
65+
let sum = (x1[n] as i32 + x1[n + 2] as i32 + ((x1[n + 1] as i32) << 1)) << 9; /* Q11 */
66+
let sum = silk_SMLAWB((x2[n + 1] as i32) << 8, sum, pred0_Q13); /* Q8 */
67+
let sum = silk_SMLAWB(sum, (x1[n + 1] as i32) << 11, pred1_Q13); /* Q8 */
68+
x2[n + 1] = silk_SAT16(silk_RSHIFT_ROUND(sum, 8)) as i16;
14969
}
150-
(*state).pred_prev_Q13[0 as usize] = *pred_Q13.offset(0 as isize) as i16;
151-
(*state).pred_prev_Q13[1 as usize] = *pred_Q13.offset(1 as isize) as i16;
152-
n = 0;
153-
while n < frame_length {
154-
sum = *x1.offset((n + 1) as isize) as i32 + *x2.offset((n + 1) as isize) as i32;
155-
diff = *x1.offset((n + 1) as isize) as i32 - *x2.offset((n + 1) as isize) as i32;
156-
*x1.offset((n + 1) as isize) = (if sum > silk_int16_MAX {
157-
silk_int16_MAX
158-
} else if sum < silk_int16_MIN {
159-
silk_int16_MIN
160-
} else {
161-
sum
162-
}) as i16;
163-
*x2.offset((n + 1) as isize) = (if diff > silk_int16_MAX {
164-
silk_int16_MAX
165-
} else if diff < silk_int16_MIN {
166-
silk_int16_MIN
167-
} else {
168-
diff
169-
}) as i16;
170-
n += 1;
70+
state.pred_prev_Q13[0] = pred_Q13[0] as i16;
71+
state.pred_prev_Q13[1] = pred_Q13[1] as i16;
72+
73+
/* Convert to left/right signals */
74+
for n in 0..frame_length {
75+
let sum = x1[n + 1] as i32 + x2[n + 1] as i32;
76+
let diff = x1[n + 1] as i32 - x2[n + 1] as i32;
77+
78+
x1[n + 1] = silk_SAT16(sum) as i16;
79+
x2[n + 1] = silk_SAT16(diff) as i16;
17180
}
17281
}

src/silk/stereo_decode_pred.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn silk_stereo_decode_pred(psRangeDec: &mut ec_dec, pred_Q13: &mut [i32; 2])
3434
ix[n][0] += 3 * ix[n][2];
3535
let low_Q13 = silk_stereo_pred_quant_Q13[ix[n][0]] as i32;
3636
let step_Q13 = silk_SMULWB(
37-
(silk_stereo_pred_quant_Q13[ix[n][0] + 1] as i32 - low_Q13),
37+
silk_stereo_pred_quant_Q13[ix[n][0] + 1] as i32 - low_Q13,
3838
SILK_FIX_CONST!(0.5 / STEREO_QUANT_SUB_STEPS as f64, 16),
3939
);
4040

0 commit comments

Comments
 (0)