1use crate::{Audio, DecodeInfo, Dither, Endian, Error, Limits, Result, SampleFormat};
3
4pub fn decode_pcm(
5 bytes: &[u8],
6 format: SampleFormat,
7 endian: Endian,
8 channels: usize,
9 rate: u32,
10 limits: &Limits,
11) -> Result<Audio> {
12 let stride = channels
13 .checked_mul(format.bytes())
14 .filter(|&n| n > 0)
15 .ok_or_else(|| Error::invalid("Invalid PCM channel count"))?;
16 if bytes.len() % stride != 0 {
17 return Err(Error::decode("Incomplete PCM frame"));
18 }
19 let frames = bytes.len() / stride;
20 limits.check(frames, channels, rate)?;
21 let mut data = vec![vec![0.0; frames]; channels];
22 for (i, frame) in bytes.chunks_exact(stride).enumerate() {
23 for (c, sample) in frame.chunks_exact(format.bytes()).enumerate() {
24 data[c][i] = read_sample(sample, format, endian)?;
25 }
26 }
27 Audio::decoded(
28 data,
29 rate,
30 DecodeInfo {
31 sample_format: Some(format),
32 ..Default::default()
33 },
34 )
35}
36
37pub(crate) fn read_sample(b: &[u8], f: SampleFormat, e: Endian) -> Result<f32> {
38 let le = e == Endian::Little;
39 let u = |n: usize| {
40 let mut v = 0u64;
41 for i in 0..n {
42 v |= (b[if le { i } else { n - 1 - i }] as u64) << (8 * i);
43 }
44 v
45 };
46 let s = match f {
47 SampleFormat::U8 => (b[0] as f32 - 128.0) / 128.0,
48 SampleFormat::S8 => b[0] as i8 as f32 / 128.0,
49 SampleFormat::S16 => u(2) as i16 as f32 / 32768.0,
50 SampleFormat::S24 => ((u(3) as i32) << 8 >> 8) as f32 / 8388608.0,
51 SampleFormat::S32 => u(4) as i32 as f32 / 2147483648.0,
52 SampleFormat::F32 => f32::from_bits(u(4) as u32),
53 SampleFormat::F64 => f64::from_bits(u(8)) as f32,
54 SampleFormat::Alaw => decode_alaw(b[0]) as f32 / 32768.0,
55 SampleFormat::Ulaw => decode_ulaw(b[0]) as f32 / 32768.0,
56 };
57 if !s.is_finite() {
58 return Err(Error::decode("Non-finite PCM sample"));
59 }
60 Ok(s)
61}
62pub fn encode_pcm(audio: &Audio, format: SampleFormat, endian: Endian) -> Result<Vec<u8>> {
63 encode_pcm_with_dither(audio, format, endian, Dither::None)
64}
65
66pub fn encode_pcm_with_dither(
72 audio: &Audio,
73 format: SampleFormat,
74 endian: Endian,
75 dither: Dither,
76) -> Result<Vec<u8>> {
77 validate_dither(format, dither)?;
78 encode_quantized(
79 audio,
80 format,
81 endian,
82 &mut quantizers(format, dither, audio.channels()),
83 )
84}
85
86pub(crate) fn validate_dither(format: SampleFormat, dither: Dither) -> Result<()> {
87 if dither != Dither::None
88 && !matches!(
89 format,
90 SampleFormat::U8
91 | SampleFormat::S8
92 | SampleFormat::S16
93 | SampleFormat::S24
94 | SampleFormat::S32
95 )
96 {
97 return Err(Error::invalid("Dither requires linear integer PCM output"));
98 }
99 Ok(())
100}
101
102const DITHER_STEP: u64 = 0x9e37_79b9_7f4a_7c15;
105fn mix(mut value: u64) -> u64 {
106 value = (value ^ (value >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
107 value = (value ^ (value >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
108 value ^ (value >> 31)
109}
110
111#[derive(Debug)]
112pub(crate) struct Quantizer {
113 scale: f64,
114 state: Option<u64>,
115}
116impl Quantizer {
117 pub(crate) fn new(bits: u32, dither: Dither, channel: usize) -> Self {
118 Self {
119 scale: (1u64 << (bits - 1)) as f64,
120 state: match dither {
121 Dither::None => None,
122 Dither::Tpdf { seed } => {
123 Some(mix(seed ^ (channel as u64 + 1).wrapping_mul(DITHER_STEP)))
124 }
125 },
126 }
127 }
128 pub(crate) fn sample(&mut self, sample: f32) -> i64 {
129 let noise = if let Some(state) = &mut self.state {
130 let mut draw = || {
131 *state = state.wrapping_add(DITHER_STEP);
132 (mix(*state) >> 11) as f64 / (1u64 << 53) as f64
133 };
134 draw() - draw()
135 } else {
136 0.0
137 };
138 (sample as f64 * self.scale + noise)
140 .round()
141 .clamp(-self.scale, self.scale - 1.0) as i64
142 }
143}
144
145pub(crate) fn quantizers(format: SampleFormat, dither: Dither, channels: usize) -> Vec<Quantizer> {
146 if dither == Dither::None {
147 Vec::new()
148 } else {
149 (0..channels)
150 .map(|c| Quantizer::new(format.bits() as u32, dither, c))
151 .collect()
152 }
153}
154
155pub(crate) fn encode_quantized(
156 audio: &Audio,
157 format: SampleFormat,
158 endian: Endian,
159 quantizers: &mut [Quantizer],
160) -> Result<Vec<u8>> {
161 let size = audio
162 .frames()
163 .checked_mul(audio.channels())
164 .and_then(|n| n.checked_mul(format.bytes()))
165 .ok_or_else(|| Error::encode("PCM size overflow"))?;
166 let mut out = Vec::with_capacity(size);
167 for i in 0..audio.frames() {
168 for (channel, c) in audio.all_channels().iter().enumerate() {
169 if let Some(q) = quantizers.get_mut(channel) {
170 let value = q.sample(c[i]);
171 write_value(
172 &mut out,
173 (if format == SampleFormat::U8 {
174 value + 128
175 } else {
176 value
177 }) as u64,
178 format.bytes(),
179 endian,
180 );
181 } else {
182 write_sample(&mut out, c[i], format, endian);
183 }
184 }
185 }
186 Ok(out)
187}
188pub(crate) fn write_sample(out: &mut Vec<u8>, sample: f32, f: SampleFormat, e: Endian) {
189 let n = f.bytes();
190 let quant = |bits: u32| -> i64 {
191 let scale = (1u64 << (bits - 1)) as f64;
192 (sample as f64 * scale).round().clamp(-scale, scale - 1.0) as i64
193 };
194 let value = match f {
195 SampleFormat::U8 => (quant(8) + 128) as u64,
196 SampleFormat::S8 => quant(8) as u64,
197 SampleFormat::S16 => quant(16) as u64,
198 SampleFormat::S24 => quant(24) as u64,
199 SampleFormat::S32 => quant(32) as u64,
200 SampleFormat::F32 => sample.to_bits() as u64,
201 SampleFormat::F64 => (sample as f64).to_bits(),
202 SampleFormat::Alaw => encode_alaw(quant(16) as i16) as u64,
203 SampleFormat::Ulaw => encode_ulaw(quant(16) as i16) as u64,
204 };
205 write_value(out, value, n, e);
206}
207fn write_value(out: &mut Vec<u8>, value: u64, n: usize, e: Endian) {
208 for i in 0..n {
209 let shift = if e == Endian::Little { i } else { n - 1 - i };
210 out.push((value >> (shift * 8)) as u8);
211 }
212}
213pub fn decode_ulaw(value: u8) -> i16 {
214 let u = !value;
215 let t = (((u & 15) as i32) * 8 + 132) << ((u >> 4) & 7);
216 if u & 128 != 0 {
217 (132 - t) as i16
218 } else {
219 (t - 132) as i16
220 }
221}
222pub fn encode_ulaw(sample: i16) -> u8 {
223 let n = sample as i32;
224 let mask = if n < 0 { 0x7f } else { 0xff };
225 let n = n.abs().min(32635) + 132;
226 let mut exp = 7u8;
227 let mut bit = 0x4000;
228 while exp > 0 && n & bit == 0 {
229 exp -= 1;
230 bit >>= 1;
231 }
232 ((exp << 4) | ((n >> (exp + 3)) & 15) as u8) ^ mask
233}
234pub fn decode_alaw(value: u8) -> i16 {
235 let a = value ^ 0x55;
236 let seg = (a >> 4) & 7;
237 let mut n = ((a & 15) as i32) << 4;
238 n += if seg == 0 { 8 } else { 264 };
239 if seg > 1 {
240 n <<= seg - 1;
241 }
242 if a & 128 != 0 { n as i16 } else { -n as i16 }
243}
244pub fn encode_alaw(sample: i16) -> u8 {
245 let n = sample as i32;
246 let mask = if n >= 0 { 0xd5 } else { 0x55 };
247 let n = if n >= 0 { n } else { -n - 1 };
248 let mut seg = 0u8;
249 let mut bound = 255;
250 while n > bound && seg < 7 {
251 seg += 1;
252 bound = (bound << 1) | 1;
253 }
254 let shift = if seg == 0 { 4 } else { seg + 3 };
255 ((seg << 4) | ((n >> shift) & 15) as u8) ^ mask
256}
257
258const IMA_STEPS: [i32; 89] = [
259 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66,
260 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
261 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272,
262 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,
263 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767,
264];
265pub(crate) fn decode_ima(
266 bytes: &[u8],
267 channels: usize,
268 rate: u32,
269 block: usize,
270 samples_per_block: usize,
271 limits: &Limits,
272) -> Result<Audio> {
273 if !(1..=2).contains(&channels)
274 || block < channels * 4
275 || samples_per_block == 0
276 || bytes.len() % block != 0
277 {
278 return Err(Error::decode("Invalid IMA ADPCM blocks"));
279 }
280 let frames = (bytes.len() / block)
281 .checked_mul(samples_per_block)
282 .ok_or_else(|| Error::limit("ADPCM frame count overflow"))?;
283 limits.check(frames, channels, rate)?;
284 let mut data: Vec<Vec<f32>> = (0..channels).map(|_| Vec::with_capacity(frames)).collect();
285 for b in bytes.chunks_exact(block) {
286 decode_ima_block(b, samples_per_block, &mut data)?;
287 }
288 Audio::decoded(data, rate, DecodeInfo::default())
289}
290
291pub(crate) fn decode_ima_block(
294 b: &[u8],
295 samples_per_block: usize,
296 data: &mut [Vec<f32>],
297) -> Result<()> {
298 let channels = data.len();
299 let mut predictor = [0i32; 2];
300 let mut index = [0i32; 2];
301 for c in 0..channels {
302 predictor[c] = i16::from_le_bytes([b[c * 4], b[c * 4 + 1]]) as i32;
303 index[c] = b[c * 4 + 2] as i32;
304 if index[c] > 88 {
305 return Err(Error::decode("Invalid ADPCM step index"));
306 }
307 data[c].push(predictor[c] as f32 / 32768.0);
308 }
309 let mut pos = channels * 4;
310 let mut emitted = [1; 2];
311 while pos < b.len() {
312 for c in 0..channels {
313 let count = if channels == 1 { b.len() - pos } else { 4 };
314 let chunk = b
315 .get(pos..pos + count)
316 .ok_or_else(|| Error::decode("Incomplete ADPCM channel group"))?;
317 for &v in chunk {
318 for shift in [0, 4] {
319 if emitted[c] >= samples_per_block {
320 break;
321 }
322 let code = (v >> shift) & 15;
323 let step = IMA_STEPS[index[c] as usize];
324 let diff = (step >> 3)
325 + if code & 1 != 0 { step >> 2 } else { 0 }
326 + if code & 2 != 0 { step >> 1 } else { 0 }
327 + if code & 4 != 0 { step } else { 0 };
328 predictor[c] = (predictor[c] + if code & 8 != 0 { -diff } else { diff })
329 .clamp(-32768, 32767);
330 index[c] =
331 (index[c] + [-1, -1, -1, -1, 2, 4, 6, 8][(code & 7) as usize]).clamp(0, 88);
332 data[c].push(predictor[c] as f32 / 32768.0);
333 emitted[c] += 1;
334 }
335 }
336 pos += count;
337 }
338 }
339 if emitted[..channels].iter().any(|&n| n != samples_per_block) {
340 return Err(Error::decode("ADPCM block has too few samples"));
341 }
342 Ok(())
343}