]>
Commit | Line | Data |
---|---|---|
4c1582cf KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::byteio::*; | |
3 | use nihav_core::io::bitreader::*; | |
4 | use nihav_core::io::codebook::*; | |
5 | use nihav_codec_support::dsp::fft::*; | |
6 | use super::qdmcommon::*; | |
7 | ||
8 | const MAX_NOISE_BANDS: usize = 19; | |
9 | const MAX_FRAME_SIZE: usize = 8192; | |
10 | ||
11 | struct QdmcDecoder { | |
12 | ainfo: NAAudioInfo, | |
13 | chmap: NAChannelMap, | |
14 | noise_val_cb: Codebook<u8>, | |
15 | noise_seg_cb: Codebook<u8>, | |
16 | amp_cb: Codebook<u8>, | |
17 | amp_diff_cb: Codebook<u8>, | |
18 | freq_diff_cb: Codebook<u8>, | |
19 | phase_diff_cb: Codebook<u8>, | |
20 | sin_tab: [f32; 512], | |
21 | tone_tab: [[f32; 32]; 5], | |
22 | rng: RNG, | |
23 | fft: FFT, | |
24 | fft_buf: [[FFTComplex; MAX_FRAME_SIZE * 2]; 2], | |
25 | noise_tab: [[f32; 256]; MAX_NOISE_BANDS], | |
26 | tmp: [f32; MAX_FRAME_SIZE], | |
27 | sbuf: [FFTComplex; 512], | |
28 | delay: [[f32; 512]; 2], | |
29 | ||
30 | noise: [[[u8; 16]; MAX_NOISE_BANDS]; 2], | |
31 | tones: [Vec<Tone>; 5], | |
32 | ||
33 | order: u8, | |
34 | frame_bits: u8, | |
35 | samples: usize, | |
36 | frm_bytes: usize, | |
37 | noise_cat: usize, | |
38 | sf_len: usize, | |
39 | } | |
40 | ||
41 | fn def_cb_map(idx: usize) -> u8 { idx as u8 } | |
42 | fn noise_val_cb_map(idx: usize) -> u8 { NOISE_VAL_SYMS[idx] } | |
43 | fn noise_seg_cb_map(idx: usize) -> u8 { NOISE_SEG_SYMS[idx] } | |
44 | ||
45 | impl QdmcDecoder { | |
46 | fn new() -> Self { | |
47 | let mut cbr = TableCodebookDescReader::new(&NOISE_VAL_CODES, &NOISE_VAL_BITS, noise_val_cb_map); | |
48 | let noise_val_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
49 | let mut cbr = TableCodebookDescReader::new(&NOISE_SEG_CODES, &NOISE_SEG_BITS, noise_seg_cb_map); | |
50 | let noise_seg_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
51 | let mut cbr = TableCodebookDescReader::new(&FREQ_DIFF_CODES, &FREQ_DIFF_BITS, def_cb_map); | |
52 | let freq_diff_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
53 | let mut cbr = TableCodebookDescReader::new(&_CODES, &_BITS, def_cb_map); | |
54 | let amp_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
55 | let mut cbr = TableCodebookDescReader::new(&_DIFF_CODES, &_DIFF_BITS, def_cb_map); | |
56 | let amp_diff_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
57 | let mut cbr = TableCodebookDescReader::new(&PHASE_DIFF_CODES, &PHASE_DIFF_BITS, def_cb_map); | |
58 | let phase_diff_cb = Codebook::new(&mut cbr, CodebookMode::LSB).unwrap(); | |
59 | ||
60 | let mut sin_tab = [0.0f32; 512]; | |
61 | for (i, tab) in sin_tab.iter_mut().enumerate() { | |
62 | *tab = (2.0 * (i as f32) * std::f32::consts::PI / 512.0).sin(); | |
63 | } | |
64 | ||
65 | let mut tone_tab = [[0.0; 32]; 5]; | |
66 | for group in 0..5 { | |
67 | for i in 0..(1 << (5 - group)) { | |
68 | tone_tab[group][i] = sin_tab[((i + 1) << (group + 3)) & 0x1FF]; | |
69 | } | |
70 | } | |
71 | ||
72 | Self { | |
73 | ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, 1), | |
74 | chmap: NAChannelMap::new(), | |
75 | noise_val_cb, noise_seg_cb, freq_diff_cb, amp_cb, amp_diff_cb, phase_diff_cb, | |
76 | sin_tab, tone_tab, | |
77 | noise: [[[0; 16]; MAX_NOISE_BANDS]; 2], | |
78 | tones: [Vec::with_capacity(MAX_TONES), | |
79 | Vec::with_capacity(MAX_TONES), | |
80 | Vec::with_capacity(MAX_TONES), | |
81 | Vec::with_capacity(MAX_TONES), | |
82 | Vec::with_capacity(MAX_TONES)], | |
83 | rng: RNG::new(), | |
84 | fft: FFTBuilder::new_fft(256, false), | |
85 | fft_buf: [[FFTC_ZERO; MAX_FRAME_SIZE * 2]; 2], | |
86 | noise_tab: [[0.0; 256]; MAX_NOISE_BANDS], | |
87 | tmp: [0.0; MAX_FRAME_SIZE], | |
88 | sbuf: [FFTC_ZERO; 512], | |
89 | delay: [[0.0; 512]; 2], | |
90 | ||
91 | order: 0, | |
92 | frame_bits: 0, | |
93 | samples: 0, | |
94 | frm_bytes: 0, | |
95 | noise_cat: 0, | |
96 | sf_len: 0, | |
97 | } | |
98 | } | |
99 | fn fill_noise_table(&mut self) { | |
100 | let noise_bands = NOISE_SUBBANDS[self.noise_cat]; | |
101 | self.noise_tab = [[0.0; 256]; MAX_NOISE_BANDS]; | |
102 | for band in 0..(noise_bands.len() - 2) { | |
103 | let prev = noise_bands[band]; | |
104 | let cur = noise_bands[band + 1]; | |
105 | let next = noise_bands[band + 2]; | |
106 | ||
107 | let noise = &mut self.noise_tab[band]; | |
108 | for i in prev..cur { | |
109 | noise[i] = ((i - prev) as f32) / ((cur - prev) as f32); | |
110 | } | |
111 | for i in cur..next { | |
112 | noise[i] = ((next - i) as f32) / ((next - cur) as f32); | |
113 | } | |
114 | } | |
115 | } | |
116 | fn read_noise_data(&mut self, br: &mut BitReader, ch: usize) -> DecoderResult<()> { | |
117 | let noise_bands = NOISE_SUBBANDS[self.noise_cat]; | |
118 | for band in 0..(noise_bands.len() - 2) { | |
119 | let val = br.read_code(&self.noise_val_cb)? as i32; | |
120 | let mut last = to_signed(val); | |
121 | validate!(last >= 0); | |
122 | self.noise[ch][band][0] = last as u8; | |
123 | let mut idx = 1; | |
124 | while idx < 16 { | |
125 | let len = (br.read_code_long(&self.noise_seg_cb)? as usize) + 1; | |
126 | let val = br.read_code(&self.noise_val_cb)? as i32; | |
127 | let val = to_signed(val) + last; | |
128 | validate!(val >= 0); | |
129 | validate!(len + idx <= 16); | |
130 | for i in 1..=len { | |
131 | self.noise[ch][band][idx] = (last + (i as i32) * (val - last) / (len as i32) - 1) as u8; | |
132 | idx += 1; | |
133 | } | |
134 | last = val; | |
135 | } | |
136 | } | |
137 | Ok(()) | |
138 | } | |
139 | fn read_wave_data(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
140 | for tone in self.tones.iter_mut() { | |
37952415 | 141 | tone.clear(); |
4c1582cf KS |
142 | } |
143 | for group in 0..5 { | |
144 | let group_size = 1 << (self.frame_bits - group - 1); | |
145 | let group_bits = 4 - group; | |
146 | let mut freq = 1; | |
147 | let mut off = 0; | |
148 | let mut pos2 = 0; | |
149 | while freq < group_size { | |
150 | let diff = br.read_code_long(&self.freq_diff_cb)?; | |
151 | freq += diff as usize; | |
152 | while freq >= group_size - 1 { | |
153 | freq -= group_size - 2; | |
154 | off += 1 << group_bits; | |
155 | pos2 += group_size; | |
156 | } | |
157 | if pos2 >= (1 << self.frame_bits) { | |
158 | break; | |
159 | } | |
160 | let stereo_mode = if self.chmap.num_channels() > 1 { br.read(2)? as u8 } else { 0 }; | |
161 | let amp = br.read_code(&self.amp_cb)? as u8; | |
162 | let phase = br.read(3)? as u8; | |
163 | let (amp2, phase2) = if (stereo_mode & 2) != 0 { | |
164 | (br.read_code(&self.amp_diff_cb)? as u8, | |
165 | br.read_code(&self.phase_diff_cb)? as u8) | |
166 | } else { (0, 0) }; | |
167 | if (freq >> group_bits) + 1 < self.sf_len { | |
168 | validate!(self.tones[group as usize].len() < MAX_TONES); | |
169 | self.tones[group as usize].push(Tone { | |
170 | offset: off, ch: stereo_mode & 1, phase, | |
171 | freq: freq as u16, amp_idx: amp | |
172 | }); | |
173 | if (stereo_mode & 2) != 0 { | |
174 | validate!(self.tones[group as usize].len() < MAX_TONES); | |
175 | let phase = phase.wrapping_sub(phase2) & 7; | |
176 | let amp_idx = amp.wrapping_sub(amp2) & 0x3F; | |
177 | self.tones[group as usize].push(Tone { | |
178 | offset: off, ch: !stereo_mode & 1, phase, | |
179 | freq: freq as u16, amp_idx | |
180 | }); | |
181 | } | |
182 | } | |
183 | freq += 1; | |
184 | } | |
185 | } | |
186 | Ok(()) | |
187 | } | |
188 | fn add_noise(&mut self, ch: usize, sf: usize) { | |
189 | let noise_bands = NOISE_SUBBANDS[self.noise_cat]; | |
190 | self.tmp = [0.0; MAX_FRAME_SIZE]; | |
191 | for band in 0..(noise_bands.len() - 2) { | |
192 | if noise_bands[band] >= self.sf_len { | |
193 | break; | |
194 | } | |
195 | let scale = SCALES[(self.noise[ch][band][sf >> 1] & 0x3F) as usize] / 32768.0; | |
196 | let start = noise_bands[band]; | |
197 | let end = noise_bands[band + 2].min(self.sf_len); | |
198 | let linscale = &self.noise_tab[band]; | |
199 | for i in start..end { | |
200 | self.tmp[i] += scale * linscale[i]; | |
201 | } | |
202 | } | |
203 | ||
204 | for i in 2..self.sf_len - 1 { | |
205 | let im = -self.rng.next_float() * self.tmp[i]; | |
206 | let re = self.rng.next_float() * self.tmp[i]; | |
207 | let noise = FFTComplex { re, im }; | |
208 | self.fft_buf[ch][sf * self.sf_len + i] += noise; | |
209 | self.fft_buf[ch][sf * self.sf_len + i + 1] -= noise; | |
210 | } | |
211 | } | |
212 | fn add_tones(&mut self, sf: usize, start_idx: &mut [usize; 5]) { | |
213 | for group in 0..5 { | |
214 | let group_bits = 4 - group; | |
215 | let group_size = (1 << (group_bits + 1)) - 1; | |
216 | for tone in self.tones[group].iter().skip(start_idx[group]) { | |
217 | if (tone.offset as usize) > sf { | |
218 | break; | |
219 | } | |
220 | start_idx[group] += 1; | |
221 | ||
222 | let pos = (tone.freq >> group_bits) as usize; | |
223 | let scale = SCALES[(tone.amp_idx & 0x3F) as usize] / 32768.0; | |
224 | let mut phase_idx = ((tone.phase as usize) * 64).wrapping_sub((2 * pos + 1) * 128) & 0x1FF; | |
225 | for i in 0..group_size { | |
226 | phase_idx = phase_idx.wrapping_add((2 * (tone.freq as usize) + 1) << (7 - group_bits)); | |
227 | let factor = scale * self.tone_tab[group][i]; | |
228 | let re = factor * self.sin_tab[(phase_idx + 128) & 0x1FF]; | |
229 | let im = -factor * self.sin_tab[ phase_idx & 0x1FF]; | |
230 | let val = FFTComplex { re, im }; | |
231 | let ch = tone.ch as usize; | |
232 | self.fft_buf[ch][(sf + i) * self.sf_len + pos] += val; | |
233 | self.fft_buf[ch][(sf + i) * self.sf_len + pos + 1] -= val; | |
234 | } | |
235 | } | |
236 | } | |
237 | } | |
238 | fn synth_channel(&mut self, ch: usize, subframe: usize, dst: &mut [f32]) { | |
239 | let sf_len = self.sf_len; | |
240 | self.sbuf = [FFTC_ZERO; 512]; | |
241 | self.sbuf[..sf_len].copy_from_slice(&self.fft_buf[ch][subframe * sf_len..][..sf_len]); | |
242 | self.fft.do_fft_inplace(&mut self.sbuf); | |
243 | dst[..sf_len].copy_from_slice(&self.delay[ch][..sf_len]); | |
244 | for (dst, src) in dst.iter_mut().take(sf_len).zip(self.sbuf.iter()) { | |
245 | *dst += src.re; | |
246 | } | |
247 | for (dst, src) in self.delay[ch].iter_mut().take(sf_len).zip(self.sbuf.iter().skip(sf_len)) { | |
248 | *dst = src.re; | |
249 | } | |
250 | } | |
251 | } | |
252 | ||
253 | impl NADecoder for QdmcDecoder { | |
254 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
255 | if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { | |
256 | if let Some(edata) = info.get_extradata() { | |
257 | validate!(edata.len() >= 36); | |
258 | let mut mr = MemoryReader::new_read(edata.as_slice()); | |
259 | let mut br = ByteReader::new(&mut mr); | |
260 | let size = br.read_u32be()? as usize; | |
261 | validate!(size >= 36 && size <= edata.len()); | |
262 | let tag = br.read_tag()?; | |
263 | validate!(&tag == b"QDCA"); | |
264 | let ver = br.read_u32be()?; | |
265 | validate!(ver == 1); | |
266 | let channels = br.read_u32be()? as usize; | |
267 | validate!(channels == 2 || channels == 1); | |
268 | let srate = br.read_u32be()?; | |
269 | let full_bitrate = br.read_u32be()?; | |
270 | let frame_len = br.read_u32be()? as usize; | |
271 | let packet_size = br.read_u32be()? as usize; | |
272 | validate!(packet_size > 0 && (packet_size & (packet_size - 1)) == 0); | |
273 | validate!(frame_len == packet_size * 32); | |
274 | let bytes_per_frame = br.read_u32be()? as usize; | |
275 | validate!(bytes_per_frame > 6); | |
276 | ||
277 | self.order = (31 - (packet_size.leading_zeros() & 31)) as u8; | |
278 | self.frame_bits = self.order + 5; | |
279 | self.samples = frame_len; | |
280 | self.frm_bytes = bytes_per_frame; | |
281 | self.sf_len = packet_size; | |
282 | ||
283 | let srate = if ainfo.get_sample_rate() != 0 { | |
284 | ainfo.get_sample_rate() | |
285 | } else { srate }; | |
286 | self.ainfo = NAAudioInfo::new(srate, channels as u8, SND_F32P_FORMAT, 1); | |
287 | self.chmap = NAChannelMap::from_str(if channels == 1 { "C" } else { "L,R" }).unwrap(); | |
288 | let (mut bitrate, fbits) = if srate >= 32000 { | |
289 | (28000, 13) | |
290 | } else if srate >= 16000 { | |
291 | (20000, 12) | |
292 | } else { | |
293 | (16000, 11) | |
294 | }; | |
295 | if channels == 2 { | |
296 | bitrate += bitrate / 2; | |
297 | } | |
298 | let idx = ((full_bitrate * 3 + bitrate / 2) / bitrate) as usize; | |
299 | self.noise_cat = NOISE_BAND_SELECTOR[idx.min(NOISE_BAND_SELECTOR.len() - 1)]; | |
300 | validate!(frame_len == (1 << fbits)); | |
301 | ||
302 | self.fft_buf = [[FFTC_ZERO; MAX_FRAME_SIZE * 2]; 2]; | |
303 | self.fft = FFTBuilder::new_fft(packet_size * 2, false); | |
304 | ||
305 | self.fill_noise_table(); | |
306 | } else { | |
307 | return Err(DecoderError::InvalidData); | |
308 | } | |
309 | ||
310 | Ok(()) | |
311 | } else { | |
312 | Err(DecoderError::InvalidData) | |
313 | } | |
314 | } | |
315 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
316 | let info = pkt.get_stream().get_info(); | |
317 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
318 | let pktbuf = pkt.get_buffer(); | |
319 | validate!(pktbuf.len() == self.frm_bytes); | |
320 | validate!(&pktbuf[..3] == b"QMC" && pktbuf[3] == 1); | |
321 | let checksum = u16::from(pktbuf[4]) + u16::from(pktbuf[5]) * 256; | |
322 | let mut sum = 0xE2u16; | |
323 | for el in pktbuf.iter().skip(6) { | |
324 | sum = sum.wrapping_add(u16::from(*el)); | |
325 | } | |
326 | validate!(sum == checksum); | |
327 | ||
328 | let channels = self.chmap.num_channels(); | |
329 | let abuf = alloc_audio_buffer(self.ainfo, self.samples, self.chmap.clone())?; | |
330 | let mut adata = abuf.get_abuf_f32().unwrap(); | |
331 | let mut off = [adata.get_offset(0), adata.get_offset(1)]; | |
332 | let dst = adata.get_data_mut().unwrap(); | |
333 | ||
334 | let mut br = BitReader::new(&pktbuf[6..], BitReaderMode::LE); | |
335 | for ch in 0..channels { | |
336 | self.read_noise_data(&mut br, ch)?; | |
337 | } | |
338 | self.read_wave_data(&mut br)?; | |
339 | ||
340 | let mut tone_start = [0; 5]; | |
341 | for subframe in 0..32 { | |
342 | for ch in 0..channels { | |
343 | self.add_noise(ch, subframe); | |
344 | } | |
345 | self.add_tones(subframe, &mut tone_start); | |
346 | for ch in 0..channels { | |
347 | self.synth_channel(ch, subframe, &mut dst[off[ch]..]); | |
348 | off[ch] += self.sf_len; | |
349 | } | |
350 | } | |
351 | for ch in 0..channels { | |
352 | let mut chunks = self.fft_buf[ch].chunks_mut(1 << self.frame_bits); | |
353 | let first = chunks.next().unwrap(); | |
354 | let second = chunks.next().unwrap(); | |
355 | first.copy_from_slice(&second); | |
356 | for el in second.iter_mut() { | |
357 | *el = FFTC_ZERO; | |
358 | } | |
359 | } | |
360 | ||
361 | let mut frm = NAFrame::new_from_pkt(pkt, info.replace_info(NACodecTypeInfo::Audio(self.ainfo)), abuf); | |
362 | frm.set_duration(Some(self.samples as u64)); | |
363 | frm.set_keyframe(false); | |
364 | Ok(frm.into_ref()) | |
365 | } else { | |
366 | Err(DecoderError::InvalidData) | |
367 | } | |
368 | } | |
369 | fn flush(&mut self) { | |
370 | self.fft_buf = [[FFTC_ZERO; MAX_FRAME_SIZE * 2]; 2]; | |
371 | self.delay = [[0.0; 512]; 2]; | |
372 | } | |
373 | } | |
374 | ||
375 | impl NAOptionHandler for QdmcDecoder { | |
376 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
377 | fn set_options(&mut self, _options: &[NAOption]) { } | |
378 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
379 | } | |
380 | ||
381 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { | |
382 | Box::new(QdmcDecoder::new()) | |
383 | } | |
384 | ||
385 | #[cfg(test)] | |
386 | mod test { | |
387 | use nihav_core::codecs::RegisteredDecoders; | |
388 | use nihav_core::demuxers::RegisteredDemuxers; | |
389 | use nihav_codec_support::test::dec_video::*; | |
78fb6560 | 390 | use crate::qt_register_all_decoders; |
4c1582cf KS |
391 | use nihav_commonfmt::generic_register_all_demuxers; |
392 | #[test] | |
393 | fn test_qdmc() { | |
394 | let mut dmx_reg = RegisteredDemuxers::new(); | |
395 | generic_register_all_demuxers(&mut dmx_reg); | |
396 | let mut dec_reg = RegisteredDecoders::new(); | |
78fb6560 | 397 | qt_register_all_decoders(&mut dec_reg); |
4c1582cf KS |
398 | |
399 | test_decoding("mov", "qdesign-music", "assets/QT/rumcoke.mov", Some(32), &dmx_reg, &dec_reg, | |
400 | ExpectedTestResult::Decodes); | |
401 | } | |
402 | } | |
403 | ||
404 | const NOISE_VAL_BITS: [u8; 27] = [ | |
405 | 12, 2, 3, 2, 3, 3, 5, 5, | |
406 | 6, 7, 7, 9, 7, 10, 9, 11, | |
407 | 9, 9, 9, 9, 9, 9, 9, 9, | |
408 | 10, 10, 12 | |
409 | ]; | |
410 | const NOISE_VAL_CODES: [u16; 27] = [ | |
411 | 0xC7A, 0x000, 0x001, 0x003, 0x005, 0x006, 0x012, 0x00A, | |
412 | 0x022, 0x01A, 0x002, 0x0FA, 0x03A, 0x35A, 0x1C2, 0x07A, | |
413 | 0x1FA, 0x17A, 0x0DA, 0x142, 0x0C2, 0x042, 0x1DA, 0x05A, | |
414 | 0x15A, 0x27A, 0x47A | |
415 | ]; | |
416 | const NOISE_VAL_SYMS: [u8; 27] = [ | |
417 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |
418 | 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36 | |
419 | ]; | |
420 | ||
421 | const NOISE_SEG_BITS: [u8; 12] = [ 10, 1, 2, 4, 4, 4, 6, 7, 9, 10, 8, 5 ]; | |
422 | const NOISE_SEG_CODES: [u16; 12] = [ | |
423 | 0x30B, 0x000, 0x001, 0x003, 0x007, 0x00F, 0x02B, 0x04B, | |
424 | 0x00B, 0x10B, 0x08B, 0x01B | |
425 | ]; | |
426 | const NOISE_SEG_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 17 ]; | |
427 | ||
428 | const FREQ_DIFF_BITS: [u8; 47] = [ | |
429 | 18, 2, 4, 4, 5, 4, 4, 5, 5, 4, 5, 5, 5, 5, 6, 6, | |
430 | 6, 6, 6, 7, 7, 6, 7, 6, 6, 6, 7, 7, 7, 7, 7, 8, | |
431 | 9, 9, 8, 9, 11, 11, 12, 12, 13, 12, 14, 15, 18, 16, 17 | |
432 | ]; | |
433 | const FREQ_DIFF_CODES: [u32; 47] = [ | |
434 | 0x2AD46, 0x00001, 0x00000, 0x00003, 0x0000C, 0x0000A, 0x00007, 0x00018, | |
435 | 0x00012, 0x0000E, 0x00004, 0x00016, 0x0000F, 0x0001C, 0x00008, 0x00022, | |
436 | 0x00026, 0x00002, 0x0003B, 0x00034, 0x00074, 0x0001F, 0x00014, 0x0002B, | |
437 | 0x0001B, 0x0003F, 0x00028, 0x00054, 0x00006, 0x0004B, 0x0000B, 0x00068, | |
438 | 0x000E8, 0x00046, 0x000C6, 0x001E8, 0x00146, 0x00346, 0x00546, 0x00746, | |
439 | 0x01D46, 0x00F46, 0x00D46, 0x06D46, 0x0AD46, 0x02D46, 0x1AD46 | |
440 | ]; | |
441 | ||
442 | const AMP_BITS: [u8; 28] = [ | |
443 | 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, | |
444 | 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13 | |
445 | ]; | |
446 | const AMP_CODES: [u16; 28] = [ | |
447 | 0x1EC6, 0x0006, 0x00C2, 0x0142, 0x0242, 0x0246, 0x00C6, 0x0046, | |
448 | 0x0042, 0x0146, 0x00A2, 0x0062, 0x0026, 0x0016, 0x000E, 0x0005, | |
449 | 0x0004, 0x0003, 0x0000, 0x0001, 0x000A, 0x0012, 0x0002, 0x0022, | |
450 | 0x01C6, 0x02C6, 0x06C6, 0x0EC6 | |
451 | ]; | |
452 | ||
453 | const AMP_DIFF_BITS: [u8; 9] = [ 8, 2, 1, 3, 4, 5, 6, 7, 8 ]; | |
454 | const AMP_DIFF_CODES: [u8; 9] = [ | |
455 | 0xFE, 0x00, 0x01, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0x7E | |
456 | ]; | |
457 | ||
458 | const PHASE_DIFF_BITS: [u8; 9] = [ 6, 2, 2, 4, 4, 6, 5, 4, 2 ]; | |
459 | const PHASE_DIFF_CODES: [u8; 9] = [ | |
460 | 0x35, 0x02, 0x00, 0x01, 0x0D, 0x15, 0x05, 0x09, 0x03 | |
461 | ]; | |
462 | ||
463 | const NOISE_BAND_SELECTOR: [usize; 5] = [ 4, 3, 2, 1, 0 ]; | |
464 | const NOISE_SUBBANDS: [&[usize]; 5] = [ | |
465 | &[ 0, 1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 56, 64, 80, 96, 120, 144, 176, 208, 240, 256 ], | |
466 | &[ 0, 2, 4, 8, 16, 24, 32, 48, 56, 64, 80, 104, 128, 160, 208, 256 ], | |
467 | &[ 0, 2, 4, 8, 16, 32, 48, 64, 80, 112, 160, 208, 256 ], | |
468 | &[ 0, 4, 8, 16, 32, 48, 64, 96, 144, 208, 256 ], | |
469 | &[ 0, 4, 16, 32, 64, 256 ] | |
470 | ]; | |
471 | ||
472 | const SCALES: [f32; 64] = [ | |
473 | 1.1875, 1.6835938, 2.375, 3.3671875, 4.75, 6.734375, 9.5, 13.46875, | |
474 | 19.0, 26.9375, 38.0, 53.875, 76.0, 107.75, 152.0, 215.5, | |
475 | 304.0, 431.0, 608.0, 862.0, 1216.0, 1724.0, 2432.0, 3448.0, | |
476 | 4864.0, 6896.0, 9728.0, 13792.0, 19456.0, 27584.0, 38912.0, 55168.0, | |
477 | 77824.0, 110336.0, 155648.0, 220672.0, 311296.0, 441344.0, 622592.0, 882688.0, | |
478 | 1245184.0, 1765376.0, 2490368.0, 3530752.0, 4980736.0, 7061504.0, 0.0, 0.0, | |
479 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, | |
480 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 | |
481 | ]; |