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 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}