silk_codec/
silk.rs

1use bytes::{Buf, BufMut};
2use std::ffi::c_void;
3use thiserror::Error;
4
5#[allow(
6    dead_code,
7    non_camel_case_types,
8    non_snake_case,
9    non_upper_case_globals
10)]
11pub(crate) mod sdk {
12    include!(concat!(env!("OUT_DIR"), "/silk_bindings.rs"));
13}
14
15macro_rules! fast_check {
16    ($call:expr) => {{
17        unsafe {
18            let code = $call;
19            if code != 0 {
20                return Err(SilkError::from(code));
21            }
22        }
23    }};
24}
25
26pub fn decode_silk<R: AsRef<[u8]>>(src: R, sample_rate: i32) -> Result<Vec<u8>, SilkError> {
27    unsafe { _decode_silk(src.as_ref(), sample_rate) }
28}
29
30unsafe fn _decode_silk(mut src: &[u8], sample_rate: i32) -> Result<Vec<u8>, SilkError> {
31    // skip tencent flag
32    if src.starts_with(&[0x02]) {
33        src.advance(1);
34    };
35
36    const SILK_HEADER: &[u8] = b"#!SILK_V3";
37    if src.starts_with(SILK_HEADER) {
38        src.advance(SILK_HEADER.len());
39    } else {
40        return Err(SilkError::Invalid);
41    };
42
43    let mut dec_control = sdk::SKP_SILK_SDK_DecControlStruct {
44        API_sampleRate: sample_rate,
45        frameSize: 0,
46        framesPerPacket: 1,
47        moreInternalDecoderFrames: 0,
48        inBandFECOffset: 0,
49    };
50
51    let mut decoder_size = 0;
52
53    fast_check!(sdk::SKP_Silk_SDK_Get_Decoder_Size(&mut decoder_size));
54
55    let mut decoder = vec![0u8; decoder_size as usize];
56
57    fast_check!(sdk::SKP_Silk_SDK_InitDecoder(
58        decoder.as_mut_ptr() as *mut c_void
59    ));
60
61    let mut result = vec![];
62    let frame_size = sample_rate as usize / 1000 * 40;
63    let mut buf = vec![0u8; frame_size];
64    loop {
65        if src.remaining() < 2 {
66            break;
67        }
68        let input_size = src.get_i16_le();
69        if input_size > frame_size as i16 {
70            return Err(SilkError::Invalid);
71        }
72        if src.remaining() < input_size as usize {
73            return Err(SilkError::Invalid);
74        }
75
76        let input;
77        (input, src) = src.split_at(input_size as usize);
78
79        let mut output_size = 0i16;
80
81        fast_check!(sdk::SKP_Silk_SDK_Decode(
82            decoder.as_mut_ptr() as *mut c_void,
83            &mut dec_control,
84            0,
85            input.as_ptr(),
86            input_size as i32,
87            buf.as_mut_ptr() as *mut i16,
88            &mut output_size,
89        ));
90
91        result.extend_from_slice(&buf[0..output_size as usize * 2])
92    }
93    Ok(result)
94}
95
96pub fn encode_silk<R: AsRef<[u8]>>(
97    src: R,
98    sample_rate: i32,
99    bit_rate: i32,
100    tencent: bool,
101) -> Result<Vec<u8>, SilkError> {
102    unsafe { _encode_silk(src.as_ref(), sample_rate, bit_rate, tencent) }
103}
104
105unsafe fn _encode_silk(
106    src: &[u8],
107    sample_rate: i32,
108    bit_rate: i32,
109    tencent: bool,
110) -> Result<Vec<u8>, SilkError> {
111    let enc_control = sdk::SKP_SILK_SDK_EncControlStruct {
112        API_sampleRate: sample_rate,
113        maxInternalSampleRate: 24000,
114        packetSize: (20 * sample_rate) / 1000,
115        bitRate: bit_rate,
116        packetLossPercentage: 0,
117        complexity: 2,
118        useInBandFEC: 0,
119        useDTX: 0,
120    };
121
122    let mut enc_status = sdk::SKP_SILK_SDK_EncControlStruct {
123        API_sampleRate: 0,
124        maxInternalSampleRate: 0,
125        packetSize: 0,
126        bitRate: bit_rate,
127        packetLossPercentage: 0,
128        complexity: 0,
129        useInBandFEC: 0,
130        useDTX: 0,
131    };
132
133    let mut encoder_size = 0;
134    fast_check!(sdk::SKP_Silk_SDK_Get_Encoder_Size(&mut encoder_size));
135
136    let mut encoder = vec![0u8; encoder_size as usize];
137
138    fast_check!(sdk::SKP_Silk_SDK_InitEncoder(
139        encoder.as_mut_ptr() as *mut c_void,
140        &mut enc_status,
141    ));
142
143    let mut result = vec![];
144    if tencent {
145        result.put_u8(b'\x02');
146    }
147    result.extend_from_slice(b"#!SILK_V3");
148
149    let frame_size = sample_rate as usize / 1000 * 40;
150    let mut output_size = 1250i16;
151    let mut buf = vec![0u8; output_size as usize];
152    for chunk in src.chunks(frame_size) {
153        output_size = 1250;
154        if chunk.len() < frame_size {
155            break;
156        }
157        fast_check!(sdk::SKP_Silk_SDK_Encode(
158            encoder.as_mut_ptr() as *mut c_void,
159            &enc_control,
160            chunk.as_ptr() as *const i16,
161            chunk.len() as i32 / 2,
162            buf.as_mut_ptr(),
163            &mut output_size,
164        ));
165        result.put_i16_le(output_size);
166        result.extend_from_slice(&buf[0..output_size as usize]);
167    }
168
169    Ok(result)
170}
171
172#[derive(Error, Debug)]
173pub enum SilkError {
174    #[error("Invalid")]
175    Invalid,
176    #[error("EncInputInvalidNoOfSamples")]
177    EncInputInvalidNoOfSamples,
178    #[error("EncFsNotSupported")]
179    EncFsNotSupported,
180    #[error("EncPacketSizeNotSupported")]
181    EncPacketSizeNotSupported,
182    #[error("EncPayloadBufTooShort")]
183    EncPayloadBufTooShort,
184    #[error("EncInvalidLossRate")]
185    EncInvalidLossRate,
186    #[error("EncInvalidComplexitySetting")]
187    EncInvalidComplexitySetting,
188    #[error("EncInvalidInbandFecSetting")]
189    EncInvalidInbandFecSetting,
190    #[error("EncInvalidDtxSetting")]
191    EncInvalidDtxSetting,
192    #[error("EncInternalError")]
193    EncInternalError,
194    #[error("DecInvalidSamplingFrequency")]
195    DecInvalidSamplingFrequency,
196    #[error("DecPayloadTooLarge")]
197    DecPayloadTooLarge,
198    #[error("DecPayloadError")]
199    DecPayloadError,
200    #[error("OTHER {0}")]
201    Other(i32),
202}
203
204impl From<i32> for SilkError {
205    fn from(code: i32) -> Self {
206        match code {
207            -1 => Self::EncInputInvalidNoOfSamples,
208            -2 => Self::EncFsNotSupported,
209            -3 => Self::EncPacketSizeNotSupported,
210            -4 => Self::EncPayloadBufTooShort,
211            -5 => Self::EncInvalidLossRate,
212            -6 => Self::EncInvalidComplexitySetting,
213            -7 => Self::EncInvalidInbandFecSetting,
214            -8 => Self::EncInvalidDtxSetting,
215            -9 => Self::EncInternalError,
216            -10 => Self::DecInvalidSamplingFrequency,
217            -11 => Self::DecPayloadTooLarge,
218            -12 => Self::DecPayloadError,
219            _ => Self::Other(code),
220        }
221    }
222}